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

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


person eiu165    schedule 10.12.2009    source источник
comment
См. stackoverflow.com/questions/ 636253 /   -  person Ben James    schedule 10.12.2009
comment
Связанное сообщение - Как настроить инструмент сравнения в Git в целом.   -  person RBT    schedule 06.04.2018


Ответы (9)


Обновление в июне 2015 года, 6 лет спустя:

Как подробно описано в «git mergetool winmerge», простого git config diff.tool winmerge будет достаточно.

Git 2.5+ (второй квартал 2015 г.) теперь знает Winmerge как инструмент сравнения или слияния!


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

(msysgit, 1.6.5, сеанс DOS)

Первая часть (с использованием Winmerge) описана в "Как просмотреть вывод 'git 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: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -u -dl "Local" -dr "Remote" "$1" "$2"

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

git difftool

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

set GIT_EXTERNAL_DIFF=winmerge.sh

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

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

Скоро будет доступно сравнение каталогов вместо файлового сравнения:
См. [ANNOUNCE] Git 1.7.11.rc1:

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

См. «Патч difftool: научите difftool обрабатывать различия в каталогах». и ответ "Сравнение каталогов веток Git" для получения дополнительных сведений.


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

Как упоминает Себа Иллингворт в его ответ, скрипт 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.bat - изменение мощности с помощью 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 сеанс.

person VonC    schedule 10.12.2009
comment
Попробуйте это с помощью git версии 1.6.5.1.1367.gcd48, и, похоже, он не создает никаких файлов в этих временных папках. Есть идеи, где искать проблему? Спасибо! - person Art; 16.09.2010
comment
@Art: в этих случаях отладки я пытаюсь изолировать проблему, упрощая сценарий: 1 / если сценарий, вызываемый с параметром 7 (первый проход git diff, для копирования файлов) 2 / является сценарием, по крайней мере, обратным вызовом в конце git diff? - person VonC; 16.09.2010
comment
Итак, я попробовал это, и у меня это не работает (git версии 1.7.2.3). echo Launching WinMergeU.exe: $1 $2 работает, пример вывода - Launching WinMergeU.exe: /tmp/waxdnW_makeHTML.cfm scheduler/makeHTML.cfm, но я никогда не вижу эту папку tmp, а при запуске Winmerge значение Left равно C: \ ColdFusion8 \ wwwroot \ archiver-git \ scheduler \ makeHTML.cfm, но правое значение пустое, и я не могу нажмите ОК - person erikvold; 23.11.2010
comment
что делает -ub? Я не вижу документального подтверждения этого аргумента. - person erikvold; 23.11.2010
comment
@Erik: относительно опции -ub см. FAQ по WinMerge: это то же, что и -u: он сообщает WinMerge не добавлять файлы в MRU. - person VonC; 23.11.2010
comment
@Erik: вы должны увидеть сравнение файлов в c:\Temp\GitDiff\old и c:\Temp\GitDiff\new, а не в "/tmp". Вы уверены, что выполняете эту программу DOS из сеанса DOS (а не из сеанса bash)? - person VonC; 23.11.2010
comment
@VonC ах, я использовал cygwin .. ваше решение отлично работает в DOS для меня, спасибо! - person erikvold; 23.11.2010
comment
Спасибо! это отлично решило мою проблему. Еще одна деталь для пользователей cygwin или git bash заключается в том, что при настройке конфигураций git необходимо экранировать символ '$', а также символы ''. - person Michael Steele; 08.04.2013
comment
@MichaelSteele Отлично! Можете ли вы отредактировать ответ, включив в него пример работы с cygwin / bash? - person VonC; 08.04.2013
comment
После выполнения первого набора инструкций git difftool дает /libexec/git-core/git-mergetool--lib: line 122: winmerge: command not found 4 раза и никогда не запускает winmerge. Я немного не понимаю, как его отлаживать, поскольку все это кажется мне немного волшебным. - person recursive; 29.05.2015
comment
Продолжая мой предыдущий комментарий: эти изменения изменили поведение интегрированного файла diff. Теперь он запускает Winmerge без открытых файлов, предлагая мне использовать C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ Common7 \ IDE \ .sh в качестве левого файла, которого на самом деле не существует и, конечно же, нет. не работает. Надеюсь, я смогу это исправить. - person recursive; 29.05.2015
comment
@recursive Было бы лучше задать отдельный вопрос, чтобы другие могли взглянуть на вашу проблему. - person VonC; 29.05.2015
comment
В команде git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\"" "$LOCAL" и "$REMOTE" будут оцениваться как "". Вместо этого используйте 'winmerge.sh "$LOCAL" "$REMOTE"'. - person coffeemakr; 18.06.2018
comment
@coffeemakr он не оценил "" в моем случае (выполнение команды git config из Windows CMD. Но вы правы: он оценил бы "", если бы был запущен из оболочки bash. - person VonC; 18.06.2018
comment
Вау, значит, вам нужно сделать все это только для того, чтобы настроить git так, чтобы он указывал на winmerge? - person Robin; 19.06.2018
comment
@Robin Тебе пришлось. В наши дни достаточно git config diff.tool winmerge. - person VonC; 19.06.2018

У меня возникла проблема с использованием первой части в 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 на (без этого возникала ошибка неправильного пути)

    #!/bin/sh
    echo Launching WinMergeU.exe: "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
    "$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
    
person Gopi    schedule 10.10.2011
comment
Я сделал именно то, что велел VonC, но получал пустые аргументы в моем скрипте winmerge.sh. Использование дополнительных слэшей решило проблему. Спасибо! - person ashagi; 16.11.2011

У меня есть сценарий, который установит инструменты 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.

person Alf47    schedule 22.09.2014
comment
Следующая команда у меня не сработала. git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\"" Примечание. Эту команду необходимо запускать из командной строки, а не из PowerShell. Вручную добавление следующего в мой раздел .gitconfig [difftool "winmerge"] помогло мне: cmd = 'C:/Program Files (x86)/WinMerge/WinMergeU.exe' -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\" - person Josh; 13.05.2015
comment
Не сработало, но с некоторыми изменениями работает: откройте cmd от имени администратора и запустите: git config --global mergetool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\"". Было несколько неправильных экранированных строк (обратите внимание на несколько дополнительных нежелательных обратных косых черт прямо перед $ - я думаю, $ не нужно экранировать). Кроме того, не было конца " после WinMergeU?.exe. Запустите git config --get mergetool.winmerge.cmd, чтобы увидеть, что было установлено на самом деле. В любом случае, спасибо за не .sh версию: +1! - person falsarella; 19.06.2015

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

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

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

Шаг 2. Введите следующие команды в Git Bash, чтобы указать git на использование winmerge.sh в качестве инструмента diff (эти параметры сохраняются в /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:

git difftool --dir-diff

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

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

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

diffdir
person robertcollier4    schedule 12.06.2013
comment
Было бы полезно, если бы кто-нибудь объяснил значение $LOCAL и $REMOTE. - person Tola Odejayi; 08.07.2016

В 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
person Caner    schedule 03.06.2015
comment
Также обратите внимание на прямые косые черты вместо обратных косых черт в пути к команде. - person wisbucky; 18.10.2016

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

git difftool --tool winmerge

Предполагая:

  • Winmerge установлен
  • Устанавливается Git для Windows, начиная с "git версии 2.12.0.windows1" или выше (хотя в более ранних версиях git эта команда могла быть представлена).
person John Bentley    schedule 01.03.2017
comment
Спасибо, это самое простое решение - person code4j; 05.01.2018

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

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

Во-первых, сконфигурируйте gitprepdiff.sh как средство распознавания, как упоминалось ранее.

#!/bin/sh
#echo ...gitprepdiff.sh
cp -v $1 "$TMP/GitDiff/old/$2"
cp -v $2 "$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\1\ (в Windows), поэтому я использую последний при вызове WinMerge.

person Shawn South    schedule 24.11.2011
comment
Я поменял gitprepdiff.sh на #!/bin/sh #echo ...gitprepdiff.sh mkdir -vp "$TMP/GitDiff/old/$(dirname $2)" cp -v $1 "$TMP/GitDiff/old/$2" cp -v --parents $2 "$TMP/GitDiff/new" Спасибо! - person dobau; 28.03.2013
comment
Кажется смешным перепрыгивать через столько обручей, чтобы справиться с этой задачей, но это действительно так. Вы получаете все различия файлов за один раз, как и должно быть. Мне также пришлось внести изменения, упомянутые @dobau, чтобы правильно обрабатывать файлы в подкаталогах. - person Tom; 25.09.2013

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: «Параметры начинаются с символа косой черты (/) или символ тире (-) "

person Steve Lang    schedule 17.03.2016

Я вижу здесь много длинных и запутанных ответов, поэтому размещаю упрощенную и минимальную версию, которая сработала для меня в 2021 году на windows10

 git config diff.tool winmerge
 git config --replace --global difftool.prompt false
person richardrichard goolmangoolman    schedule 01.02.2021