{"thread":{"id":"65919","subject":"Programmatically edit the git rebase sequence?","startedAt":"2026-07-03T12:10:03Z","lastAt":"2026-07-08T17:58:35Z","messageCount":6,"participants":["Matthias Beyer","Michal Suchánek","brian m. carlson","Matt Hunter","D. Ben Knoble","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"547075","messageId":"akei64goQf3nFhX4@hikari","threadId":"65919","inReplyTo":null,"subject":"Programmatically edit the git rebase sequence?","fromName":"Matthias Beyer","fromEmail":"mail@beyermatthias.de","sentAt":"2026-07-03T12:02:33Z","receivedAt":"2026-07-03T12:10:03Z","isPatch":false,"body":"Hi git people,\n\nin a recent conversation at work, the question of how to\nprogrammatically edit the git-rebase sequence came up.\n\nExample use case:\n\nI have a branch that touches a number of files, adds some files and\nremoves some files.\nWhen rebasing, I want to split all commits that touched a certain subset\nof files, for the clearity of the history.\n\nI look at the output of\n\n    git log master..mybranch --oneline --diff-filter=M -- \"./subdir/*.rs\"\n\nto find all commits in that subdir that only touched the files. All of\nthese commits are to be \"edit\"ed.\n\nNow I fire up `git rebase -i master` and manually(!) match the list from\nabove `git-log` call and find the respective commits to edit them.\n\nIs there a way I am not aware of to do that manual step programatically?\nSomething like\n\n    git rebase -i master --edit-commits=\"$(git log master..mybranch --diff-filter=M --format=\"%H\" -- \"./subdir/*.rs\")\"\n\nwould be convenient here, although I would understand if that is too\nmuch clutter for the already very heavy git CLI interface :-)\n\nMaybe I am just not aware of the obvious solution - I would be happy to\nlearn that there is already one!\n\nBest,\nMatthias\n"},{"id":"547076","messageId":"akeoaWAkrENbpi1G@kunlun.suse.cz","threadId":"65919","inReplyTo":"akei64goQf3nFhX4@hikari","subject":"Re: Programmatically edit the git rebase sequence?","fromName":"Michal Suchánek","fromEmail":"msuchanek@suse.de","sentAt":"2026-07-03T12:17:45Z","receivedAt":"2026-07-03T12:17:48Z","isPatch":false,"body":"On Fri, Jul 03, 2026 at 02:02:33PM +0200, Matthias Beyer wrote:\n> Hi git people,\n> \n> in a recent conversation at work, the question of how to\n> programmatically edit the git-rebase sequence came up.\n> \n> Example use case:\n> \n> I have a branch that touches a number of files, adds some files and\n> removes some files.\n> When rebasing, I want to split all commits that touched a certain subset\n> of files, for the clearity of the history.\n> \n> I look at the output of\n> \n>     git log master..mybranch --oneline --diff-filter=M -- \"./subdir/*.rs\"\n> \n> to find all commits in that subdir that only touched the files. All of\n> these commits are to be \"edit\"ed.\n> \n> Now I fire up `git rebase -i master` and manually(!) match the list from\n> above `git-log` call and find the respective commits to edit them.\n> \n> Is there a way I am not aware of to do that manual step programatically?\n> Something like\n> \n>     git rebase -i master --edit-commits=\"$(git log master..mybranch --diff-filter=M --format=\"%H\" -- \"./subdir/*.rs\")\"\n> \n> would be convenient here, although I would understand if that is too\n> much clutter for the already very heavy git CLI interface :-)\n> \n> Maybe I am just not aware of the obvious solution - I would be happy to\n> learn that there is already one!\n\nHello,\n\nyou could probably set a script as EDITOR (environment variable). Not\ngreat for one-off scripts I guess.\n\nThanks\n\nMichal\n"},{"id":"547093","messageId":"ake8OAIyK-ELs-fU@fruit.crustytoothpaste.net","threadId":"65919","inReplyTo":"akei64goQf3nFhX4@hikari","subject":"Re: Programmatically edit the git rebase sequence?","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2026-07-03T13:42:17Z","receivedAt":"2026-07-03T13:42:25Z","isPatch":false,"body":"On 2026-07-03 at 12:02:33, Matthias Beyer wrote:\n> Hi git people,\n> \n> in a recent conversation at work, the question of how to\n> programmatically edit the git-rebase sequence came up.\n> \n> Example use case:\n> \n> I have a branch that touches a number of files, adds some files and\n> removes some files.\n> When rebasing, I want to split all commits that touched a certain subset\n> of files, for the clearity of the history.\n> \n> I look at the output of\n> \n>     git log master..mybranch --oneline --diff-filter=M -- \"./subdir/*.rs\"\n> \n> to find all commits in that subdir that only touched the files. All of\n> these commits are to be \"edit\"ed.\n> \n> Now I fire up `git rebase -i master` and manually(!) match the list from\n> above `git-log` call and find the respective commits to edit them.\n> \n> Is there a way I am not aware of to do that manual step programatically?\n> Something like\n> \n>     git rebase -i master --edit-commits=\"$(git log master..mybranch --diff-filter=M --format=\"%H\" -- \"./subdir/*.rs\")\"\n> \n> would be convenient here, although I would understand if that is too\n> much clutter for the already very heavy git CLI interface :-)\n\nYes, such a thing exists.  You want `GIT_SEQUENCE_EDITOR`, which is an\n`EDITOR`-like command that edits the rebase list in place.  So tools\nlike `ed`, `ex`, `sed -i`, `perl -i`, or `ruby -i` would be useful here.\n\nSo you might want something like this (untested):\n\n    GIT_SEQUENCE_EDITOR=\"perl -pi -e 's/^pick ($(git log master..mybranch --diff-filter=M --format=\"%h\" -- \"./subdir/*.rs\" | paste -d '\\''|'\\'' -s -))/edit \\$1/'\" \\\n    git rebase -i master\n\nNote the use of `%h`, since by default the object IDs are abbreviated.\n\nIf you want something simpler, you can also write a shell script which\nedits the first argument in place and specify that.  Arbitrary shell is\nallowed in `GIT_SEQUENCE_EDITOR`, much like in `EDITOR` and `VISUAL`.\n\nI personally use this alias, which explicitly does not edit the sequence\nlist, to automatically squash in all squash and fixup commits without\nprompting:\n\n    srebase = \"!f() { GIT_SEQUENCE_EDITOR=true git rebase -m -i --autosquash \\\"$@\\\"; };f\"\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"547097","messageId":"DJP0D7IZJ8WX.S1DDPT3KTQ95@lfurio.us","threadId":"65919","inReplyTo":"ake8OAIyK-ELs-fU@fruit.crustytoothpaste.net","subject":"Re: Programmatically edit the git rebase sequence?","fromName":"Matt Hunter","fromEmail":"m@lfurio.us","sentAt":"2026-07-03T14:33:14Z","receivedAt":"2026-07-03T14:33:16Z","isPatch":false,"body":"On Fri Jul 3, 2026 at 9:42 AM EDT, brian m. carlson wrote:\n> On 2026-07-03 at 12:02:33, Matthias Beyer wrote:\n>> \n>> Now I fire up `git rebase -i master` and manually(!) match the list from\n>> above `git-log` call and find the respective commits to edit them.\n>> \n>> Is there a way I am not aware of to do that manual step programatically?\n>> Something like\n>> \n>>     git rebase -i master --edit-commits=\"$(git log master..mybranch --diff-filter=M --format=\"%H\" -- \"./subdir/*.rs\")\"\n>> \n>> would be convenient here, although I would understand if that is too\n>> much clutter for the already very heavy git CLI interface :-)\n>\n> Yes, such a thing exists.  You want `GIT_SEQUENCE_EDITOR`, which is an\n> `EDITOR`-like command that edits the rebase list in place.  So tools\n> like `ed`, `ex`, `sed -i`, `perl -i`, or `ruby -i` would be useful here.\n\nInteresting tip - thanks!\n\n>\n> I personally use this alias, which explicitly does not edit the sequence\n> list, to automatically squash in all squash and fixup commits without\n> prompting:\n>\n>     srebase = \"!f() { GIT_SEQUENCE_EDITOR=true git rebase -m -i --autosquash \\\"$@\\\"; };f\"\n\n'git rebase --autosquash' does work now without the need to invoke\n--interactive mode.  I believe we got this with f8f87e082798\n(Merge branch 'ak/rebase-autosquash')\n"},{"id":"547103","messageId":"CALnO6CCaAaVTDABQT9APasnhmvL3w_C1VKo3UYhgDt29OYPmFg@mail.gmail.com","threadId":"65919","inReplyTo":"ake8OAIyK-ELs-fU@fruit.crustytoothpaste.net","subject":"Re: Programmatically edit the git rebase sequence?","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-07-03T15:31:14Z","receivedAt":"2026-07-03T15:31:28Z","isPatch":false,"body":"On Fri, Jul 3, 2026 at 9:46 AM brian m. carlson\n<sandals@crustytoothpaste.net> wrote:\n>\n> On 2026-07-03 at 12:02:33, Matthias Beyer wrote:\n> > Is there a way I am not aware of to do that manual step programatically?\n> > Something like\n> >\n> >     git rebase -i master --edit-commits=\"$(git log master..mybranch --diff-filter=M --format=\"%H\" -- \"./subdir/*.rs\")\"\n> >\n> > would be convenient here, although I would understand if that is too\n> > much clutter for the already very heavy git CLI interface :-)\n>\n> Yes, such a thing exists.  You want `GIT_SEQUENCE_EDITOR`, which is an\n> `EDITOR`-like command that edits the rebase list in place.  So tools\n> like `ed`, `ex`, `sed -i`, `perl -i`, or `ruby -i` would be useful here.\n>\n> So you might want something like this (untested):\n>\n>     GIT_SEQUENCE_EDITOR=\"perl -pi -e 's/^pick ($(git log master..mybranch --diff-filter=M --format=\"%h\" -- \"./subdir/*.rs\" | paste -d '\\''|'\\'' -s -))/edit \\$1/'\" \\\n>     git rebase -i master\n\nYep. Although, the last time I wrote a program that used\nGIT_SEQUENCE_EDITOR, I had to deal with enough shell-nesting that it\nwas more convenient to make the editor program separate:\n\n- git-split-topic [1] sets up a sequence editor with some interpolated\narguments that also re-invokes the original\n- split-topic-editor [2] pre-processes the rebase script with ed\n\n[1]: https://github.com/benknoble/Dotfiles/blob/ca48a09f783b78e038a41c5d60ee6b163337f580/links/bin/git-split-topic#L47-L53\n[2]: https://github.com/benknoble/Dotfiles/blob/master/links/bin/split-topic-editor\n\nSee the comments in [1] for some weirdness in the invocation of the\nsequence editor, where it gets \"$@\" appended to the command string\n(meaning the last command in a chain might need to be written\nspecially).\n\nAnd yes, I'm sure there's a few ways for things to go wrong with the\nway some of the shell script variables are embedded into strings for\nanother shell to evaluate later; if I rewrote with Zsh, I could at\nleast use the ${(q)var} forms to perhaps handle that better…\n\n-- \nD. Ben Knoble\n"},{"id":"547521","messageId":"32e8c83a-69f3-8ef3-8d9c-f9860fda2fbb@gmx.de","threadId":"65919","inReplyTo":"akei64goQf3nFhX4@hikari","subject":"Re: Programmatically edit the git rebase sequence?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2026-07-08T17:58:24Z","receivedAt":"2026-07-08T17:58:35Z","isPatch":false,"body":"Hi Matthias,\n\nOn Fri, 3 Jul 2026, Matthias Beyer wrote:\n\n> in a recent conversation at work, the question of how to\n> programmatically edit the git-rebase sequence came up.\n\nThe easiest way is probably to have the interactive rebase stop at the top\nof the rebase script:\n\n\t# insert a `b` (for `break`) before the first line\n\tGIT_SEQUENCE_EDITOR=\"sed -i 1ib\" git rebase -i ...\n\n(Note that this is GNU sed syntax, with BSD/macOS sed you'll have to get a\nbit creative, or write a real script and refer to it via the path.)\n\nThen you can use a script to transform the rebase script before `git\nrebase --continue`.\n\nI frequently use this technique with LLMs because they seem to be unable\nto control an interactive editor correctly.\n\n> I have a branch that touches a number of files, adds some files and\n> removes some files.\n> When rebasing, I want to split all commits that touched a certain subset\n> of files, for the clearity of the history.\n> \n> I look at the output of\n> \n>     git log master..mybranch --oneline --diff-filter=M -- \"./subdir/*.rs\"\n\nNoting that the OIDs in $(git rev-parse --git-path\nrebase-merge/git-rebase-todo) are expanded, you could match them via the\nOIDs obtained using `rev-list` instead of `log`, to enumerate the OIDs\ninstead of full commit history, then turning that into some kind of regex.\nSomething along the lines\n\n\tregex=$(git rev-list master..mybranch --diff-filter=M -- \"subdir/*.rs\" |\n\t\t# read all lines, then turn newlines into `\\|`\n\t\tsed ':1;$b2;N;b1;:2;s/\\n/\\\\|/g')\n\n\tGIT_REBASE_TODO=\"$(git rev-parse --git-path rebase-merge/git-rebase-todo)\"\n\ttest -z \"$regex\" ||\n\tsed -i \"s/^pick \\($regex\\)/edit \\1/\" $GIT_REBASE_TODO\n\nThis _should_ work, but you'll most likely want to adapt it to your\nparticular use cases.\n\nCiao,\nJohannes\n\n> \n> to find all commits in that subdir that only touched the files. All of\n> these commits are to be \"edit\"ed.\n> \n> Now I fire up `git rebase -i master` and manually(!) match the list from\n> above `git-log` call and find the respective commits to edit them.\n> \n> Is there a way I am not aware of to do that manual step programatically?\n> Something like\n> \n>     git rebase -i master --edit-commits=\"$(git log master..mybranch --diff-filter=M --format=\"%H\" -- \"./subdir/*.rs\")\"\n> \n> would be convenient here, although I would understand if that is too\n> much clutter for the already very heavy git CLI interface :-)\n> \n> Maybe I am just not aware of the obvious solution - I would be happy to\n> learn that there is already one!\n> \n> Best,\n> Matthias\n> \n"}]}