When you resolve a conflict, then stage the changes, then do a git diff, it shows you two columns of +'s and -'s, one for "ours" and one for "theirs". Given a merge commit in a repo's git history, how do I see that resolution, which was done by someone else? In other instances, I've seen it before (in gitk, I think), but I can't seem to determine it for this SHA1 that I have.
To see the beginning of the merge conflict in your file, search the file for the conflict marker <<<<<<< . When you open the file in your text editor, you'll see the changes from the HEAD or base branch after the line <<<<<<< HEAD .
Git can handle most merges on its own with automatic merging features. A conflict arises when two separate branches have made edits to the same line in a file, or when a file has been deleted in one branch but edited in the other. Conflicts will most likely happen when working in a team environment.
Go to your merge request. Select Overview, and scroll to the merge request reports section. Find the merge conflicts message, and select Resolve conflicts. GitLab shows a list of files with merge conflicts.
If you know the ref, then git show <MERGE_COMMIT>
will show you the resolution done (if any) for the merge commit.
For log, use git log -p -c
or git log -p --cc
. From the manpage of git log:
-c With this option, diff output for a merge commit shows the differences from each of the parents to the merge result simultaneously instead of showing pairwise diff between a parent and the result one at a time. Furthermore, it lists only files which were modified from all parents. --cc This flag implies the -c option and further compresses the patch output by omitting uninteresting hunks whose contents in the parents have only two variants and the merge result picks one of them without modification.
The more recent (2022, nine years later) option is:
git log --remerge-diff
With Git 2.36 (Q2 2022), "git log --remerge-diff
"(man) shows the difference from mechanical merge result and the result that is actually recorded in a merge commit.
See commit 0dec322, commit 0d83d82, commit 20323d1, commit 95433ee, commit 6054d1a, commit a28d094, commit 24dbdab, commit 35f6967, commit 7b90ab4, commit db757e8 (02 Feb 2022) by Elijah Newren (newren
).
See commit 5046831 (21 Dec 2021) by Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
-- in commit 90b7153, 16 Feb 2022)
show, log
: provide a --remerge-diff capabilitySigned-off-by: Elijah Newren
When this option is specified, we remerge all (two parent) merge commits and diff the actual merge commit to the automatically created version, in order to show how users:
- removed conflict markers,
- resolved the different conflict versions, and
- potentially added new changes** outside of conflict regions in order to resolve semantic merge problems (or, possibly, just to hide other random changes).
This capability works by creating a temporary object directory and marking it as the primary object store.
This makes it so that any blobs or trees created during the automatic merge are easily removable afterwards by just deleting all objects from the temporary object directory.There are a few ways that this implementation is suboptimal:
log --remerge-diff
becomes slow, because the temporary object directory can fill with many loose objects while running- the log output can be muddied with misplaced "warning: cannot merge binary files" messages, since
ll-merge.c
unconditionally writes those messages to stderr while running instead of allowing callers to manage them.- important conflict and warning messages are simply dropped; thus for conflicts like modify/delete or rename/rename or file/directory which are not representable with content conflict markers, there may be no way for a user of
--remerge-diff
to know that there had been a conflict which was resolved (and which possibly motivated other changes in the merge commit).- when fixing the previous issue, note that some unimportant conflict and warning messages might start being included.
We should instead make sure these remain dropped.
Subsequent commits will address these issues.
diff-options
now includes in its man page:
--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc|remerge|r)
diff-options
now includes in its man page:
--diff-merges=remerge:
--diff-merges=r:
--remerge-diff:
With this option, two-parent merge commits are remerged to create a temporary tree object -- potentially containing files with conflict markers and such.
A diff is then shown between that temporary tree and the actual merge commit.
The output emitted when this option is used is subject to change, and so is its interaction with other options (unless explicitly documented).
Note that one of the commits above is somewhat reverted with With Git 2.36 (Q2 2022):
See commit 624a935 (02 Mar 2022) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit 8b44e05, 13 Mar 2022)
merge-ort
: exclude messages from inner merges by defaultSigned-off-by: Elijah Newren
merge-recursive would only report messages from inner merges when the
GIT_MERGE_VERBOSITY
was set to 5. Do the same formerge-ort
.Note that somewhat reverts 0d83d82 ("
merge-ort
: mark conflict/warning messages from inner merges as omittable", 2022-02-02, Git v2.36.0 -- merge listed in batch #4) based on two facts:
- This commit basically removes the showing of messages from inner merges as well, at least by default.
The only difference is that users can request to get them back by turning up the verbosity.- Messages from inner merges are specially annotated since 4a3d86e ("
merge-ort
: make informational messages from recursive merges clearer", 2022-02-17, Git v2.36.0 -- merge listed in batch #8).
The ability to distinguish them from outer merge comments make them less problematic to include, and easier for humans to parse.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With