Updating a Git branch without first checking it out

git icon, created for the Open Icon Library

If you work with multiple developers all pushing and pulling into a single remote Git repository, you know about outdated branches. Regular pull-and-rebase operations can become quite annoying. What’s worse is when you add feature branches into the mix, though. If you need to rebase feature branches before merging, keeping your main branch up to date can be painful. However, it doesn’t have to be!

git pull only updates the current branch from a remote repository. Using it means having to go through a number of steps: Check out the main branch, pull updates, check out the feature branch, merge. Fortunately, it’s not the only way to update a branch. We can fetch all the commits from our remote repository and use one of Git’s plumbing commands to avoid the mess of multiple checkouts. And so long as your main branch has no local-only commits, it’s perfectly safe to do.

Given a branch develop and a remote repository origin, we can update our local branch to point at the same commit as the remote branch like so:

$ git fetch --all
$ git update-ref refs/heads/develop refs/remotes/origin/develop

As a developer, you should be well aware of what git fetch does, but you might not have encountered update-ref before. Fortunately, it’s quite self-explanatory: the update-ref command simply moves the named reference to the specified commit. If you specify another reference instead, it will find the related commit and use that as the target of the updated reference. Since Git branches are just automatically-updated head references, this one update-ref command is all you need.

You can easily set this up as a Git alias as well:

update-branch = "!f() { git update-ref refs/heads/$1 refs/remotes/origin/$1; }; f"

We need to use a shell function in order to get parameters in our alias. That lets us expand this out further, though. The function can check if the branch exists, and we can parameterize the remote name (with a default value, too). I’ll leave that as an exercise to the reader, however, since this isn’t a lesson on shell scripting.