2012-04-05 9 views
23

Come posso far funzionare automaticamente git git mergetool per qualsiasi conflitto di merge? Ciò dovrebbe valere per tutte le unioni, utilizzando merge, rebase, pull, eccCome faccio a fare git aprire automaticamente il mergetool se c'è un conflitto di merge?

+1

Forse è possibile utilizzare un [githook] (http://www.kernel.org/pub/software/scm/git/docs/githooks.html), ad es. 'post-checkout' (non so se è effettivamente invocato durante un'unione.' post-merge' richiede un'unione riuscita) –

+1

@TobiasKienzler Potresti essere su qualcosa. Se riesci a trovare una soluzione funzionante, ti darò la taglia per questa domanda. –

+0

@QuinnStrahl Non penso che esista attualmente un hook che viene eseguito prima di ciascuno dei vari comandi che portano a un'unione, quindi [il wrapper di rospov] (http://stackoverflow.com/a/17620046/321973) è probabilmente il soluzione più semplice. Ovvero o modificando la sorgente git per implementare una funzionalità di hook di "pre-merge", nel qual caso potreste semplicemente avere git eseguire mergetool sui conflitti a seconda di un'impostazione di configurazione comunque ... –

risposta

3

Si può sempre usare alias

alias 'git-merge'='git merge && git mergetool' 
alias 'git-rebase'='git rebase && git mergetool' 
alias 'git-pull'='git pull && git mergetool' 

e/o scrivere uno script di aiuto in questo senso

#/bin/bash 
git $* 
[ "$(git ls-files –abbrev –unmerged | wc -l)" -gt 0 ] && git mergetool 

e poi

alias git='~/.git/git-script' 

C'è nessun modo diretto di invocare mergetool, perché è solo uno dei vari modi di unire (vedi "COME RISOLVERE I CONFLITTI" in man 1 git-merge).

+3

Come ho già detto, voglio solo chiamare 'mergetool' se c'è un conflitto. L'argomento "solo uno dei tanti modi per unire" non è convincente. Sì, ci sono molti modi, ma è abbastanza ragionevole sceglierne uno come predefinito. –

+1

git mergetool non farà nulla se non c'è conflitto. – j13r

+2

Stampa un messaggio. –

2

Per quanto ne so, non esiste un modo in porcellana per farlo.

Si può avere un wrapper git come questo (file git_mergetool.sh, sul vostro percorso, +x):

#!/bin/bash 

SEARCH="CONFLICT" 
OUTPUT=$(git "[email protected]" 2>&1 | tee /dev/tty) 
if `echo ${OUTPUT} | grep -i "${SEARCH}" 1>/dev/null 2>&1` 
then 
    git mergetool 
fi 

Quindi aggiungere alias:

echo alias git=\"git_mergetool.sh\" >> ~/.bashrc 

Ogni volta che si richiama git, l'involucro controllerà se compare la parola "CONFLICT". Se lo fa - wrapper lancia mergetool.

Questo può essere migliorata con l'aggiunta di frase più precisa al $SEARCH (come "merge auto non riuscito; risolvere i conflitti e quindi commettere il risultato."), Così come controllando se il primo argomento ($1) è nella lista dei comandi risultanti in un conflitto di unione (pull, merge, ecc.). Altrimenti finirai per analizzare molti dati non necessari se l'output del comando git è troppo lungo.

+0

E 'possibile senza aliasing efficacemente git? –

+0

@QuinnStrahl È possibile denominare script 'git' (senza estensione file) e inserire il percorso prima dell'eseguibile eseguibile git. Ma è praticamente solo un altro modo di fare alias. Quindi no, non conosco un modo per ottenerlo senza fare il git alias. –

+2

Dovrebbe essere un po 'lavorabile, ma l'espressione regolare CONFLICT necessita di miglioramenti. Penso che al momento lo raccoglierà ovunque, anche ad es. uscita diff. Almeno puoi filtrare per posizione di linea (ad esempio un'ancora), e magari espandere il testo. –

5

Non puoi (ancora) fare git a fare questo.


Questa soluzione potrebbe non essere accettabile.

Creare una funzione nella vostra ~/.bashrc:

git() 
{ 
    if [[ $1 == "merge" ]] || [[ $1 == "rebase" ]] || [[ $1 == "pull" ]]; then 
    command git "[email protected]" 
    rc=$? 
    if [[ $rc == 1 ]]; then 
     echo "There are conflicts, better run git-mergetool!!!" 
     # There might be some other condition that returns a '1', 
     # if so you can add another check like this: 
     # if grep Conflicts $(git --git-dir)/MERGE_MSG; 
     command git mergetool 
    fi 
    else 
    command git "[email protected]" 
    fi 
} 

mergetool non viene richiamato quando si fonde:

$ git merge non_conflicting_branch 
Merge made by the 'recursive' strategy. 
bar | 0 
1 file changed, 0 insertions(+), 0 deletions(-) 
create mode 100644 bar 

mergetool viene chiamata quando ci sono conflitti:

$ git merge conflicting_branch 
Auto-merging foo 
CONFLICT (content): Merge conflict in foo 
Automatic merge failed; fix conflicts and then commit the result. 
There are Conflicts, better run git-mergetool!!! 

mergetool non viene chiamato su altri errori:

$ git merge adasds 
fatal: adasds - not something we can merge 
+0

Questo non sta facendo aprire git automaticamente a mergetool, questo sta facendo fare alla shell. –

+0

Perché il downvote? Questo è essenzialmente un modo più pulito per implementare la risposta di Rosipov. – onionjake

+0

Com'è pulito? Ti mancano alcuni tipi di conflitti (come 'git stash pop'). Poiché non filtra per comando, non è un problema. Come ti noti, il codice corrente avvierà 'git mergetool' su qualsiasi errore con 1 stato. –

Problemi correlati