0

Is there a way to format a git diff (e.g. git diff HEAD^ or git diff origin/foo origin/bar) in the format used by merge resolution?

For example, I have a patch which (in part) looks like

   yield (
     api.test('check the foos') +  #
-    api.properties(foos=[]) +  #
     api.frobozz(bar) +  #
     ...
   )

And I would like to see this section as

yield (
   api.test('check the foos') +  #
<<<<<<<<<<<<<<<<<<<<<< origin
   api.properties(foos=[]) +  #
=============================
>>>>>>>>>>>>>>>>>>>>>>>> HEAD
   api.frobozz(bar) +  #
   ...
)
Jacob Kopczynski
  • 392
  • 3
  • 13
  • https://stackoverflow.com/questions/31644096/git-merge-treat-any-auto-file-change-as-a-conflict-do-not-stage-like-a-sq may be useful here. I can't see how to turn it into an answer to my question, but several answers seem like relevant pieces. – Jacob Kopczynski Mar 24 '20 at 19:03

1 Answers1

1

The short answer is no: git diff only compares two commits, and git merge runs two different git diff operations, and then combines the results of those two diffs, which is why git merge has the necessary information.

To get the necessary information, you need a third commit: a common starting point for the two different diffs that you will generate and then combine. What is the common starting point for these two commits? If you can find or manufacture one, then you can get what you'd like.

(If you just want to manufacture a fake third commit by editing the output of git diff, you can write a program to do that, of course. But you must write the program: Git does not come with any such thing.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • There is only one commit. Not two. If there were two, I could get this with a rebase. What part of my example was not clear? – Jacob Kopczynski Mar 26 '20 at 05:24
  • Well, OK, in your case there's one commit and one other file-tree, either in the index, or in your work-tree. The point is, to get the kind of diff you want, you need *three* file trees (three commits, or two commits and the index, etc). In any case the short answer remains no: Git won't do that for you. – torek Mar 26 '20 at 05:49
  • How would someone achieve this with 3 trees? – zaabson Apr 29 '22 at 10:07
  • @zaabson: what output would you like when tree A has file F1 with contents C1, tree B has file F1 with contents C2, and tree C has file F2 (renamed from F1) with contents C1? What sort of diff should this show when a file exists in all three trees but has differing contents in each? (There are potential answers to these questions: Git produces *combined diffs* for some situations. However, combined diffs have issues, so there's no *right* answer.) – torek Apr 29 '22 at 18:25
  • @torek I imagine one tree being a common ancestor of the two. And the diff to show on top of the base from common ancestor, where the two newer trees differ. – zaabson Apr 30 '22 at 11:28
  • 1
    @zaabson That sounds a lot like the combined diff you get with `-c` or `--cc` applied to a merge commit (see [this section of the diff docs](https://git-scm.com/docs/git-diff#_combined_diff_format)). But there's no mechanism in the `git diff` family to invoke it on some trees, and it's the reverse of what you've suggested: instead of a single ancestor with two or more descendants, it's a single descendant (the merge commit) with two or more ancestors. – torek Apr 30 '22 at 19:05