Git resolve o conflito usando --ours / - deles para todos os arquivos

111

Existe uma maneira de resolver o conflito para todos os arquivos usando checkout --ourse --theirs? Eu sei que você pode fazer isso para arquivos individuais, mas não conseguiu encontrar uma maneira de fazer isso para todos.

exe163
fonte
7
Funciona git checkout --ours -- .? Os .meios do diretório atual, quando aplicado a partir da raiz diretório de trabalho, por isso basicamente significa que todo o diretório de trabalho. Não tenho certeza se isso vai funcionar com o --ourssinalizador, e não tenho certeza de como ele vai lidar com conflitos de arquivos excluídos ou renomeados.
@Cupcake eu usei com sucesso. Talvez isso deva ser uma resposta?
Pedro Gimeno

Respostas:

90

Basta navegar pelo diretório de trabalho e enviar a saída por meio do comando xargs:

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

ou

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

Como isso funciona: greppesquisará todos os arquivos no diretório atual (o .) e subdiretórios recursivamente (o -rsinalizador) procurando por marcadores de conflito (a string '<<<<<<<')

o sinalizador -lou --files-with-matchesfaz com que o grep exiba apenas o nome do arquivo onde a string foi encontrada. A digitalização é interrompida após a primeira correspondência, de modo que cada arquivo correspondido é reproduzido apenas uma vez.

Os nomes de arquivo correspondentes são então canalizados para xargs , um utilitário que divide o fluxo de entrada canalizado em argumentos individuais para git checkout --oursou--theirs

Mais neste link .

Já que seria muito inconveniente ter que digitar isso todas as vezes na linha de comando, se você se pegar usando muito, pode não ser uma má ideia criar um alias para o shell de sua escolha: Bash é o usual .

Este método deve funcionar com pelo menos as versões 2.4.x do Git

Dmitri
fonte
14
Em vez de grep, acho que também é possível usar git diff --name-only --diff-filter=U.
Tailandês
10
Também git status | grep both | awk '{print $3}' | xargs git checkout --[theirs|ours]. Mais rápido do que o grep se você tiver um projeto grande.
joshbodily
1
@joshbodily Nice. Não tenho projetos tão grandes que notaria uma diferença, mas posso ver como seria muito mais rápido, especialmente se poucos arquivos foram alterados em comparação com o número total no diretório ---- que deve ser o caso para normal compromete.
Dmitri
1
Observe que isso não funciona para conflitos de renomeação / renomeação, por exemplo,CONFLICT (rename/rename): Rename "a.txt"->"c.txt" in branch "HEAD" rename "a.txt"->"b.txt" in "master"
Borek Bernard
1
Outra opção: git status --porcelain | egrep '^UU' | cut -d ' ' -f 2 |xargs git checkout --[theirs|ours].
Zitrax
52

Você pode -Xoursou -Xtheirscom git mergetambém. Assim:

  1. abortar a mesclagem atual (por exemplo, com git reset --hard HEAD)
  2. mesclar usando a estratégia de sua preferência ( git merge -Xoursou git merge -Xtheirs)

AVISO LEGAL: é claro que você pode escolher apenas uma opção, -Xoursou -Xtheirsuse uma estratégia diferente, você deve ir arquivo por arquivo.

Não sei se existe uma maneira para checkout, mas honestamente não acho que seja terrivelmente útil: selecionar a estratégia com o comando checkout é útil se você quiser soluções diferentes para arquivos diferentes, caso contrário, basta ir para a abordagem de estratégia de fusão.

Obrigado por todos os peixes
fonte
Obrigado, não sabia que eles tinham '--ours' e '--theirs' para mesclar. Parece que, para mesclar, eles não fazem parte da estratégia '-s', mas sim das opções recursivas '-X'. A nossa versão '-s' na verdade apenas substitui todos os arquivos sem mesclar e a deles não existe.
exe163
Não há --theirsou --ours-Option para git v1.9.4. Uma abordagem seria git merge -s recursive -Xtheirs BRANCH.
fbmd
--theirse --oursnão estão disponíveis nem com git 2.2.0. Ou minha resposta não foi precisa ou eles estavam disponíveis em uma versão mais antiga do git (essa resposta é muito antiga na época da TI). A abordagem certa é com -X. Eu atualizo de acordo
ThanksForAllTheFish
A partir da versão 2.4.0 --ours e --theirs ainda estão disponíveis git-scm.com/docs/git-checkout
Dmitri
Tentei isso e recebi "falha na mesclagem automática, consertar conflitos". Este comando claramente não funciona conforme o esperado e recomendo evitá-lo - é muito complicado.
Adam
37

git checkout --[ours/theirs] .fará o que você quiser, desde que você esteja na raiz de todos os conflitos. o nosso / deles afeta apenas os arquivos não mesclados, então você não deve ter que usar o grep / find / etc conflitos especificamente.

Cory Petosky
fonte
5
Para mim, isso não parece recursar em subdiretórios.
Daniel Baughman
5
Eu entendo error: path 'foo/bar/blah' does not have our version.
Robin Green de
Estou usando o git versão 2.16.2.windows.1 e funciona perfeitamente para mim. Obrigado!
Pankwood de
30
git diff --name-only --diff-filter=U | xargs git checkout --theirs

Parece fazer o trabalho. Observe que você precisa ter o cd do diretório raiz do repositório git para fazer isso.

Peter
fonte
3
Acho que esta é uma resposta melhor do que a mais votada porque (1) ela se aplica a todos os arquivos, não apenas ao diretório de trabalho; e (2) não terá nenhuma fragilidade em torno do grepping para marcadores de conflito. O comando 'git diff' lista todos os caminhos não mesclados, que é exatamente o que queremos verificar.
bchurchill
Agradável! Sempre me preocupei com a confiabilidade dos marcadores de conflito grep
00-BBB
2
function gitcheckoutall() {
    git diff --name-only --diff-filter=U | sed 's/^/"/;s/$/"/' | xargs git checkout --$1
}

Eu adicionei esta função no arquivo .zshrc .

Use-os desta forma: gitcheckoutall theirsougitcheckoutall ours

iWheelBuy
fonte