George Garside Blog

A place of many ramblings about macOS and development. If you find something useful on here, it's probably an accident.

git.day/5 • See all at git.day

Git history tells a story. Tell the best story you can using rebase.

If you need to make changes to commits older than HEAD, an interactive rebase session is a great way to do it. For example, given a graph of commits produced by Git of the day #4: git log --oneline --graph that look like this:

* (master) ffff F
| * (HEAD -> foo) eeee E
| * dddd D
| * cccc C
|/
* bbbb B
* aaaa A

Having done some work on the foo branch, three commits were made. If C and D do not need to be separate commits, rebase can be used to squash them. Specifying the rebase should be of C to HEAD can be done with git rebase -i HEAD~2. This opens your Git editor with a file showing the 3 commits.

pick cccc C
pick dddd D
pick eeee E

The verb beginning the line is the operation to perform on the commit. pick is the default that keeps the commit as normal, but there are a whole bunch of verbs that can be used.

To stop and modify a commit in the list, use reword to edit the commit message or edit to also edit the commit content (then use git rebase --continue). In this case, we not only want to make a change to one commit but to combine the contents of two commits into one. Two verbs to do this are squash and fixup; the former opens an editor for the commit message starting with the two commit messages concatenated, and the latter discards the commit message of the commit being fixup’d.

pick cccc C
fixup dddd D
pick eeee E

This combines C and D, producing the following commit history:

* (master) ffff F
| * (HEAD -> foo) eeeh E’
| * cccg C’
|/
* bbbb B
* aaaa A

C’ and E’ are new commits present on the foo branch and remain branched off commit B.

Leave a Reply

No comments