Git rebase & co.
Table of Contents
- 1. context: code review/development iteration
- 2. keeping the history linear
- 3. rebasing
- 4. rebase, “history rewriting”
1 context: code review/development iteration
1.1 the process: (1) submit, (2) review, (3) goto 1
1.2 iteration history
1.2.1 squash intermediate commits because they don’t matter
1.2.2 adjust commits and commit logs according to review
2 keeping the history linear
2.1 what ‘git merge’ and ‘git pull’ (and ‘git push’ sometimes) do
2.1.1 creates a “merge commit”
see the awesome Git for Computer Scientists
2.2 why should i care?
2.2.1 helps understand code evolution
2.2.2 helps bisection (‘git bisect’)
2.2.3 possibly helps continuous integration
2.3 visualizing the history
- using
gitk
(which is part of Git) - using Magit (in Emacs)
- using a Web interface (GitLab, cgit, etc.)
2.4 pull/merge requests
2.4.1 by default, they introduce merge commits!
2.5 note: sometimes you do need parallel dev branches, that’s fine!
3 rebasing
3.1 the Git commit graph
Do not miss Git for Computer Scientists!
3.2 rebasing your changes before pushing
For example, assuming you are working on the ‘master’ branch and have a bunch of local commits ready to be pushed, you would run these commands:
$ git pull --rebase # fetch remote changes, and rebase on top of them $ git push
Sometimes ‘git pull –rebase’ will result in conflicts that need to be resolved. Assuming ‘foo.cpp’ has a conflict, you would edit it to fix those conflicts (look for “>>>”), and then:
$ git add foo.cpp $ git rebase --continue
3.3 make ‘git pull’ rebase by default
git config branch.master.rebase true
From now on ‘git pull’ will always rebase. \o/
3.4 tell GitLab to rebase when you accept merge requests
4 rebase, “history rewriting”
4.1 Caveat: don’t rebase a published branch!
4.3 amending the last commit of a branch
git add foo # stage changes git commit --amend # amend the last commit on the branch
4.4 rebasing a branch on top of another one
This will simplify the reviewers life by make sure the changes apply on the latest ‘master’, for example.
git checkout master git pull # update my copy of 'master' git checkout my-feature-branch git rebase master # rebase 'my-feature-branch' on 'master'
4.5 squashing, dropping, reordering, rewriting commits
All with ‘git rebase -i’ (or similar in your favorite UI). Glossary:
- squashing two or more commits: turning them into a single commit
- dropping: get rid of commits you don’t like, after all
- reodering: you can change the order of commits in the history
- rewriting: change the commit log and/or what the commit does
4.6 pro tip: autosquash (thanks bgoglin!)
- Write “squash! the summary line” in your commit log and then ‘git rebase n–autosquash’ will automatically flag it as candidate for squashing with the commit that has “the summary line”. See git-rebase(1). Also works with “fixup!” (difference is that the fixup commit log is discarded.)
git config branch.THE-BRANCH.autoSquash true
- Actually, ‘git commit –fixup ID’ creates the right summary line!