Repository navigation
Conversation
|
I'm not sure if I understand the problem correctly, but it seems you care about the situation that history changes happen during the rebuilding, but then this PR doesn't seem to fix the issue that the history changes are lost, though it fixes the superficial inconsistency in the wskip? |
|
you're right. my explanation was sloppy. I think it's easier to show with a way to reproduce: You need:
these were always true for me when debugging the slow macos history load time, so i hit the bug frequently. now it's really hard to reproduce, but it's there. Steps to reproduce. Every block is one command: 1. setup sessiontmp=$(mktemp -d)
# 100 entries; entry 98 is an encoded multiline command, inside the last 50
for i in $(seq 100); do
if ((i == 98)); then printf "eval -- \$'echo multi\\\\necho line2'\n"; else printf 'echo cmd%d\n' "$i"; fi
done > "$tmp/histtest"
cat > "$tmp/rc" <<'EOF'
[[ $- == *i* ]] && source ~/project/ble.sh/out/ble.sh --attach=none
bleopt history_share=1
shopt -s histappend
PS1='A$ '
eval "$(declare -f ble/history:bash/resolve-multiline/.worker | sed '1s|.*|function ble/history:bash/resolve-multiline/.worker.orig|')"
function ble/history:bash/resolve-multiline/.worker { sleep 5; ble/history:bash/resolve-multiline/.worker.orig "$@"; }
[[ ! ${BLE_VERSION-} ]] || ble-attach
EOF
HISTFILE=$tmp/histtest HISTSIZE=50 HISTFILESIZE=100 bash --rcfile "$tmp/rc" -i2. In the sessionFirst within less than 5 seconds of opening the session: echo one # wait 5 secondsWait at least 5 seconds. Type nothing. A space-prefixed command or a repeat of the previous command makes option:s return early, and history -a then runs its "uncontrolled change" repair, which hides the bug. then one command each echo twoecho threetail -n 4 $HISTFILE; history | tail -n 5;Outcome on master. echo two is missing from HISTFILE. A$ tail -n 4 $HISTFILE; history | tail -n 5 ; 54/100%
echo cmd100
echo one # wait 5 seconds
echo three
tail -n 4 $HISTFILE; history | tail -n 5 ;
49 echo cmd100
50 echo one # wait 5 seconds
51 echo two
52 echo three
53 tail -n 4 $HISTFILE; history | tail -n 5Outcome with fix: A$ tail -n 4 $HISTFILE; history | tail -n 5 ; 54/100%
echo one # wait 5 seconds
echo two
echo three
tail -n 4 $HISTFILE; history | tail -n 5 ;
49 echo cmd100
50 echo one # wait 5 seconds
51 echo two
52 echo three
53 tail -n 4 $HISTFILE; history | tail -n 5 ;Why this helps: the rebuild replays Bash's list with the root cause is that ble.sh stores "written up to here" as an absolute number while the only operation that renumbers is this one rebuild, so re-deriving the number in .load is the minimal correct fix. structurally tracking unwritten entries as account everywhere in .write and .check-uncontrolled-change might be better, but is a much bigger change. |
And one more. this is a race.
ble.sh's multiline resolution rebuilds the bash history list (history -c and re-add), which renumbers it and can change the entry count, but the "written up to here" pointer (wskip/prevmax) isn't adjusted. The rebuild runs asynchronously and takes seconds on macOS, so it regularly finishes after the first command has been recorded, and the next history -a re-appends already written entries (here: the previous session's last entry and the first command). Keep the number of unwritten entries constant across the rebuild instead.