42

I have 3 branches.

     master [ Live Server]
      \
       stage [ Stage Server Where we test changes; merge commits ]
        \ 
         Dev [ Local Machine ]

I would like to downstream the changes to. Each of these branches are set to tracking each other.

Normally, to downstream the changes i do this:

git checkout stage && git merge master

Then i checkout dev and i do the same

git checkout dev && git merge stage

Then push them all: git push origin --all

Is there a way to downstream those changes without checking out into each branch?

I maybe using the wrong terminology. I'm not totally sure if i'm using upstream/downstream terminology correctly.

chrisjlee
  • 21,691
  • 27
  • 82
  • 112
  • would master branch get your dev code as well? – TheOneTeam Jul 21 '11 at 14:37
  • Yes that's what i'm looking for. – chrisjlee Jul 21 '11 at 14:41
  • 1
    Your usage of downstream isn't incompatible with what I understand about "upstream/downstream": http://stackoverflow.com/questions/2739376/definition-of-downstream-and-upstream/2749166#2749166 – VonC Jul 21 '11 at 14:45
  • if you git merge master, master branch would not get your stage code, but only your stage branch get your master code... – TheOneTeam Jul 21 '11 at 14:53
  • @Kit Ho is that a question or a statement? – chrisjlee Jul 21 '11 at 15:05
  • @Chris: It's a statement. `git checkout stage && git merge master` will merge changes from master into stage. It won't add any commits to master. I believe this is your intention, but your first reply to @Kit seems to indicate otherwise. – Tom Anderson Jul 21 '11 at 15:35
  • @Tom Anderson Yes it is. I meant the other way around. dev would get the commits from master. – chrisjlee Jul 21 '11 at 15:45
  • yes. what i am pointing is exactly what @Chris say, i just wonder why you merge your master code to dev. branch. Dev. branch is supposed to have to newest commit in your whole repository. – TheOneTeam Jul 21 '11 at 16:27
  • @kit ho i do that but the changes need to be on the staging server too. – chrisjlee Jul 21 '11 at 20:42
  • 4
    possible duplicate of [Merging Branches Without Checkout](http://stackoverflow.com/questions/4156957/merging-branches-without-checkout) – krlmlr Dec 04 '13 at 00:42
  • Possible duplicate of [Git checkout-and-merge without touching working tree](http://stackoverflow.com/q/1402993/456814). –  May 29 '14 at 19:31
  • 2
    Possible duplicate of [Update/pull a local Git branch without checking it out?](http://stackoverflow.com/q/3216360/456814). –  May 29 '14 at 19:31
  • Possible duplicate of [Merging without changing the working directory](http://stackoverflow.com/questions/3408532/merging-without-changing-the-working-directory). –  May 29 '14 at 19:32
  • Possible duplicate of [Merging Branches Without Checkout](http://stackoverflow.com/q/4156957/456814). –  May 29 '14 at 19:32
  • Re-added: Possible duplicate of [Merge, update, and pull Git branches without using checkouts](http://stackoverflow.com/q/3216360/367456) – hakre Nov 24 '14 at 11:10

3 Answers3

73

You can indeed "merge" a branch B into branch A without having to check out branch A, but only if it's a fast-forward merge.

You can use a refspec with fetch to do the "merge". If merging branch B into branch A using git merge would result in a fast-forward merge, then you can do the following without having to checkout A:

git fetch <remote> B:A

The Documentation

The above matches the refspec format

git fetch <remote> <source>:<destination>

From the documentation for git fetch (emphasis mine):

The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref that matches it is fast-forwarded using <src>.

See Also

  1. Git checkout and merge without touching working tree

  2. Merge, update, and pull Git branches without using checkouts

  3. Merging without changing the working directory

  4. Merging Branches Without Checkout

user85421
  • 28,957
  • 10
  • 64
  • 87
  • 12
    (For the lazy who don't want to dig through the other answers): You can also use a . in place of the the remote for operation on local branches. – David Sep 08 '15 at 15:28
  • This is such a good find. I've haphazardly passed this in the documentation a handful of times and never picked up on this. – Carrie Kendall Dec 03 '15 at 01:07
  • @CarrieKendall it's really easy to miss. It's been a long while, but I think that the only reason I discovered this was because my bash auto-completed the refspec one day, and being curious, I decided to hit enter and see what would happen... –  Dec 03 '15 at 03:08
  • 5
    Here's a practical example: `git fetch . foo:master` this will do a fast-forward merge of foo into master no matter what branch you are on. The `.` refers to the local repository. – Jason Axelson Jul 13 '16 at 08:03
17

Enter git-forward-merge:

Without needing to checkout destination, git-forward-merge <source> <destination> merges source into destination branch.

https://github.com/schuyler1d/git-forward-merge

lkraider
  • 4,111
  • 3
  • 28
  • 31
  • @chrisjlee please accept this answer since it's hidden under accepted answer which also has a bounty and it's really easy to miss it. `git-forward-merge` also states in the README that it uses the now-accepted approach if possible. – Jiří Brabec Oct 13 '20 at 14:57
6

You can't merge into a branch in the general case without having it checked out. There's a good reason for this, however. You need the proper working tree in order to denote and resolve merge conflicts.

Karl Bielefeldt
  • 47,314
  • 10
  • 60
  • 94
  • This isn't a new comment, just editing out the link to my answer because, in hindsight, linking to my own answer like that was distasteful. Edited comment: This isn't entirely correct. If the merge would result in a fast-forward merge, then there will be no conflicts, and thus it's not necessary to have a working copy, and thus it's possible to merge without having to have the destination branch checked-out. –  Sep 08 '15 at 16:43