On Wed, Aug 25 2021, Konstantin Kharlamov wrote: > I think, one of the most frequent git features used is `rebase -i`. There's a common > workflow I think everyone knows: you have commits 1, 2, 3, then you decide "Nah, 2nd > commit needs a change", so you do `git rebase -i HEAD~2`, then in popped up editor > you modify the `pick` on the first line to become `edit`, then you do the change, > then `git rebase --continue`. > > The boilerplate part here: even though you know that you want to edit HEAD~2, there > is no way to tell git that right away. Every time you have to launch editor, edit the > line manually, then save it, close it. > > I have seen here some discussions about improving that, someone even posted patches, > but I'm not aware if it went anywhere. So I created 2 years ago a shell wrapper > `rebase-at`¹, which upon called as `rebase-at e HEAD~2`, does the thing described > above automatically. Under the hood I simply substitute EDITOR with `sed` command > that replaces `pick` on the first line (the HEAD~2 commit) with `e`. If used with > shell autocompletion, it is now practically instantaneous. > > I'm almost happy with `rebase-at`, except I don't know of any way to make it work > with `reword` git action. You see, "rewording a commit" requires to run EDITOR twice: > first to substitute `pick` with `reword`, and then to actually edit the commit > message. But since EDITOR was substituted with sed, the 2nd run won't give you an > actual editor to change the commit message. > > Any ideas, how can I tell `git` that I want to "reword" nth commit right away? Sure, > I am not the first one to stumble upon it, am I? Any ideas? > > 1: https://github.com/Hi-Angel/dotfiles/blob/0b9418224e4ce7c9783dbc2d9473fd1991b9b0b2/.zshrc#L148-L160 Have your GIT_EDITOR do one thing or the other depending on whether it's asked to edit git-rebase-todo. This works for me: # rebase-at <action> <comit-ids-and-co> function rebase-at() { local action=$1 shift 1 GIT_EDITOR='perl -MFile::Basename=basename -wE '"'"' my $f = shift; exec qw[sed -i -E], q[1s/\\w+/'$action'/], $f if basename($f) eq q[git-rebase-todo]; exec "$ENV{EDITOR} $f"; '"'" git rebase -i "$@" }