2.31. Resolving Conflicts

TortoiseGit

2.31. Resolving Conflicts

During a merge, the working tree files are updated to reflect the result of the merge. Once in a while, you will get a conflict when you merge another branch, cherry-pick commits, rebase or apply a stash: Among the changes made to the common ancestor's version, non-overlapping ones (that is, you changed an area of the file while the other side left that area intact, or vice versa) are incorporated in the final result verbatim. When both sides made changes to the same area, however, Git cannot randomly pick one side over the other, and asks you to resolve it by leaving what both sides did to that area. Whenever a conflict is reported you need to resolve it!

The conflicting area is marked in the file like this (also cf. the section called “HOW CONFLICTS ARE PRESENTED”):

<<<<<<< yours
    your changes
=======
    changes from the code merged
>>>>>>> their

You can use any editor to manually resolve the conflict or you can launch an external merge tool/conflict editor with TortoiseGitEdit Conflicts. Then TortoiseGit will place three additional files in your directory for the selected conflicted file and launch the configured conflict editor:

filename.ext.BASE.ext

This is the common ancestor's version of the conflicted file (this version does contain neither any of your nor any of the changes of the to be merged branch/revision, especially it does not contain any conflict markers).

filename.ext.LOCAL.ext

This is your file as it existed in your working tree before you started the merge (i.e., the file conforms to the latest committed state of the HEAD of your local repository) - that is, without conflict markers. Therefore, this state/version is often also called "mine".

Just for completeness "mine" means for "stash"/"merge"/"pull"/"cherry-pick" the HEAD version in your working tree and for "rebase" the version on the branch you rebase.

filename.ext.REMOTE.ext

This is the version of file of the revision you want to merge (on a normal merge this correspondents to MERGE_HEAD). As you want to merge other changes, this state/version is often also called "theirs".

Just for completeness "theirs" means for "stash"/"merge"/"pull"/"cherry-pick" the version of the to be merged commit/branch and for "rebase" the version of the branch you rebase onto.

Afterwards execute the command TortoiseGitResolved and commit your modifications to the repository (if the conflict occurred while rebasing or cherry-picking make sure you use the cherry-pick resp. rebase dialog for committing and not the normal commit dialog!). Please note that the Resolve command does not really resolve the conflict. It uses "git add" to mark file status as resolved to allow you to commit your changes and it removes the filename.ext.BASE.ext, filename.ext.LOCAL.ext and filename.ext.REMOTE.ext files.

If you have conflicts with binary files, Git does not attempt to merge the files itself. The local file remains unchanged (exactly as you last changed it). In order to resolve the conflict use TortoiseGitResolve... and then right click on the conflicted file and choose one of Resolved (the current version of the file which is in the working tree will be used), Resolve conflict using 'mine' (the version of the file of your HEAD will be used), and Resolve conflict using 'theirs' (the version of the file of the merged revision/branch will be used). After that commit.

You can use the Resolved command for multiple files if you right click on the parent folder and select TortoiseGitResolve... This will bring up a dialog listing all conflicted files in that folder, and you can select which ones to mark as resolved.

Figure 2.57. The resolve conflicts dialog

The resolve conflicts dialog

[Important] Important

Git (unlike SVN) does not automatically create filename.ext.BASE.ext, filename.ext.LOCAL.ext and filename.ext.REMOTE.ext files for conflicted files. These are only created on-demand by TortoiseGit when you use the command Edit Conflicts.

[Important] Important

In Git (unlike SVN) you have to commit after resolving conflicts. However, if the conflict occurred while rebasing or cherry-picking make sure you use the cherry-pick resp. rebase dialog for committing and not the normal commit dialog!

2.31.1. Special conflict cases

2.31.1.1. Delete-modify conflicts

A special conflict case is a delete-modify conflict. Here, a file is deleted on one branch and the same file is modified on another branch. In order to resolve this conflict the user has to decide whether to keep the modified version or delete the file from the working tree.

Figure 2.58. Resolve delete-modify conflict Dialog

Resolve delete-modify conflict Dialog


2.31.1.2. Submodule conflicts

Another special conflict case is a conflict involving a submodule. Here, a submodule is changed in different (conflicting) ways on two branches.

The resolve submodule conflict dialog shows the base, the local and the remote commit of the conflicting submodule as well as the commit type (rewind, fast-forward, ...).

Figure 2.59. Resolve submodule conflict Dialog

Resolve submodule conflict Dialog


[Important] Uninitialized submodules

If the submodule is not yet initialized the resolve submodule conflict dialog only shows the commit IDs (SHA-1). Also, the conflict cannot be resolved automatically: First, you have to manually clone the submodule into the right folder. Then, you can resolve the conflict using TortoiseGit or git (by checking out the right commit in the submodule and commiting the parent working tree).