используйте Winmerge внутри Git для файла diff

есть ли способ использовать Winmerge внутри git для выполнения различий?

8 ответов


обновление июнь 2015, 6 лет спустя:

как подробно описано в "git mergetool winmerge", простой git config diff.tool winmerge будет достаточно.

Git 2.5+ (Q2, 2015) теперь знает о Winmerge как инструменте diff или merge!


оригинальный ответ (2009-2012)

(msysgit, 1.6.5, DOS сессия)

первая часть (с использованием winmerge) описывается в "как просмотреть вывод "git diff" с помощью visual diff программа?"

C:\myGitRepo>git config --replace --global diff.tool winmerge
C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
C:\myGitRepo>git config --replace --global difftool.prompt false

С winmerge.sh хранится в каталоге часть вашего PATH:

#!/bin/sh
echo Launching WinMergeU.exe:  
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -u -dl "Local" -dr "Remote" "" ""

(см. WinMerge параметры командной строки)

git difftool

теперь запустим WinMerge.
Если вы хотите git diff чтобы запустить WinMerge, просто установите:

set GIT_EXTERNAL_DIFF=winmerge.sh

но реальная добавленная стоимость исходит из возможности использовать тот же инструмент diff для представить все различия в одном пакете вместо представляя их последовательно, заставляя вас закрывать окна инструментов diff по одному файлу за раз.

Обновление За Июнь 2012 Г. (два с половиной года спустя):

сравнение каталогов вместо файла по файлу будет доступно в ближайшее время:
См.[объявить] Git 1.7.11.ник1:

"git difftool" узнал "--dir-diff" возможность порождать внешние инструменты diff, которые могут сравните две иерархии каталогов одновременно после заполнения двух временных каталогов,вместо запуска экземпляра внешнего инструмента один раз на пару файлов.

в разделе "патч difftool: учить difftool для обработки каталогов diffs", и ответ "сравнение каталогов ветвей Git" для получения более подробной информации.


оригинальный скрипт difftool по каталогам (декабрь 2009)

As Себа Иллингворт говорится в ответ, сценарий git-diffall.sh (также положите в путь) может сделать именно это:

#!/bin/sh
git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-prompt "$filename" &
done

но это работает только на открытие n окна n файлы (если вы пытаетесь использовать -s опция WinMerge, она не будет работать из-за временных файлов, удаляемых difftool слишком рано)


вот почему мне нравится подход GitDiff.бат - мощность-сравниваете с GI, которая позволяет вам чтобы просмотреть список файлов с разницей, прежде чем выбрать один, чтобы изучить его внутренние различия.
Я настроил его, чтобы использовать только команды DOS

@echo off

setlocal

if "%1" == "-?" (
    echo GitDiff - enables diffing of file lists, instead of having to serially
    echo diff files without being able to go back to a previous file.
    echo Command-line options are passed through to git diff.
    echo If GIT_FOLDER_DIFF is set, it is used to diff the file lists. Default is windff.
    goto END
)

if "%GIT_DIFF_COPY_FILES%"=="" (
    rd /s /q %TEMP%\GitDiff
    mkdir %TEMP%\GitDiff
    mkdir %TEMP%\GitDiff\old
    mkdir %TEMP%\GitDiff\new

    REM This batch file will be called by git diff. This env var indicates whether it is
    REM being called directly, or inside git diff
    set GIT_DIFF_COPY_FILES=1

    set GIT_DIFF_OLD_FILES=%TEMP%\GitDiff\old
    set GIT_DIFF_NEW_FILES=%TEMP%\GitDiff\new

    set GIT_EXTERNAL_DIFF=%~dp0\GitDiff.bat
    echo Please wait and press q when you see "(END)" printed in reverse color...
    call git diff %*

    if defined GIT_FOLDER_DIFF (
        REM This command using GIT_FOLDER_DIFF just does not work for some reason.
        %GIT_FOLDER_DIFF% %TEMP%\GitDiff\old %TEMP%\GitDiff\new
        goto END
    )

    if exist "%ProgramFiles%\Beyond Compare 2\BC2.exe" (
        set GIT_FOLDER_DIFF="%ProgramFiles%\Beyond Compare 2\BC2.exe"
        "%ProgramFiles%\Beyond Compare 2\BC2.exe" %TEMP%\GitDiff\old %TEMP%\GitDiff\new
        goto END
    )

    "%ProgramFiles(x86)%\WinMerge\WinMergeU.exe" -r -e -dl "Local" -dr "Remote"  %TEMP%\GitDiff\old %TEMP%\GitDiff\new
    goto END
)

REM diff is called by git with 7 parameters:
REM     path old-file old-hex old-mode new-file new-hex new-mode
copy %TEMP%\%~nx2 %GIT_DIFF_OLD_FILES%\%1
copy %5 %GIT_DIFF_NEW_FILES%

:END

он недостаточно надежен для обработки файлов с одинаковыми именами в разных каталогах, но он дает вам общее представление о том, что возможно:
Здесь откроется только один WinMerge, со списком файлов, имеющих внутренние различия. Вы можете нажать на те, которые вы хотите рассматривает, то простой ESC закрыть все WinMerge-diff сессии.


я столкнулся с проблемой, используя первую часть в 2 местах и исправил ее следующим образом

  1. вторая команда для настройки winmerge.cmd требовал дополнительной косой черты на cmdline (до $LOCAL и $REMOTE), иначе cygwin подставлял переменную в cmdline

    C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
    
  2. изменил winmerge.sh файл to (без этого получалась ошибка right-path-invalid)

    #!/bin/sh
    echo Launching WinMergeU.exe: "$(cygpath -aw "")" "$(cygpath -aw "")"
    "$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$(cygpath -aw "")" "$(cygpath -aw "")"
    

поскольку поток становится запутанным и раздвоенным, вот сводные инструкции для списка каталогов "--dir-diff" WinMerge метод для msysgit Git Windows.

Шаг 1 - создайте файл с именем winmerge.sh в месте, доступном для вашего пути (например, /home/bin/winmerge.sh) со следующим содержанием.

#!/bin/sh
echo Launching WinMergeU.exe:  
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -r -ub -dl "Remote" -dr "Local" "" ""

Шаг 2 - введите следующие команды в Git Bash, чтобы проинструктировать git использовать winmerge.sh как difftool (эти параметры сохраняются в /home/.gitconfig хранит настройки):

git config --replace --global diff.tool winmerge
git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
git config --replace --global difftool.prompt false

Шаг 3 - теперь вы можете проверить, введя следующую команду в Git Bash, чтобы начать WinMerge diff:

git difftool --dir-diff

Шаг 4 - для более быстрого доступа создайте псевдоним для этой команды, добавив эту строку .bashrc в домашнем каталоге (или создать .файл bashrc с этой строкой, если файл еще не существует):

alias diffdir='git difftool --dir-diff'

Шаг 5 - теперь вы можете быстро увидеть различия в WinMerge просто введя следующую команду в Git Bash

diffdir

У меня есть скрипт, который установит инструменты Diff и Merge в конфигурации Git с правильными параметрами, которые не требуют отдельного .sh файл для существования. Кажется, у меня все в порядке.

git config --global diff.tool winmerge
git config --global difftool.prompt false
git config --global difftool.winmerge.cmd "\"$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\""

git config --global merge.tool winmerge
git config --global mergetool.prompt false
git config --global mergetool.winmerge.trustExitCode true
git config --global mergetool.winmerge.cmd "\"$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\""

Примечание - все .часть cmd цитируется так, что параметры будут перечислены в .gitconfig хранит настройки правильно


я был смущен тем, почему решение было представлено как пакетный файл DOS, так как моя установка Git поставляется с оболочкой bash. Я также не смог получить контекст DOS, запущенный из bash, поэтому я попытался адаптировать то, что ранее было разделено в контексте bash.

С git diff Кажется, чтобы запустить указанную команду один раз для каждого файла, я разделил свое решение на два сценария bash:

во-первых, настроить gitprepdiff.sh быть difftool как ранее упомянуто

#!/bin/sh
#echo ...gitprepdiff.sh
cp -v  "$TMP/GitDiff/old/"
cp -v  "$TMP/GitDiff/new"

я также отметил, что результаты git configure команды можно найти и отредактировать непосредственно в C:\Users\<username>\.gitconfigure

gitdiff.sh затем запустить в командной строке, где вы обычно называете git diff

#!/bin/sh
#echo Running gitdiff.sh...

DIFFTEMP=$TMP/GitDiff

echo Deleting and re-creating $DIFFTEMP...
rm -rf $DIFFTEMP;
mkdir $DIFFTEMP;

echo Creating $DIFFTEMP/old...
mkdir $DIFFTEMP/old;

echo Creating $DIFFTEMP/new...
mkdir $DIFFTEMP/new;

git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-prompt "$filename";
done

"$PROGRAMFILES\WinMerge\WinMergeU.exe" -r -e -dl "Repository" -dr "Working" $LOCALAPPDATA\Temp\1\GitDiff\old $LOCALAPPDATA\Temp\1\GitDiff\new

также стоит отметить, что на мои установки, /tmp (в bash) сопоставляется %LOCALAPPDATA%\Temp\ (в Windows), поэтому я использую последний в своем вызове WinMerge.


в windows вы можете сделать это следующим образом:

1) Открыть .файл gitconfig хранит настройки. Он находится в вашем домашнем каталоге: c:\users\username.gitconfig хранит настройки

2) Добавьте строки ниже. Обратите внимание на одинарные кавычки, обертывающие путь к winmerge:

[diff]
    tool = winmerge
[difftool "winmerge"]
    cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" -e "$LOCAL" "$REMOTE"
[difftool]
    prompt = false
[merge]
    tool = winmerge
[mergetool "winmerge"]
    cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" \"$MERGED\" \"$REMOTE\"
[mergetool]
    keepBackup = false
    trustExitCode = false

без конфигурации:

git difftool --tool winmerge

предположим:

  • Winmerge установлен
  • Git для windows установлен, из " Git версии 2.12.0.windows1 " или выше (хотя более ранние версии git, возможно, ввели команду).

git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "\"$PROGRAMFILES\WinMerge\WinMergeU.exe\" -u -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\""
git config --global difftool.prompt false

на WinMerge руководство командной строки: "параметры имеют префикс с символом косой черты ( / ) или тире ( -)"