Eu não quero uma ferramenta de mesclagem visual e também não quero ter que vi o arquivo em conflito e escolher manualmente entre HEAD (meu) e a alteração importada (deles). Na maioria das vezes, eu quero todas as alterações deles ou todas as minhas. Geralmente, isso ocorre porque minha alteração o elevou e está voltando para mim através de um puxão, mas pode ser ligeiramente modificada em vários lugares.
Existe uma ferramenta de linha de comando que se livre dos marcadores de conflito e escolha de uma maneira ou de outra com base na minha escolha? Ou um conjunto de comandos git que eu também posso fazer para cada um.
# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"
Fazer isso é bastante irritante. Para 'aceitar o meu', tentei:
randy@sabotage ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.
randy@sabotage ~/linus $ git checkout Makefile
error: path 'Makefile' is unmerged
andy@sabotage ~/linus $ git reset --hard HEAD Makefile
fatal: Cannot do hard reset with paths.
Como devo me livrar desses marcadores de mudança?
Eu posso fazer:
git reset HEAD Makefile; rm Makefile; git checkout Makefile
Mas isso parece bastante complexo, deve haver uma maneira melhor. E, neste momento, não tenho certeza se o git acha que a fusão aconteceu, então não acho que isso funcione necessariamente.
Indo para o outro lado, fazer 'aceitar os deles' é igualmente confuso. A única maneira de descobrir isso é:
git show test-branch:Makefile > Makefile; git add Makefile;
Isso também me dá uma mensagem de confirmação confusa, que contém Conflicts: Makefile duas vezes.
Alguém pode apontar como executar as duas ações acima de uma maneira mais simples? obrigado
Respostas:
A solução é muito simples.
git checkout <filename>
tenta fazer check-out do arquivo do índice e, portanto, falha na mesclagem.O que você precisa fazer é (por exemplo, finalizar uma confirmação ):
Para fazer o checkout de sua própria versão, você pode usar um dos seguintes:
ou
ou
Para fazer o checkout da outra versão, você pode usar um dos seguintes:
ou
ou
Você também precisará executar 'add' para marcá-lo como resolvido:
fonte
--ours
e--theirs
significa exatamente o oposto do que eu intuitivamente pensou quando experimentar este comando ...git show
- isso ignora a normalização da nova linha.--
é usado pelo Git para separar revisões (nomes de filiais etc.) dos nomes de caminhos (nomes de arquivos, diretórios). É importante se o Git não puder decidir se um nome é o nome da ramificação ou o nome do arquivo. Isso segue a convenção POSIX (ou GNU) de usar traço duplo para separar opções de argumentos (nomes de arquivos).theirs
/ours
pode aparecer trocado se você estiver resolvendo conflitos no contexto de uma operação de rebase. Como o rebase funciona verificando o ramo de destino, a seleção de cerejas confirmada do "seu" ramo para o destino, a alteração recebida ("deles") é do ramo "seu" e o ramo atual é o ramo de destino ("nosso" )Tente o seguinte:
Para aceitar as alterações deles:
git merge --strategy-option theirs
Para aceitar o seu:
git merge --strategy-option ours
fonte
Com base na resposta de Jakub, você pode configurar os seguintes aliases de git por conveniência:
Opcionalmente, eles usam um ou vários caminhos de arquivos para resolver e o padrão para resolver tudo no diretório atual, se nenhum for fornecido.
Adicione-os à
[alias]
seção do seu~/.gitconfig
ou executefonte
[alias]
seção no seu~.gitconfig
ou usegit config --global accept-ours "..."
. Editei minha resposta.~/.gitconfig
.!f() { git checkout --ours -- "${@:-.}" git add -u "${@:-.}; }; f
Com base na resposta de kynan, aqui estão os mesmos aliases, modificados para que possam lidar com espaços e traços iniciais nos nomes de arquivos:
fonte
A situação ideal para a resolução de conflitos é quando você sabe antecipadamente como deseja resolvê-los e pode passar as opções da estratégia de mesclagem recursiva
-Xours
ou-Xtheirs
. Fora disso, posso ver três cenários:Para resolver esses três cenários, você pode adicionar as seguintes linhas ao seu
.gitconfig
arquivo (ou equivalente):A
get(ours|theirs)
ferramenta apenas mantém a respectiva versão do arquivo e joga fora todas as alterações da outra versão (para que não haja mesclagem).A
merge(ours|theirs)
ferramenta refaz a fusão de três maneiras das versões local, base e remota do arquivo, optando por resolver conflitos na direção especificada. Isso tem algumas ressalvas, especificamente: ignora as opções diff que foram passadas para o comando mesclar (como manipulação de algoritmo e espaço em branco); faz a mesclagem limpa dos arquivos originais (para que sejam descartadas quaisquer alterações manuais no arquivo, o que pode ser bom ou ruim); e tem a vantagem de que não pode ser confundido por marcadores diff que deveriam estar no arquivo.A
keep(ours|theirs)
ferramenta simplesmente edita os marcadores diff e as seções fechadas, detectando-os por expressão regular. Isso tem a vantagem de preservar as opções diff do comando mesclar e permitir que você resolva alguns conflitos manualmente e depois resolva automaticamente o restante. Tem a desvantagem de que, se houver outros marcadores de conflito no arquivo, ele poderá ficar confuso.Todos são usados executando
git mergetool -t (get|merge|keep)(ours|theirs) [<filename>]
onde, se<filename>
não for fornecido, processa todos os arquivos em conflito.De um modo geral, supondo que você saiba que não há marcadores diff para confundir a expressão regular, as
keep*
variantes do comando são as mais poderosas. Se você deixar amergetool.keepBackup
opção desabilitada ou verdadeira, após a mesclagem, poderá diferenciar o*.orig
arquivo do resultado da mesclagem para verificar se faz sentido. Como exemplo, executei o seguinte apósmergetool
apenas para inspecionar as alterações antes de confirmar:Nota : Se
merge.conflictstyle
não fordiff3
, o/^|||||||/
padrão nased
regra precisará ser/^=======/
.fonte