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:
- if the conflicting files are comitted with the conflict markers (i.e., the conflicting files are comitted with
<<<
,===
, and>>>
markers); - 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.