Como resolver os conflitos de junção no Git
Existe uma boa maneira de explicar como resolver conflitos de fusão no Git?
30 answers
git mergetool
Abre uma interface gráfica que te ajuda a ultrapassar cada conflito, e tu escolhes como te fundir. Às vezes requer um pouco de edição manual depois, mas geralmente é suficiente por si só. É muito melhor do que fazer tudo à mão, certamente.
Como @JoshGlover comentário:O comando não abre necessariamente uma interface gráfica a menos que instale uma. A execução de git mergetool
para mim resultou na utilização de vimdiff
. Você pode instalar uma das seguintes ferramentas para usá-lo em vez: meld
, opendiff
, kdiff3
, tkdiff
, xxdiff
, tortoisemerge
, gvimdiff
, diffuse
, ecmerge
, p4merge
, araxis
, vimdiff
, emerge
.
Abaixo está o procedimento de amostragem a usar vimdiff
para resolver conflitos de junção. Baseado em esta ligação
Passo 1 : executar os seguintes comandos no seu terminal
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false
Isto irá definir o vimdiff como a ferramenta de junção predefinida.
Passo 2 : executar o seguinte comando no terminal
git mergetool
Passo 3 : irá ver um ecrã vimdiff no seguinte formato
+----------------------+
| | | |
|LOCAL |BASE |REMOTE |
| | | |
+----------------------+
| MERGED |
| |
+----------------------+
Estas 4 vistas são
LOCAL-este é o ficheiro do ramo actual
Base-ancestral comum, como o ficheiro estava antes de ambas as alterações
Ficheiro remoto estás a fundir-te no teu ramo
Resultado da fusão-fusão, isto é o que é gravado no repo
Você pode navegar entre estas vistas usando ctrl+w
. Você poderá chegar directamente à vista reunida usando ctrl+w
seguido de j
.
Mais informações sobre a navegação vimdiff aqui e aqui
Passo 4 . Você poderá editar a vista reunida da seguinte forma
Se Quiser Obter alterações à distância
:diffg RE
Se Quiser Obter alterações na BASE
:diffg BA
Se Quiser Obter alterações a partir do LOCAL
:diffg LO
Passo 5 . Gravar, sair, enviar e limpar
:wqa
gravar e sair de vi
git commit -m "message"
git clean
Remover ficheiros extra (por exemplo *.orig) criado pela ferramenta diff.
Aqui está um provável caso de Uso, do topo:
Vais fazer algumas mudanças, mas não estás actualizado.git fetch origin
git pull origin master
From ssh://[email protected]:22/projectname
* branch master -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.
Por isso, actualiza-te e tenta de novo, mas tens um conflito.
git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master
From ssh://[email protected]:22/projectname
* branch master -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.
Então você decide dar uma olhada nas mudanças:
git mergetool
Oh, meu Deus, a montante mudou algumas coisas, mas só para usar as minhas mudanças ... não ... as mudanças deles...
git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"
E depois tentamos uma última vez.
git pull origin master
From ssh://[email protected]:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Ta-da!
Dica Um
A melhor coisa que encontrei foi usar o estilo de conflito" diff3":
git config merge.conflictstyle diff3
Isto produz marcadores de conflito como este:
<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a
feature/topic branch.
>>>>>>>
A secção do meio é como era o ancestral comum. Isto é útil. porque você pode compará-lo com as versões de cima e de baixo para obter um melhor senso do que foi mudado em cada branch, o que lhe dá uma idéia melhor para qual era o propósito de cada mudança.
Se o conflito é apenas algumas linhas, isso geralmente torna o conflito muito óbvio. (Saber como resolver um conflito é muito diferente;você precisa estar ciente do que as outras pessoas estão trabalhando. Se estás confuso, é melhor chamar essa pessoa para o teu quarto para que ela possa ver o que tu és. a olhar.)
Se o conflito for mais longo, então eu vou cortar e colar cada uma das três seções em três arquivos separados, tais como "meu", "comum" e "deles".
Então posso executar os seguintes comandos para ver os dois blocos de diferenças que causaram o conflito:
diff common mine
diff common theirs
Isto não é o mesmo que usar uma ferramenta de junção, uma vez que uma ferramenta de junção irá incluir todos os blocos de diferenças não-conflitantes também. Acho que isso distrai.
Dica Dois
Alguém já mencionou isso, mas compreender a intenção por trás de cada pedaço de diff é geralmente muito útil para entender de onde um conflito veio e como lidar com ele.git log --merge -p <name of file>
Isto mostra todos os commits que tocaram no ficheiro entre o ancestral comum e as duas cabeças que estão a fundir. (Para que não inclua commits que já existem em ambos os ramos antes da fusão.) Isto ajuda-o a ignorar os tipos de diferenças que claramente não são um factor no seu conflito actual.
Dica Três
Verifique as suas alterações com ferramentas automáticas.
Se tiverem testes automáticos, façam-nos. Se tem um fio dental, verifique isso. Se for um projeto buildable, então construa-o antes de você commit, etc. Em todos os casos, você precisa fazer um pouco de teste para se certificar de que suas alterações não quebraram nada. (Heck, even a merge without conflicts can break working code.)Dica Quatro
Planeie com antecedência; comunique com os colegas de trabalho.
Planear com antecedência e estar ciente de o que outros estão trabalhando pode ajudar a prevenir conflitos de junção e / ou ajudar a resolvê-los mais cedo -- enquanto os detalhes ainda estão frescos em mente.
Por exemplo, se você sabe que você e outra pessoa estão ambos trabalhando em diferentes refactoring que afetará ambos o mesmo conjunto de arquivos, você deve falar uns com os outros antes do tempo e obter um melhor senso para que tipos de mudanças cada um de vocês está fazendo. Você pode economizar tempo e esforço considerável se você conduzir as suas mudanças planejadas em série em vez de em paralelo.
Para os principais refactores que atravessam uma grande faixa de código, você deve considerar seriamente trabalhar em série: Todo mundo pára de trabalhar nessa área do Código, enquanto uma pessoa executa o Refactor completo.
Se você não pode trabalhar em série (devido à pressão de tempo, talvez), em seguida, a comunicação sobre os conflitos de fusão esperados, pelo menos ajuda você a resolver os problemas mais cedo, enquanto os detalhes ainda estão frescos em mente. Por exemplo, se um co-trabalhador série disruptiva de commits ao longo de um período de uma semana, você pode optar por mesclar/refazer nesse ramo de colegas de trabalho uma ou duas vezes por dia durante essa semana. Dessa forma, se você encontrar conflitos merge/rebase, você pode resolvê-los mais rapidamente do que se você esperar algumas semanas para juntar tudo em um grande bloco.
Dica Cinco
Se não tem a certeza de uma fusão, não a force. A fusão pode parecer esmagadora, especialmente quando há muitos ficheiros conflituosos e os marcadores de conflito cobrem centenas de linhas. Muitas vezes, quando estimamos projetos de software, não incluímos tempo suficiente para itens gerais, como lidar com uma junção gnarly, por isso parece um verdadeiro arrasto para passar várias horas dissecando cada conflito. A longo prazo, planear com antecedência e estar ciente do que os outros estão a trabalhar são as melhores ferramentas para antecipar conflitos de fusão e preparar-se para resolvê-los correctamente em menos tempo.Identifique quais arquivos estão em conflito (Git deve lhe dizer isso).
Abra cada arquivo e examine os diffs; Git os demarca. Esperemos que seja óbvio qual a versão de cada bloco a manter. Você pode precisar discuti-lo com outros desenvolvedores que cometeram o código.
Uma vez que você tenha resolvido o conflito em um arquivo {[[0]}.
Depois de resolver todos os conflitos, Faça
git rebase --continue
ou qualquer outro comando Git disse para fazer quando completaste.
Confira as respostas no Estouro de Pilha pergunta Abortar uma impressão em série no Git, especialmente Charles Bailey resposta, que mostra como ver as diferentes versões do ficheiro com problemas, por exemplo,
# Common base version of the file.
git show :1:some_file.cpp
# 'Ours' version of the file.
git show :2:some_file.cpp
# 'Theirs' version of the file.
git show :3:some_file.cpp
Os conflitos de junção ocorrem quando são feitas alterações num ficheiro ao mesmo tempo. Aqui está como resolvê-lo.
git
CLI
Aqui estão passos simples o que fazer quando você entrar em estado de conflito:
- repare na lista de ficheiros em conflito com:
git status
(na secçãoUnmerged paths
). -
Resolva os conflitos separadamente para cada ficheiro por uma das seguintes abordagens:
Use a interface gráfica para resolver os conflitos:
git mergetool
(a mais fácil forma).Para aceitar a versão remota / outra, use:
git checkout --theirs path/file
. Isto irá rejeitar quaisquer alterações locais que tenha feito para esse ficheiro.-
Para aceitar a versão local / nossa, use:
git checkout --ours path/file
No entanto, você tem que ter cuidado, como mudanças remotas que conflitos foram feitos por alguma razão.
Relacionado: Qual é o significado preciso de" nosso "e" deles " em git?
Editar os ficheiros em conflito manualmente e procurar o bloco de código entre
<<<<<
/>>>>>
em seguida, escolha a versão de cima ou de baixo=====
. Veja: Como os conflitos são apresentados .Os conflitos de localização e nomes de ficheiros podem ser resolvidos por
git add
/git rm
.
-
Finalmente, reveja os ficheiros prontos para enviar usando:
git status
.Se ainda tiver algum ficheiro em
Unmerged paths
, e tiver resolvido o conflito manualmente, então diga ao Git que o resolveu por:git add path/file
. Se todos os conflitos fossem resolvido com sucesso, commit the changes by:
git commit -a
and push to remote as usual.
Ver também: resolver um conflito de junção a partir da linha de comando no GitHub
DiffMerge
Usei com sucesso O DiffMerge que pode comparar e juntar visualmente ficheiros no Windows, macOS e Linux/Unix.
Ele graficamente pode mostrar as mudanças entre 3 arquivos e permite a fusão automática (Quando seguro para fazê-lo) e controle total sobre a edição do ficheiro resultante.
Fonte Da Imagem: DiffMerge (imagem do Linux)
Faça o download e execute em repo como:
git mergetool -t diffmerge .
MacOS
Em macOS pode instalar através de:
brew install caskroom/cask/brew-cask
brew cask install diffmerge
E provavelmente (se não for fornecido) você precisa do seguinte Invólucro extra simples colocado no seu caminho (ex. /usr/bin
):
#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"
Depois pode usar o seguinte teclado atalhos:
- ⌘-Alt-subir/descer para saltar para as alterações anteriores/seguintes.
- ⌘-Alt-esquerda/direita para aceitar a alteração da esquerda ou da direita
Em alternativa, poderá usar o opendiff (parte das ferramentas do Xcode), que lhe permite juntar dois ficheiros ou pastas para criar um terceiro ficheiro ou pasta.
Se você está fazendo pequenos commits frequentes, então comece por olhar para os comentários de commit com {[[0]}. Então git diff
mostrar-lhe-á os conflitos.
git config merge.tool "your.tool"
irá definir a sua ferramenta escolhida e depois git mergetool
Depois de uma junção falhada irá mostrar-lhe o diffs no contexto.
Cada vez que editar um ficheiro para resolver um conflito, git add filename
irá actualizar o índice e o seu 'diff' deixará de o mostrar. Quando todos os conflitos forem tratados e os seus ficheiros tiverem sido git add
- ed, git commit
irá completar a sua junção.
Ver como os conflitos são apresentados ou, no Git, a documentação git merge
para compreender quais são os marcadores de conflito da junção.
Também, a Secção Como Resolver Conflitos explica como resolver os conflitos:
Depois de ver um conflito, pode-se fazer duas coisas:
Decide não fundir. As únicas limpezas de que precisa são de repor o ficheiro de índice no Compromisso
HEAD
para reverter o 2. e para limpar as mudanças de árvore de trabalho feito por 2. e 3.;git merge --abort
pode ser usado para isto.Resolver os conflitos. O Git marcará os conflitos na árvore de trabalho. Edite os ficheiros em forma e
git add
para o índice. Usegit commit
para fechar o negócio.Você pode trabalhar através do conflito com uma série de ferramentas:
Use um mergetool.
git mergetool
para lançar uma ferramenta de junção gráfica que irá funcionar com a junção.Olha para os diffs.
git diff
vai mostrar uma diferença de três vias, destacando as alterações das versõesHEAD
eMERGE_HEAD
.Olha para os diffs de cada ramo.
git log --merge -p <path>
irá mostrar os diffs primeiro para a versãoHEAD
e depois para a versãoMERGE_HEAD
.Olha para os originais.
git show :1:filename
mostra o ancestral comum,git show :2:filename
mostra a versãoHEAD
, egit show :3:filename
mostra a versãoMERGE_HEAD
.
Você também pode ler sobre marcadores de conflitos de fusão e como resolvê-los no Pro Git secção do livro conflitos básicos de junção .
Para os utilizadores Emacs que querem resolver conflitos de junção semi-manualmente:
git diff --name-status --diff-filter=U
Mostra todos os ficheiros que necessitam de resolução de conflitos.
Abra cada um desses arquivos um por um, ou todos de uma vez por:
emacs $(git diff --name-only --diff-filter=U)
Ao visitar um buffer que necessita de edições em Emacs, Tipo
ALT+x vc-resolve-conflicts
Isto vai abrir três buffers (o meu, o deles e o buffer de saída). Navegar carregando em ' n '(próxima região), 'p' (região de prevision). Carregue em " a " E " b " para copiar o meu ou a sua região para o buffer de saída, respectivamente. E / ou editar o buffer de saída directamente.
Quando terminar: carregue em 'q'. O Emacs pergunta-lhe se deseja gravar este buffer: sim. Depois de terminar um buffer, marque-o como resolvido correndo do teriminal:
git add FILENAME
Quando terminar com todos os tampões de choque
git commit
Para terminar a fusão.
Por Favor, siga os seguintes passos para corrigir os conflitos de junção no Git:
Verificar o estado do Git: estado do git
Pega no espartilho.: git fetch (obter o 'patch' direito do seu commit Git)
Obter um ramo local (temp1 no meu exemplo aqui): caixa git-B temp1
Retire o conteúdo recente do master: git pull -- rebase origin mestre.
Inicie o mergetool e verifique os conflitos e corrija-os...e verifique as alterações no ramo remoto com o seu ramo actual: git mergetool
Verifique novamente o estado: estado do git
Apaga os ficheiros indesejados criados localmente pelo mergetool, normalmente o mergetool cria um ficheiro extra com *.extensão orig. Por favor, apague esse arquivo como este é apenas o duplicado e corrigir as alterações localmente e adicione a versão correta de seus arquivos. git add #your_changed_correct_files
Verifique novamente o estado: estado do git
Persistir as alterações no mesmo ID de persistência (isto evita um novo conjunto de alterações separado): git commit --amend
Empurre para o ramo mestre: git push (para o seu repositório Git)
Simplesmente, se você sabe bem que mudanças em um dos repositórios não é importante, e quer resolver todas as mudanças em favor do outro, use:
git checkout . --ours
Para resolver as alterações a favor de o seu repositório, ou
git checkout . --theirs
Para resolver as alterações a favor do outro ou do repositório principal .
Ou então terá de usar uma ferramenta de junção GUI para passar pelos Ficheiros um a um, digamos que a ferramenta de junção é p4merge
, ou escrever o nome de qualquer um que já tenha instalado
git mergetool -t p4merge
E depois de terminar um arquivo, você terá que salvar e fechar, de modo que o próximo irá abrir.
Quero a minha versão completa ou a sua versão completa, ou quero rever as alterações individuais e decidir por cada uma delas.
Aceitar totalmente a minha versão ou a deles:
Aceita a minha versão (local, nossa):
git checkout --ours -- <filename>
git add <filename> # Marks conflict as resolved
git commit -m "merged bla bla" # An "empty" commit
Aceita a versão deles (remota, deles):
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
Se quiser fazer para todos os ficheiros de conflitos, execute:
git merge --strategy-option ours
Ou
git merge --strategy-option theirs
Rever todas as alterações e aceitá-las individualmente
git mergetool
- revê as alterações e aceita qualquer versão para cada uma delas.
git add <filename>
git commit -m "merged bla bla"
Por omissão mergetool
funciona na linha de comandos . Como usar uma linha de comando mergetool deve ser uma questão separada.
Também pode instalar ferramenta visual para isto, por exemplo meld
e executar
git mergetool -t meld
Irá abrir a versão local (NOSSA), a versão "base" ou a versão "fundida" (o resultado actual da junção) e versão remota (deles). Grava a versão reunida quando terminar, execute git mergetool -t meld
de novo até obter "sem ficheiros que necessitem de junção", depois vá para os passos 3. e 4.
Você poderia corrigir os conflitos de junção de uma série de maneiras como outras foram detalhadas.
Acho que a verdadeira chave é saber como as mudanças fluem com repositórios locais e remotos. A chave para isso é entender os ramos de rastreamento. Eu descobri que eu penso no ramo de rastreamento como a "peça em falta no meio" entre mim o meu diretório local, Arquivos reais e o remoto definido como origem. Eu pessoalmente tenho o hábito de duas coisas para ajudar a evitar isto.Em vez disso de:
git add .
git commit -m"some msg"
Que tem duas desvantagens.
A) todos os ficheiros novos/alterados são adicionados e isso pode incluir algumas alterações indesejadas.
b) Você não pode rever a lista de arquivos primeiro.
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
Desta forma, você é mais deliberado sobre quais arquivos são adicionados e você também pode rever a lista e pensar um pouco mais ao usar o editor para a mensagem. Acho que também melhora as minhas mensagens de commit quando uso um editor de ecrã completo em vez do -m
Opcao.
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]
Também (e mais relevante para a sua situação), tento evitar:
git pull
Ou
git pull origin master.
Porque o pull implica uma junção e se tiver alterações localmente que não queria que fossem fundidas, poderá facilmente acabar com os conflitos de código e/ou junção para códigos que não deveriam ter sido fundidos.
Em vez disso, tento fazer ...git checkout master
git fetch
git rebase --hard origin/master # or whatever branch I want.
Você também pode achar isso útil:
Git branch, fork, fetch, merge, rebase e clone, quais são as diferenças?
Bónus:
Falando de puxar / buscar / mesclar nas respostas acima, gostaria de compartilhar um truque interessante e produtivo,git pull --rebase
Este comando acima é o comando mais útil na minha vida git que salvou muito tempo.
Antes de carregar a sua alteração recém-comprometida no servidor remoto, tente git pull --rebase
em vez de git pull
e manual merge
e irá sincronizar automaticamente as últimas alterações do servidor remoto (com uma junção fetch +) e irá colocar o seu local o mais recente envio no topo do git log. Não há necessidade de se preocupar com o puxão/junção manual.
Em caso de conflito, basta usar
git mergetool
git add conflict_file
git rebase --continue
Encontra os detalhes em: http://gitolite.com/git-pull--rebase
(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too
<<<<<<<<<<<
(Code not in conflict here)
Escolha uma das alternativas ou uma combinação de ambas de uma forma que você queira que o novo código seja, enquanto remove sinais iguais e colchetes de ângulo.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Não parece funcionar sempre para mim e normalmente acaba por mostrar cada commit que era diferente entre os dois ramos, isto acontece mesmo quando se usa --
para separar o caminho do comando.
O Que eu faço para resolver este problema é abrir duas linhas de comando e de uma vez
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
E no outro
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
Substituindo $MERGED_IN_BRANCH
com o ramo em que me fundi e [path]
com o ficheiro que está em conflito. Este comando irá registar todos os commits, em formulário de patch, entre ([6]} dois commits. Se deixar um lado vazio, como nos comandos acima do git, irá usar automaticamente HEAD
(a ramificação em que se irá juntar neste caso).
Isto permitirá que você veja o que commits entrou no arquivo nos dois ramos depois que eles divergiram. Normalmente torna muito mais fácil resolver conflitos.
A partir de 12 de dezembro de 2016, pode fundir sucursais e resolver conflitos em github.com
Assim, se você não quiser usar a linha de comando ou quaisquer ferramentas de terceiros que são oferecidos aqui a partir de respostas mais antigas, vá com a ferramenta nativa do GitHub.
Este post do blog explica em detalhe, mas o básico é que, ao 'fundir' dois ramos através da UI, irá agora ver uma opção de 'resolver conflitos' que o levará a um editor que lhe permite lidar com estes conflitos de fusão.
Existem 3 passos:
-
Descubra quais os ficheiros que causam conflitos pelo comando
git status
-
Verifique os ficheiros, nos quais irá encontrar os conflitos marcados como
<<<<<<<<head blablabla
-
Muda - o para o modo que quiseres, e depois Comanda com os comandos
git add solved_conflicts_files git commit -m 'merge msg'
Usando patience
Surpreende-me que mais ninguém tenha falado em resolver conflitos usando a estratégia recursiva da fusão. Para um grande conflito de fusão, o uso de patience
forneceu bons resultados para mim. A idéia é que ele vai tentar combinar blocos em vez de linhas individuais.
Se mudar a indentação do seu programa, por exemplo, a estratégia de junção do Git por omissão corresponde às vezes a um único aparelho {
que pertence a diferentes funções. Isto é evitado com patience
:
git merge -s recursive -X patience other-branch
Da documentação:
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
Comparação com o ancestral comum
Se você tem um conflito de fusão e quer ver o que os outros tinham em mente ao modificar o seu ramo, às vezes é mais fácil comparar o seu ramo diretamente com o ancestral comum (em vez do nosso ramo). Para isso você pode usar merge-base
:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
Normalmente, você só quer ver as alterações para um determinado ficheiro:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
- mestre de checkout git (venha ao ramo principal)
- git pull (actualize o seu mestre para obter o último código)
- git checkout - b mybranch (Checkout a new a branch and start working on that branch so that your master always remains top of trunk.)
- git add . E git commit e git push (no seu ramo local após as suas alterações)
- git checkout master (volte para o seu mestre.)
Se quiser juntar-se do ramo (teste) ao mestre, pode seguir estes passos:
Passo 1: Ir para o ramo
git checkout test
Passo 2: git pull --rebase origin master
Passo 3: Se houver alguns conflitos, vá a esses arquivos para modificá-lo.
Passo 4: Adicionar estas alterações
git add #your_changes_files
Passo 5: git rebase --continue
git push origin +test
Passo 7: e não há conflito entre o teste e o mestre. Você pode usar a junção diretamente.
Conflitos de junção podem ocorrer em diferentes situações:
- ao executar "git fetch" e depois "git merge"
- ao executar "git fetch" e depois "git rebase"
- ao executar " git pull "(que é realmente igual a uma das condições acima mencionadas) {[[8]}
- ao executar "git stash pop"
- quando está a aplicar patches git (commits que são exportados para ficheiros a transferir, por exemplo, por e-mail)
Tem de instalar uma ferramenta de junção que é compatível com o Git para resolver os conflitos. Eu uso o KDiff3 pessoalmente, e achei-o agradável e útil. Pode obter a sua versão para o Windows aqui:
Https://sourceforge.net/projects/kdiff3/files/
BTW se instalar extensões Git, existe uma opção no seu assistente de configuração para instalar o Kdiff3.
Então configure git configus para usar o Kdiff como o seu mergetool:
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false
$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false
(Lembre-se de substituir a localização pela localização actual do Kdiff exe arquivo.)
Então cada vez que se depara com um conflito de fusão só precisa de executar este comando:
$git mergetool
Então abre o Kdiff3, e primeiro tenta resolver os conflitos de junção automaticamente. A maioria dos conflitos seriam resolvidos espontaneamente e você precisa corrigir o resto manualmente.
Aqui está o aspecto do Kdiff3:Depois de terminar, salve o arquivo e ele vai para o próximo arquivo com conflito e você faz a mesma coisa novamente até que todos os conflitos sejam resolvidos.
Para verificar se tudo está reunido com sucesso, basta executar o comando mergetool de novo, você deverá obter este resultado:
$git mergetool
No files need merging
Esta resposta é adicionar uma alternativa para aqueles usuários VIM como eu que prefere fazer tudo dentro do editor.
TL; DR
O Tpope inventou um grande plugin para a VIM chamadofugitivo . Logo que esteja instalado, poderá executar :Gstatus
para verificar os ficheiros que têm conflito e :Gdiff
para abrir o Git de uma junção de 3 formas.
Uma vez nos 3 caminhos se fundem, fugitivo vai deixar você obter as mudanças de qualquer um dos ramos que você estão a fundir-se da seguinte forma:
-
:diffget //2
, obter as alterações do ramo original (HEAD ): -
:diffget //3
, Obter alterações do ramo de fusão:
Depois de terminar a junção do ficheiro, escreva :Gwrite
no buffer resultante da fusão.
Vimcasts lançou um grande vídeoexplicando em detalhes estes passos.
Git fetch
git checkout o seu ramo
git rebase master
Neste passo você vai tentar corrigir o conflito usando o seu IDE de preferência
Você pode seguir este link para verificar ho resolver o conflito no file
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
Agora tudo está bem e vais encontrar o teu commit em gerrit.Git add
git rebase -- continue
git commit --amend
git origem do push Cabeça: refs / rascunhos / mestre (empurrar como um rascunho)
Espero que isto ajude a todos nesta questão.
Pode ajudá-lo muito bem, mostrando quais são as alterações feitas ao original e se você aceitar {[[0]} ou
current change
(significa original antes da fusão)'?.
PS: só funcionará se tiver configurado o git com com o seu código e o código Visual do estúdio.
Para aqueles que estão a usar o Visual Studio (2015 no meu caso)
Fechar o seu projecto em VS. especialmente em grandes projectos VS tende a passar-se ao fundir-se com a UI.
-
Faça a junção na linha de comandos.
Git checkout target_ Branch
Git merge source_ Branch
Em seguida, abrir o projeto em VS e ir para equipe Explorer - > Branch. Agora há uma mensagem que diz que a junção está pendente e os arquivos em conflito estão listados abaixo mensagem.
Carregue no ficheiro em conflito e terá a opção de fundir, comparar, tomar o código, tomar o alvo. A ferramenta de junção em VS é muito fácil de usar.
Se estiver a utilizar intelij como IDE Tente juntar o pai à sua ramificação por
git checkout <localbranch>
git merge origin/<remotebranch>
Mostrará todos os conflitos como este
Agora note que o ficheiro TestClass.java é mostrado a vermelho em intelliJ Também o estado do git irá mostrarA_MBPro:teste a origem da junção anu$ git/ junção automática src / test / java/com/.../ TestClass.conflito java (conteúdo): juntar o conflito em src / test / java/com/.../ TestClass.java
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
Abra o arquivo em intelij, ele terá secções com
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
Onde a cabeça é mudanças no seu ramo local e origem / é mudanças do ramo remoto. Fique com as coisas que precisa e remova as coisas que não precisa.Depois disso, os passos normais devem servir. Isso é
git add TestClass.java
git commit -m "commit message"
git push
O processo para corrigir o conflito da junção:
Primeiro, puxe a última da ramificação de destino à qual deseja juntar
git pull origin develop
À medida que você obtém as últimas do Destino, agora resolva o conflito manualmente no IDE, apagando esses caracteres extras.
Faça um
git add
para adicionar estes ficheiros editados à fila git para que possa sercommit
epush
no mesmo ramo em que está a trabalhar no.Como
git add
está feito, faça umgit commit
para enviar as alterações.Agora empurre as mudanças para o seu ramo de trabalho por
git push origin HEAD
Uma maneira mais segura de resolver conflitos é usar git-mediate (as soluções comuns sugeridas aqui são bastante propensas a erros imho).
Ver este post para uma introdução rápida sobre como usá-lo.
git checkout branch1
git fetch origin
git rebase -p origin/mainbranch
Se houver conflitos de fusão, corrige-os. Em seguida, continuar o processo de ajuste de base, executando: git rebase –-continue
Depois da correcção, poderá persistir e empurrar o seu ramo local para um ramo remoto
git push origin branch1