Git risolve i conflitti usando --ours / - theirs per tutti i file


112

C'è un modo per risolvere il conflitto per tutti i file utilizzando checkout --ourse --theirs? So che puoi farlo per singoli file ma non riesci a trovare un modo per farlo per tutti.


7
Funziona git checkout --ours -- .? I .mezzi directory corrente, quando applicata dalla radice directory di lavoro, quindi significa sostanzialmente sull'intera directory di lavoro. Non sono sicuro se questo funzionerà con il --oursflag, e non sono sicuro di come gestirà i conflitti di file cancellati o rinominati.

@ Cupcake l'ho usato con successo. Forse dovrebbe essere una risposta?
Pedro Gimeno

Risposte:


90

Basta grep attraverso la directory di lavoro e inviare l'output tramite il comando xargs:

grep -lr '<<<<<<<' . | xargs git checkout --ours

o

grep -lr '<<<<<<<' . | xargs git checkout --theirs

Come funziona: grepcercherà in ogni file nella directory corrente (la .) e nelle sottodirectory in modo ricorsivo (il -rflag) cercando i marcatori di conflitto (la stringa '<<<<<<<')

il flag -lo --files-with-matchesfa sì che grep restituisca solo il nome del file in cui è stata trovata la stringa. La scansione si interrompe dopo la prima corrispondenza, quindi ogni file corrispondente viene emesso una sola volta.

I nomi dei file corrispondenti vengono quindi reindirizzati a xargs , un'utilità che suddivide il flusso di input reindirizzato in singoli argomenti per git checkout --ourso--theirs

Maggiori informazioni a questo link .

Dato che sarebbe molto scomodo doverlo digitare ogni volta dalla riga di comando, se ti ritrovi a usarlo molto, potrebbe non essere una cattiva idea creare un alias per la tua shell preferita: Bash è il solito .

Questo metodo dovrebbe funzionare almeno con le versioni di Git 2.4.x


14
Invece di grepping, penso che sia anche possibile usare git diff --name-only --diff-filter=U.
Thai

10
Inoltre git status | grep both | awk '{print $3}' | xargs git checkout --[theirs|ours]. Più veloce del grepping se hai un grande progetto.
joshbodily

1
@joshbodily Nice. Non ho progetti così grandi che noterei una differenza, ma posso vedere come sarebbe molto più veloce soprattutto se pochi file sono cambiati rispetto al numero totale nella directory ---- che dovrebbe essere il caso normale impegna.
Dmitri

1
Nota che questo non funziona per rinominare / rinominare i conflitti, ad esempio,CONFLICT (rename/rename): Rename "a.txt"->"c.txt" in branch "HEAD" rename "a.txt"->"b.txt" in "master"
Borek Bernard,

1
Ancora un'altra opzione: git status --porcelain | egrep '^UU' | cut -d ' ' -f 2 |xargs git checkout --[theirs|ours].
Zitrax

52

Puoi -Xourso anche -Xtheirscon git merge. Così:

  1. interrompi la fusione corrente (ad esempio con git reset --hard HEAD)
  2. unisci usando la strategia che preferisci ( git merge -Xourso git merge -Xtheirs)

DISCLAIMER: ovviamente puoi scegliere solo un'opzione, -Xoursoppure -Xtheirs, se usi una strategia diversa dovresti ovviamente andare file per file.

Non so se ci sia un modo checkout, ma onestamente non penso che sia terribilmente utile: selezionare la strategia con il comando checkout è utile se vuoi soluzioni diverse per file diversi, altrimenti scegli l'approccio della strategia di unione.


Grazie, non sapevo di avere "--ours" e "--theirs" per l'unione. Sembra che per l'unione non facciano effettivamente parte della strategia "-s" ma parte delle opzioni ricorsive "-X". La nostra versione "-s" sostituisce in realtà tutti i file senza unirli e la loro non esiste.
exe163

Non c'è l' opzione --theirso --ours-Opzione per git v1.9.4. Sarebbe un approccio git merge -s recursive -Xtheirs BRANCH.
fbmd

--theirse --oursnon sono disponibili nemmeno con git 2.2.0. O la mia risposta non era precisa o erano disponibili nella versione git precedente (questa risposta è piuttosto vecchia in epoca IT). L'approccio giusto è con -X. Mi
aggiorno di

A partire dalla versione 2.4.0, i nostri e i loro sono ancora molto disponibili git-scm.com/docs/git-checkout
Dmitri

Provato questo, e ottenuto "unione automatica fallita, risolvere i conflitti". Questo comando chiaramente non funziona come previsto e consiglio di evitarlo: troppo bacato.
Adam

37

git checkout --[ours/theirs] .farà quello che vuoi, fintanto che sei alla radice di tutti i conflitti. ours / theirs influisce solo sui file non uniti, quindi non dovresti dover grep / find / etc specificatamente.


5
Per me questo non sembra ricorrere alle sottodirectory.
Daniel Baughman

5
Capisco error: path 'foo/bar/blah' does not have our version.
Robin Green

Sto usando git versione 2.16.2.windows.1 e funziona perfettamente per me. Grazie!
Pankwood

30
git diff --name-only --diff-filter=U | xargs git checkout --theirs

Sembra fare il lavoro. Nota che devi essere trasferito nella directory principale del repository git per ottenere ciò.


3
Penso che questa sia una risposta migliore di quella più votata perché (1) si applica a tutti i file, non solo alla directory di lavoro; e (2) non avrà alcuna fragilità attorno all'ingordigia di segnalini di conflitto. Il comando "git diff" qui elenca tutti i percorsi non uniti, che è esattamente ciò che vogliamo controllare.
bchurchill

Bello! Sono sempre stato preoccupato per l'affidabilità dei marker di conflitto grep
00-BBB il


2
function gitcheckoutall() {
    git diff --name-only --diff-filter=U | sed 's/^/"/;s/$/"/' | xargs git checkout --$1
}

Ho aggiunto questa funzione nel file .zshrc .

Usali in questo modo: gitcheckoutall theirsogitcheckoutall ours

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.