108

I want to merge all files manually with meld or any other diff tool, how can I do this with Git?
When I run git mergetool it says no files need merging. So I suppose I can do it only if I have conflicts.

9
  • Please provide us some context of what you want to merge and why you don't want this done automatically.
    – johnsyweb
    Commented Jan 11, 2011 at 11:31
  • 3
    I want to merge text files :) I used to mercurial's manual merging and like to see 3 files simultaneously, if something goes wrong I always can edit all of them by myself
    – gennad
    Commented Jan 11, 2011 at 11:53
  • 13
    Yes, I would like to merge manually in some cases because in such situations I know that everything goes as I want, not as the app decided
    – gennad
    Commented Jan 11, 2011 at 16:14
  • 1
    What about merging automatically and fixing problems if happen? Commented Jan 11, 2011 at 20:08
  • 6
    @TomaszWysocki because there is no way for me to know if a "problem as deemed problematic by the human" has arisen. There is only a way for me to know if a "problem as deemed problematic by git" has arisen. Git merges files automatically and I don't get to checkmark all of git's automatic decision-making results. It can decide to make a specific change that I don't like. I want to approve all changes before they are made.
    – cake
    Commented Aug 20, 2019 at 18:49

7 Answers 7

128

There is much simpler way:

git merge --no-commit merge_branch

As man says:

With --no-commit perform the merge but pretend the merge failed and do not autocommit, to give the user a chance to inspect and further tweak the merge result before committing.

4
  • 7
    Thank you. Is there perhaps a way to use mergetool/meld to review and merge the changes piecewise with a nice threeway interface?
    – James
    Commented Nov 30, 2014 at 21:17
  • 21
    By adding --no-ff the fast forwarding is disabled, which will happen if there are no conflicts.
    – Løiten
    Commented Sep 25, 2016 at 10:40
  • And of course, use git mergetool if there are conflicts.
    – Pluto
    Commented Dec 18, 2018 at 1:56
  • 23
    This is still an automatic merge, so this doesn't answer the origin question. Commented Jul 17, 2019 at 17:58
90

I had a scenario where:

git merge --no-commit merge_branch 

just caused a Fast Forward.

If this happens you can use:

git merge --no-commit --no-ff merge_branch

and then you'll be able to review your changes

5
  • 1
    Is it possible to pull it in the same way? I need to verify ALL conflicts manually if fast-forward is not possible.
    – Maxim
    Commented Apr 17, 2016 at 21:58
  • 1
    @Maxim no but since pull is just the combination of fetch and merge do first call git fetch merge_branch then latter do merge
    – Top-Master
    Commented Oct 9, 2018 at 5:28
  • using both --no-commit --no-ff is like having .gitattributes file in root dir containing * -merge, but with per merge choice to use it or not
    – Top-Master
    Commented Oct 9, 2018 at 7:04
  • 5
    I get Automatic merge went well; stopped before committing as requested upon running that. When I try to run git mergetool it says No files need merging.
    – Unknow0059
    Commented Oct 28, 2020 at 8:08
  • Just speculating this method is effectively like copying files from another source (eg a clone from this repository with current branch 'merge_branch' and clean). In this case I would expect only 'git difftool' showing any changes.
    – grenix
    Commented Oct 27, 2021 at 12:55
23

A similar question is How to prevent an automerge using git?

FractalSpace gave an answer which I think useful:

$ git checkout master
$ git difftool -t kdiff3 local-branch HEAD

The idea is using difftools instead of auto-merging tools to manually pick what you need and create new files.

3
  • I've added an answer comparing this answer to the git merge answers to help clarify things for anyone else who stumbles into this page.
    – stevegt
    Commented Apr 27, 2019 at 21:45
  • When I try to manually merge this way with kdiff3 or meld, it saves changes to a temporary file in /tmp and does not change the working dir. But I need to store changes to the working dir.
    – porton
    Commented Feb 16, 2021 at 18:24
  • the history might get lost here. Also this dies not show up like a merged branch. For git this might just look like a huge commit out of the void.
    – Cutton Eye
    Commented Feb 17, 2021 at 10:03
20

For anyone who just needs to micromanage a merge, jump to the Hybrid section below.

For anyone who is wondering about the difference between @True's answer using git difftool and the other answers that use git merge, see Git mergetool vs difftool.

Here are more details:

Difftool

If you have git configured to use a modern diff.tool such as kdiff3, meld, or vimdiff, you'll be able to manually merge using that diff tool, and the command line can be simple:

git difftool other_branch

...this will let you do a two-way manual merge between your current branch and other_branch (described as $LOCAL and $REMOTE in man git-config).

Mergetool

The "correct" way the other answers discuss would be to instead configure git to use e.g. kdiff3 or vimdiff as your merge.tool, and use:

git merge --no-commit --no-ff other_branch
git mergetool

...this command can do an N-way manual merge between $BASE, $LOCAL, and $REMOTE, into $MERGED. See https://stackoverflow.com/a/2235841/1264797 for one example of how to configure git. You many not need to configure the mergetool.*.cmd entry at all if you use one of the tools git already knows about. (Meld can only show three panes, so if you use meld with the default settings, you'll not see $BASE.)

Difftool vs mergetool

Someone might jump in to correct me, but the main differences between the above difftool and mergetool techniques seem to be:

  • mergetool can do an N-way merge if configured accordingly
  • mergetool adds other_branch as a parent on the new commit so history works correctly
  • difftool lets you manually see and select each and every changed line, but you lose the above two benefits of mergetool

Hybrid -- best of both worlds

A method that combines merging and diffing would look something like this:

git merge --no-commit --no-ff other_branch
git mergetool
git difftool HEAD
git commit

...this does the N-way merge to resolve conflicts and make history work right, and then shows you the complete set of diffs so you can review and tweak before you commit.

2
  • When I try to manually merge this way with kdiff3 or meld, it saves changes to a temporary file in /tmp and does not change the working dir. But I need to store changes to the working dir.
    – porton
    Commented Feb 16, 2021 at 18:22
  • @porton You may have to do some more experimentation, but one of the panes should be the working dir file, or should be a file that gets automatically copied into the working dir after you exit. I don't remember which, and it may be dependent on your git version and tool config.
    – stevegt
    Commented Mar 12, 2021 at 18:37
11

I found the other answers unsatisfactory and became frustrated searching for an answer. A solution to this question I finally found here: https://stackoverflow.com/a/11593308/1351182

If you run these commands, you will create a new commit which essentially takes the latest commit of branchToMergeFrom and allows you to apply a patch on top of it, which I think is like an additional commit on top.

git checkout branchToMergeTo
git checkout --patch branchToMergeFrom [file]

You will then be prompted (file-by-file if you didn't specify file) on exactly which 'hunks' you want to merge. In this way it walks you through each part of what would have been the automatic merge process and instead asks for manual arbitration on which bits and pieces you want to accept from the mergefrom branch. Here's an example of what it looked like in my project:

@@ -249,7 +251,8 @@ def draw_everything():
  
     draw_bg()
     draw_balls(ax)
-    plt.show(block=False)
+    if show:
+        plt.show(block=False)
 
 def advance(ms, accel_fun, collision_matrix_fun):
     global balls
(3/6) Apply this hunk to index and worktree [y,n,q,a,d,K,j,J,g,/,e,?]?

After typing y and <Enter>, I was presented with the next hunk, (4/6) for that file. This prompt at the bottom lets you simply accept the merge 'hunk' with y, reject it with n, or even go in and edit it manually. Here are the options:

y - apply this hunk to index and worktree
n - do not apply this hunk to index and worktree
q - quit; do not apply this hunk or any of the remaining ones
a - apply this hunk and all later hunks in the file
d - do not apply this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

I wanted to go in and manually edit one hunk, as I didn't want to accept or reject the merge exactly as it was posed. So I chose e and was given a file to edit. I was pleased when I noticed there were even instructions at the bottom on how to edit the hunk properly. You can even split hunks into smaller ones with the s option as above.

I would recommend this process if what you want is manual merging where you still leverage the automatic process as much as possible. The difference is that you get to oversee every merge 'hunk' and edit them as you please. I hope this helps future readers.

After this process, you probably want to run git checkout branchToMergeTo && git merge branchToMergeFrom in order to formally merge the history of branchToMergeFrom into branchToMergeTo.

8

Note, if you insists of merging manually (perhaps for a certain class of files), you still can define a merge driver.
You have a concrete example in "Git - how to force merge conflict and manual merge on selected file".

That way, your merge driver script can call any merge tool you want.

1

I pick strategy ours (it exist also as a pick in TortoiseGit), after doing a manual diff where you have brought-in changes you wanted manually.

From: https://git-scm.com/docs/merge-strategies

The merge mechanism (git merge and git pull commands) allows the backend 'merge strategies' to be chosen with -s option. Some strategies can also take their own options, which can be passed by giving -X arguments to git merge and/or git pull.

ours

This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches. Note that this is different from the -Xours option to the 'recursive' merge strategy.

What Bitbucket see later however is a mystery to me, it recognise the commit as merge but fail to actually merge the branch (does not solve a pull-request) - probably Bitbucket guru could help on this issue, I can not even give you any logs/error messages since I do not have that visibility - git/TortoiseGit does not complain at all though.

Not the answer you're looking for? Browse other questions tagged or ask your own question.