Home > Software design >  Is it possible to use the git merge tools on files that contain conflict markers (i.e., `<<<
Is it possible to use the git merge tools on files that contain conflict markers (i.e., `<<<

Time:11-23

Problem description

When merging two branches in git with conflicting files, git adds markers to the conflicting areas. For example, a file with conflict would look like this

Some code

<<<<<<< HEAD
Changes in branch A
||||||| cbf9a68
Original code
=======
changes in branch B
>>>>>>> branch-B

some more code

where branch-A/HEAD is the branch to merge into, branch-B is the branch to merge, and <<<, ===, and >>> are referred to as conflict markers. There are various tools that help in resolving these conflicts. These include meld, vimdiff, diffview, and many more. However, these tools can only be used in git repos that are in conflict-resolution status (i.e., when the two branches are not yet merged).

There are situations where these tools can no longer be used (as far as I'm aware), and these include:

  1. if the conflicting files are comitted with the conflict markers (i.e., the conflicting files are comitted with <<<, ===, and >>> markers);
  2. if the conflicting file with the conflict markers are moved outside a git repo (e.g., to keep track of conflicts).

In such situations, the git merge tools can no longer be used to resolve these conflicts.

It seems that these conflict tools are only possible to use in a git repo, which makes sense. So, my question is as follow: is it possible to use the git merge tools on files that contain conflict markers (i.e., <<<, ===, and >>>) outside a git repo (or after comitting the file with conflict markers)?

That is, I would like the process to look like this:

git checkout branch-A
git merge branch-B

# Part 1: committing file with conflict markers
git add foo.txt                           # Add conflicting file, with conflict markers (i.e., withOUT resolving conflicts)
git commit -m "Add conflicting file"      # Commit file with conflict markers

# Part 2: resolve conflict on committed files (i.e., this is what I'm asking for)
# TODO: Use conflict resolution tools such as meld, diffview, etc. to find conflict markers and resolve them
git add foo.txt                           # Stage and commit files after resolving conflicts
git commit -m "Conflicts resolved"

When is this problem encountered?

I understand this is an unusual way to use the git merge tools, but here's a situation where it can be used. Some organizations ask developers to commit the conflicting files with the conflict markers, and then resolve the conflicts in another commit. The reasoning is that when creating a PR, the reviewers can see how the developer resolved the conflicts.

I understand this may be considered a bad practice (e.g., committing the files with conflict markers means there's a commit at which the code doesn't work or compile). However, my question is not about this practice since I have no option but to follow this convention.

Sub-optimal solution

A possible sub-optimal solution to the problem above is the following

git checkout branch-A
git merge branch-B

# Part 1: committing file with conflict markers
git add foo.txt                           # Add conflicting file, with conflict markers (i.e., withOUT resolving conflicts)
git commit -m "Add conflicting file"      # Commit file with conflict markers

# Part 2: committing file to another branch after conflict resolution
git checkout HEAD~1                       # Checkout previous commit (i.e., before merging)
git checkout -b branch-A-resolved         # Create a branch at which the conflicts are to be resolved
git merge branch-B                        # Merge branch-B
# Resolve conflicts
git add foo.txt                           # Add file *after* resolving conflicts
git commit -m "Resolve conflicts"         # Commit file withOUT conflict markers

# Part 3: cherry-pick conflict-resolved files into branch-A
git checkout branch-A
git cherry-pick branch-A-resolved -m 1 -X theirs  # `theirs` is used since `branch-A-resolved` contains the resolved file
git branch -D branch-A-resolved

The above solution works, but as you can see, it's quite tedious.

CodePudding user response:

Unclear what you mean by the Git merge tools; the tools you mention don't belong to Git. The tools I use are a really good text editor and my brain. That's all you need to resolve a conflicted file containing the markers. The tools you mention don't tell you anything that you can't see with your own eyes just by looking at the marked up file (especially when the file is marked up in diff3 style, as yours is).

CodePudding user response:

The short answer is "no". matt has already covered some of the longer answer, but there's one more item to know here: when you run git mergetool, Git grabs the three copies of the file that exist in Git's index aka staging area. Git does not directly use the working tree copy, with its conflict markers, to invoke your chosen merge tool.

If all you have is a single marked-up-with-conflicts file, the only way to make git mergetool work with it would be to read it, construct the three inputs, insert them into the index using git update-index, and then run git mergetool. Many conflicted (marked-up) files don't have enough information to construct the original three inputs, but you could construct something that might (or might not) be good enough for your purposes, whatever those purposes are. Whether that's the case depends on your needs.

Note: You're probably better off constructing the three input files and invoking your chosen merge tool directly, rather than using git update-index and running git mergetool. This cuts out a lot of the complexities and means you don't need a Git repository in the first place.

  • Related