| 1 | #!/bin/bash
|
| 2 | # P4 finding: `oak switch B` SIGKILLed mid-materialization leaves a half-switched
|
| 3 | # worktree. The store still says branch A (sqlite3 metadata), status reports the
|
| 4 | # other branch's files as the user's uncommitted changes, and re-running
|
| 5 | # `oak switch B` refuses ("Working directory has uncommitted changes", exit 4)
|
| 6 | # with no recovery guidance. Committing now would record B's partial tree on A.
|
| 7 | # Usage: switch-kill.sh <oak> <outdir> [kill_after_seconds]
|
| 8 | set -u
|
| 9 | OAK=$1; OUT=$2; DELAY=${3:-0.4}
|
| 10 | rm -rf "$OUT"; mkdir -p "$OUT/home" "$OUT/a"
|
| 11 | export HOME=$OUT/home OAK_NO_UPDATE_CHECK=1 OAK_API_KEY=p4tok OAK_AUTHOR=p4
|
| 12 | unset OAK_REMOTE OAK_REPO OAK_TOKEN
|
| 13 | PORT=$(python3 -c 'import socket;s=socket.socket();s.bind(("127.0.0.1",0));print(s.getsockname()[1])')
|
| 14 | "$OAK" serve --dir "$OUT/srv" --port $PORT --token p4tok >"$OUT/serve.log" 2>&1 & SP=$!
|
| 15 | trap 'kill $SP 2>/dev/null' EXIT
|
| 16 | for i in $(seq 1 100); do curl -s -o /dev/null http://127.0.0.1:$PORT/api/capabilities && break; sleep 0.05; done
|
| 17 | cd "$OUT/a"; "$OAK" init . >/dev/null 2>&1
|
| 18 | for i in $(seq 0 199); do mkdir -p d$((i%10)); printf 'base %s\n%.0s' $i $(seq 1 40) > d$((i%10))/f$i.txt; done
|
| 19 | "$OAK" commit >/dev/null 2>&1; "$OAK" push --repo p4/r -r http://127.0.0.1:$PORT >/dev/null 2>&1 || { echo push failed; exit 2; }
|
| 20 | A=$(sqlite3 .oak/oak.db "select value from metadata where key='current_branch'")
|
| 21 | "$OAK" switch -c side >/dev/null 2>&1
|
| 22 | for i in $(seq 0 199); do printf 'side %s\n%.0s' $i $(seq 1 40) > d$((i%10))/f$i.txt; done
|
| 23 | "$OAK" commit >/dev/null 2>&1; "$OAK" switch "$A" >/dev/null 2>&1
|
| 24 | "$OAK" switch side >/dev/null 2>&1 & P=$!
|
| 25 | python3 -c "import time;time.sleep($DELAY)"; kill -9 $P 2>/dev/null && echo "killed switch after ${DELAY}s"; wait $P 2>/dev/null
|
| 26 | echo "store current_branch: $(sqlite3 .oak/oak.db "select value from metadata where key='current_branch'")"
|
| 27 | echo "files with side content: $(grep -l '^side' d*/f*.txt | wc -l | tr -d ' ') / 200"
|
| 28 | "$OAK" status --json | python3 -c 'import sys,json;d=json.load(sys.stdin);print("status branch:",d["branch"],"changes:",len(d["working_changes"]["changes"]))'
|
| 29 | "$OAK" switch side; echo "re-run switch exit=$?"
|