git checkout master; use topic branches and detached heads.
It’s good to use so-called “topic” or “feature” branches to organize your work into individual features, instead of committing onto what I’ll call “mainline” or “persistent” branches directly. This is a fairly common practice, and I won’t go into full detail on why I think it’s important, but a few good reasons:
- Ensures you have an easy way of getting back to a known good state that’s not in the middle of some new feature.
- Logically groups individual features/bug fixes.
- Easy to manage multiple concurrent changes.
Referring to master
Even if we don’t commit directly onto a local master branch, we still often need to refer to the remote master branch to do things like:
- Start new feature branches off of master.
- Take changes that have been made to master and pull them into a feature branch.
- Do diffs against master.
So if we don’t checkout master locally, how do we these things? Easy — git already allows you to refer to remote branches directly, via remote tracking branches, like
- Need to do a diff against master?
git diff origin/master
- Need to pull in changes from master?
git merge origin/master(usually after a
git fetch origin; or just do
git pull origin masterin one step)
- Need to start a new branch based on master?
git branch new-branch origin/master
There’s no reason to have a local master branch to do any of these things.
Sometimes we need more direct access to the content at master. E.g., maybe we want to just do a build at master, without necessarily starting a new topic branch.
We can do this using detached head. You can just checkout a remote tracking branch directly, with
git checkout origin/master. This is similar to checking out a local branch as you would with
git checkout master, but the difference is that any commits you make won’t update
origin/master, or any other branch) to point to the new commit. Instead, the commit won’t be associated with any branch, until you give it a specific name.
Generally though, when using a detached head, the idea is just that you won’t be making commits at all. It’s just a way to access a specific snapshot of the repository without making changes.
Why not just checkout master?
Because it’s simpler not to:
- If you do checkout master locally, you now need to mentally deal with your local view of the remote master (
origin/master) and your local copy of master (
master), which can diverge.
- Merging with master is easier: you can just
git pull origin master. If you have a local copy of master (and you don’t want it to become stale), you’d instead need to:
git checkout master
git pull origin master
git checkout my-branch
git merge master