Используйте Winmerge внутри Git для создания файла diff
Есть ли способ использовать Winmerge внутри git для выполнения Diffs?
9 ответов
Обновление июнь 2015, 6 лет спустя:
Как подробно описано в " git mergetool winmerge ", простой git config diff.tool winmerge
будет достаточно.
Git 2.5+ (Q2, 2015) теперь знает о Winmerge как инструменте сравнения или слияния!
Оригинальный ответ (2009-2012)
(msysgit, 1.6.5, сессия DOS)
Первая часть (с использованием winmerge) описана в разделе " Как просмотреть вывод" git diff "с помощью программы 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 г. (два с половиной года спустя):
Сравнение каталогов вместо файла к файлу будет доступно в ближайшее время:
Смотрите [ОБЪЯВЛЕНИЕ] Git 1.7.11.rc1:
"
git difftool
"узнал"--dir-diff
"возможность порождать внешние инструменты сравнения, которые могут сравнивать две иерархии каталогов за раз после заполнения двух временных каталогов, вместо того, чтобы запускать экземпляр внешнего инструмента один раз для пары файлов.
Смотрите " Патч difftool
: учат difftool
для обработки каталогов diffs ", и ответ" Сравнение каталогов Git ветвей "для более подробной информации.
Оригинальный скрипт difftool по каталогам (декабрь 2009)
Как упоминает Seba Illingworth в своем ответе, скрипт 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 - Power-Diffing с 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 местах и исправил это следующим образом
Вторая команда для настройки winmerge.cmd требовала дополнительной косой черты на cmdline (до $LOCAL и $REMOTE), иначе cygwin подставлял переменную в cmdline
C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
изменил файл winmerge.sh на (без этого получал ошибку right-path-invalid)
#!/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")"
Без конфигурации:
git difftool --tool winmerge
Предполагая, что:
- Winmerge установлен
- Установлен Git для Windows, начиная с "git version 2.12.0.windows1" или выше (хотя в более ранних версиях git могла быть введена команда).
На окнах вы можете сделать это следующим образом:
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
У меня есть скрипт, который установит инструменты 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.
Поскольку поток становится запутанным и раздвоенным, здесь представлены сводные инструкции для метода WinMerge для каталога 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 в качестве 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
Я вижу здесь много длинных и запутанных ответов, поэтому публикую упрощенную и минимальную версию, которая работала у меня в 2021 году на Windows10.
git config diff.tool winmerge
git config --replace --global difftool.prompt false
Я был озадачен тем, почему решение было представлено в виде пакетного файла DOS, поскольку моя установка Git шла с оболочкой bash. Мне также не удалось запустить контекст DOS из bash, поэтому я попытался адаптировать то, что ранее использовалось в контексте bash.
поскольку git diff
По-видимому, чтобы выполнить указанную команду один раз для каждого файла, я разделил свое решение на два сценария bash:
Сначала настройте gitprepdiff.sh
быть difftool, как упоминалось ранее
#!/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.
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: "Параметры начинаются с символа косой черты ( /) или тире ( -)"