64

I happily use vim as my default editor for commits, and do not wish to change it. However, when it comes to rebasing, I find myself squashing dozens and dozens of commits which I find much easier with an interactive editor like Textwrangler (substituting "pick" with "squash" in all but the top commit).

Is there any way to specify an alternate editor for a one-off rebase command?

I know in vim I can do:

:%s/pick/squash/

but that has its own minor annoyances.

EDIT - as stated in the comments, you can squash all but the top commit very efficiently by going to the 2nd line and executing

:,$s/pick/squash/

(note the comma and dollar are different to the original)

Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106
  • 5
    In vim, you can do `:,$s/pick/squash/` which will change all occurrences from the *current line* through to the end of the file. – Greg Hewgill Oct 31 '13 at 18:35
  • That's a great tip, thanks Greg. Yes, that was the "minor annoyance" I was alluding to. – Sridhar Sarnobat Oct 31 '13 at 18:36
  • Assuming you have an up to date vim version or have install Tim Pope's vim-git plugin, you can use the `:Cycle` or `:Squash` commands. You may even want to use a mapping. Maybe use the `:global` command: `:+,$g/./Squash` – Peter Rincker Oct 31 '13 at 18:37
  • May I ask what :Cycle and :Squash do? I'm having trouble finding the documentation for those commands. – Sridhar Sarnobat Oct 31 '13 at 18:39
  • I also use "marks" heavily. Go to the first line you want to change, type `ma` (set mark `a`), go to the last you want to change, type `:'a,.s/this/that/`. Single quote followed by a mark-letter means "the line where that mark is set". – torek Oct 31 '13 at 19:18
  • `:Cycle` will cycle through the rebase options: `pick`, `squash`, `edit`, `rework`, and `fixup`. `:Squash` will mark a line as `squash`. Take a look at `e $VIMRUNTIME/ftplugin/gitrebase.vim` for more information. – Peter Rincker Oct 31 '13 at 20:08
  • Thanks for the info Peter, and torek. – Sridhar Sarnobat Oct 31 '13 at 20:14

4 Answers4

77

Try adding the GIT_EDITOR environment variable before your command, like so:

GIT_EDITOR=<editor of choice> git rebase <...>

For example, to use nano I would type:

GIT_EDITOR=nano git rebase -i abcdef1234
Rob Bajorek
  • 6,382
  • 7
  • 44
  • 51
  • Since you aren't exporting it, does that variable value get reset when the command terminates? (that would be ideal, but I'm guessing you need to reset it manually) – Sridhar Sarnobat Oct 31 '13 at 18:37
  • 1
    The variable is only set for that one command invocation. Try running `git rebase` again without `GIT_EDITOR` and you'll use your default editor again. – Rob Bajorek Oct 31 '13 at 18:43
  • Awesome, this is the right answer then. Though I think my fears of learning a bit more vim were irrational – Sridhar Sarnobat Oct 31 '13 at 19:14
  • 1
    Awesome indeed. For some reason my ancient server-side OS defaulted to `vi` instead of `vim` --so now I know how to perma-fix this. – MarkHu May 06 '16 at 17:31
  • This helped me a lot thanks, i believe a lot of people are looking for `GIT_EDITOR=nano git rebase -i @~9` this will show your last nine commits and you should be able to modify them. – Bobby Axe May 28 '20 at 16:14
  • For visual code use GIT_EDITOR="code --wait" git rebase -i abfa452 – EddyXorb Mar 16 '21 at 06:55
  • Just put this in your env and it's perfect yup – Guillaume Munsch Aug 22 '23 at 10:14
18

There is an even better option for all your interactive rebase.

https://github.com/sjurba/rebase-editor

It is a custom CLI app written in node specifically for interactive rebase.

To install:

npm install -g rebase-editor
git config --global sequence.editor rebase-editor 

Or with yarn:

yarn global add rebase-editor
git config --global sequence.editor rebase-editor 
Tim
  • 7,746
  • 3
  • 49
  • 83
barsju
  • 4,408
  • 1
  • 19
  • 24
  • 4
    dang this tool is awesome sauce – Antony Stubbs May 21 '19 at 15:20
  • This tool is now required part of my setup. Being able to select each action with the single press of a key makes "git rebase" a teachable process. – Dan Ciborowski - MSFT Feb 21 '22 at 17:10
  • I went to this tool's documentation with the intension to use it, but unfortunately this doesn't work with git-bash on windows (https://github.com/sjurba/rebase-editor/issues/7). Tried the hack `git config --global sequence.editor 'winpty rebase-editor.cmd'`, but that didn't work out for me. Can't put much time in this so will live with the vim editor on gitbash for now. – Afshar Nov 23 '22 at 12:57
1

With Git 2.40 (Q1 2023), just like "git var GIT_EDITOR"(man)" abstracts the complex logic to choose which editor gets used behind it, "git var" now give support to GIT_SEQUENCE_EDITOR.

See commit 4c3dd93 (17 Dec 2022) by Sean Allred (vermiculus).
(Merged by Junio C Hamano -- gitster -- in commit 48475f4, 28 Dec 2022)

var: add GIT_SEQUENCE_EDITOR variable

Signed-off-by: Sean Allred

The editor program used by Git when editing the sequencer "todo" file is determined by examining a few environment variables and also affected by configuration variables.
Introduce "git var GIT_SEQUENCE_EDITOR"(man)" to give users access to the final result of the logic without having to know the exact details.

This is very similar in spirit to 44fcb49 (Teach git var about GIT_EDITOR, 2009-11-11, Git v1.6.6-rc0 -- merge) that introduced "git var GIT_EDITOR".

git var now includes in its man page:

GIT_SEQUENCE_EDITOR

Text editor used to edit the 'todo' file while running git rebase -i. Like GIT_EDITOR, the value is meant to be interpreted by the shell when it is used.

The order of preference is:

  • the $GIT_SEQUENCE_EDITOR environment variable, then
  • sequence.editor configuration, and then
  • the value of git var GIT_EDITOR.
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

In my case, I have set an interactive editor for rebases. However, I found it could not do something I wanted it to, so in the case that I want to specify an alternative editor for the occasional invocation, the following works:

git -c sequence.editor=vim rebase -i upstream/main

The -c sequence.editor=<value> sets the value of the sequence.editor config key for that single command. You can use this syntax for any command, and it comes in handy from time to time.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742