C'è un modo per usare Winmerge all'interno di git per fare differenze?
C'è un modo per usare Winmerge all'interno di git per fare differenze?
Risposte:
Aggiornamento giugno 2015, 6 anni dopo:
Come spiegato in " git mergetool winmerge ", un semplice git config diff.tool winmerge
sarà sufficiente.
Git 2.5+ (Q2, 2015) è ora a conoscenza di Winmerge come strumento di differenza o unione!
Risposta originale (2009-2012)
(msysgit, 1.6.5, sessione DOS)
La prima parte (usando winmerge) è descritta in " Come posso visualizzare l'output di 'git diff' con il programma 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
Con winmerge.sh
memorizzato in una directory parte del tuo PATH
:
#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -u -dl "Local" -dr "Remote" "$1" "$2"
(vedi Opzioni della riga di comando di WinMerge )
git difftool
lancerà ora WinMerge.
Se vuoi git diff
avviare WinMerge, imposta semplicemente:
set GIT_EXTERNAL_DIFF=winmerge.sh
Ma il vero valore aggiunto deriva dalla possibilità di utilizzare lo stesso strumento diff per presentare tutte le differenze in un batch invece di presentarle in sequenza, costringendoti a chiudere le finestre dello strumento diff un file alla volta.
Aggiornamento giugno 2012 (2 anni e mezzo dopo):
Il confronto tra directory invece di file per file sarà presto disponibile:
Vedi [ANNOUNCE] Git 1.7.11.rc1 :
"
git difftool
" appreso "--dir-diff
" l'opzione per generare strumenti di diff esterni che possono confrontare due gerarchie di directory contemporaneamente dopo aver popolato due directory temporanee, invece di eseguire un'istanza dello strumento esterno una volta per coppia di file .
Vedere " Patch difftool
: insegnare difftool
a gestire le differenze di directory " e la risposta " Confronto di directory dei rami Git " per maggiori dettagli.
Difftool originale per script directory (dicembre 2009)
Come afferma Seba Illingworth nella sua risposta , uno script git-diffall.sh (inserito anche nel percorso) può fare proprio questo:
#!/bin/sh
git diff --name-only "$@" | while read filename; do
git difftool "$@" --no-prompt "$filename" &
done
Ma funziona solo aprendo n finestre per n file (se provi a utilizzare l' -s
opzione di WinMerge, non funzionerà perché i file temporanei vengono eliminati troppo presto dal difftool)
Questo è il motivo per cui mi piace l'approccio di GitDiff.bat - power-diffing con GI , che consente di rivedere l'elenco dei file con una differenza, prima di selezionarne uno per esaminarne le differenze interne.
L'ho ottimizzato per utilizzare solo comandi 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
Non è abbastanza robusto per gestire file con lo stesso nome in directory diverse, ma ti dà un'idea generale di cosa è possibile:
qui si aprirà solo un WinMerge, con l'elenco dei file con differenze interne. Puoi fare clic su quelli che vuoi esaminare, quindi un semplice ESCchiuderà l'intera WinMerge-diff
sessione.
git diff
?
-ub
, vedere le FAQ di WinMerge : è lo stesso di -u
: dice a WinMerge di non aggiungere i file all'MRU.
c:\Temp\GitDiff\old
e c:\Temp\GitDiff\new
, non ' /tmp
'. Sei sicuro di eseguire questo programma DOS da una sessione DOS (e non da una sessione bash)?
""
nel mio caso (eseguendo il git config
comando da un CMD di Windows. Ma hai ragione: valuterà ""
se eseguito da una shell bash.
Ho riscontrato problemi nell'utilizzo della prima parte in 2 punti e l'ho risolto come segue
Il secondo comando per l'impostazione di winmerge.cmd richiedeva una barra extra su cmdline (prima di $ LOCAL e $ REMOTE), altrimenti cygwin stava sostituendo la variabile in cmdline
C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
cambiato il file winmerge.sh in (senza questo, riceveva un errore di percorso corretto non valido)
#!/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")"
Poiché il thread sta diventando confuso e biforcato, ecco le istruzioni consolidate per il metodo WinMerge dell'elenco di directory "--dir-diff" per msysgit Git Windows.
Passaggio 1 : crea un file denominato winmerge.sh in una posizione accessibile al tuo percorso (come /home/bin/winmerge.sh) con i seguenti contenuti.
#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -r -ub -dl "Remote" -dr "Local" "$1" "$2"
Passaggio 2 : digitare i seguenti comandi in Git Bash per istruire git a utilizzare winmerge.sh come difftool (queste opzioni vengono memorizzate in /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
Passaggio 3 : ora puoi eseguire il test digitando il seguente comando in Git Bash per avviare il tuo WinMerge diff:
git difftool --dir-diff
Passaggio 4 : per un accesso più rapido, creare un alias per questo comando aggiungendo questa riga a .bashrc nella cartella home (o creare il file .bashrc con questa riga se il file non esiste già):
alias diffdir='git difftool --dir-diff'
Passaggio 5 - Ora puoi vedere rapidamente una differenza in WinMerge semplicemente digitando il seguente comando in Git Bash
diffdir
$LOCAL
e $REMOTE
.
Ho uno script che imposterà gli strumenti Diff e Merge nella configurazione Git con i parametri corretti che non richiedono l'esistenza di un file .sh separato. Sembra che funzioni bene per me.
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\""
Nota : l'intera porzione .cmd viene citata in modo che i parametri vengano elencati correttamente in .gitconfig
git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""
Nota: questo comando deve essere eseguito da un prompt dei comandi e non da PowerShell. L'aggiunta manuale di quanto segue alla mia [difftool "winmerge"]
sezione .gitconfig ha funzionato per me: cmd = 'C:/Program Files (x86)/WinMerge/WinMergeU.exe' -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\"
git config --global mergetool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\""
. C'erano alcune stringhe di escape errate (nota alcune barre rovesciate aggiuntive indesiderate lì subito prima del $
- immagino $
che non sia necessario eseguire l'escape). Inoltre, mancava una fine "
dopo WinMergeU?.exe
. Corri git config --get mergetool.winmerge.cmd
a vedere cosa era stato effettivamente impostato. Comunque, grazie per la mancata .sh
versione: +1!
Su Windows puoi farlo in questo modo:
1) Apri il file .gitconfig. Si trova nella tua home directory: c: \ users \ username.gitconfig
2) Aggiungi le righe seguenti. Presta attenzione alle virgolette singole che racchiudono il percorso per 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
Senza configurazione:
git difftool --tool winmerge
Supponendo:
Ero confuso sul motivo per cui la soluzione è stata presentata come un file batch DOS, poiché la mia installazione di Git veniva fornita con una shell bash. Non sono stato inoltre in grado di ottenere un contesto DOS in esecuzione da bash, quindi ho tentato di adattare ciò che era precedentemente condiviso in un contesto bash.
Poiché git diff
sembra che esegua il comando specificato una volta per ogni file, ho diviso la mia soluzione in due script bash:
Per prima cosa, configura gitprepdiff.sh
come difftool come accennato in precedenza
#!/bin/sh
#echo ...gitprepdiff.sh
cp -v $1 "$TMP/GitDiff/old/$2"
cp -v $2 "$TMP/GitDiff/new"
Ho anche notato che i risultati dei git configure
comandi possono essere trovati e modificati direttamente inC:\Users\<username>\.gitconfigure
gitdiff.sh
viene quindi eseguito dalla riga di comando dove normalmente chiameresti 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
Vale anche la pena notare che, sulla mia installazione, /tmp
(in bash) mappato su %LOCALAPPDATA%\Temp\1\
(in Windows), ecco perché sto usando quest'ultimo nella mia chiamata a WinMerge.
gitprepdiff.sh
per #!/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"
Grazie!
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
Secondo il manuale della riga di comando di WinMerge : "I parametri sono preceduti da un carattere barra (/) o trattino (-)"