Como posso antever uma fusão no git?
eu tenho um branch git (a linha principal, por exemplo) e eu quero me fundir em outro branch de desenvolvimento. Ou tenho?
para decidir se realmente quero fundir este ramo, gostaria de ver algum tipo de antevisão do que o merge fará. De preferência com a capacidade de ver a lista de commits que estão sendo aplicados.
Até agora, o melhor que consigo arranjar émerge --no-ff --no-commit
, e depois diff HEAD
.
10 answers
Eu descobri que a solução que melhor funciona para mim é apenas realizar a junção e abortar se você não gosta dos resultados. Esta sintaxe em particular parece-me limpa e simples. Se você quiser garantir que você não bagunça seu ramo atual, ou você simplesmente não está pronto para se fundir independentemente da existência de conflitos, basta criar um novo sub-ramo fora dele e fundir isso.
Estratégia 1: a via segura – fundir-se de um ramo temporário:
git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch
Assim podes basta jogar fora o ramo temporário se você só quer ver quais são os conflitos. Você não precisa se preocupar em "abortar" a junção, e você pode voltar ao seu trabalho -- basta checar 'mybranch' novamente e você não terá nenhum código fundido ou conflitos de junção em seu branch.
Isto é basicamente um ensaio a seco.
Estratégia 2: Quando você definitivamente quer se fundir, mas apenas se não houver conflitos
git checkout mybranch
git merge some-other-branch
Se o git comunicar conflitos (e só se houver conflitos) você pode então fazer:
git merge --abort
Se a junção for bem sucedida, não a poderá interromper (apenas reiniciar).
Se não estiver pronto para se fundir, use o mais seguro acima.
[[4]} [editar: 2016-Nov-I trocou a estratégia 1 por 2, porque parece que a maioria das pessoas está procurando "o caminho seguro". A estratégia 2 é agora mais uma nota que você pode simplesmente abortar a junção se a junção tiver conflitos com os quais você não está pronto para lidar. Tenha em mente se ler comentários!]-
git log ..otherbranch
- Lista de alterações que serão reunidas no ramo actual.
-
git diff ...otherbranch
- diferenças de ancestral comum (merge base) para a cabeça do que será fundido. Note os três pontos , que têm um significado especial em comparação com dois pontos (ver abaixo).
-
gitk ...otherbranch
- representação gráfica dos ramos desde que foram fundidos da última vez.
O Texto vazio implica HEAD
, por isso é por que apenas ..otherbranch
em vez de HEAD..otherbranch
.
Os dois vs. três pontos têm um significado ligeiramente diferente para o diff do que para os comandos que listam revisões (log, gitk, etc.). Para log e outros dois pontos (a..b
) significa tudo o que está em b
mas não a
e três pontos (a...b
) significa tudo o que está em apenas um de a
ou b
. Mas diff funciona com duas revisões e lá o caso mais simples representado por dois pontos (a..b
) é a diferença simples de a
para b
e três pontos (a...b
) média diferença entre ancestral comum eb
(git diff $(git merge-base a b)..b
).
git fetch
primeiro para que o seu repo local tenha as atualizações apropriadas para comparar.
$ git fetch origin
$ git diff --name-status origin/master
D TableAudit/Step0_DeleteOldFiles.sh
D TableAudit/Step1_PopulateRawTableList.sh
A manbuild/staff_companies.sql
M update-all-slave-dbs.sh
Ou se quiseres uma diferença da tua cabeça para o comando:
$ git fetch origin
$ git diff origin/master
[[5]}IMO esta solução é muito mais fácil e menos propensa a erros (e, portanto, muito menos arriscada) do que a solução de Topo que propõe "merge e abortar".
Se já obtiveste as alterações, o meu favorito é:
git log ...@{u}
Isso precisa do git 1.7.mas acredito em X. A notação @{u}
é uma "abreviação" para o ramo a montante, por isso é um pouco mais versátil do que git log ...origin/master
.
Nota: Se usar o zsh e o extended glog ligado, provavelmente terá de fazer algo do género:
git log ...@\{u\}
Adicionando às respostas existentes, pode ser criado um nome alternativo para mostrar a diferença e/ou registo antes de uma junção. Muitas respostas omitem o {[[2]} a ser feito primeiro antes de "antever" a junção; este é um pseudónimo que combina estes dois passos em um (emulando algo semelhante ao do mercurial)hg incoming
/ outgoing
)
git log ..otherbranch
", você pode adicionar o seguinte para ~/.gitconfig
:
...
[alias]
# fetch and show what would be merged (use option "-p" to see patch)
incoming = "!git remote update -p; git log ..@{u}"
Para simetria, o seguinte nome falso pode ser usado para mostrar o que é cometido e seria empurrado, antes de empurrar:
# what would be pushed (currently committed)
outgoing = log @{u}..
E então você pode executar "git incoming
"para mostrar um monte de mudanças, ou" git incoming -p
"para mostrar o patch (ou seja, o "diff"), "git incoming --pretty=oneline
", para um resumo, etc. Você pode então (opcionalmente) executar "git pull
" para realmente fundir. (No entanto, uma vez que você já obteve, a junção pode ser feita diretamente.)
Da mesma forma," git outgoing
"mostra o que seria empurrado se você fosse correr"git push
".
git log currentbranch..otherbranch
dar-lhe-á a lista de commits que irão para a ramificação actual se fizer uma junção. Os argumentos usuais para log que dão detalhes sobre os commits lhe darão mais informações.
git diff currentbranch otherbranch
dar-lhe-á a diferença entre os dois commits que se tornará um. Este será um diff que lhe dá tudo o que vai se fundir.
A menos de realmente realizar a fusão de uma forma fora (veja a resposta de Kasapo), não parece haver uma maneira confiável de ver isso.
Dito isto, eis um método que se aproxima marginalmente:git log TARGET_BRANCH...SOURCE_BRANCH --cherry
Isto dá uma indicação justa de quais os commits que o farão entrar na fusão. Para ver os diffs, adicionar -p
. Para ver os nomes dos ficheiros, adicione qualquer --raw
, --stat
, --name-only
, --name-status
.
O problema com a aproximação git diff TARGET_BRANCH...SOURCE_BRANCH
(ver a resposta de Jan Hudec) é, você vai ver diffs para as alterações já na sua ramificação de destino, se a sua ramificação de origem contiver uma junção cruzada.
Pedido de puxar-eu usei a maioria das ideias já apresentadas, mas uma que eu também uso frequentemente é (especialmente se for de outro dev ) fazer um pedido de puxar que dá uma maneira útil de rever todas as mudanças em uma junção antes que ela ocorra. Sei que é o GitHub, não o git, mas dá jeito.
Não quero usar o comando git merge como precursor para rever ficheiros em conflito. Eu não quero fazer uma fusão, eu quero identificar problemas potenciais antes de me fundir - problemas que a auto-fusão pode esconder de mim. A solução que eu tenho procurado é como ter git cuspir uma lista de arquivos que foram alterados em ambos os ramos que serão unidos juntos no futuro, em relação a algum ancestral comum. Uma vez que eu tenho essa lista, Eu posso usar Outras ferramentas de comparação de arquivos para explorar mais as coisas. Procurei várias vezes, e ainda não encontrei o que quero num comando git nativo.
Aqui está a minha solução, caso ajude mais alguém lá fora. Neste cenário, Tenho um ramo chamado QA que tem muitas mudanças nele desde o último lançamento de produção. Nosso último lançamento de produção é marcado com"15.20.1". Eu tenho outro ramo de desenvolvimento chamado new_stuff que eu quero me fundir no ramo QA. Tanto a QA como o new_ stuff apontam para commits that "follow" (as reported by gitk) the 15.20.1 tag.git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files
Aqui estão algumas discussões que mostram por que estou interessado em focar esses arquivos específicos:
Como posso confiar no git merge?
Https://softwareengineering.stackexchange.com/questions/199780/how-far-do-you-trust-automerge