użyj Winmerge wewnątrz Git do pliku diff

Czy istnieje sposób na użycie Winmerge wewnątrz Gita do robienia Diffów?

Author: Toby Allen, 2009-12-10

8 answers

Aktualizacja czerwiec 2015, 6 lat później:

Jak opisano w "git mergetool winmerge ", wystarczy prosty git config diff.tool winmerge.

Git 2.5+ (Q2, 2015) jest teraz świadomy Winmerge jako narzędzia diff lub merge!


Oryginalna odpowiedź (2009-2012)

(msysgit, 1.6.5, DOS session)

Pierwsza część (używająca winmerge)jest opisana w "Jak wyświetlić wyjście 'git diff' za pomocą programu 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

Z winmerge.sh przechowywanym w katalogu część Twojego PATH:

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

(zobacz Opcje wiersza poleceń WinMerge )

git difftool

Uruchomi WinMerge.
Jeśli chcesz git diff uruchomić WinMerge, po prostu ustaw:

set GIT_EXTERNAL_DIFF=winmerge.sh

Ale prawdziwa wartość dodana wynika z możliwości użycia tego samego narzędzia do różnicowania do prezentowania wszystkich różnic w jednej partii zamiast prezentowania ich sekwencyjnie, zmuszając do zamykania okien narzędzi różnicowania po jednym pliku na raz.

Aktualizacja Czerwiec 2012

Porównywanie katalogów zamiast pliku po Pliku będzie dostępne wkrótce:
Zobacz [ANNOUNCE] Git 1.7.11.rc1 :

"git difftool" nauczyłem się opcji " --dir-diff", aby wywoływać zewnętrzne narzędzia różnicowe, które mogą porównywać dwie hierarchie katalogów w czasie po wypełnieniu dwóch katalogów tymczasowych, zamiast uruchamiać instancję zewnętrznego narzędzia raz na parę plików .

Zobacz "Patch difftool: teach difftool to handle directory diffs", i odpowiedź "porównanie katalogów gałęzi Git " po więcej szczegółów.


Original difftool by directory script (grudzień 2009)

Jako Seba Illingworth wspomina w swoją odpowiedź , scenariusz git-diffall.sh (również umieścić w ścieżce) może zrobić tylko to:

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

Ale to działa tylko przez otwarcie N okien dla N plików (jeśli spróbujesz użyć opcji -s WinMerge nie będzie działać, ponieważ tymczasowe pliki są usuwane przez difftool zbyt wcześnie) {]}


Dlatego podoba mi się podejście Gitdiffa.bat-power-diffing with gi , który pozwala przejrzeć listę plików z różnicą, przed wyborem jednego do zbadania jego wewnętrznych różnic.
Poprawiłem go, aby używać tylko poleceń 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

Nie jest wystarczająco wytrzymały, aby obsługiwać pliki o tych samych nazwach w różnych katalogach, ale daje ogólne idea tego, co jest możliwe:
Tutaj otworzy się tylko jeden WinMerge, z listą plików mających wewnętrzne różnice. Możesz kliknąć na te, które chcesz zbadać, a następnie prosty ESC zamknie całą sesję WinMerge-diff.

 111
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:19

Napotkałem problemy z użyciem pierwszej części w 2 miejscach i naprawiłem to w następujący sposób

  1. Drugie polecenie do Ustawienia winmerge.cmd wymagało dodatkowego ukośnika na cmdline( przed $LOCAL i $REMOTE), w przeciwnym razie cygwin podstawiał zmienną w cmdline

    C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
    
  2. Zmienił winmerge.sh file to (without this, was getting right-path-invalid error)

    #!/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")"
    
 19
Author: Gopi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-10 04:57:04

Ponieważ wątek jest coraz bardziej mylący i rozwidlony, oto skonsolidowane instrukcje dla metody WinMerge" --dir-diff " dla systemu Msysgit Git.

Krok 1 - Utwórz plik o nazwie winmerge.sh w miejscu dostępnym dla twojej ścieżki (np. /home/bin/winmerge.sh) o następującej treści.

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

Krok 2 - wpisz następujące polecenia w Git Bash, aby polecić użycie git winmerge.sh jako difftool (opcje te zapisywane są w /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

Krok 3 - Teraz możesz przetestować wpisując następujące polecenie w Git Bash, aby uruchomić WinMerge diff:

git difftool --dir-diff

Krok 4 - aby uzyskać szybszy dostęp, utwórz alias dla tego polecenia, dodając tę linię do .bashrc w folderze domowym (lub utwórz .plik bashrc z tą linią, jeśli plik jeszcze nie istnieje):

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

Krok 5 -Teraz możesz szybko zobaczyć różnicę w WinMerge wpisując następujące polecenie w Git Bash

diffdir
 6
Author: robertcollier4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-22 07:10:02

Mam skrypt, który ustawi narzędzia Diff i Merge w Git config z odpowiednimi parametrami, które nie wymagają oddzielnego pliku .SH do istnienia. Wygląda na to, że działa dobrze dla mnie.

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\""

Uwaga - całość .część cmd jest cytowana tak, że parametry zostaną wymienione w.gitconfig properly

 6
Author: Alf47,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 20:00:27

Byłem zdezorientowany, dlaczego rozwiązanie zostało przedstawione jako plik wsadowy DOS, ponieważ moja instalacja Git została dostarczona z powłoką bash. Nie udało mi się również uzyskać kontekstu DOS działającego z bash, więc próbowałem dostosować to, co wcześniej było udostępniane w kontekście bash.

Ponieważ git diff wydaje się uruchamiać określone polecenie raz dla każdego pliku, podzieliłem moje rozwiązanie na dwa skrypty bash:

Najpierw skonfiguruj gitprepdiff.sh jako difftool, jak wcześniej wspomniano

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

Zauważyłem również że wyniki poleceń git configure można znaleźć i edytować bezpośrednio w C:\Users\<username>\.gitconfigure

gitdiff.sh jest następnie uruchamiany w wierszu poleceń, w którym normalnie wywołasz 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

Warto również zauważyć, że w mojej instalacji /tmp (w bash) zmapowano do %LOCALAPPDATA%\Temp\1\ (W Windows), dlatego używam tego ostatniego w moim wywołaniu do WinMerge.

 2
Author: Shawn South,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-24 00:59:36

Na windows możesz to zrobić w ten sposób:

1) Otwórz .plik gitconfig. Znajduje się w katalogu domowym: c:\users\username.gitconfig

2) Dodaj wiersze poniżej. Zwróć uwagę na pojedyncze cudzysłowy zawijające ścieżkę do 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
 2
Author: Caner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-03 08:44:43

Bez konfiguracji:

git difftool --tool winmerge

Zakładając:

  • Winmerge jest zainstalowany
  • Git dla windows jest zainstalowany, od " git w wersji 2.12.0.windows1 " lub wyżej (chociaż wcześniejsze wersje git mogły wprowadzić polecenie).
 1
Author: John Bentley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 13:34:08
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

Zgodnie z instrukcją linii poleceń WinMerge: "parametry są poprzedzone znakiem ukośnika ( / ) lub myślnika ( - )"

 0
Author: Steve Lang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-17 01:09:52