12

Is it possible to set a custom tool for merging files with a specific extension in Git?

Thanks for any pointers!

Update

I wasn't able to come up with any better solution than defining a custom difftool and calling it by hand as @jarodeells suggested:

[diff]
    tool = mydiff
[difftool "mydiff"]
    cmd="script.sh \"$LOCAL\" \"$REMOTE\""

Then calling it explicitly:

$ git difftool -t mydiff someFileWith.ext
rlegendi
  • 10,466
  • 3
  • 38
  • 50
  • Can you be please more specific about the solution? Also I think there is one extra quote at the end of cmd line. – Halil Jul 22 '14 at 18:12
  • Actually, there was an additional `"` after `script.sh` which wasn't necessary. Now it should be fine :-) – rlegendi Jul 24 '14 at 06:07
  • I did the solution you proposed but when I do `git difftool --cached` script does not catch the option and does not work. Have you encountered that problem? – Halil Jul 31 '14 at 16:50

2 Answers2

6

Update: See @Ackdari comments below. The external tool doesn't have to be command-line based. I'm not sure how git uses binary = True when an external tool is used, but I suspect it might be needed for all flows to work.

If your external diff tool* is command-line only (no GUI), You can use the built-in gitattributes for this:

in .gitconfig add:

[diff "my_diff"]
    command = Tools/csv_diff
    binary = true # Not sure this is required.

and in .gitattributes (either global or per repository, see here) add:

*.csv diff=my_diff

[*] The command for the external diff tool will be called by git with the 7 parameters detailed under GIT_EXTERNAL_DIFF in the manual here.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
OmerB
  • 4,134
  • 3
  • 20
  • 33
  • Well, your comment actually threw me off-balance now :-). Git makes some distinction between a "diff driver" (which is defined under `diff` section in `.gitconfig`) and a "diff tool" (defined under `difftool` section), and I remember reading that a driver has to be text-based, but I don't see it anywhere in the manual now. So please try it out, it may work! if it does, post a comment and I'll update the answer. Another thing I don't know how I missed before is the option to add `binary = true` to the driver definition (right under `command = Tools/csv_diff`). Maybe this is the change needed. – OmerB Feb 19 '19 at 12:24
  • Tested it and it works (Have written a programm what just displays the cli arguments and with .jpg as binary files) but `binary = true` was not necessary for me. But I'm still wondring why I can't alter how the cli arguments are provided like for `merge..driver` (see [docu](https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver)) – Ackdari Feb 19 '19 at 15:41
  • @Ackdari Cool! One thing I'm wondering about is what git does when it *needs* to show textual diffs and a GUI tool is defined (e.g. when you do git log -p for a few commits back)... – OmerB Feb 19 '19 at 16:14
  • in my setup git just shows `Binary files /dev/null and b/bild.jpg differ` – Ackdari Feb 20 '19 at 08:06
  • Ok, that's what git usually shows for binary files, so I'm guessing it's detected as binary somewhere along the way. – OmerB Feb 20 '19 at 13:22
  • Thanks! I just needed one additional change to set my default atrributes file: `git config --global core.attributesfile /home/alex/.gitattributes`. NB if you only want it in one repo then you need to write to `.git/info/attributes` (at least on Linux git). – Alex Zeffertt Mar 21 '22 at 11:15
2

If not already supported, install a shell script that keys off the extension and calls the correct merge tool.

jarodeells
  • 356
  • 1
  • 5
  • 14
  • 2
    Yeah, that could be a solution, but I'd like to avoid custom solutions. I'm interested if it is possible through `gitconfig` (as the tags indicate). – rlegendi Sep 11 '12 at 16:01