pbyrne84.github.io

Git Rebase

Rewriting history, so we can at least pretend to be coherent creatures.

Do not do this on a shared branch without communication with all users of that branch

Why do we want to do this?

In reality, when we work, it is fairly chaotic. At the end of a task, our commit history can be all over the place. It is no use to anyone and makes git annotate useless to get an overview of what was done and why. I generally annotate to find out what task/story instigated that piece of code to be written. Getting x or wip back just makes that a lot more difficult.

It is not about blame, it is about ease of verification. We share culpability for more things than the direct thing we are working on. Making things hard just means they will not be done.

Git graph alias (make looking at git commit history prettier on the command line)

(Windows replace ‘ with “)

git config --global alias.graph 'log --oneline --abbrev-commit --all --graph --decorate'

git-graph.png

Each indentation level is a branch. Sometimes merge commits infect things and break rebasing/githubs ability. Instead of merging from main into the branch I am working on I will use

git rebase origin/main

I will usually squish my branch down before I do this as it will deal with conflicts per commit, so if you have been changing your mind a lot there may be needless conflicts to deal with.

Interactive rebase (-i)

This allows you to squish commits and rewrite commit messages. I use this instead of amend message.

Using VIM

VIM is quite alien to use at first. You need to switch between operating modes. To actually start typing, you need to switch to interactive mode by pressing i. I forget this quite a lot and trigger interactive mode by typing a word with i in it.

When in interactive mode we need to press Escape to get out to do things like the following

(: and then q) etc.

There are jokes about quitting out of VIM https://thenewstack.io/how-do-you-exit-vim-a-newbie-question-turned-tech-meme/

Example

Here I have a branch that I have done

git rebase -i origin/main

And it has opened VI (Oh Noes :))

interactive-rebase-start.png

We then switch to interactive mode with the i key.

On this screen we cannot actually change the messages, what we can do is denote each commit instead of pick with the following.

Often I will just use f on everything but the first commit and then all changes are just put under that commit.

interactive-rebase-flatten-all.png

Then press Escape

and type :wq and then Enter

vim-save-quit-wq.png

to save and quit then force push

push -f

Again don’t do this on a shared branch

More complicated example with rewrite messages

(Usually I will just squash everything but first commit and then use r in a separate rebase to change the message as I am clumsy )

Commit and push changes first, if there is a problem then you can reset with

git reset --hard origin/branch-name

We have 4 commits on a branch.

git graph

git-rebase-step1.png

We start an interactive rebase again origin/main

git rebase -i origin/main

git-rebase-step1.png

We press i to edit. We want to rewrite the message, keep the 3rd commit message by squashing. The 2nd and 4th references will be squashed down.

You cannot change messages in this view

git-rebase-step3 .png

Press escape and then :wq

git-rebase-step4.png

Now you can edit things by pressing i again (in non-interactive mode dd deletes a line)

git-rebase-step4.png

Escape and :wq again will take you to

git-rebase-step6.png

Force push

push -f

which will look like this in a pull request (bad spelling included)

git-rebase-step7.png