How to configure kdiff3 instead of emerge as a git mergetool? - macos

I have Git on mac OSX Snow Leopard and I tried to edit my merge and diff tool to use kdiff3 instead of emerge.
But when I try to use it does not launch the GUI of kdiff and keeps me with a cmd based interface.
My setting in gitconfig are:
[merge]
tool = kdiff3
[mergetool "kdiff3"]
cmd = /Applications/kdiff3.app/Contents/MacOS/kdiff3
args = $base $local $other -o $output
trustExitCode = false
[diff]
tool = kdiff3
[difftool "kdiff3"]
cmd = /Applications/kdiff3.app/Contents/MacOS/kdiff3
args = $base $local $other -o $output
trustExitCode = false
There is obviously something missing but what did I do wrong ?

Recent Git versions have built-in support for kdiff3, so there's no need to configure it manually using the generic cmd and args settings. Instead do:
$ git config --global merge.tool kdiff3
And if kdiff3 is not in your PATH environment also do:
$ git config --global mergetool.kdiff3.path /Applications/kdiff3.app/Contents/MacOS/kdiff3
This makes git mergetool launch kdiff3. Note that there is no way to configure Git to automatically launch your merge tool after a manual merge that has conflicts.
In case you really want to see how Git is calling kdiff3 internally, take a look at the built-in mergetool configuration for kdiff3.
Edit: For Beyond Compare 4, which now also supports Mac OS X, simply exchange kdiff3 with bc3 (yes, "3") and adjust the path in the above lines. Starting with Git 2.2.0 you'll be able to use bc as an alias for bc3 so that you do not have to care about the version number.

Recent Git versions have built-in support for kdiff3
Yes, but only Git 2.12 (Q1 2017) will allow those built-in tools to trust their exit code.
See commit 2967284, commit 7c10605 (29 Nov 2016) by David Aguilar (davvid).
(Merged by Junio C Hamano -- gitster -- in commit c4a44e2, 16 Dec 2016)
mergetool: honor mergetool.$tool.trustExitCode for built-in tools
Built-in merge tools contain a hard-coded assumption about whether or not a tool's exit code can be trusted to determine the success or failure of a merge.
Tools whose exit codes are not trusted contain calls to check_unchanged() in their merge_cmd() functions.
A problem with this is that the trustExitCode configuration is not honored for built-in tools.
Teach built-in tools to honor the trustExitCode configuration.
(See kdiff3)
Extend run_merge_cmd() so that it is responsible for calling check_unchanged() when a tool's exit code cannot be trusted.
Remove check_unchanged() calls from scriptlets since they are no longer responsible for calling it.

Related

git help in Windows command prompt

The git help command on Windows (msysgit distribution) spawns web browser each time I run it. I tried git help -m which reports "No manual entry for ..." and git help -i which says "info: Terminal type 'msys' is not smart enough to run Info." The same happens in bash under Cygwin.
Is there any sensible way to get light-weight help in cmd terminal?
It works for particular commands: git <command> -h
Edit, thanks to #the-happy-hippo
But it shows only a brief description, not the full one, as git help <command> or git <command> --help gives on Windows.
git <verb> -h shows a command usage in the same terminal window.
On the other hand, git <verb> --help and git help <verb> open a browser.
Update for Git 2.x (June 2017, Git 2.13.1)
You still don't have man:
> git -c help.format=man help add
warning: failed to exec 'man': No such file or directory
fatal: no man viewer handled the request
Same for git <verb> --help.
git <verb> -h does not print the man page, only the short usage section (nothing to do with man)
With Git 2.34 (Q4 2021), when git cmd -h shows more than one line of usage text (e.g. the cmd subcommand may take sub-sub-command), parse-options API learned to align these lines, even across i18n/l10n.
See commit 4631cfc (21 Sep 2021), and commit 84122ec, commit 78a5091, commit 5d70198 (13 Sep 2021) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit d7bc852, 13 Oct 2021)
parse-options: properly align continued usage output
Signed-off-by: Ævar Arnfjörð Bjarmason
Some commands such as "git stash"(man) emit continued options output with e.g. git stash -h, because usage_with_options_internal() prefixes with its own whitespace the resulting output wasn't properly aligned.
Let's account for the added whitespace, which properly aligns the output.
The "git stash" command has usage output with a N_() translation that legitimately stretches across multiple lines;
N_("git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
" [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
[...]
We'd like to have that output aligned with the length of the initial "git stash" output, but since usage_with_options_internal() adds its own whitespace prefixing we fell short, before this change we'd emit:
$ git stash -h
usage: git stash list [<options>]
or: git stash show [<options>] [<stash>]
[...]
or: git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message <message>]
[...]
Now we'll properly emit aligned output.
I.e.
the last four lines above will instead be (a whitespace-only change to the above):
[...]
or: git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message <message>]
[...]
This change is relatively more complex since I've accounted for making it future-proof for RTL translation support.
Later in usage_with_options_internal() we have some existing padding code dating back to d7a38c5 ("parse-options: be able to generate usages automatically", 2007-10-15, Git v1.5.4-rc0 -- merge) which isn't RTL-safe, but that code would be easy to fix.
Let's not introduce new RTL translation problems here.
Original answer (2014)
No, even though an alternative, based on a 'cat' of the htlp txt files, is suggested in "how do I get git to show command-line help in windows?".
There man.<tool>.cmd config introduced in 2008, allows to set a custom command, but msys shell isn't shipped with man.exe.
World's most overengineered workaround for this problem: use WSL
(that is, unless you already are a WSL user, in which case it's merely an ordinary workaround)
Install one of the linux distros via Windows Store
Go in and ensure it has the git package installed
From the Windows command line, bash -c 'git help fetch' etc.
Here's an alias for that last one:
[alias]
hep = "!f() { $SYSTEMROOT/System32/bash -c \"git help $1\"; }; f"
(And no you can't override git built-ins, but you can make a shell command to intercept and reroute help.)

Is it possible to find the difference between two arbitrary text files using Git?

These files are not necessarily version controlled.
I'm using Git and Git GUI on Windows XP.
You'll need to use the --no-index option unless one or both of the files are outside of a Git repository:
git diff --no-index path/to/file.txt path/to/other/file.txt
You can also use git difftool with the same arguments to invoke your GUI tool.
Yes, git diff works on two unversioned paths, both files and directories (recursive diff). I don't think you can do this from the GUI; you'll need to use the command line.
If you want GUI, I suggest installing KDiff3 instead. It can also be used by Git as a merge tool than if you set diff.tool = kdiff3, diff.guitool = kdiff3 and difftool.kdiff3.path = path-to-kdiff3.exe
You can do that not only with git diff (with git diff --no-index -- file1 file2), but now (Git 2.22, Q2 2019) again with git difftool too!
It was not possible for the past two years.
"git difftool" can now run outside a repository.
See commit 20de316, commit 1a85b49, commit 1dcda05 (14 Mar 2019) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit b72e907, 25 Apr 2019)
difftool: allow running outside Git worktrees with --no-index
As far as this developer can tell, the conversion from a Perl script to
a built-in caused the regression in the difftool that it no longer runs
outside of a Git worktree (with --no-index, of course).
It is a bit embarrassing that it took over two years after retiring the
Perl version to discover this regression, but at least we now know, and
can do something, about it.
It fixes git-for-windows/git issue 2123.
In Git Bash you can just use diff file1 file2.
Using TortoiseGit, select both files, right click select TortoiseGit and click diff.

Use Xcode 4 as Git difftool

I want to use Xcode 4's "Version Editor" view as my standard difftool for Git.
In other words, I want to be able to set this option:
git config --global diff.external <XCODE>
And have the diff open in Xcode's diff viewer (because it's cool).
Is this possible? How?
Sadly not possible. Here's hoping Apple changes that someday though.
I'm guessing you already know the following, but for the benefit of others who may not, you can use Apple's FileMerge application instead for a similar, albeit somewhat lesser, experience with a command like:
git difftool path/to/file
My git defaults to using FileMerge as the difftool, but you can configure it explicitly with:
git config --global diff.tool opendiff
(This stops git from listing the candidate tools every time too.) I also like to disable git's difftool pre-launch prompting:
git config --global difftool.prompt false
It is possible to configure git so that git diff will invoke FileMerge as well, or instead. (I prefer to just leave git diff the way it is myself.) If you want that you first need to create a shell script to map the appropriate arguments to opendiff:
#!/bin/sh
/usr/bin/opendiff "$2" "$5" -merge "$1"
and then run
git config --global diff.external /path/to/shell/script

`git difftool` refuses to run under Emacs inferior shell

When I type git difftool under plain cygwin shell, I just receive benign exit:
~/sb/ws> git difftool
~/sb/ws>
But when I type exactly the same thing under Emacs inferior shell (running the same cygwin bash), I receive the following error:
~/sb/ws> git difftool
git difftool
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LC_ALL = (unset),
LANG = "ENU"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
~/sb/ws>
Any idea why this is happening and how to fix this?
(all other git commands, by the way, work perfectly under this Emacs inferior shell, so I can only assume this must be something specific to difftool)
EDIT (providing variant & version information on the tools involved):
cygwin-1.7.8-1
GNU Emacs 23.2.1 (i386-mingw-nt6.1.7600) of 2010-05-08 on G41R2F1
git version 1.7.4
Windows 7 Ultimate 64-bit
you're really have wrong LANG, look onto /usr/share/locale for list of available locales..
But really question is - why're using git directly in Emacs, when it has several good git modes, and magit - the best between them? Why not perform all tasks using Emacs?
P.S. I have an article about Emacs + Git...
Update 6 years later (2017)
all other git commands, by the way, work perfectly under this Emacs inferior shell, so I can only assume this must be something specific to difftool
What is specific to difftool is that it is still (but not for long) written in perl: git-difftool.perl
But that will change soon with Git 2.12 (Q1 2017).
That means difftool should run under Emacs just fine, not being bothered with Perl anymore.
See commit 03831ef and commit 019678d (19 Jan 2017) by Johannes Schindelin (dscho).
difftool: implement the functionality in the builtin
The motivation for converting the difftool is that Perl scripts are not at all native on Windows, and that git difftool therefore is pretty slow on
that platform, when there is no good reason for it to be slow.
In addition, Perl does not really have access to Git's internals.
That means that any script will always have to jump through unnecessary
hoops, and it will often need to perform unnecessary work (e.g. when
reading the entire config every time git config is called to query a
single config value).
The current version of the builtin difftool does not, however, make full
use of the internals but instead chooses to spawn a couple of Git
processes, still, to make for an easier conversion. There remains a lot
of room for improvement, left later.
Note: to play it safe, the original difftool is still called unless the
config setting difftool.useBuiltin is set to true.
The reason: this new, experimental, builtin difftool was shipped as part
of Git for Windows v2.11.0, to allow for easier large-scale testing, but
of course as an opt-in feature.
The speedup is actually more noticable on Linux than on Windows: a quick
test shows that t7800-difftool.sh runs/
in (2.183s/0.052s/0.108s) (real/user/sys) in a Linux VM, down from (6.529s/3.112s/0.644s), while
on Windows, it is (36.064s/2.730s/7.194s), down from (47.637s/2.407s/6.863s).
The culprit is most likely the overhead incurred from still having to
shell out to mergetool-lib.sh and difftool--helper.sh.
Still, it is an improvement.

How to set Araxis as diff / merge tool for MSYS git?

I'm trying to use Araxis Merge as my diff / merge tool for MSYSGit.
I found a few resources on the net:
On the Araxis site, they mention an "easy" way, but it implies a executables (araxisgitdiff.exe and araxisgitmerge.exe) that are not part of my distro.
I also found some info in gitguru, but the actual information re: Araxis is sparse at best, and I could not make anything out of that.
Finally, there was some info on an older stackoverflow post, but the suggested method doesn't work for me. That particular info was geared towards OS X. I "translated" to Windows as best as I could, but without success:
I created /bin/git-diff-driver.sh
#!/bin/sh
"/c/Program Files/Araxis/Araxis Merge/compare.exe" -title1:"$1 (repo version)" -title2:"$1 " -max "$2" "$5"
and edited gitconfig
[merge]
tool = araxismerge
[mergetool "araxismerge"]
cmd = "/c/Program Files/Araxis/Araxis Merge/compare.exe" -3 -merge -wait $LOCAL $BASE $REMOTE $MERGED
[diff]
external = "/bin/git-diff-driver.sh"
and the only result I get is:
$ git diff HEAD^ HEAD
external diff died, stopping at PowerEditor/src/Notepad_plus.cpp.
Edit:
I've also tried with the exe named as "c:/Program Files/Araxis/Araxis Merge/compare.exe" as suggested by one of the answers, with the same results.
Edit:
I've found that it can easily be set if you use TortoiseGit, but it seems to handle diff by itself and no settings from TortoiseGit give any indication on how to set up Araxis as a merge tool when diff is invoked from the command line.
Edit:
So, the question is: Is there anybody who successfully uses Araxis Merge to diff and merge stuff with MSYSGit, and if so, how do you it?
If you want to have 'git diff' always use araxis you can use the instructions in the help file, but if you want to have control to use 'git diff' as you normally would from the command line and 'git difftool' to engage the Araxis GUI.
Try adding the following to your git config::
[difftool "araxis"]
path = "/c/Program Files/Araxis/Araxis Merge/compare.exe"
renames = true
trustExitCode = true
[diff]
tool = araxis
stat = true
[mergetool "araxismergetool"]
cmd = 'C:\\Program Files\\Araxis\\Araxis Merge\\araxisgitmerge.exe' "$REMOTE" "$BASE" "$PWD/$LOCAL" "$PWD/$MERGED"
trustExitCode = false
[mergetool]
keepBackup = false
[merge]
tool = araxismergetool
stat = true
The documentation at araxis has been updated: http://www.araxis.com/merge/documentation-windows/integrating-with-other-applications#Git
I can use the configuration shown there without any modifications.
Right... I got it working, with msysgit version 1.6.3.2.1299.gee46c, under DOS or Git Bash, with an evaluation license for Araxis Merge 2009, v2009.3713:
The approach is to use the new git difftool and git mergetool, instead of plain diff.
First, let's setup some scripts for those diff and merge tool
C:\>git config --global diff.tool adifftool
C:\>git config --global diff.external git-difftool--helper
C:\>git config --global difftool.adifftool.cmd "difftool.sh \"$LOCAL\" \"$REMOTE\" \"$MERGED\""
C:\>git config --global difftool.prompt false
Notes:
by setting diff.external to the Git script git-difftool--helper, I will use difftool even when I will type 'git diff'.
do not forget to pass $MERGED to your difftool script: that is the only variable with the real name of the file being diff'ed. $LOCAL and $REMOTE are temporary names.
For the merge tool, you would set the following global values:
C:\>git config --global merge.tool amergetool
C:\>git config --global mergetool.amergetool.cmd "mergetool.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\""
C:\>git config --global mergetool.prompt false
By setting those tools to some shell scripts, you will be able to switch tools from within those scripts.
Another approach is to name your tools (mergetool.araxis.cmd, mergetool.winmerge.cmd, ...) and to specify the right tool in the diff.tool or merge.tool setting.
Create difftool.sh and mergetool.sh in a directory referenced by your global environment variable PATH. They will work even from DOS (and they are sh -- shell -- scripts)
difftool.sh
#!/bin/sh
echo Launching Araxis Merge.exe: $3
t1="'$3 (from)'"
t2="'(to)'"
"C:/Program Files/Araxis/Araxis Merge/Compare.exe" -max -nowait -2 -title1:${t1} -title2:${t2} "$1" "$2"
Notes:
Impossible to have -title1:"someTitle With Space"... only title without space does work..., so for now, try it without any 'titleN' option.
Got it! You cannot pass the title value directly to the -title option, you need to set it to a local variable, with "' '" quotes combinations (the double quotes will disappear during the shell script execution, leaving the simple quotes, allowing spaces within a title!)
$3 represent the real name and not some temporary file name for diff purpose. Hence the use of $3 within the title1 option, with space in it.
git diff HEAD^ HEAD would not work in DOS session: only git diff "HEAD^" HEAD would.
mergetool.sh
#!/bin/sh
# Passing the following parameters to mergetool:
# local base remote merge_result
alocal=$1
base=$2
remote=$3
result=$4
t1="'$4 (current branch)'"
t2="'(common ancestor)'"
t3="'(to be merged)'"
if [ -f $base ]
then
"C:/Program Files/Araxis/Araxis Merge/Compare.exe" -max -wait -merge -3 -a2 -title1:${t1} -title2:${t2} -title3:${t3} "$alocal" "$base" "$remote" "$result"
else
"C:/Program Files/Araxis/Araxis Merge/Compare.exe" -max -wait -merge -3 -a2 -title1:${t1} -title2:${t2} -title3:${t3} "$alocal" "$result" "$remote" "$result"
fi
I am not sure I those scripts do work properly when multiple files are involved (multiple diffs, multiple files to be merged).
Just tested it: it works, and Araxis compare.exe does open one tab per file to diff or merge.
Give it a try and let us know ;)
I think that you need to be a bit more careful with your escaping in your .gitconfig.
Unfortunately, due to the way the config variable is expanded and evaled, your string needs to be an valid shell command which is then 'git config' escaped.
Try something like this:
[mergetool "araxismerge"]
cmd = \"/c/Program Files/Araxis/Araxis Merge/compare.exe\" -3 -merge -wait \"$LOCAL\" \"$BASE\" \"$REMOTE\" \"$MERGED\"
Yes, not very pretty, I know. It's one of the cases where using git config directly is actually easier.
git config --global mergetool.araxismerge.cmd '"/c/Program Files/Araxis/Araxis Merge/compare.exe" -3 -merge -wait "$LOCAL" "$BASE" "$REMOTE" "$MERGED"'
I struggled with this problem for quite a while, and now I finally can say, that all suggested dirty hacks (like intermediate shell scripts) are rather unnecessary =D. Thing is, all of the latest versions of MSYSGit (I have 1.6.4) support Araxis Merge (I have 2008) out of the box. It comes at no surprise, that internally it's called "araxis". So, all that you need is to set
[merge]
tool = araxis
in your .gitconfig. Also you have to include Araxis folder into your PATH environment variable (MSYSGit looks for Compare.exe).
For a good measure, other Git settings related to "araxis" mergetool, that you could have configured (especially, if you happen to choose exactly that name, as did some people on this page), should all be removed. That includes everything under [mergetool "araxis"] section. Be sure to remove them from all configs (system, global, and repository), otherwise, they might interfere with normal "internal tool" behavior.
In any case, if you're interested in how MSYSGit will start your Araxis Merge, or wondering what other mergetools it supports out of the box, the place to look is \share\git-gui\lib\mergetool.tcl script in your MSYSGit installation folder.
PS. You might be able to avoid setting PATH environment variable, by configuring mergetool.araxis.path in .gitconfig. Personally, I never bothered to do so, since
I use Araxis Merge from command line anyway.
Specifying directory path in .gitconfig (especially the one like "C:\Program Files\Araxis\Araxis Merge\", which contains spaces) can prove hard to be done correctly, since it is prone to backslash/forwardslash issues, that plague MSYSGit.
PPS. All of the above applies to making Araxis your difftool, too. I.e, you need to add
[diff]
tool = araxis
and remove anything else in [difftool "araxis"] section, if you have it in your config (don't forget to set up PATH, though).
You could try to follow the script mentioned in my answer about diffMerge (for Windows) and see if it works.
The executable path could be better expressed with:
#!/bin/sh
"C:/Program Files/Araxis/Araxis Merge/compare.exe" -title1:"$1 (repo version)" -title2:"$1 " -max "$2" "$5"
One way I found to do it "simply" is to install TortoiseGit and set the diff / merge tools in TortoiseGit options.
However, this does not address the issue if you want to diff from the command line.
Since I've been bitten to customised git differs/mergers, I thought I would try to fix this one for once and for all. I got to the point where AraxisMerge started, but without the titles of the tabs. So that will be left as an exercise for the reader :)
Observations and comments:
I didn't have AraxisMerge, so I downloaded it and got a free 30-days evaluation license to try it out with. This version (7.0 it seems) comes with araxisgitdiff.exe, and the link with instructions you send works. So that would be option #1: upgrade araxis merge.
Since I'm working from CMD.EXE, 'git diff HEAD HEAD^' does not work. The '^' needs to be escaped to 'git diff HEAD "HEAD^"'.
For my own work I use kdiff3 as a free replacement on Windows which works reasonably well (it helps that it is supported by default by git)
Starting with the git-diff-driver.sh gave the same error to me. After changing the script to only contain 'echo', this did not change. So the error is independent from the contents of the script.
Then I removed the '/bin' part from .gitconfig, so the line becomes
external = "git-diff-driver.sh"
...and this started to work: it started the merger, but it does not escape the '(repo) ' part correctly. As a workaround I got it working without the titles with:
#!/bin/sh
"/c/Program Files/Araxis/Araxis Merge/compare.exe" -max "$2" "$5"
Good luck!

Resources