Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple diff Tools

I had set up my git to use P4Merge as the diff tool, as described here. So, git diff will trigger the P4Merge.

However, sometimes I find working with the UNIX diff is faster and more efficient (because no GUI involved). How do I set up git so that I can easily choose which diff tool I would like to trigger? Is this possible? For example:

$ git diff     # to trigger P4Merge
$ git difftool # to trigger UNIX diff

My git config --list:

code.editor=vi
merge.tool=p4merge
mergetool.extMerge.cmd=extMerge $BASE $LOCAL $REMOTE $MERGED
mergetool.extMerge.trustexitcode=false
diff.external=extDiff
mergetool.prompt=false
mergetool.keepbackup=false
mergetool.p4merge.path=/usr/local/bin/p4merge
like image 301
moey Avatar asked Jan 27 '12 10:01

moey


3 Answers

You can just explicitly indicate which difftool you want to use. I have this in my ~/.gitconfig:

[diff]
    tool = vimdiff

[difftool "winmerge"]
    name = WinMerge
    trustExitCode = true
    cmd = "/c/Users/rkasten/Google\\ Drive/Apps/WinMerge/WinMergeU.exe" -u -e $LOCAL $REMOTE

And then I have the following aliases setup:

alias gdt='git difftool'
alias gdtw='git difftool --tool=winmerge'

Using masukomi's example, you could just add the following to your gitconfig:

[difftool "Kaleidoscope"]
    cmd = ksdiff --whatevs

And use alias gdtk='git difftool --tool=Kaleidoscope' to use Kaleidoscope.

All this works in git 2.7.

like image 157
DrStrangepork Avatar answered Oct 21 '22 13:10

DrStrangepork


Git can easily manage a visual and command line diff. No fancy tweaking is required

git diff (by default) uses unix diff

if you want to use a visual diffing tool as well the correct way to set it up is in your ~/.gitconfig file with a section like this:

[difftool "Kaleidoscope"]
    cmd = ksdiff --partial-changeset --relative-path \"$MERGED\" -- \"$LOCAL\" \"$REMOTE\"

What comes after the cmd = is specific to your particular visual diffing application.

It is not standard practice to manipulate git diff to send content to a visual diffing app. As such, the question seeks an answer that is 100% backwards from the built in functionality.

See the git-difftool man page for more details.

like image 45
masukomi Avatar answered Oct 21 '22 14:10

masukomi


UPDATE: If like OP you want to make git difftool invoke the default diff functionality instead of an external tool then simple version at the end of this answer works. However the method I prefer and recommend if you just want multiple diff tools is the .gitconfig file method as described in DrStrangeprok's answer.


You can set the following bash script as your external editing tool.
(ie: replace the contents of extDiff with it)
It is not quite as simple as git diif1 / git diff2 but it works.

EDIT: see bottom for a simpler version

#!/bin/bash

# Parameters from git:
# 1    2        3       4        5        6       7
# path old-file old-hex old-mode new-file new-hex new-mode

CONTINUE=1
while [ $CONTINUE == 1 ]
do

    # Present Options
    echo "1. P4Merge"
    echo "2. Unix diff"
    echo "3. Cancel"
    echo -n "Choose diff tool[1]: "

    # Read in user choice
    read -n 1 OPTION

    # move down a line
    echo ""

    # if user didn't enter a choice default to 1
    if [[ $OPTION == "" ]] ; then
        OPTION="1"
    fi

    # Launch diff tool based on OPTION
    case $OPTION in
        1) /Applications/p4merge.app/Contents/MacOS/p4merge "$2" "$5" ; CONTINUE=0 ;;
        2) diff "$2" "$5" ; CONTINUE=0 ;;
        3) exit ;;
        *) echo "\"$OPTION\" is not valid " ;;
    esac


    # This sleep has two purposes
    # 1) on an invalid choice it delays the menu just a hair
    # 2) keeps this script alive long enough that git will not just move onto the next file
    #    instantly if diffing multiple files.
    sleep 1

done

Simple Version without a menu
add this function to your .bashrc if you use 'git difftool' then it will use the default diff

function git {

    if [[ $1 == "difftool" ]] ; then
        git config --global --unset diff.external
        command git diff
        git config --global diff.external extDiff
    else
        command git "$@"
    fi

}
like image 31
Appak Avatar answered Oct 21 '22 12:10

Appak