Is it possible to use winmerge to view git diffs f

2019-03-21 13:06发布

问题:

I like to use git on cygwin, but the only downside I have is when I want to git difftool I cannot use anything useful. git diff is fine for me most of the time, but sometimes I'd like to use winmerge to view these diffs via git difftool is there some way to set this up?

回答1:

For cygwin, the SO question "How can I configure Mercurial to use WinMerge for merges, under cygwin?" can be applied to git (when combining the following winmerge script with the older question "use Winmerge inside of Git to file diff")

#!/bin/sh
"/cygdrive/c/Program Files/WinMerge/WinMergeU.EXE" /e /ub /dl other /dr local `cygpath -aw $1` `cygpath -aw $2` `cygpath -aw $3`

Process

You have more details in this article "Git + WinMerge + Cygwin" (from Thiru Thirunavukarasu):
(but I would still recommend the WinMergeU.exe options from above)

Add the following lines to your .gitconfig file:

  [diff]
    tool = winmerge
  [difftool "winmerge"]
    cmd = git-difftool-winmerge-wrapper.sh \"$LOCAL\" \"$REMOTE\"
  [difftool]
    prompt = false

The last option (prompt = false) is optional. You can omit it if you do want Git to prompt you before opening each diff.

Create a file named git-difftool-winmerge-wrapper.sh and place it in your path.
I just dropped it in my home directory. You can change the default Cygwin path to include your home directory by modifying the .bash_profile file (also in your home directory) and adding PATH=${PATH}:${HOME}

Add the following to git-difftool-winmerge-wrapper.sh:

  #!/bin/sh
  echo "Launching WinMergeU.exe \"$(cygpath -aw "$1")\" \"$(cygpath -aw "$2")\""
  if [ -f "$1" -a -f "$2" ]
  then
    "C:/Program Files (x86)/WinMerge/WinMergeU.exe" -e -u -wl -dl "Base" -dr "Mine" "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
  else
    echo "skipping as one file doesn't exist"
  fi

(again, do some testing with those WinMerge options)


Scripts

If you want to go "all WinMerge", both for diff and merge git functions, you have this gist page to follow from ecerulm (Ruben Laguna):

diffmerge-diff.sh

#!/bin/sh
# Use SourceGear DiffMerge as mergetool for git in cygwin.
#   git config --global mergetool.diffmerge.cmd "diffmergetool.sh \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
#   git config --global mergetool.diffmerge.trustExitCode false
#   git difftool -t diffmerge branch1..branch2

# Reference: http://www.tldp.org/LDP/abs/abs-guide.pdf

library=githelperfunctions.sh

#[ -f $library ] && . $library
. $library

echo Launching DiffMerge.exe - diffmerge-diff.sh: 

set_path_vars "$1" "$2" "$3" "$4"

echo "$diffmergewinpath" -t1=FROM_VERSION -t2=TO_VERSION --caption=$caption $localwinpath $remotewinpath
"$diffmergewinpath" -t1=FROM_VERSION -t2=TO_VERSION --caption="$caption" "$localwinpath" "$remotewinpath"

diffmerge-merge.sh

#!/bin/sh
# Use SourceGear DiffMerge as mergetool for git in cygwin.
#   git config --global mergetool.diffmerge.cmd "diffmergetool.sh \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
#   git config --global mergetool.diffmerge.trustExitCode false
#   git mergetool -t diffmerge

# Reference: http://www.tldp.org/LDP/abs/abs-guide.pdf

library=githelperfunctions.sh

#[ -f $library ] && . $library
. $library

echo Launching DiffMerge.exe - diffmerge-merge.sh: 

set_path_vars "$1" "$2" "$3" "$4"

"$diffmergewinpath" --merge -t1=FROM_VERSION -t2=MERGED -t3=TO_VERSION --result="$mergedwinpath" --caption="$caption" "$localwinpath" "$basewinpath" "$remotewinpath"

unix2dos "$merged"

githelperfunctions.sh

# Helper functions


convert_path () {
    file=$1

    if [ "$file" == '/dev/null' ] || [ ! -e "$file" ]
        then 
           file="/tmp/nulla"
           `echo "">$file`
    fi
    echo `cygpath -w -a "$file"`
}


set_path_vars () {
    local=$1
    remote=$2
    base=$3
    merged=$4

    echo ========= Cygwin paths =======
    echo "LOCAL   :  $local"
    echo "REMOTE  :  $remote"
    echo "BASE    :  $base"
    echo "MERGED  :  $merged"

    localwinpath=$(convert_path "$local")
    remotewinpath=$(convert_path "$remote")
    basewinpath=$(convert_path "$base")
    mergedwinpath=$(convert_path "$merged")

    echo ========= Win paths =======
    echo "LOCAL   :  $localwinpath"
    echo "REMOTE  :  $remotewinpath"
    echo "BASE    :  $basewinpath"
    echo "MERGED  :  $mergedwinpath"

    caption=`basename "$merged"`
    diffmergewinpath="C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe"
    winmergewinpath="C:/Program Files/WinMerge/WinMergeU.exe"
#   diffmergewinpath=`cygpath -u C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe`
#   winmergewinpath=`cygpath -u \"C:\Program Files\WinMerge\WinMergeU.exe\"`
}

winmerge-diff.sh

#!/bin/sh
# Use winmerge as mergetool for git in cygwin.
#   git config --global difftool.winmerge.cmd "winmerge-diff.sh \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\""
#   git config --global mergetool.winmerge.trustExitCode false
#   git difftool -t winmerge branch1..branch2   

# Reference: http://www.tldp.org/LDP/abs/abs-guide.pdf
# Reference: http://winmerge.org/docs/manual/CommandLine.html


library=githelperfunctions.sh

#[ -f $library ] && . $library
. $library

echo Launching winmerge.exe - winmerge-diff.sh: 

set_path_vars "$1" "$2" "$3" "$4"

"$winmergewinpath" /dl "LOCAL.$caption" /dr "TO_VERSION.$caption" "$localwinpath" "$remotewinpath" 

winmerge-merge.sh

#!/bin/sh
# Use winmerge as mergetool for git in cygwin.
#   git config --global mergetool.winmerge.cmd "winmerge-merge.sh \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
#   git config --global mergetool.winmerge.trustExitCode false
#   git mergetool -t diffmerge

# Reference: http://www.tldp.org/LDP/abs/abs-guide.pdf
# Reference: http://winmerge.org/docs/manual/CommandLine.html

library=githelperfunctions.sh

#[ -f $library ] && . $library
. $library

echo Launching winmerge.exe - winmerge-merge.sh: 


set_path_vars "$1" "$2" "$3" "$4"

# -- use WinMergeU conflictFile
"$winmergewinpath" "$mergedwinpath"