Which version of the git file will be finally used: LOCAL, BASE or REMOTE?

103,640

Solution 1

It's the one in the middle : BASE.

In fact, BASE is not the common ancestor, but the half-finished merge where conflicts are marked with >>>> and <<<<.

You can see the file names on the top of meld editing window.

See the screenshot here

meld base

You can edit the BASE file as you want with or without using meld commands.
You can also get rid of meld and just edit the file with your favorite text editor.

  • The code between <<<< HEAD and ===== markers is the one of your local file before the merge.
  • The code between ==== and >>>> <branch name> is the one of the remote file.

Solution 2

Meld has a hidden 3-way merge feature activated by passing in the 4th parameter:

meld $LOCAL $BASE $REMOTE $MERGED

The right and left panes are opened in read-only mode, so you can't accidentally merge the wrong way around. The middle pane shows the result of merge. For the conflicts it shows the base version so that you can see all the important bits: original text in the middle, and conflicting modifications at both sides. Finally, when you press the "Save" button, the $MERGED file is written - exactly as expected by git.

The ~/.gitconfig file I use contains the following settings:

[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED

this opens meld with 3 tabs, 1st and 2nd tab containing the simple diffs I'm trying to merge, and the 3rd tab, open by default, shows the 3-way merge view.

Now, the reason the feature is hidden is that it's not polished enough yet. It's very useful as it is now, but Kai Willadsen, the meld author, pointed to few wrinkles that need ironing out. For example there's no GUI to start the 3-way merge mode, command line syntax is a bit arcane, and such. If you speak python and have some time on your hands - you know what to do.

Edit: In newer versions of Meld, the synax has changed slightly. This was in the comments, but it belongs in the answer.

The meld command now uses the --output option, so the last line from the snippet above should be:

cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

Solution 3

There are 4 files involved:

  1. $LOCAL The file on the branch where you are merging; untouched by the merge process when shown to you

  2. $REMOTE The file on the branch from where you are merging; untouched by the merge process when shown to you

  3. $BASE The common ancestor of $LOCAL and $REMOTE, ie. the point where the two branches started diverting the considered file; untouched by the merge process when shown to you

  4. $MERGED The partially merged file, with conflicts; this is the only file touched by the merge process and, actually, never shown to you in meld


The $MERGED file is the one that contains the <<<<<<, >>>>>>, ===== (and, maybe, ||||||) markers (that delimit conflicts). This is the file that you edit manually to correct conflicts.

The manual conflicts editing and the visual conflicts editing are done on different files and presented different informations.

When using the mergetool (assume meld), the files that are seeing therein are: $LOCAL, $BASE, $REMOTE. Note that you don't see the $MERGED file, although this is passed as a hidden parameter to meld to write the result of the edit there.

In other words, in meld, you are editing the file in the middle, the $BASE file, and you pick all the changes from left or from the right manually. It is a clean file, not touched by the merge process. The only glitch is that, when you save, you do not save into the $BASE file, but in the fourth hidden parameter of meld, that is the $MERGED file (that you do not even see). The $BASE file does not contain any conflicts or partial successful merges because it is not the $MERGED file.

In the visual editing, when presenting to you the $BASE file (instead of the $MERGED file) git basically discards all its attempts to do the merging (those attempts are visible, if you want, in the $MERGED file) and lets you to completely do the merging from scratch.

The bottom line is that in manual and visual merging conflicts you are not looking at the same files, but the final result is written in the same file (that is the $MERGED file).

The manual correction of the conflicts is done on $MERGED because git has no mean to present you three files, so it squashes the information from the three files ($LOCAL, $BASE, $REMOTE) in that $MERGED file.

But the visual tools have the means to show you three files: they show you the $LOCAL, $BASE, $REMOTE files. You are picking changes from the $LOCAL and $REMOTE files and you are bringing those into the $BASE file, completely re-building and even overwriting the failed attempt of merging that is the $MERGED file.

Solution 4

Cosmin's solution works, but the $BASE file is updated--not $MERGED. This will update the $MERGED file:

Meld: v1.8.4

[merge]
  conflictstyle = diff3
  tool = mymeld
[mergetool "mymeld"]
  cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE --diff $BASE $LOCAL --diff $BASE $REMOTE

Solution 5

With Meld 1.7 the Solution by Tomek Bury does not work anymore.

The default settings didn't satisfy me:

Default settings

Instead for Meld >=1.7 I suggest one of two other solutions.

First solution:

 meld $LOCAL $BASE $REMOTE --auto-merge

first solution

Second solution:

 meld $LOCAL $MERGED $REMOTE

second solution

.gitconfig

Copy & paste this in your .gitconfig file to get the solutions as described above:

[merge]
    tool = meld16
[mergetool "meld17"]
    # use this for Meld >=1.7
    # see http://stackoverflow.com/a/22911793/859591
    # second solution:
    cmd = meld $LOCAL $MERGED $REMOTE
    # first solution:
    #cmd = meld $LOCAL $BASE $REMOTE --auto-merge
[mergetool "meld16"]
    cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

[include]
    # requires git v1.7.10+
    path = .gitconfig.local

Copy & paste this in a .gitconfig.local file to set meld17 or meld16 only for this machine in case you use your .gitconfig on multiple machines:

# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
    tool = meld17
Share:
103,640

Related videos on Youtube

tsusanka
Author by

tsusanka

Updated on August 18, 2020

Comments

  • tsusanka
    tsusanka almost 4 years

    When there's a collison during git merge, I open a mergetool called Meld. It opens three files LOCAL, BASE and REMOTE. As I've read LOCAL is my local branch, BASE is common ancestor and REMOTE is the branch to be merged.

    Now to my question: which version of the file will be finally used? Is it REMOTE? If so, can I edit it as I want, regardless what's in the BASE branch for example?

  • kostix
    kostix almost 12 years
    Some people get better understanding of the conflicting chunks in a file which failed automatic merging if they have the merge.conflictstyle configuration option set to diff3 instead of the default merge.
  • tsusanka
    tsusanka almost 12 years
    I actually don't see the HEAD, <<< and === sings. In the case you provided the middle window would be empty. But that's just a note for the others, thx for your answer.
  • Fabien Quatravaux
    Fabien Quatravaux almost 12 years
    If you don't see the HEAD, <<<<< and ===== signs, it means that there is no conflict at all. In this case, the middle window will not be empty, it will show the merge result, but there will be no "red" part
  • Teemu Leisti
    Teemu Leisti over 11 years
    When I'm doing merges with Meld, I don't see any <<<<<<, ====== nor >>>>>> markers in the middle pane (i.e. the BASE version) either; and sometimes, the middle pane will be empty, like aGr reported. Maybe this difference is due to different settings. When I start the Meld tool, the following files will exist, assuming that the name of the file in the repository is X.java: X.java, X.java.orig, X.java.BACKUP.#, X.java.BASE.#, X.java.LOCAL.#, X.java.REMOTE.#, where # is some number. Calling the merge result the BASE version is confusing; MERGED would be better.
  • yoniLavi
    yoniLavi over 10 years
    I just wanted that there are tools (e.g. beyond compare) that do show all 4 files
  • user1284631
    user1284631 over 10 years
    @yoniYalovitsky: yes, or p4merge
  • lumbric
    lumbric over 10 years
    @Jesse This seems to work with Meld 1.6.0, but not with Meld 1.7.0.
  • Johann
    Johann over 10 years
    @Jesse, @lumbric, it appears that newer versions of meld use the flag --output for the $MERGED result. I discovered this while looking at the meld launch script that came with my version of git: github.com/git/git/blob/master/mergetools/meld
  • cosmin
    cosmin about 10 years
    I can confirm this.Saad's solution works for me on Ubuntu. As far as the original question goes this is the current correct answer.
  • lumbric
    lumbric about 10 years
    @Johann Hm yes you are right, but that does not solve the problem. The launch script you linked, does not provide the advanced functionality as described in the solution by Tomek Bury.
  • Johann
    Johann about 10 years
    @lumbric I believe it does, for Meld 1.7.x+ with the --output option. See this line in the launch script: "$merge_tool_path" --output "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
  • lumbric
    lumbric about 10 years
    @Johann Yes. You are right, thanks a lot! Actually a recent git version comes with a correctly configured launch script. After doing a dist upgrade I noticed that my meld configuration does not work anymore. Simply removing my custom config for meld solves all issues.
  • RoboAlex
    RoboAlex over 9 years
    In latest meld (version > 1.8.4), we have to use --auto-merge option. cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --auto-merge $LOCAL $BASE $REMOTE --output $MERGED
  • MartinM
    MartinM over 9 years
    In my version of meld - 3.11, this command works great: cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
  • mishmashru
    mishmashru about 9 years
    I used to use merge tool from ClearCase package
  • pingpongboss
    pingpongboss almost 9 years
    In Meld 1.8.4, the 3rd tab does not open by default. My .gitconfig contains: [merge] tool = mymeld conflictstyle = diff3 [mergetool "mymeld"] cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --auto-merge $LOCAL $BASE $REMOTE --output $MERGED
  • farmir
    farmir over 8 years
    I had the same problem as @pingpongboss using Meld 1.8.4: Meld was opening things in a separate pane, instead of opening 3rd tab. The command the finally worked fine is: cmd = meld $LOCAL $BASE $REMOTE --auto-merge --output $MERGED. So, this opens 3 tabs (good old way), auto merges non-conflicting merges into the middle, where the middle is $MERGED, and will be used as conflict resolution output.
  • farmir
    farmir over 8 years
    This does not work on Meld 1.8.4. If you run cmd = meld $LOCAL $BASE $REMOTE --auto-merge, the middle pane will be the $BASE, and not the $MERGE which is actually used as the output of conflict resolution.
  • farmir
    farmir over 8 years
    why would you need --diff $BASE $LOCAL --diff $BASE $REMOTE at the end? for me on 1.8.4, this works fine (as far as I can see): cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
  • levsa
    levsa over 8 years
    The syntax for output may be --output=<file> or -o <file>, see meld --help
  • Sam Kauffman
    Sam Kauffman over 8 years
    @farmir: It's not necessary. It opens two more tabs in meld so you can see LOCAL and REMOTE compared against BASE individually.
  • Sam Kauffman
    Sam Kauffman over 8 years
    No matter what order I try with those arguments, the three-way tab is always the third tab, while the first tab is always selected by default. Is there a way to make the three-way tab selected by default?
  • mattst
    mattst over 8 years
    BASE is in fact the common ancestor, MERGED is the name of the file with the partial merge information in it. Please see my question and answer Setting up and using Meld as your git difftool and mergetool which explains exactly how it works. HTH.
  • MadMad666
    MadMad666 almost 8 years
    Excuse me, Is this configuration inux compatible ?
  • Edwin Hoogerbeets
    Edwin Hoogerbeets over 7 years
    The part I was missing to get this to work is that I didn't know the git command line to run to get this to work: git merge otherbranch followed by git mergetool. The second command launches meld for each conflicted file.
  • aff
    aff about 7 years
    I see that using the shorter meld $LOCAL $BASE $REMOTE --output $MERGED works fine. What's the purpose of having three separate --diff in the command line? I can't have it (command with --diff) work with my SourceTree (on Windows) -- Meld opens fine but SourceTree prematurely consider the merge as completed.
  • Alex78191
    Alex78191 about 7 years
    @farmir You chose $BASE as the second tab.
  • Brandon Loudermilk
    Brandon Loudermilk almost 7 years
    The reason you don't see HEAD, <<<<, & ==== is that with a default configuration setting the middle window is set to $BASE (the ancestor). If you switch your config to cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED" then you middle is $MERGED and you will see the <<<, ===, etc. See this thread
  • wnasich
    wnasich almost 7 years
    I found useful the answer of @lumbric stackoverflow.com/a/22911793/641892
  • Sam Kauffman
    Sam Kauffman almost 7 years
    I upgraded to Debian 9, and with it came Meld 3.16.4, and this no longer works. Meld only opens one tab even though the command includes three tabs. Anyone know how to fix that?
  • supervacuo
    supervacuo about 6 years
    this may be correct for Meld, but is mad confusing in general — BASE is definitely the common ancestor as far as git is concerned, e.g. see this other answer
  • BeeOnRope
    BeeOnRope almost 6 years
    @yoniLavi - well these tools show 4 panes, but not necessarily all four files as described in this answer. In particular, you can set up these 4-pane tools to show you $LOCAL, $REMOTE, $BASE and the output initially equal to $BASE, but which is different from $MERGED in that it doesn't have git's attempt to merge the files and the conflict markers and so on. In fact, that would be the way to use these tools that is most similar to the 3-pane approach of LOCAL/REMOTE/BASE+OUTPUT, which doesn't show merged. The 4th pane just allows you to separate the base from the output.
  • ANewGuyInTown
    ANewGuyInTown almost 4 years
    Wrong - Base is the common ancestor.