Diferença de Git entre ramificação atual e mestre, mas não incluindo confirmações mestre não imersas

171

Eu quero um diff de todas as alterações em um ramo que ainda não foi mesclado para mestre.

Eu tentei:

git diff master
git diff branch..master
git diff branch...master

No entanto, em cada um desses casos, o diff contém conteúdo no master que ainda não foi incorporado ao meu ramo.

Existe uma maneira de fazer uma diferença entre minha ramificação e mestre que exclua alterações no mestre que ainda não foram mescladas em minha ramificação?

pillarOfLight
fonte
9
Se você virar em torno da segunda versão, você consegue o que quer: git diff master..branch. Você pode reduzi-lo git diff master..se estiver no ramo. A r1..r2sintaxe é curta, o ^r1 r2que significa "mostre-me tudo o que desce r2e não é alcançável r1". git help gitrevisionstem informações sobre as várias sintaxes que você pode usar.
John Szakmeister
1
Expandi minha resposta depois de ler mais sobre a ...sintaxe de git diff. Seu comentário está errado, @jszakmeister, porque os intervalos de revisão descritos em gitrevisionsnada têm a ver git diff. Diff compara dois pontos na história, não pode trabalhar com um intervalo.
Palec
Você está certo. Eu sempre esqueço que isso git difffunciona de maneira diferente dos outros comandos ... um fato que acho frustrante. :-(
John Szakmeister
certifique-se de atualizar a cópia local do mestre antes de comparar
joe

Respostas:

232
git diff `git merge-base master branch`..branch

A base de mesclagem é o ponto de onde branchdivergiu master.

O diff do Git suporta uma sintaxe especial para isso:

git diff master...branch

Você não deve trocar os lados, porque você obteria o outro ramo. Você quer saber o que mudou branchdesde que divergiu master, e não o contrário.

Relacionado livremente:


Observe que a sintaxe ..e ...não tem a mesma semântica que em outras ferramentas Git. Difere do significado especificado em man gitrevisions.

Citação man git-diff:

  • git diff [--options] <commit> <commit> [--] [<path>…]

    Isso é para visualizar as alterações entre duas arbitrárias <commit>.

  • git diff [--options] <commit>..<commit> [--] [<path>…]

    Isso é sinônimo do formulário anterior. Se <commit>um lado for omitido, terá o mesmo efeito que o uso HEAD.

  • git diff [--options] <commit>...<commit> [--] [<path>…]

    Este formulário é para exibir as alterações no ramo que contém e até o segundo <commit>, iniciando em um ancestral comum de ambos <commit>. " git diff A...B" é equivalente a " git diff $(git-merge-base A B) B". Você pode omitir qualquer um dos <commit>que tem o mesmo efeito que o uso HEAD.

No caso de você estar fazendo algo exótico, observe que tudo <commit>na descrição acima, exceto nas duas últimas formas que usam notações "..", pode ser qualquer um <tree>.

Para obter uma lista mais completa de maneiras de escrever <commit>, consulte a seção "ESPECIFICANDO REVISÕES" em gitrevisions[7]. No entanto, "diff" consiste em comparar dois pontos de extremidade, não intervalos, e as notações de intervalo (" <commit>..<commit>" e " <commit>...<commit>") não significam um intervalo conforme definido na seção "SPECIFYING RANGES" em gitrevisions[7].

Palec
fonte
Para mim $ git diff master...branchproduzido fatal: ambiguous argument 'master...branch': unknown revision or path not in the working tree.- este é um comando dependente da versão?
Joel Peltonen
Na verdade, eu só percebi que "ramo" deve ser o nome do seu ramo, eu pensei que era uma referência para o ramo atual
Joel Peltonen
4
Você está certo, minha resposta depende do ramo que está sendo chamado branch. Eu escolhi ficar com o nome que o OP havia escolhido na pergunta. Se você deseja usar a ramificação atual, substitua branchpor HEAD.
Palec 9/09/16
14
Observe que você pode usar git diff master...para evitar especificar a ramificação (a atual será obtida).
VasiliNovikov
1
O comando original funciona após o check-out devel, @ChrisGuest? Provavelmente, o Git criou a filial para você durante o checkout, como uma cópia local de uma filial remota (normalmente origin/devel). Se fosse esse o caso, git diff origin/devel...bugfix/API-353-api-allows-database-access-whenteria funcionado mesmo antes do checkout.
Palec
44

Aqui está o que funcionou para mim:

git diff origin/master...

Isso mostra apenas as alterações entre minha ramificação local selecionada no momento e a ramificação mestre remota e ignora todas as alterações na ramificação local que vieram de confirmações de mesclagem.

Jeshurun
fonte
Para referência, se você precisar das referências de confirmação de confirmações que contêm essas alterações, use git cherry origin/master.
Jaytibann # 15/19
Se isso mostra um monte de lixo que você não esperava, masterpode ter rebocado um conjunto de confirmações de baixo de você.
Michael - Onde está Clay Shirky,
21

Como também observado por John Szakmeister e VasiliNovikov, o comando mais curto para obter o diff completo da perspectiva do mestre em seu ramo é:

git diff master...

Isso usa sua cópia local do mestre.

Para comparar um arquivo específico, use:

git diff master... filepath

Exemplo de saída:

Exemplo de uso

Andrew Schreiber
fonte