How to pull into multiple branches at once with git


In a repo I have multiple branches, among them "master" and "develop", which are set up to track remote branches "origin/master" and "origin/develop".

Is it possible to specify that I want both master and develop to be merged(fast-forwarded) at once?

When I do git pull now I get something like this:

remote: Counting objects: 92, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 70 (delta 29), reused 28 (delta 8)
Unpacking objects: 100% (70/70), done.
   5386563..902fb45  develop    -> origin/develop
   d637d67..ba81fb2  master     -> origin/master
Updating 5386563..902fb45

all the remote branches are fetched, but only the branch I'm currently on is merged with its corresponding remote branch.

So I have to do git checkout master

Switched to branch 'master'
Your branch is behind 'origin/master' by 106 commits, and can be fast-forwarded.

…and then git pull again, and then switch back to develop, to get the desired result.

I know I can make aliases/scripts that does these steps. But I want to avoid that if possible, as it is error prone and not very efficient.
Edit: ok let me rephrase that. My goal was not to discourage or frown upon script/alias customizing of git. I would just prefer a builtin solution if it exists 🙂

Best Answer

You can set up an alias that uses git fetch with refspecs to fast-forward merge your branches with just one command. Set this up as an alias in your user .gitconfig file:

    sync = "!sh -c 'git checkout --quiet --detach HEAD && \
                    git fetch origin master:master develop:develop ; \
                    git checkout --quiet -'"

Usage: git sync.

Here is why it works:

  1. git checkout --quiet HEAD directly checks out your current commit, putting you into detached head state. This way, if you're on master or develop, you detach your working copy from those branch pointers, allowing them to be moved (Git won't allow you to move the branch references while your working copy has them checked out).

  2. git fetch origin master:master develop:develop uses refspecs with fetch to fast-forward the master and develop branches in your local repo. The syntax basically tells Git "here is a refspec of the form <source>:<destination>, take <destination> and fast-forward it to the same point as <source>". So the sources in the alias are the branches from origin, while the destinations are the local repo versions of those branches.

  3. Finally, git checkout --quiet - checks out the branch you were last on, regardless of whether or not there was a failure in the previous commands. So if you were on master when you ran git sync, and everything succeeds, you'll leave detached head state and check out the newly updated master.

See also my answer to git: update a local branch without checking it out?.

Related Question