{"thread":{"id":"66124","subject":"BUG? git rebase -x \"git commit --amend …\" loses notes","startedAt":"2026-08-05T13:13:49Z","lastAt":"2026-08-06T12:01:22Z","messageCount":4,"participants":["D. Ben Knoble","Phillip Wood"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"549694","messageId":"CALnO6CDh6kbL5KH=Nt00ksZCaDbJAnjbepU_tyRTcbGekSyeMg@mail.gmail.com","threadId":"66124","inReplyTo":null,"subject":"BUG? git rebase -x \"git commit --amend …\" loses notes","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-08-05T13:13:37Z","receivedAt":"2026-08-05T13:13:49Z","isPatch":false,"body":"Sigh… I haven't minimized a reproduction case here yet, but maybe\nsomeone can tell me how I'm holding it wrong.\n\nI have a local branch with notes in refs/notes/benknoble/commits (in\nparticular, the tip commit has a note). I forgot to adjust my author\nemail before creating some of these commits, and I wanted to adjust it\nto match the mailmap patch I just sent out, so I ran\n\n    git rebase -x \"git commit --no-verify --no-edit --amend\n--author='$(git config get user.name) <$(git config get user.email)>'\"\n\nUpon checking (much) later, I discovered the note was missing! It had\nnot been rewritten. And yet:\n\n    git config get --all --regexp --show-names --show-scope notes | column -t\n    global  format.notes      true\n    global  notes.rewriteref  refs/notes/commits\n    local   core.notesref     refs/notes/benknoble/commits\n    local   notes.rewriteref  refs/notes/benknoble/commits\n    local   notes.displayref  refs/notes/origin/amlog\n\nSo I would have expected the notes to get rewritten?\n\n- Running \"git commit … --amend …\" (author change and all) rewrites the notes\n- Running \"git rebase -x echo\" rewrites the notes (well, it has\nnothing to do right now, so it doesn't modify anything; however, I'm\n99.9% convinced that when I did a plain rebase earlier today the notes\nwere preserved, just like they are all the time)\n\nIt's just the combination that loses them :/\n\n-- \nD. Ben Knoble\n"},{"id":"549696","messageId":"307abaeb-b033-4c55-8edf-1ea765199dce@gmail.com","threadId":"66124","inReplyTo":"CALnO6CDh6kbL5KH=Nt00ksZCaDbJAnjbepU_tyRTcbGekSyeMg@mail.gmail.com","subject":"Re: BUG? git rebase -x \"git commit --amend …\" loses notes","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-08-05T13:42:33Z","receivedAt":"2026-08-05T13:42:38Z","isPatch":false,"body":"Hi Ben\n\nOn 05/08/2026 14:13, D. Ben Knoble wrote:\n> Sigh… I haven't minimized a reproduction case here yet, but maybe\n> someone can tell me how I'm holding it wrong.\n> \n> I have a local branch with notes in refs/notes/benknoble/commits (in\n> particular, the tip commit has a note). I forgot to adjust my author\n> email before creating some of these commits, and I wanted to adjust it\n> to match the mailmap patch I just sent out, so I ran\n> \n>      git rebase -x \"git commit --no-verify --no-edit --amend\n> --author='$(git config get user.name) <$(git config get user.email)>'\"\n> \n> Upon checking (much) later, I discovered the note was missing! It had\n> not been rewritten. And yet:\n\nI suspect the note was rewritten to the un-amended commit (i.e. the \ncommit created by rebase before it ran the exec command). The way the \nnote writing works is that as rebase picks commits it remembers the new \nobject id of each commit and after all the commits have been rebased \npasses a list of \"old-oid new-oid\" pairs to \"git notes copy\". If a \ncommit gets amended by an exec command then we don't record the new \nobject id correctly. I have some old, half finished, patches that try to \nfix that by making \"git commit --amend\" update the file where rebase \nstores the list of rewritten commits. I think it worked for exec \ncommands that run \"git commit amend\", but the effort got bogged down \ntrying to improve the way we handle commits that are edited. I've just \npushed them to [1] if anyone is interested (though the commit messages \nare dreadful so I don't know how much help the patches will be).\n\nThanks\n\nPhillip\n\n[1] https://github.com/phillipwood/git/commits/wip/rebase-update-rewritten\n\n>      git config get --all --regexp --show-names --show-scope notes | column -t\n>      global  format.notes      true\n>      global  notes.rewriteref  refs/notes/commits\n>      local   core.notesref     refs/notes/benknoble/commits\n>      local   notes.rewriteref  refs/notes/benknoble/commits\n>      local   notes.displayref  refs/notes/origin/amlog\n> \n> So I would have expected the notes to get rewritten?\n> \n> - Running \"git commit … --amend …\" (author change and all) rewrites the notes\n> - Running \"git rebase -x echo\" rewrites the notes (well, it has\n> nothing to do right now, so it doesn't modify anything; however, I'm\n> 99.9% convinced that when I did a plain rebase earlier today the notes\n> were preserved, just like they are all the time)\n> \n> It's just the combination that loses them :/\n> \n\n"},{"id":"549745","messageId":"de96a0de-a0a3-4e3e-b44e-8991f8ae87d3@gmail.com","threadId":"66124","inReplyTo":"307abaeb-b033-4c55-8edf-1ea765199dce@gmail.com","subject":"Re: BUG? git rebase -x \"git commit --amend …\" loses notes","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-08-05T16:31:07Z","receivedAt":"2026-08-05T16:30:44Z","isPatch":false,"body":"On 05/08/2026 14:42, Phillip Wood wrote:\n> On 05/08/2026 14:13, D. Ben Knoble wrote:\n>> Sigh… I haven't minimized a reproduction case here yet, but maybe\n>> someone can tell me how I'm holding it wrong.\n>>\n>> I have a local branch with notes in refs/notes/benknoble/commits (in\n>> particular, the tip commit has a note). I forgot to adjust my author\n>> email before creating some of these commits, and I wanted to adjust it\n>> to match the mailmap patch I just sent out, so I ran\n>>\n>>      git rebase -x \"git commit --no-verify --no-edit --amend\n>> --author='$(git config get user.name) <$(git config get user.email)>'\"\n>>\n>> Upon checking (much) later, I discovered the note was missing! It had\n>> not been rewritten. And yet:\n> \n> I suspect the note was rewritten to the un-amended commit (i.e. the \n> commit created by rebase before it ran the exec command). The way the \n> note writing works is that as rebase picks commits it remembers the new \n> object id of each commit and after all the commits have been rebased \n> passes a list of \"old-oid new-oid\" pairs to \"git notes copy\". If a \n> commit gets amended by an exec command then we don't record the new \n> object id correctly. I have some old, half finished, patches that try to \n> fix that by making \"git commit --amend\" update the file where rebase \n> stores the list of rewritten commits. I think it worked for exec \n> commands that run \"git commit amend\", but the effort got bogged down \n> trying to improve the way we handle commits that are edited. I've just \n> pushed them to [1] if anyone is interested (though the commit messages \n> are dreadful so I don't know how much help the patches will be).\n\nAnother approach would be to copy the notes before we stop for an \"exec\" \nor \"edit\" command (the latter is complicated by the fact it might have \nconflicts) so that \"git commit --amend\" could just copy them to the \namended commit. If we did that we'd want to copy the notes in-process \nrather than forking \"git notes copy\" before each \"exec\" command.\n\nThanks\n\nPhillip\n\n> Thanks\n> \n> Phillip\n> \n> [1] https://github.com/phillipwood/git/commits/wip/rebase-update-rewritten\n> \n>>      git config get --all --regexp --show-names --show-scope notes | \n>> column -t\n>>      global  format.notes      true\n>>      global  notes.rewriteref  refs/notes/commits\n>>      local   core.notesref     refs/notes/benknoble/commits\n>>      local   notes.rewriteref  refs/notes/benknoble/commits\n>>      local   notes.displayref  refs/notes/origin/amlog\n>>\n>> So I would have expected the notes to get rewritten?\n>>\n>> - Running \"git commit … --amend …\" (author change and all) rewrites \n>> the notes\n>> - Running \"git rebase -x echo\" rewrites the notes (well, it has\n>> nothing to do right now, so it doesn't modify anything; however, I'm\n>> 99.9% convinced that when I did a plain rebase earlier today the notes\n>> were preserved, just like they are all the time)\n>>\n>> It's just the combination that loses them :/\n>>\n> \n\n"},{"id":"549850","messageId":"CALnO6CC82PCbYrrj4nGPSjs=+U5tsZo5XuLpO8DXtzPiNsJAUA@mail.gmail.com","threadId":"66124","inReplyTo":"de96a0de-a0a3-4e3e-b44e-8991f8ae87d3@gmail.com","subject":"Re: BUG? git rebase -x \"git commit --amend …\" loses notes","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-08-06T12:01:10Z","receivedAt":"2026-08-06T12:01:22Z","isPatch":false,"body":"On Wed, Aug 5, 2026 at 12:30 PM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>\n> On 05/08/2026 14:42, Phillip Wood wrote:\n> > On 05/08/2026 14:13, D. Ben Knoble wrote:\n> >> Sigh… I haven't minimized a reproduction case here yet, but maybe\n> >> someone can tell me how I'm holding it wrong.\n> >>\n> >> I have a local branch with notes in refs/notes/benknoble/commits (in\n> >> particular, the tip commit has a note). I forgot to adjust my author\n> >> email before creating some of these commits, and I wanted to adjust it\n> >> to match the mailmap patch I just sent out, so I ran\n> >>\n> >>      git rebase -x \"git commit --no-verify --no-edit --amend\n> >> --author='$(git config get user.name) <$(git config get user.email)>'\"\n> >>\n> >> Upon checking (much) later, I discovered the note was missing! It had\n> >> not been rewritten. And yet:\n> >\n> > I suspect the note was rewritten to the un-amended commit (i.e. the\n> > commit created by rebase before it ran the exec command). The way the\n> > note writing works is that as rebase picks commits it remembers the new\n> > object id of each commit and after all the commits have been rebased\n> > passes a list of \"old-oid new-oid\" pairs to \"git notes copy\". If a\n> > commit gets amended by an exec command then we don't record the new\n> > object id correctly.\n\nAh, thanks. That explains what went wrong.\n\n> > I have some old, half finished, patches that try to\n> > fix that by making \"git commit --amend\" update the file where rebase\n> > stores the list of rewritten commits. I think it worked for exec\n> > commands that run \"git commit amend\", but the effort got bogged down\n> > trying to improve the way we handle commits that are edited. I've just\n> > pushed them to [1] if anyone is interested (though the commit messages\n> > are dreadful so I don't know how much help the patches will be).\n>\n> Another approach would be to copy the notes before we stop for an \"exec\"\n> or \"edit\" command (the latter is complicated by the fact it might have\n> conflicts) so that \"git commit --amend\" could just copy them to the\n> amended commit. If we did that we'd want to copy the notes in-process\n> rather than forking \"git notes copy\" before each \"exec\" command.\n\nYeah. I wonder if we could give enough information to \"exec\" commands\nso they know what the old OID is, to let them decide what to do with\nit? That is, could we expose the old–new list rebase keeps around as a\nreadable artifact?\n\nThe other option that occurs to me is to have an easy way to feed\nold–new to \"git notes copy\" (or any other command) *post* rebase. I\ncan get at the mapping using git-range-diff, but I still have to\ncopy-paste or parse the output in a way that feels likely to be\nbrittle, I think.\n\n> > [1] https://github.com/phillipwood/git/commits/wip/rebase-update-rewritten\n\nI probably won't be taking a look anytime soon, but thanks!\n\n-- \nD. Ben Knoble\n"}]}