Quick conclusion
On September 20, 2026, I finished a GitHub sync that looked successful. The branches matched, the push had completed, and Git showed a clean working tree.
A later audit found 3,064 paths in the untracked-file tree of a stash. At that point, 2,991 of those paths were temporarily absent from the working tree. Git had not permanently deleted 3,064 files. The problem was that I had treated a clean status as evidence that the Vault was complete without checking the stash inventory.
The recovery audit later found all 3,064 paths present. It also confirmed matching hashes for 123 work files. The full browser-profile binary hash comparison was still incomplete as of September 27, 2026. That is why path recovery and complete content verification remain separate claims.
That distinction changed how I define “done” in an AI-assisted Git workflow. A successful command and a clean status are useful signals. They do not replace checking which files were moved, where they went, and what was verified after recovery.
What happened after the GitHub sync
In Part 1 of this series, I tested a path between a ChatGPT session, a private GitHub repository, and my local Obsidian Vault. The test worked, but local and remote commits later diverged. I used Git stash while trying to preserve the local state and reconcile the branches.
The sync work then appeared to finish normally. I committed visible local changes, merged the remote test commit, pushed, and checked that the local and remote branch tips matched. Git reported no current working-tree changes.
Later, I noticed that some work files were missing from the Vault. I checked the commits involved in the sync and found no tracked-file deletion commit or deletion diff in that history. The audit instead found paths stored in the stash’s untracked-file tree. They had not all been brought back into the working tree before I reported the sync as complete.
This was a completion-check failure. The workflow checked the visible changes and the branch state, but it did not check every path held by the stash.
What the 3,064 paths actually represented
The number 3,064 was the number of paths in the untracked-file tree of the stash I examined. It was not a count of files Git had permanently deleted.
| Group | Paths | State before recovery |
|---|---|---|
| Work files from another project | 123 | Temporarily absent from the working tree |
| Browser-profile entries | 2,867 | Temporarily absent from the working tree |
| One error-output file | 1 | Temporarily absent from the working tree |
| Other untracked files | 73 | Still present in the working tree and included in a later commit |
| Total | 3,064 | 2,991 temporarily absent; 73 still present |
The other 73 were still in the working tree. The categories also matter because “path present” and “file contents fully verified” are different results.
The audit found no Git deletion commit in the sync history. The missing paths had been preserved in the stash, but the sync process had not restored and inventoried all of them before the clean-status check.
What the recovery checks proved, and what they did not
After recovery, the audit found all 3,064 paths from that stash in the working tree. For the 123 work files, individual hash comparisons matched. The profile entries were restored and their paths were checked, but the full binary hash comparison was still incomplete in the research record through September 27, 2026.
That supports a specific statement: the recovery audit found no missing path among the 3,064 paths in that stash. It does not support the broader statement that every file’s contents were compared byte for byte. It also says nothing about files that had already been absent before the stash was created, or files that were never included in that stash.
A September 27 snapshot found no stashes. The checker therefore had no stash paths to inspect. This described the current state on that date, not a second audit of the original 3,064-path stash.
When reporting recovery, I now separate at least three questions:
- Does the expected path exist?
- Does the content hash match for the files that need that level of verification?
- Which files were in scope for the check?
If I only confirmed the first, I say that I confirmed path existence. I do not turn it into a claim about complete content integrity.
Why a clean Git status missed the gap
Git’s status documentation describes the relationship between the current commit, the index, and the working tree. It can also report untracked files that are present in the working tree. It does not inventory the contents of an older stash.
The stash documentation explains that git stash push -u includes untracked files and removes them from the working tree. The -a option also includes ignored files. Once files are stored in a stash, they are outside the current working-tree view that a normal status check reports.
In the stash from this incident, the untracked paths were stored in a third-parent tree. That is how I found the 3,064 paths in this particular Git object. The exact parent structure is evidence about this stash; readers should inspect their own stash rather than assume every stash has the same layout.
A clean status answered a narrow question: the current index and working tree had no reported changes relative to the current commit. It did not answer whether every expected Vault path was present or whether the stash had been fully restored.
A practical “done” check for AI-assisted Git work
Before moving between branches or syncing a shared repository, I use a small set of separate checks:
- Inventory the working tree. Record tracked and untracked changes, including individual untracked paths when the count matters. Review ignored data separately if it is part of the material you expect to preserve.
- Inventory stashes. Check the stash list and inspect the stash you are handling. When untracked files were included, confirm their paths are visible in the stash inspection.
- Compare before and after. Compare path lists and counts after restoration. For important work, compare content hashes too. A successful restore command is not a substitute for these checks.
- Keep the claims separate. Report working-tree status, commit completion, remote synchronization, path existence, and content-hash coverage as distinct states.
- Keep the recovery source. Do not drop a stash until the expected paths and important contents have been checked. Do not classify a cache or browser profile as disposable just from its name.
For the specific stash I investigated, I used the third-parent tree to list the untracked paths:
git ls-tree -r --name-only '<stash>^3'
That command reflects the structure of the object I examined. It is not a universal replacement for inspecting the stash format in your own repository. Git’s git stash show --name-status --include-untracked '<stash>' can also help show the files associated with a stash.
For me, “done” now means I can explain what was in scope, what returned, which contents were compared, and whether local and remote commits match. A clean status is one item in that report, not the entire completion contract.
What changed after the incident
A later follow-up added a read-only checker that compares paths stored in stashes with paths in the working tree, then connected it to a pre-commit check. The follow-up record reports four passing regression tests, the pre-commit connection, and a later push of those prevention changes.
That guard helps catch a stash-only path that has not returned to the working tree. It does not compare every file’s content. The research record, current through September 27, still listed the full browser-profile hash comparison and the policy for checking or retaining profile data as unresolved.
FAQ
Did Git delete 3,064 files?
No deletion commit was found in the sync history. The 3,064 paths were present in a stash’s untracked-file tree. Of those, 2,991 were temporarily absent from the working tree before recovery.
Does a clean Git status prove that my Vault is complete?
No. It reports the state of the current commit, index, and working tree. It does not inspect files held only in a stash or prove that every expected file exists.
Were all 3,064 file contents verified?
No. The recovery audit confirmed path existence for all 3,064 paths and matching hashes for the 123 work files. The September 27 research record still listed the full binary hash comparison for the browser-profile entries as incomplete.
Was the incident fully resolved?
The stored paths were recovered and the incident record classified recovery as resolved. Follow-up records show that the stash-path guard was implemented and pushed. As of September 27, the profile’s full binary hash comparison and handling contract were still unresolved.
Next steps
Part 1 tested whether a ChatGPT session could work with my Vault through GitHub. This follow-up looks at the less visible requirement: checking that files are accounted for after a Git operation, including files held in a stash.