50

I have an application running in a git repository on a branch (say dev). The application modifies the content in some the repository and commits them. I now have to merge these changes into another branch (say master) but the snag is that I don't want to git checkout master before doing this. Is there some way to say "merge current branch into master"?

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
  • 6
    And precisely how do you intend to resolve conflicts? – sehe Jul 01 '11 at 12:42
  • 5
    Lets say that I'm sure I will have none. Can I do it then? – Noufal Ibrahim Jul 01 '11 at 17:21
  • 3
    +1 This is indeed a very interesting question that pushes the git knowledge forward and deserves more upvotes! – rtn Jul 02 '11 at 12:19
  • 1
    Possible duplicate of [Merge, update, and pull Git branches without using checkouts](http://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts) – Steve Chambers Sep 15 '16 at 13:36

4 Answers4

40

The "master" in your case appears to be "fast-forwardable". You could "push" the branch to master.

cd /path_to_dir_with_no_branch_switch/
git push . appbranch:master
Frank Szczerba
  • 5,000
  • 3
  • 31
  • 31
Anil
  • 554
  • 4
  • 4
5

This works very well for me when wanting to merge two branches without having to checkout either of them:

git fetch . <modified branch>:<destination branch>

Other options are described here.

G-Man
  • 1,138
  • 16
  • 20
4

One possible solution would be to clone make another working tree from the same local repo and perform the merge in said working tree (with main checked out), being able to solve potential conflicts there.
Creating a separate working tree is much faster than making a separate clone (which was my original suggestion back in 2011): it uses the Git 2.5+ (July 2015) git worktree command.

Then, at a later date, when able to switch to main in the local repo (your first working tree, where you are working), you would then restore the updated main branch from the separate working tree.


Alternatively, Bernardo Dal Corno suggests in the comments a 2014 tool/script: schuyler1d/git-forward-merge from Schuyler Duveen.

git forward-merge creates a temporary Git index file and working directory to be used only for the merge, without interfering with the actual index file and working directory.
(Unless the merge is a fast-forward, in which case the merge is done trivially by a local push.)

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I will not be able to checkout `master` in my original repo. I just need to merge the `dev` changes into it. Your solution is what I'm using now. THe problem is that the clone takes a while and I'm looking for ways to optimise that. – Noufal Ibrahim Jul 01 '11 at 17:23
  • 2
    @Noufal Ibrahim: If the clone's taking a long time that suggests to me that you're using a URL for which hard-linking won't be the default. Have you tried adding `--local` to your `git clone` invocation to force that? – Mark Longair Jul 01 '11 at 18:24
  • That's an awful hack. Imagine doing that with large repos or frequently. – Bernardo Dal Corno Jun 23 '21 at 15:17
  • 1
    @BernardoDalCorno 10 years later, I full agree. I have updated the answer to use a more modern command (`git worktree`) which makes that process faster and not "hackish". – VonC Jun 23 '21 at 15:33
  • 1
    thanks @VonC , this seems to be the best approach nowadays. Seems worth to check this [git-forward-merge](https://github.com/schuyler1d/git-forward-merge) as well – Bernardo Dal Corno Jun 23 '21 at 20:14
  • @BernardoDalCorno Thank you. I have included your comment in the answer for more visibility. – VonC Jun 23 '21 at 20:42
1

Even if your branch isn't fast-forwardable and even if it has real conflicts, you can still merge without a full checkout. Say you want to merge your current tip dev into master. It's worth trying the git push . dev:master if you think it might work, that checks whether a fastforward is the right move and if so does it right there, but if you can't just re-hang the label your next step is

git clone -nsb master . `mktemp -d`
cd $_
git reset -q
git merge origin/dev
git push
cd -

and you have now done a "minimum-checkout merge". The clone, cd and reset takes less time to run than it takes to type on a not-small project (3.5G history, 1.2G full checkout is >70K files) on a ten-year-old midrange because it doesn't duplicate anything.

jthill
  • 55,082
  • 5
  • 77
  • 137