Everybody and their mother are now writing Git tutorials of various kinds, so I decided to jump on the bandwagon and do my own just like the thousands that already exist.
Just kidding. My one will be different.
Joking aside, I really could not find a decent, step-by-step tutorial for the situation I was in today: I wanted to use rebase
--interactive
to actually edit (not just reword) several past commits. So this is a kind of reminder for myself (even if very simple), and I suppose it might be useful for someone else, too.
Let us start with this.
cd /tmp rm -rf rebase-edit-tutorial # in case you run this again git init rebase-edit-tutorial cd rebase-edit-tutorial echo 'Initial commit' > file.txt git add file.txt git commit -m 'Zeroth commit' echo -e 'Atfer\nthe first commit.' > file.txt git add file.txt git commit -m 'First commit' echo -e 'After\nteh second\ncommit.' >> file.txt git add file.txt git commit -m 'Second commit' echo -e 'After\nthe third and last\ncommit.' >> file.txt git add file.txt git commit -m 'Third commit'
Running the above script will create a fake Git repo in the current directory, with three stupidly simple and meaningless commits. (Note that I included a “zeroth commit” – a parentless one – since I will want to start rebasing from the “First commit”. Rebasing from the root commit is possible with the --root
option, but that would be an exceptional situation.)
Let’s now assume that we want to fix both typos introduced in the first and the second commit. (Can you spot them?) Here is a step-by-step recipe.
We start at the “First commit”. You have to give git rebase -i
the last commit you don’t want to modify. (Yes, Git is weird.)
git rebase -i HEAD^^^
Next, we edit the list of commits so that the first two lines say edit
instead of pick
. We save the list and exit the editor.
Saying git status
will give some information about what is happening right now. Saying cat file.txt
will confirm where we are. Go on, try these things, I’ll wait. (In fact, it is a good idea to do git
status
after every command presented here to see what is going on.)
…
Good, you’re back. Now fix the typo and say
git add file.txt git commit --amend -m 'First commit' git rebase --continue
Notice how we used git commit --amend
.
Let’s now fix the second commit in the editor and say
git add file.txt git commit --amend -m 'Second commit' git rebase --continue
Boom, done! Of course, as every tutorial will tell you, don’t do that if you already pushed your changes to some server, blah, blah – you already know it.
Now what many other tutorials don’t tell you is what happens if you forget to say --amend
. The answer is simple: you will introduce new commits, right after the ones marked for editing.
Also, things might get a little more hairy if you fix stuff in the same place, or introduce editing conflicts – but that will have to wait for another time.