How to rebase many branches (with the same base commit) at once?

GitRebaseGit Rebase

Git Problem Overview


I have a master branch in my project, that I use to pull changes from other people. From that, I usually have several topic branches on which I'm currently working.

My question is: Is there a way for me to pull new changes into my master and then rebase ALL of my topic branches onto that at once?

This is the situation:

        D--E topic1
       /
A--B--C master
       \
        F--G topic2

And I want to accomplish this with one single command (H came from upstream) :

D'--E' topic1
/
A--B--C--H master

F'--G' topic2

Now, I know I can accomplish this by rebasing topic1 and topic2 onto master, and I could even write a script to automate this. But what if I have several other branches, create new ones and delete others frequently and I receive upstream changes all the time?

This operation (several rebases), when done by hand, is both tiring and error-prone.

Is there an easier way?

Git Solutions


Solution 1 - Git

I'm fairly sure that there isn't a way to automatically do this. Remember that "git rebase master" can also drop you back to the shell needing you to resolve merge conflicts, so if you want to write a script to automate all this you need to take that into account.

You can fairly easily track which branches need updating, though. Hmm, for any branch, "git rev-list branch..master" will produce output if the branch is not up-to-date wrt (i.e. just commits on top of) master. So you need to loop through all the local heads except master to produce a report (nb "git show-branch" will approximately do this):

git for-each-ref 'refs/heads/*' | \
  while read rev type ref; do
    branch=$(expr "$ref" : 'refs/heads/\(.*\)' )
    revs=$(git rev-list $rev..master)
    if [ -n "$revs" ]; then
      echo $branch needs update
      git diff --summary --shortstat -M -C -C $rev master
    fi
  done

So if you were feeling brave, you could replace that "git diff" with something like "git checkout $branch && git rebase master" (or maybe just "git pull --rebase" if you've set that up). I think you'd then have to check for the existence of a ".git/rebase-apply" directory or check the index for unmerged files ("git ls-files -u") to test if we've been left waiting to do a merge.

Of course, if there are no conflicts, then it's easy... it's producing something that also works when it's not easy that's the problem :p

And this doesn't necessarily address what happens if one of your branches is based on something else... that's why I mentioned using "git pull --rebase" instead, because that would rebase according to the branch configuration, not blindly from master. Although the detection isn't based on the branch configuration... maybe it would be easiest just to check out each branch and do "git pull" and let the branch configuration handle everything, including whether to rebase or merge?

Solution 2 - Git

You can always just write a shell one-liner like this:

for branch in topic1 topic2 topic3;do git rebase master $branch;done

Since the topic branches you would like to rebase will probably change over time, this is a quick-and-dir^H^H^Hflexible solution :-)

Solution 3 - Git

I have turned this into a robust script, maintained in my git-extensions repository:

$ git-urebaselocalbr --help
Rebase all / the last committed N local branches (except for the current branch
and master) to the updated upstream head.
Usage: git-urebaselocalbr [--continue|--skip|--abort] [--branches "<branch1> ..."] [N] [-i|--interactive] [options]

Solution 4 - Git

git branch | sed 's/\*/ /g' | xargs -n1 git rebase master

Solution 5 - Git

If you would like to rebase all local branches onto master, you could try this:

git branch | cut -c 3- | for branch in $(cat); do git rebase master $branch; done

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmalvimView Question on Stackoverflow
Solution 1 - GitaraqnidView Answer on Stackoverflow
Solution 2 - GitflacsView Answer on Stackoverflow
Solution 3 - GitIngo KarkatView Answer on Stackoverflow
Solution 4 - GittdrdView Answer on Stackoverflow
Solution 5 - GitHuang C.View Answer on Stackoverflow