I’m a strong proponent for rebase workflows with Git – it just makes so much more sense to me, having the history be based on the latest changes, rather than interweaving the changes with back merges. Okay, but that’s a topic for another time, here’s what new thing I just found out about git rebase
:
The git rebase -i
or git rebase --interactive
command doesn’t just allow you to pick, drop, squash, edit, etc. commits, but you can also reorder the commits.
Say you have the following commit history (git log --oneline
):
ad02dde1ff (HEAD -> feature/new-world) Last commit
301b3af2ba Second commit
154c2d2b5b First commit
e62403ebeb (master, origin/master, origin/HEAD) Master commit
Now if you do git rebase -i origin/master
(e.g. after a git fetch -p
), you’ll get a list of all the commits that sit on top of origin/master
in your preferred editor (default: vi/vim):
pick 154c2d2b5b First commit
pick 301b3af2ba Second commit
pick ad02dde1ff Last commit
You can now change the text for pick
to reword
, edit
, squash
, etc., but you can also move the commits around, like this:
pick 154c2d2b5b First commit
pick ad02dde1ff Last commit
pick 301b3af2ba Second commit
And after saving and closing the file and thus initiating the rebase, the commits will be reordered:
ad02dde1ff (HEAD -> feature/new-world) Second commit
301b3af2ba Last commit
154c2d2b5b First commit
e62403ebeb (master, origin/master, origin/HEAD) Master commit
Of course if you have commits that depend on each other, you’ll likely run into conflicts during the rebase. However, if the commits are orthogonal to each other, it can be very useful. For example to get the commit you want to apply additional updates to, to be the last commit, so you can just --amend
all the changes, or if you want to squash two commits that aren’t in order.
Bonus TIL: src refspec does not match any
If you created a new branch or renamed a local one and then run git push -u origin feature/my-feature
you can run into the following error:
error: src refspec feature/my-feature does not match any
Which is a rather confusing error message and there are two main causes that I’ve seen for this:
- You have an empty repository without a single commit, so there’s nothing to push and no reference exists
- The branch name used in the command is simply wrong
For the second point, this can often be, if you’re used to master
, but now the branch is named main
. And to stick with the example, it might actually be feature/my_feature
with an underscore. So double check for branch name typos in your command.