Repository navigation
Description
Description
Snapshot tracking can silently reuse an old tree when git add --all fails.
In the repro below, snapshot tracking first captures file.txt as v1. The file is then changed to v2, but adding a nested Git repo with no checked-out commit makes git add --all fail. A later write-tree still returns the old v1 tree hash. If OpenCode treats that as a valid current snapshot, a later restore can overwrite newer disk state with stale content.
This can make undo/redo unsafe because the snapshot hash returned after a failed add does not actually represent the current working tree.
lost a 2 days of work cause of it :(
Plugins
None
OpenCode version
Local dev / 1.14.48
Steps to reproduce
WORK=/tmp/oc-snapshot-repro
SNAP=/tmp/oc-snapshot-repro-snapshot
ERR=/tmp/oc-snapshot-add.err
rm -rf "$WORK" "$SNAP" "$ERR"
mkdir -p "$WORK" "$SNAP"
echo "== 1. Real repo starts at v1 =="
git -C "$WORK" init
printf 'v1\n' > "$WORK/file.txt"
git -C "$WORK" add file.txt
git -C "$WORK" -c user.email=[email protected] -c user.name=repro commit -m init
echo "== 2. Snapshot captures v1 =="
GIT_DIR="$SNAP" GIT_WORK_TREE="$WORK" git init
git --git-dir="$SNAP" --work-tree="$WORK" add --all --sparse -- file.txt
SNAP_V1=$(git --git-dir="$SNAP" --work-tree="$WORK" write-tree)
git --git-dir="$SNAP" show "$SNAP_V1:file.txt"
echo "== 3. Disk changes to v2 =="
printf 'v2\n' > "$WORK/file.txt"
cat "$WORK/file.txt"
echo "== 4. Add a nested git repo with no commit =="
mkdir "$WORK/nested-unborn"
git -C "$WORK/nested-unborn" init
printf 'nested\n' > "$WORK/nested-unborn/file.txt"
echo "== 5. Snapshot add fails =="
git --git-dir="$SNAP" --work-tree="$WORK" add --all --sparse -- . 2>"$ERR"
ADD_CODE=$?
echo "snapshot add exit code: $ADD_CODE"
cat "$ERR"
echo "== 6. write-tree still returns old snapshot =="
SNAP_SUPPOSED_V2=$(git --git-dir="$SNAP" --work-tree="$WORK" write-tree)
echo "SNAP_V1=$SNAP_V1"
echo "SNAP_SUPPOSED_V2=$SNAP_SUPPOSED_V2"
git --git-dir="$SNAP" show "$SNAP_SUPPOSED_V2:file.txt"
echo "== 7. Later disk changes to v3 =="
printf 'v3\n' > "$WORK/file.txt"
cat "$WORK/file.txt"
echo "== 8. Restore snapshot caller thinks is v2 =="
git --git-dir="$SNAP" --work-tree="$WORK" read-tree "$SNAP_SUPPOSED_V2"
git --git-dir="$SNAP" --work-tree="$WORK" checkout-index -a -f
cat "$WORK/file.txt"
Actual result:
git add fails, but write-tree returns the old v1 tree. Restoring that snapshot overwrites disk content back to v1.
Expected result:
OpenCode should not return/use a snapshot after snapshot staging fails. It should fail closed, surface a warning, and avoid recording undo/redo metadata for that response.
Screenshot and/or share link
Operating System
macOS
Terminal
WezTerm
Activity
github-actions commentedon Jul 11, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.