Como ver quais confirmações em um ramo não estão no outro?

180

Eu tenho dois ramos devele next. No desenvolvimento, tenho uma quantidade mais ou menos enorme de confirmações. Alguns dos commits são escolhidos a dedo next. Também adicionei alguns commits para os próximos, que são mesclados devel.

Agora eu gostaria de ver o que está faltando next, para que eu possa testar as alterações em detalhes antes de trazê-las para next. Minha pergunta é agora, como posso ver quais confirmações estão, develmas não as próximas?

Sascha Effert
fonte
seu título é um pouco enganador, pois o que você deseja comparar é a ponta dos dois ramos. e eu vim aqui à procura de uma comparação específica solução de dois (diferentes) commits de dois ramos
thebugfinder
Duplicar ?: stackoverflow.com/questions/1710894/…
reinierpost

Respostas:

210

O comando pouco usado git cherrymostra os commits que ainda não foram selecionados. A documentação para git cherryestá aqui , mas, resumindo, você deve ser capaz de:

git checkout devel
git cherry next

... e veja a saída um pouco como esta:

+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9

Os commits que começam com +serão os que você ainda não escolheu next. Nesse caso, eu tinha escolhido apenas um commit até o momento. Você pode adicionar o -vparâmetro ao git cherrycomando, para que ele também produza a linha de assunto de cada confirmação.

Mark Longair
fonte
Ótimo, era disso que eu precisava. Também seria bom obter uma breve descrição dos testes, mas posso criar um script para isso.
Sascha Effert 28/09/11
29
Você não precisa git checkout devel, você pode simplesmente fazer git cherry next devel.
precisa
21
"Pode querer adicionar o -v" ? Cereja sem a -vé como lssem uma -la. ; -J
Slipp D. Thompson
1
E você não saberia como cherrymarcar ou excluir confirmações equivalentes, não é? cherryparece um comando de encanamento, mas não parece oferecer muitas opções. Pelo que estou atualmente no meio, git cherryme dá falsos positivos, mas @ sehe git log --cherry-pickexclui corretamente os commits escolhidos / reencaminhados anteriormente.
Slipp D. Thompson
A documentação fornece um exemplo concreto: git-scm.com/docs/git-cherry#_concrete_example
ams
107

Além disso, você pode usar

git log --left-right --graph --cherry-pick --oneline devel...next

para obter uma boa lista de confirmações diferentes reais não compartilhadas entre as filiais.

A palavra operativa é --cherry-pick

--cherry-pick

Omita qualquer confirmação que introduza a mesma alteração que outra confirmação no "outro lado" quando o conjunto de confirmações estiver limitado pela diferença simétrica. Por exemplo, se você tiver duas ramificações, A e B, uma maneira usual de listar todas as confirmações em apenas um lado delas é com - esquerda-direita, como no exemplo acima na descrição dessa opção. No entanto, mostra os commits que foram escolhidos cereja do outro ramo (por exemplo, "3rd on b" pode ser escolhido cereja do ramo A). Com esta opção, esses pares de confirmações são excluídos da saída.

Atualização Como mencionado em um comentário, versões recentes do git adicionaram --cherry-mark:

--cherry-mark

Como --cherry-pick (veja abaixo), mas marque equivalente cometa com = em vez de omiti-lo, e sem igual com +.

ver
fonte
1
Isto não funcionou para mim. Minha versão do git não sabe --one-line, portanto eu o removi. Depois tive que trocar devel e depois e deu certo. Muito agradável!
Sascha Effert 28/09/11
@ SaschaEffert: você não precisou mudar o desenvolvimento e o próximo (observe TRÊS pontos, não DOIS). Dito isto, as coisas podem ser diferentes se você usou uma versão antiga do git (?), Mas nesse caso você deveria ter recebido um erro de análise de revisão nos três pontos.
sehe
2
Por diversão, descobri que a sintaxe de revisão de análise '...' (diferença simétrica) foi adicionada em julho de 2006 e a documentação para isso foi atualizada em junho de 2008 . A alegria do código aberto!
sehe
1
'gls - first-parent --cherry mark - left-only develop ... next' onde gls é o meu alias do log do git com toda a formatação bonita. cherry-mark mostra confirmações de cherry picking e não cherry cherry no desenvolvimento, mas as marca de maneira diferente.
Angularsen
1
adicionar --no-fusões talvez melhor
MervynYang
51

Você pode tentar fazer subconjuntos de log do git:

git log --oneline devel ^next
Bryan Buckley
fonte
4
Esta é a melhor solução na minha opinião (a resposta da @ sehe também mostra commits no próximo que não estão em desenvolvimento - no contexto do OP, não há, mas na minha existem - o uso --left-onlyseria melhor). No entanto, este pode ser melhorado um pouco, adicionando --no-mergespara omitir qualquer confirmação de mesclagem (por exemplo, se um recurso ou ramo de hotfix foi mesclado (separadamente) no devel e no próximo). A rigor, é claro, a resolução de conflitos em fusões pode criar outras diferenças, mas esse geralmente não é o caso. A --no-mergesopção também pode ser aplicada às outras respostas.
Alex Dupuy
27

E se

git log next..devel

O resultado é semelhante à resposta de Byran (ordem diferente de confirmações), mas ambas as respostas produzirão confirmações diferentes entre as ramificações, mostrando apenas o que está em uma ramificação e não na outra.

justingordon
fonte
4
Você também pode omitir a segunda ramificação se estiver atualmente nessa ramificação. isto é,git log next..
jmaxyz
btw 'git log next..devel' é diferente de 'git log devel..next' #
Eugene Kaurov
1

Para obter a lista de confirmações que não foram integradas ao ramo de lançamento (a seguir), você pode usar:

git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt

Verifique git-rev-list para mais informações.

Mihai
fonte
comando desta resposta está faltando os ramos reais em questão, ou seja,next...devel
Alex Dupuy
@AlexDupuy Yah, é uma resposta meio idiota. Como também não é a resposta mais simples e não explica por que essa abordagem seria melhor, estou usando a -1 .
Slipp D. Thompson
-1

@ Mark Longair acertou em sua resposta aqui , mas gostaria de acrescentar algumas dicas adicionais.

Relacionado e responder à pergunta de como interromper uma solicitação pull grande (PR), especialmente ao esmagar seus commits, é impraticável devido a uma ou mais mesclagens de master em seu feature_branch

Minha situação:
fiz um grande feature_branchcom 30 commits e abri um Pull Request (PR) no GitHub para mesclá-lo master. Branch mastermudou uma tonelada debaixo de mim e recebeu 200 commits que eu feature_branchnão tinha. Para resolver conflitos que fiz git checkout feature_branche git merge mastermesclar masteras alterações no meu feature_branch. Eu escolhi, mergee não porque isso pode acabar com o histórico de comentários da revisão do GitHub no PR. Portanto, mesclei o mestre na ramificação de recursos e resolvi conflitos uma única vez. Tudo foi bem. Meu PR, no entanto, era grande demais para meus colegas revisarem. Eu precisava dividir. Eu fui esmagar meus 30 commits e OH NÃO! ONDE ELES ESTÃO? Estão todos entrelaçados com os 200 commits recentes agora, porque eu me fundei no meurebase entrar no mestre mais recente, ter que resolver os conflitos apenas uma vez, em vez de potencialmente 30 vezes (uma vez para cada um dos meus commits). Eu não queria esmagar meus 30 commits em 1 primeiro e depois me refazer nos últimosmastermastermasterfeature_branch! O QUE EU FAÇO?

git cherryuso no caso de você querer tentar git cherry-pickconfirmações individuais:

git cherry para o resgate (mais ou menos)!

Para ver todos os commits que estão, feature_branchmas NÃO estão, mastereu posso fazer:

git checkout feature_branch
git cherry master

OR, posso verificar commits de qualquer ramo, sem garantir que eu estou no feature_branchprimeiro, fazendo git cherry [upstream_branch] [feature_branch], assim. Novamente, isso verifica para ver quais confirmações estão, feature_branchmas NÃO estão upstream_branch( masterneste caso):

git cherry master feature_branch

A adição -vtambém mostra as linhas de assunto da mensagem de confirmação:

git cherry -v master

A canalização para "contagem de palavras" "-lines" ( wc -l) conta quantas confirmações existem:

git cherry master | wc -l

Você pode comparar essa contagem com o número de confirmação mostrado no seu GithHub PR para se sentir melhor em saber se git cherryrealmente está funcionando. Você também pode comparar os hashes do git um por um e ver se eles correspondem ao git cherryGitHub. Note-se que git cherrynão contará nenhum commit mesclagem onde se fundiram masterem feature_branch, mas GitHub vontade. Portanto, se você encontrar uma pequena discrepância na contagem, pesquise na página de confirmação do GitHub PR a palavra "mesclar" e provavelmente verá que esse é o culpado que não está aparecendo git cherry. Ex: um commit intitulado "Merge branch 'master' into feature_branch" será exibido no GitHub PR, mas não quando você executar git cherry master feature_branch. Isso é bom e esperado.

Portanto, agora eu tenho um meio de descobrir quais diferenças eu posso escolher em uma ramificação de recursos novos para dividir essa diferença: eu posso usar git cherry master feature_branchlocalmente ou examinar os commits no GitHub PR.

Como o esmagamento poderia ajudar - se pudéssemos esmagar:

Uma alternativa, no entanto, para dividir meu grande diff é compactar todos os 30 dos meus commits em um, corrigir isso em um novo ramo de recurso, redefinir suavemente o commit do patch e usar git guipara adicionar pedaços arquivo por arquivo, pedaço por pedaço ou linha por linha. Depois de obter um sub-recurso, posso confirmar o que adicionei e verificar um novo ramo, adicionar um pouco mais, confirmar, verificar um novo ramo, etc., até que meu grande recurso seja dividido em vários sub-recursos . O problema é que meus 30 commits são misturados com os outros 200 commits de outras pessoas devido a minha git merge masterno meu feature_branch, então rebasing é, portanto, impraticável, pois eu teria que peneirar 230 commits para re-ordem e esmagar meus 30 commits.

Como usar um arquivo de correção como um substituto muito mais fácil para esmagar:

Uma solução alternativa é simplesmente obter um arquivo de correção contendo um "equivalente a squash" de todos os meus 30 commits, corrigi-lo em uma nova bifurcação de master(uma nova ramificação de sub-recurso) e trabalhar a partir daí, da seguinte maneira:

git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master 
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch

Agora eu tenho meu patch de 30 confirmações aplicado localmente, mas sem estágio e sem confirmação.

Agora use git guipara adicionar arquivos, pedaços e / ou linhas e interromper seu grande PR ou "diff":

Note que se você não possui git gui, você pode instalá-lo facilmente no Ubuntu com sudo apt install git-gui.

Agora posso executar git guie começar a adicionar arquivos, pedaços e / ou linhas (clicando com o botão direito do mouse no programa GUI git) e dividir o ramo do recurso de confirmação 30 em sub branches como descrito acima, adicionando, confirmando e bifurcando repetidamente uma nova ramificação de recurso e repetindo esse ciclo até que todas as alterações tenham sido adicionadas a uma ramificação de subfuncionalidade e meu recurso de consolidação 30 seja dividido com êxito em 3 ou 4 subfuncionalidades. Agora, posso abrir um PR separado para cada um desses sub-recursos, e será mais fácil para minha equipe revisar.

Referências:

  1. Crie um arquivo patch ou diff a partir do repositório git e aplique-o a outro repositório git diferente
Gabriel Staples
fonte
Eu precisava fazer referência a esta resposta hoje, mas não consegui encontrá-la rapidamente. Felizmente, ele teve um voto negativo para me ajudar a encontrá-lo mais fácil; portanto, um simples clique no ícone da copa de prêmios no canto superior direito da tela mostrou onde recentemente perdi 2 pontos, e clicar nele me trouxe de volta aqui onde posso Agora faça referência à minha própria resposta aqui! Espero que eu não receba mais votos negativos, mas para o votante negativo, obrigado pelo serviço que me ajudou acidentalmente!
Gabriel Staples