2

When a conflict arises during a git merge, I sometimes wonder which line is the correct one (which one was modified the last). Example:

<<<<<<< HEAD
  div.some-class
=======
  div.another-class
>>>>>>> commit message that doesn't give clue which commit to choose
#no clue which is good

How can I determine which line was modified last?

(We assume that the last commit is correct, situation where both branches modified it are more troublesome.)

Bartłomiej Skwira
  • 1,701
  • 1
  • 16
  • 24
  • 2
    The last version of the line in question may not be the "correct" one... The date shouldn't factor in your decision to keep one version of that line rather than the other; only intent/semantics should. – jub0bs Oct 14 '14 at 12:58
  • Well yes, but let's assume that the last one is correct. That's the case in most situations. When we have a problem that the line has been modified on both branches then we have a pickle. – Bartłomiej Skwira Oct 14 '14 at 13:00
  • If your commit messages are meaningless then that might be a hint as to the actual problem. – Edward Thomson Oct 14 '14 at 14:37
  • @EdwardThomson not entirely meaningless, a message that says what this code change does, but doesn't answer the question: [in a merge] 'which version should I pick' – Bartłomiej Skwira Oct 15 '14 at 09:54

3 Answers3

1

If you really are only concerned with the dates, git show HEAD should provide you the date and time of your HEAD. If you need more detail about specific lines, git blame <filename> should help you find the relevant commits, and then you can use git show <commit> to find those dates and times.

Similarly, for the "some meaningless commit message", that line should contain a SHA-1 hash which you can also use with git show <commit> to find the date and time of that commit.

However, it is worth reiterating that in most cases, it is far more important to examine the content of the conflicting commits and to make a decision based on that.

Edit after further research: It is possible that there is a merge strategy (git merge -s <strategy> [-X <strategy-option>]) that would do the merging automatically based on timestamp, but I have not been able to find such an option in the documentation.

Edit after even more research: See here for a similar yet less contentious SO question that might relate to your interests. You may not want an automated process, and the solution there may not work for your situation, but perhaps the custom merge driver offered there will help you.

Community
  • 1
  • 1
pattivacek
  • 5,617
  • 5
  • 48
  • 62
  • 1
    `merge.conflictstyle` is just used to toggle whether the `base` changes are shown or not (2-way vs 3-way) – Andrew C Oct 14 '14 at 14:49
  • *It is possible that there is a setting of the merge.conflictstyle configuration variable that would show the commit timestamp in the diff [...]* AFAIK, `merge.conflictstyle` can only take two values: `merge` (the default) and `diff3` (which also shows the version of the problematic hunk recorded in the common parent). Anyway, I think the date has/should have very little to do in the resolution of a merge conflict. – jub0bs Oct 14 '14 at 15:09
  • I agree that `merge.conflictstyle` does not seem helpful, but I couldn't help but wonder if there were undocumented or otherwise obscure options that might help. And while I also agree with practically every other commenter here that the timestamp is generally not a good tool for merge conflict resolution, that's what the OP asked for and that's what I tried to answer. – pattivacek Oct 14 '14 at 20:04
  • BTW, I removed the reference to `merge.conflictstyle` since that seemed unlikely to be helpful. – pattivacek Oct 14 '14 at 20:14
0

In a stock Git configuration where you are distributed between multiple repositories you cannot rely on dates to reliably tell you anything about which commit is "newer" than another one.

Even if you could, I would be hesitant to adopt a merge strategy based on it.

Also, if you are looking at the conflict markers you would probably be better off choosing a graphical merge tool to resolve your conflicts (it doesn't matter which one, they are all superior to hand merging). If you want to hand merge configuring merge.conflictstyle diff3 is recommended.

That said ...

For conflicted files you could do

git log --pretty=%cd -1 HEAD -- <conflicted_file>
git log --pretty=%cd -1 MERGE_HEAD -- <conflicted_file>

This will give you the committer date of the most recent modification of the file on each branch (as mentioned before, this is semi-reliable at best). You could wrap this in a simple script that executed the above for each unmerged file, and then printed out the file and "ours" or "theirs" even.

Andrew C
  • 13,845
  • 6
  • 50
  • 57
-1

Not exist correct or incorrect lines for git, you decides which is the best option, you only must see the tag "header" and "[other branch]", header is your current branch.

<<<<<<< HEAD (your actually branch)
  div.some-class
======= (other branch)
  div.another-class
>>>>>>> some meaningless commit message

If you need both class, you must write the new line

div.some-class.another-class
Felipe Pincheira
  • 442
  • 1
  • 6
  • 21