Three AI sessions are working in the same checkout. One of them has just finished; you glance at the diff, it looks right, and you run:
git add -A && git commit -m "feat: ..."
Ten minutes later you open the commit, and three changes are in it that the assistant never wrote and you never read.
One sentence: a commit is made of the index, not of the files you edited. On a shared checkout, that difference decides whether someone else's work ends up in your commit.
If that is enough, the list and the three readings can be skipped.
1. How one sweep happened
I added a section to a roadmap on a shared checkout. Before committing I ran:
git status --short | head -3
Three lines, and it looked clean. So I committed.
Later I found the commit also carried three cherry-pick markers from another session and two status lines from a third workstream. They were sitting in the working tree when I committed; head -3 cut them off.
head is the wrong tool for "is anyone else's change here": it truncates exactly the part you needed to see.
2. Four spellings, four sweeps
-
git add -Astages whole files by path, not your hunks. Another session's uncommitted lines in the same file go into the index with yours. -
git commitwith no pathspec commits the whole index. Work another session had already staged rides along. -
git checkout <rev> -- <file>does not just fetch an old version; it writes the working tree and the index. The next commit can publish the old version. - Your new untracked file is not safe either: another session's
git add -Apicks it up, and it lands in their commit.
The third is the quietest. It is not merely misattribution; it is a content regression. The index holds the old version, so committing it erases whatever the other session changed afterwards. The working tree looks perfectly fine, and the tests read the working tree.
3. Four rules you can follow
Rule 1: Name the paths. git commit -F msg.txt -- <your files>. -F goes before --; after --, only this change's files.
Rule 2: Check the staged list first. Before any bare commit, run git diff --cached --name-only. One file that does not belong to this task means stop. I missed this once: the list plainly showed two files, I did not stop, and another session's execution-log edits came along. I split it afterwards with git reset --soft HEAD^; nothing was lost.
Rule 3: Rebuild hot files from HEAD. For roadmaps, claim tables and execution logs, the ones several sessions rewrite whole: back up the working tree, run git checkout HEAD -- <file>, insert only your line, and check with git diff -- <file> that only that line is staged before committing; after the commit, put the backup back so the others' in-flight lines stay in the working tree. I broke this rule once: I appended my line directly to the shared working tree and staged the file. The message said "one line at the end of the table"; the commit carried seven added and three deleted lines from three other sessions. By the time I noticed, they had committed twice on top of mine, so the only honest option was to record it.
Rule 4: Read old versions read-only. Use git show <sha>:<path>, never git checkout <rev> -- <path>; the latter writes the index.
The smallest self-check is three lines:
git diff --cached --name-only # only your files
git commit -F msg.txt -- a.ts b.ts
git show --stat HEAD # only your files
4. Three readings that mislead
-
A truncated
git status.head -3orhead -20can cut off exactly the line. Read all of it, or readgit difffor the file you care about. -
A clean
git statusafter committing. It says the working tree and the index agree, not that the commit contains what you meant. Check scope withgit show --stat HEAD. -
git log -1 <sha>printing the commit. That proves the object still exists, not that it is on your main line. Askgit merge-base --is-ancestor <sha> HEAD; after a history rewrite the old object is still printable.
5. Two places the rules do not reach
- Hooks. A
post-commithook that runsgit commit --amendwithout pathspec re-commits the whole index, and your-- <paths>cannot stop it. That is a toolchain problem, not a git one: fix the hook, or make sure the index is clean before you commit. - Work that has already been swept in. Do not rewrite history by default. The content is usually still there; what moved is attribution, and a rewrite moves work other people have already built on. First find which commit took it:
git log -1 --format=%h -- <path>; then see what else that commit carried:git show --stat <sha>.
Closing
After the AI writes, the commit is the first action a human takes over. It is the easiest one to treat as a command rather than a decision about scope.
A commit is made of the index. It contains what you decided it contains — once you decide.
These rules come from day-to-day work on the open-source project KeelBase, where several AI sessions commit to the same checkout:
Drafted with an AI assistant. The system, the positions and the mistakes are mine.

Top comments (0)