використовуйте Winmerge всередині Git для файлу розл


Відповіді:


113

Оновлення червня 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

Але реальна додана вартість походить від здатності використовувати той самий інструмент diff, щоб представити всі відмінності в одній партії, а не представляти їх послідовно, змушуючи закривати вікна інструменту diff по одному файлу за один раз.

Оновлення червня 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 windows для n файлів (якщо ви спробуєте скористатися -sопцією WinMerge, вона не працюватиме через те, що файли temp видаляються 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сеанс.


1
Спробуйте це з версією git 1.6.5.1.1367.gcd48 і, схоже, не генерує жодних файлів у цих тимчасових папках. Будь-які ідеї, де шукати проблему? Дякую!
Арт

@Art: у цих випадках налагодження я намагаюся вирішити проблему, спростивши скрипт: 1 / якщо скрипт викликається параметром 7 (перший пропуск git diff, щоб скопіювати файли) 2 /, сценарій принаймні викликається назад в кінці git diff?
VonC

1
@Erik: щодо цього варіанта -ubдив. FAQ щодо WinMerge : він такий же, як -u: він каже WinMerge не додавати файли до MRU.
VonC

1
@Erik: ви повинні побачити порівняння файлів у, c:\Temp\GitDiff\oldа c:\Temp\GitDiff\newне ' /tmp'. Ви впевнені, що виконуєте цю програму DOS з сеансу DOS (а не баш-сесії)?
VonC

1
@coffeemakr ""в моєму випадку це не оцінило (виконання git configкоманди з Windows CMD. Але ви маєте рацію: він би оцінив, ""чи виконується з оболонки bash.
VonC,

19

Я зіткнувся з проблемою, використовуючи першу частину в 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")"
    

3
Я робив саме те, як доручив VonC, але в моєму сценарії winmerge.sh я отримував порожні аргументи. Використання додаткових косої риски вирішило проблему. Дякую!
ашагі

6

Оскільки потік стає заплутаним і роздвоєним, тут наведені консолідовані інструкції до списку каталогів "--dir-diff" метод 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

Було б корисно, щоб хтось пояснив значення $LOCALта $REMOTE.
Tola Odejayi

6

У мене є скрипт, який встановить інструменти 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 належним чином


1
Наступна команда не працювала для мене. git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\"" Примітка. Ця команда повинна бути запущена з командного рядка, а не з командної оболонки. Вручну додавши наступне до мого [difftool "winmerge"]розділу .gitconfig , працював для мене: cmd = 'C:/Program Files (x86)/WinMerge/WinMergeU.exe' -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\"
Джош

1
Це не спрацювало, але з деякими змінами, він працює відкритий 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!
фальсарела

5

У Windows ви можете це зробити так:

1) Відкрийте файл .gitconfig. Він розташований у вашому домашньому каталозі: c: \ users \ username.gitconfig

2) Додайте рядки нижче. Зверніть увагу на одиничні цитати, що обгортають шлях до зимівлі:

[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

Також зверніть увагу на косої нахили вперед, а не на косої риски в командному шляху.
wisbucky

5

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

git difftool --tool winmerge

Припустимо:

  • Winmerge встановлений
  • Git для Windows встановлюється з "git версії 2.12.0.windows1" або вище (хоча раніші версії git, можливо, ввели команду).

Дякую, це найпростіше рішення
code4j

2

Мене збентежило те, чому рішення було представлено у вигляді пакетного файлу DOS, оскільки моя установка Git поставилася з bash shell. Я також не зміг отримати контекст 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.


2
Я змінився 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"Дякую!
dobau

Здається смішним стрибати через стільки обручів, щоб зробити цю роботу, але це так. Ви отримуєте всі файли різниць за один раз, як це має бути. Мені довелося також внести зміни, згадані @dobau, щоб правильно обробити файли в підкаталогах.
Том,

1
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 : "Параметри мають префікс або символом нахилу вперед (/) або тире (-)"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.