Configurare e usare Meld come git difftool e mergetool


255

Sebbene molte delle informazioni in questa domanda e risposta siano disponibili su StackOverflow , sono distribuite su molte pagine e tra le altre risposte che sono errate o fuorvianti. Mi ci è voluto un po 'per mettere insieme tutto quello che volevo sapere.

Esistono molti programmi diversi che possono essere usati come git difftool e mergetool, e certamente non c'è consenso su quale sia il migliore (opinioni, requisiti e sistemi operativi differiranno chiaramente).

Meld è una popolare scelta gratuita, open source e multipiattaforma (UNIX / Linux, OSX, Windows), come mostrato nella domanda StackOverflow , Qual è il miglior strumento di unione visiva per Git? , in cui la risposta che propone Meld ha più di 3 volte i voti di qualsiasi altro strumento.

Alle seguenti 2 domande verrà data risposta nella mia risposta di seguito:

  • Come configuro e utilizzo Meld come mio git difftool?
  • Come configuro e uso Meld come mio git mergetool?

Nota: non è necessario utilizzare lo stesso programma sia del difftool che del mergetool, è possibile impostare programmi diversi per entrambi.


Risposte:


423

Come configuro e utilizzo Meld come mio git difftool?

git difftool mostra il diff usando un programma diff GUI (cioè Meld) invece di visualizzare l'output diff nel tuo terminale.

Sebbene sia possibile impostare il programma GUI sulla riga di comando mediante -t <tool> / --tool=<tool>esso, ha più senso configurarlo nel .gitconfigfile. [Nota: vedere le sezioni relative alla fuga tra virgolette e percorsi di Windows in basso.]

# Add the following to your .gitconfig file.
[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"

[Nota: queste impostazioni non modificheranno il comportamento git diffche continuerà a funzionare normalmente.]

Usi git difftoolesattamente allo stesso modo in cui usi git diff. per esempio

git difftool <COMMIT_HASH> file_name
git difftool <BRANCH_NAME> file_name
git difftool <COMMIT_HASH_1> <COMMIT_HASH_2> file_name

Se configurato correttamente, si aprirà una finestra Meld che mostra il diff utilizzando un'interfaccia GUI.

L'ordine dei riquadri della finestra della GUI di Meld può essere controllato dall'ordine di $LOCALe $REMOTEin cmd, vale a dire quale file è mostrato nel riquadro sinistro e quale nel riquadro destro. Se li vuoi viceversa, semplicemente scambiali in questo modo:

    cmd = meld "$REMOTE" "$LOCAL"

Infine, la prompt = falselinea semplicemente impedisce a git di chiederti se vuoi avviare Meld o meno, per impostazione predefinita git emetterà un prompt.


Come configuro e uso Meld come mio git mergetool?

git mergetool ti permette di usare un programma di unione GUI (cioè Meld) per risolvere i conflitti di unione che si sono verificati durante un'unione.

Come difftool, puoi impostare il programma GUI sulla riga di comando usando -t <tool> / --tool=<tool>ma, come prima, ha più senso configurarlo nel tuo .gitconfigfile. [Nota: vedere le sezioni relative alla fuga tra virgolette e percorsi di Windows in basso.]

# Add the following to your .gitconfig file.
[merge]
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines (not both!) explained below.
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

NON si utilizza git mergetoolper eseguire una fusione effettiva. Prima di usare git mergetoolesegui un'unione come al solito con git. per esempio

git checkout master
git merge branch_name

Se c'è un conflitto di unione, git mostrerà qualcosa del genere:

$ git merge branch_name
Auto-merging file_name
CONFLICT (content): Merge conflict in file_name
Automatic merge failed; fix conflicts and then commit the result.

A questo punto file_nameconterrà il file parzialmente unito con le informazioni sul conflitto di unione (che è il file con tutte le voci >>>>>>>e <<<<<<<in esso).

Ora è possibile utilizzare Mergetool per risolvere i conflitti di unione. Lo inizi molto facilmente con:

git mergetool

Se configurato correttamente, si aprirà una finestra Meld che visualizza 3 file. Ogni file sarà contenuto in un riquadro separato della sua interfaccia GUI.

Nella .gitconfigvoce di esempio sopra, vengono suggerite 2 linee come [mergetool "meld"] cmdlinea. In effetti ci sono tutti i tipi di modi per gli utenti avanzati di configurare la cmdlinea, ma questo va oltre lo scopo di questa risposta.

Questa risposta ha 2 cmdlinee alternative che, tra loro, soddisfano la maggior parte degli utenti e saranno un buon punto di partenza per utenti avanzati che desiderano portare lo strumento al livello successivo di complessità.

Innanzitutto ecco cosa significano i parametri:

  • $LOCAL è il file nel ramo corrente (ad es. master).
  • $REMOTE è il file nel ramo da unire (ad esempio nome_ramo).
  • $MERGED è il file parzialmente unito con le informazioni di conflitto di unione in esso.
  • $BASEè l'antenato del commit condiviso di $LOCALe $REMOTE, vale a dire il file com'era quando il ramo contenente $REMOTEera stato originariamente creato.

Ti suggerisco di usare:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"

o:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
    # See 'Note On Output File' which explains --output "$MERGED".

La scelta è se usare $MERGEDo $BASEtra $LOCALe $REMOTE.

In entrambi i casi, Meld visualizzerà 3 riquadri con $LOCALe $REMOTEnei riquadri sinistro e destro e $MERGEDo $BASEnel riquadro centrale.

In ENTRAMBI i casi, il riquadro centrale è il file che è necessario modificare per risolvere i conflitti di unione. La differenza sta proprio nella posizione di modifica iniziale che preferisci; $MERGEDper il file che contiene il file parzialmente unito con le informazioni sul conflitto di unione o $BASEper l'antenato del commit condiviso di $LOCALe $REMOTE. [Dato che entrambe le cmdrighe possono essere utili le tengo entrambe nel mio .gitconfigfile. La maggior parte delle volte uso la $MERGEDlinea e la $BASElinea è commentata, ma il commento può essere scambiato se invece voglio usare la $BASElinea.]

Nota sul file di output: non preoccuparti che --output "$MERGED"venga utilizzato cmdindipendentemente dal fatto che $MERGEDsia $BASEstato usato in precedenza nella cmdriga. L' --outputopzione indica semplicemente a Meld in quale nome di file git desidera salvare il file di risoluzione dei conflitti. Meld salverà le modifiche ai conflitti in quel file indipendentemente dal fatto che tu usi $MERGEDo $BASEcome punto di modifica iniziale.

Dopo aver modificato il riquadro centrale per risolvere i conflitti di unione, è sufficiente salvare il file e chiudere la finestra Combina. Git eseguirà l'aggiornamento automaticamente e il file nel ramo corrente (ad es. Master) conterrà ora tutto ciò che hai trovato nel riquadro centrale.

git avrà eseguito un backup del file parzialmente unito con le informazioni di conflitto di unione in esso aggiungendo .origal nome file originale. es file_name.orig. Dopo aver verificato che sei soddisfatto dell'unione e aver eseguito tutti i test che potresti voler fare, il .origfile può essere eliminato.

A questo punto ora puoi eseguire un commit per eseguire il commit delle modifiche.

Se, durante la modifica dei conflitti di unione in Combinazione, si desidera abbandonare l'uso di Combinazione, quindi chiudere Combinazione senza salvare il file di risoluzione di unione nel riquadro centrale. git risponderà con il messaggio file_name seems unchangede poi chiederà Was the merge successful? [y/n], se rispondi, nla risoluzione del conflitto di unione verrà interrotta e il file rimarrà invariato. Nota che se hai salvato il file in Meld in qualsiasi momento, non riceverai l'avviso e il prompt da git. [Ovviamente puoi semplicemente eliminare il file e sostituirlo con il .origfile di backup che git ha creato per te.]

Se hai più di 1 file con conflitti di unione, git aprirà una nuova finestra di fusione per ognuno, uno dopo l'altro fino a quando non saranno stati completati. Non saranno tutti aperti contemporaneamente, ma quando finisci di modificare i conflitti in uno e chiudi Meld, git aprirà il successivo e così via fino a quando tutti i conflitti di unione non saranno stati risolti.

Sarebbe sensato creare un progetto fittizio per testare l'utilizzo git mergetoolprima di utilizzarlo su un progetto dal vivo . Assicurati di utilizzare un nome file contenente uno spazio nel test, nel caso in cui il tuo sistema operativo richieda di sfuggire alle virgolette nella cmdriga, vedi sotto.


Caratteri di citazione di escape

Alcuni sistemi operativi potrebbero dover avere le virgolette in cmdescape. Gli utenti meno esperti dovrebbero ricordare che le righe di comando di configurazione devono essere testate con nomi di file che includono spazi e se le cmdlinee non funzionano con i nomi di file che includono spazi, prova a sfuggire alle virgolette. per esempio

cmd = meld \"$LOCAL\" \"$REMOTE\"

In alcuni casi potrebbe essere necessario scappare virgolette più complesse. Il primo dei collegamenti del percorso di Windows di seguito contiene un esempio di triplo escape di ogni preventivo. È noioso ma a volte necessario. per esempio

cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\"

Percorsi di Windows

Gli utenti Windows avranno probabilmente bisogno di un'ulteriore configurazione aggiunta alle cmdlinee di fusione . Potrebbe essere necessario utilizzare il percorso completo a meldc, progettato per essere richiamato su Windows dalla riga di comando, oppure potrebbe essere necessario o desiderare utilizzare un wrapper. Dovrebbero leggere le pagine StackOverflow collegate di seguito che riguardano l'impostazione della cmdlinea Meld corretta per Windows. Dato che sono un utente Linux, non sono in grado di testare le varie cmdlinee di Windows e non ho ulteriori informazioni sull'argomento oltre a raccomandare di usare i miei esempi con l'aggiunta di un percorso completo a Meld o meldc, o l'aggiunta della cartella del programma Meld alla tua path.

Ignorando gli spazi bianchi finali con Meld

La combinazione ha una serie di preferenze che possono essere configurate nella GUI.

Nella Text Filtersscheda delle preferenze ci sono diversi filtri utili per ignorare cose come i commenti quando si esegue un diff. Sebbene ci siano filtri da ignorare All whitespacee Leading whitespace, non esiste alcun Trailing whitespacefiltro da ignorare (questo è stato suggerito come aggiunta nella mailing list di Meld ma non è disponibile nella mia versione).

Ignorare gli spazi vuoti finali è spesso molto utile, specialmente durante la collaborazione, e può essere aggiunto manualmente facilmente con una semplice espressione regolare nella Text Filtersscheda Preferenze di fusione .

# Use either of these regexes depending on how comprehensive you want it to be.
[ \t]*$
[ \t\r\f\v]*$

Spero che questo possa aiutare tutti.


2
Grazie, che è molto più facile da utilizzare [mergetool "meld"] cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"in ~/.gitconfig, poi basta risolvere i conflitti evidenziati in rosso nella padella mezzo e risparmia! Dovrebbe essere l'impostazione predefinita.
KrisWebDev,

1
$LOCAL $MERGED $REMOTEè l'impostazione che uso la maggior parte delle volte, quando ci sono solo pochi conflitti per risolverlo è eccellente ed è anche il mio valore predefinito. $LOCAL $BASE $REMOTEsi presenta davvero quando c'è molto da fare e sai esattamente quali sezioni di codice provengono da quale file; l'antenato del commit condiviso può essere un ottimo punto di partenza senza ingombri, a volte l'evidenziazione del conflitto si mette in mezzo e una base più pulita è una benedizione.
mattst

4
Nota: se sei su OSX e hai installato la fusione tramite homebrew, il parametro di output richiederà un =simile:cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output="$MERGED"
Alteisen

2
Per gli utenti Mac che hanno installato il .dmg e scoprono che 'meld' non è nel loro percorso, assicurati di seguire il set alternativo di istruzioni qui: yousseb.github.io/meld
KC Baltz

3
È molto meglio della spiegazione di Git Configuration: git mergetool . Grazie in particolare per aver spiegato la differenza tra $ MERGED e $ BASE. Mi ha salvato dal diventare pazzo!
ChrisG

81

Mentre l'altra risposta è corretta, ecco il modo più veloce per andare avanti e configurare Meld come strumento di visualizzazione visiva. Basta copiare / incollare questo:

git config --global diff.tool meld
git config --global difftool.prompt false

Ora esegui git difftoolin una directory e Meld verrà avviato per ogni diverso file.

Nota a margine : la fusione è sorprendentemente lenta nel confrontare i file CSV e nessuno strumento diff Linux che ho trovato è più veloce di questo strumento Windows chiamato Compare It! (ultimo aggiornamento nel 2010).


13
Probabilmente vuoi anche una git config --global difftool.meld.cmd 'meld "$LOCAL" "$REMOTE"'linea lì dentro. Questo è il "valore predefinito", ma non appena si configura un mergetool, difftoolinizierà a utilizzare la configurazione di fusione come predefinito se non viene trovata la configurazione di diff. Poiché l'unione è generalmente configurata per passare tre file per un'unione a 3 vie, significa che la tua finestra meld diff avrà improvvisamente tre riquadri che non hanno alcun senso.
BeeOnRope,

Perché non controllare la configurazione, dopo aver impostato con $ git config -l
agfe2

56

Per Windows . Esegui questi comandi in Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global mergetool.prompt false

(Aggiorna il percorso del file per Meld.exe se il tuo è diverso.)

Per Linux . Esegui questi comandi in Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "/usr/bin/meld"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "/usr/bin/meld"
git config --global mergetool.prompt false

Puoi verificare il percorso di Meld usando questo comando:

which meld

1
Ho ricevuto un errore quando eseguo git difftool "La combinazione di strumenti diff non è disponibile come 'D: \ software \ melddiff \ Meld.exe'"
Allen Vork,

@AllenVork: hai confermato che Meld.exe si trova nella cartella che hai specificato? Riesci a eseguirlo al di fuori di Git con successo? Cosa restituisce Git quando corri git config --global --get-regex diff*?
MarredCheese,

L'ho risolto. Lo cambio in "D: /software/melddiff/Meld.exe" e funziona. Il formato .gitconfig è ubuntu non Windows.
Allen Vork,

Non avrebbe dovuto essere git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe":?
Jonathan Rosenne,

@AllenVork, stai usando git per Cygwin?
Adrian,

25

Preferisco impostare meld come comando separato, in questo modo:

git config --global alias.meld '!git difftool -t meld --dir-diff'

Questo lo rende simile allo script git-meld.pl qui: https://github.com/wmanley/git-meld

Quindi puoi semplicemente correre

git meld

Ho appena avuto una fusione lavorando con Cygwin, e ora è rotto. Questo l'ha risolto. Grazie! (Anche se ho rimosso la --dir-diffparte come preferenza personale.)
PfunnyGuy

3

Per Windows 10 ho dovuto inserire questo nel mio .gitconfig:

[merge]
  tool = meld
[mergetool "meld"]
  cmd = 'C:/Program Files (x86)/Meld/Meld.exe' $LOCAL $BASE $REMOTE --output=$MERGED
[mergetool]
  prompt = false

Tutto il resto che devi sapere è scritto in questa super risposta di mattst più in alto.

PS: Per qualche motivo, questo ha funzionato solo con Meld 3.18.x, Meld 3.20.x mi dà un errore.


1

Questa è una risposta rivolta principalmente agli sviluppatori che utilizzano Windows, poiché la sintassi del percorso dello strumento diff differisce dalle altre piattaforme.

Uso Kdiff3 come git mergetool, ma per configurare git difftool come Meld, ho prima installato l'ultima versione di Meld da Meldmerge.org, quindi ho aggiunto quanto segue al mio .gitconfig globale usando:

git config --global -e

Nota, se preferisci Sublime Text 3 invece di Vim predefinito come core ditor, puoi aggiungerlo al file .gitconfig:

[core]
editor = 'c:/Program Files/Sublime Text 3/sublime_text.exe'

Quindi aggiungi inn Meld come difftool

[diff]
tool = meld
guitool = meld 

[difftool "meld"]
cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" \"$LOCAL\" \"$REMOTE\" --label \"DIFF 
(ORIGINAL MY)\"
prompt = false
path = C:\\Program Files (x86)\\Meld\\Meld.exe

Nota la barra iniziale nel cmd sopra, su Windows è necessario.

È anche possibile impostare un alias per mostrare l'attuale git diff con un'opzione --dir-diff . Questo elencherà i file modificati all'interno di Meld, il che è utile quando sono stati modificati più file (uno scenario molto comune).

L'alias appare così all'interno del file .gitconfig, sotto la sezione [alias] :

showchanges = difftool --dir-diff

Per mostrare le modifiche che ho apportato al codice, basta inserire il seguente comando:

git showchanges

L'immagine seguente mostra come questa opzione --dir-diff può mostrare un elenco di file modificati (esempio): Combina l'elenco di file con modifiche tra $ LOCAL e $ REMOTE

Quindi è possibile fare clic su ciascun file e mostrare le modifiche all'interno di Meld.


0

Può essere complicato calcolare un diff nella tua testa dalle diverse sezioni in $ MERGED e applicarlo. Nella mia configurazione, meld aiuta mostrandoti queste differenze visivamente, usando:

[merge]
    tool = mymeld
    conflictstyle = diff3

[mergetool "mymeld"]
    cmd = meld --diff $BASE $REMOTE --diff $REMOTE $LOCAL --diff $LOCAL $MERGED

Sembra strano ma offre un flusso di lavoro molto conveniente, usando tre schede:

  1. nella scheda 1 vedi (da sinistra a destra) la modifica che dovresti fare nella scheda 2 per risolvere il conflitto di unione.

  2. nella parte destra della scheda 2 si applica la "modifica da apportare" e si copia l'intero contenuto del file negli Appunti (usando ctrl-a e ctrl-c).

  3. nella scheda 3 sostituisci il lato destro con il contenuto degli appunti. Se tutto è corretto, ora vedrai - da sinistra a destra - la stessa modifica mostrata nella scheda 1 (ma con contesti diversi). Salva le modifiche apportate in questa scheda.

Appunti:

  • non modificare nulla nella scheda 1
  • non salvare nulla nella scheda 2 perché ciò produrrà fastidiosi popup nella scheda 3

È forse meglio della fusione a 3 vie (locale / base / remoto) in una singola scheda?
André Werlang,

@ AndréWerlang Il vantaggio della fusione a 3 vie in una singola scheda è che devi solo gestire le modifiche in conflitto (le altre modifiche vengono unite automaticamente). Ma preferisco il "mio" approccio nei casi in cui è difficile capire nella fusione a 3 vie cosa è cambiato e come fondersi in modo da preservare tutti i cambiamenti. Se a un certo punto l'unione a 3 vie non mi confonde più, allora posso tornare ad essa.
lunedì

Come ha sottolineato l'utente mattst, è possibile utilizzare $BASEinvece di $MERGEDiniziare l'operazione di unione
André Werlang
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.