2

I know this question was already asked here: https://stackoverflow.com/questions/2329716/merging-changes-from-master-into-all-branches-using-git, but I would like to see real code that does this.

I have a master branch and many branches for features. I would like that all changes made in master are reflected in all features branch.

When I commit into master, all the changes should be reflected on all the other branches (basically it would be the same as checking out all branches and merging master, but with an automated process).

edi9999
  • 19,701
  • 13
  • 88
  • 127
  • 2
    In the link you give, the next answer says "for BRANCH in $(ls .git/refs/heads); do git rebase master $BRANCH; done". What are you missing with that code ? – Ingo Blackman Jan 25 '14 at 23:38
  • I'm a bit scared of doing rebases, in particular on all branches, that could lead to bigger issues in the future: http://www.git-scm.com/book/en/Git-Branching-Rebasing#The-Perils-of-Rebasing . The issue is that I need to look whether the branches which I want to merge are not published. – edi9999 Jan 25 '14 at 23:43
  • Ok, then what about "for BRANCH in $(ls .git/refs/heads); do git checkout $BRANCH; git merge master; done". If that's still scary: You could simply keep a file around called "branches_to_merge.txt" which contains all the branches you want to merge with master; and then use "for BRANCH in $(cat branches_to_merge.txt); do git checkout $BRANCH; git merge master; done" – Ingo Blackman Jan 25 '14 at 23:57
  • @edi9999 Ingo's initial suggestion is the best one. Rebasing is fundamental to git. Check to see if the branches have been published, and if not, do that. Nothing to be afraid of - there's practically nothing you can do it git that you can't unwind. If they the branches have been published to the remote server, use merge of course. – Mike Monkiewicz Jan 26 '14 at 01:38
  • possible duplicate of [Merging changes from master into all branches using Git?](http://stackoverflow.com/questions/2329716/merging-changes-from-master-into-all-branches-using-git) – ChrisGPT was on strike Jan 26 '14 at 04:35

1 Answers1

1

The issue is that I need to look whether the branches which I want to merge are not published.

If they aren't published, you should rebase them.
But checking if a rebase is actually possible is a tiny bit tricky:


First, after fetching, you easily can check if you have local commits not yet pushed:

 git log origin/master..master

        o--o--o (origin/master)
       /
x--x--x--y--y   (master)

It is perfectly ok to rebase in this instance, except if master was already pushed to another branch from your repo.
But you also can check that easily with:

git branch -r --contains master

If any remote (-r) branch contains the branch you want to rebase, then it is a less safe idea, and a merge is preferable.

But, if the remote branch itself was rebased (and forced pushed), then you need to be careful, as detailed in "How do you deal with a public repository that has already been rebased?":

        o--o--o (OLD origin/master)
       /
x--x--X--y--y   (master)
    \
     o'--o'--o' (origin/master, as seen after a 'git fetch')

Rebasing blindly master on top of origin/master would replay commit X, which was left out when origin/master was rebased. Not good.

Today (January 2014), the only way to deal with this case is to:

  • make a 'tmp' marker branch on origin/master,
  • git fetch,
  • check if git branch --contain tmp lists origin/master (which has been fetched and is possibly with a different history if it was rebased and forced pushed).

Tomorrow (git 1.9, Q1 2014), you won't have to mark your remote branch before fetching:

fork_point=$(git merge-base --fork-point origin/upstreamBranch yourBranch)
# return X
git rebase --onto origin/upstreamBranch $fork_point yourBranch

To recap:

After a git fetch (after marking origin/master before the fetch),

  • if git log origin/master..master returns commits from master which aren't part of origin/master (meaning those local commits haven't been pushed to origin/master)
  • AND if git branch -r --contains master is empty (meaning master wasn't pushed anywhere else, on any remote tracking branch you can see through a git fetch)

Then:

  • if origin/master include the marker branch 'tmp' (meaning origin/master itself wasn't rebased), you can git rebase origin/master master.
  • else: you can git rebase --onto origin/master $(git merge-base tmp master) master
    (you need tmp here to rebase just your branch. Git 1.9 will make the need for a tmp branch needless)

In any other cases: merge origin/master to master.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I like the new `--fork-point`, but oh man, I dread attempting to *explain* the new `--fork-point`... :-) – torek Jan 26 '14 at 17:37
  • @torek But it does return the true common ancestor between 2 branches), digging it from the reflog, seems easy enough, no? Just kidding :) – VonC Jan 26 '14 at 17:39