1

Today I check the last merges in our GIT repository, because several modifications are lost.

If I open the overview I just get the following output on plattform:

Merge branch 'master' of bitbucket.org:<ourProject>/<ourRepo>

# Conflicts:
#   <pathToTheFile>.cs

Is it possible to show all modifications of a merge? And if it's possible, how can I check it?

michael-mammut
  • 2,595
  • 5
  • 28
  • 46
  • Do you mean something like `git diff`? Keep in mind that you may not know what exactly happened during the resolution of a merge conflict. – Tim Biegeleisen Jul 09 '18 at 12:54
  • I think `git diff` will only give you a difference before commit. After merge conflicts, I think there is no way to verify each and every line of code. What you can do is, You can compare with two commits to check what was actually happened during the merge. – Hardik Shah Jul 09 '18 at 12:58
  • currently it try this, `git diff 16da8c7 17cef3a` but there are some problem. 'fatal: ambiguous argument '16da8c7': unknown revision or path not in the working tree.' I try to find the mistake – michael-mammut Jul 09 '18 at 12:59
  • git comes with the `gitk` utility. there you can select the merge commit and see which changes have been made to resolve the conflicts. **--** BTW: having a set of unittests would be great to verify merge conflict resolution before commiting it... – Timothy Truckle Jul 09 '18 at 13:05
  • @TimothyTruckle thank you.. it work but, `gitk` shows only the commits/merges til 25 jan 2018 :( – michael-mammut Jul 09 '18 at 13:26
  • *"shows only the commits/merges til 25 jan 2018"* maybe this is the last commit date in your current branch. try *view->crreate new view* from the menu, click *all refs* and *all (local) branches* – Timothy Truckle Jul 09 '18 at 13:32

1 Answers1

3

All Git commits are snapshots. This is true of merge commits as well as of regular boring non-merge commits. The key difference between a merge commit and a non-merge commit is that a merge commit has (at least) two parents, instead of just one.1

When you view ordinary, single-parent commits with git show <hash> or git log -p, Git notices that these are in fact ordinary single-parent commits, and so Git extracts the parent commit's snapshot first, and then extracts the commit's snapshot, and then Git runs:

git diff [options] <parent-hash> <commit-hash>

and that tells you what changed between this commit's parent, and this commit.

You can, manually, do precisely the same thing yourself for any commit, including merge commits. But because a merge commit has two parents, you will discover that you must choose one of the two parents before you can produce this diff.

This is why git log -p doesn't bother showing anything for a merge commit: it's too hard to know which parent to choose. Well, that is, except for the fact that to see what changes the merge brought in to the main line, you usually want the first parent.2 Or, if you do want the second parent, well, just specify that! The git log command tells you about both parents:

commit 085d2abf57be3e424cad0b7dc8c27fe41921258e
Merge: cf22247b63 c3749f6e59
Author: ...

so here we can run:

git diff cf22247b63 085d2abf57be3e424cad0b7dc8c27fe41921258e

to view the changes between the first parent and the commit, or the obvious other git diff command to view the changes between the second parent and the commit.

The git show command, when applied to a merge, will show what Git calls a combined diff by default: it will run a diff against each parent, then throw out from this diff any file that exactly matches either parent, and show you only changes to the remaining files, mostly where conflicts were. If that's insufficient—as it very often is—there is a simple option to apply here:

git show -m 085d2abf57be3e424cad0b7dc8c27fe41921258e

will "split" the commit into two separate virtual commits (neither gets stored anywhere). Git can then diff 085d2abf57be3e424cad0b7dc8c27fe41921258e (from cf22...) against its first parent first, and then diff 085d2abf57be3e424cad0b7dc8c27fe41921258e (from c374...) against its second parent. The result is two separate diffs, as if there were two separate, non-merge commits, and this lets you find out what changed.


1A root commit has no parents. Any Git repository with at least one commit has at least one root commit, since the very first commit has no parent.

2This assumes you don't use git pull, which creates what some call a foxtrot merge.

torek
  • 448,244
  • 59
  • 642
  • 775