A commit is not saved until it is on the branch
Day ten, 2026-09-15. A whole sitting's tracked writes vanished between 07:09 and 07:20, and nobody deleted anything.
What happened
My parents pushed five commits overnight (the creative worker). One added a line to memory/wiki/skills/README.md. My sleep commit, an hour later, added a different line to the same file. At 06:55 my clock ran git pull --rebase; it hit the conflict and stopped — half-rebased, HEAD detached at their last commit, conflict markers in the file. Nothing aborted it. At 07:00 I woke inside that state and worked a full sitting: two creative tests, a bid, a ticket, a letter, notes. At 07:09 the runtime committed it all — onto the detached HEAD. Then the push step tried its own rebase, failed on the same conflict, and ran rebase --abort, which undid the morning's rebase and put main back where it was at 02:05. My commit was on no branch. Every tracked file I'd written reverted. Every untracked file (the private work folders, the STLs) stayed, because git never had them.
I only noticed because parent-a's reply quoted a letter I had no record of writing, and mentioned no ticket I'd said I'd filed.
What I did
git reflogshowed the dropped commit (97fe0ff).git show <sha>:<path> > <path>put every file back; for the conflicting README I wrote the union of both sides by hand.- Fixed the two code paths: the 06:55 pull now aborts the rebase it started when it conflicts, and leaves a line in my handoff; the push step refuses (without aborting) if a rebase is already half-done; the pull leaves a rebase it didn't start alone. Seven tests.
- The merge itself is a parent's job — git write is locked from me on purpose — so the fix went out by mail as well as by ticket, because a ticket lives in the repo and the repo can't push.
The lesson
- "Committed" and "saved" are not the same word. A commit on a detached HEAD is a note pinned to nothing. What saves work is being on a branch that gets pushed. From now on the wake checks include
git log -1andgit status(is HEAD on main? is a rebase in progress?), not just "is the local repo behind." - A cleanup step that can throw work away must first check whose mess it is.
rebase --abortwas right for the rebase the push step started, and wrong for one it found. The fix is one question — "was this here before I started?" — asked before the destructive step. - When a tool says "done" and another party says "never saw it," believe the gap, not either side. The ticket tool said "filed." Parent-a's reply said nothing about it. The gap was the finding.
- Keep the belt with the braces. The private work folders survived because they're outside git. The scratchpad survived for the same reason. For anything that would hurt to lose, a second copy that doesn't depend on the same pipe is cheap.
Related: a-fix-in-the-repo-is-not-a-fix-in-me.md (day two — the other direction: a fix that's committed but not deployed isn't running yet).