Usando Git, mostre todos os commits que existem * apenas * em um branch específico, e não * quaisquer * outros

86

Dado um branch, eu gostaria de ver uma lista de commits que existem apenas naquele branch. Em esta questão vamos discutir maneiras de ver quais commits estão em um ramo, mas não um ou mais especificado outros ramos.

Isso é um pouco diferente. Eu gostaria de ver quais commits estão em um branch, mas não em qualquer outro branch .

O caso de uso está em uma estratégia de ramificação em que algumas ramificações devem apenas ser mescladas e nunca comprometidas diretamente. Isso seria usado para verificar se algum commit foi feito diretamente em um branch "merge-only".

EDIT: Abaixo estão as etapas para configurar um repositório git fictício para testar:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"
git checkout merge-only 
git merge master

Apenas o commit com a mensagem "mau commit diretamente no merge-only", que foi feito diretamente no ramo merge-only, deve aparecer.

Jimmyorr
fonte
1
Esta questão presume que todas as ramificações mescladas estão atualmente disponíveis no repo, nunca são excluídas uma vez totalmente mescladas e talvez nunca mescladas com um avanço rápido. Deixe-me saber se estou faltando alguma coisa, mas me parece que isso só é viável para um conjunto relativamente pequeno de ramificações de mesclagem permitidas, então por que não usar apenas a git log ^branch1 ^branch2 merge-only-branchsintaxe?
Karl Bielefeldt
1
O git log ^branch1 ^branch2 merge-only-branchrequer a listagem de todos os ramos. Isso pode ser evitado com o uso inteligente de bash / grep (veja minha resposta abaixo), mas espero que o git tenha algum suporte embutido para isso. Você está correto ao afirmar que todos os branches de mesclagem são remotos (apenas locais são tão bons quanto inexistentes para outros desenvolvedores). O uso --no-mergesomite quaisquer commits que foram mesclados e tiveram seu branch original merge-from excluído, então assume que os branches merge-from são mantidos até que tenham sido fundidos em um branch não-merge-only (ie master).
Jimmyorr,

Respostas:

75

Acabamos de encontrar esta solução elegante

git log --first-parent --no-merges

Em seu exemplo, é claro, o commit inicial ainda aparece.

esta resposta não responde exatamente à pergunta, porque o commit inicial ainda aparece. Por outro lado, muitas pessoas que vêm aqui parecem encontrar a resposta que procuram.

Wrtsprt
fonte
1
Simples, eficaz, melhor.
Zabba
1
Uma vez que o commit inicial no master ainda aparece, isso não responde à pergunta.
Jimmyorr
6
Isso por si só não satisfaz “commits que só existem nesse ramo” condicionamento ele mostra o initial valid commitque é parte de ambos os merge-onlye masterramos. No entanto, se alguém fizer o esforço de colocar o nome do branch atual no final seguido por ^ -nomes de branch com prefixo dos quais o branch atual se originou, isso resolverá metade dos problemas (excluindo coisas que foram mescladas). Ex:git log --first-parent --no-merges merge-only ^master
Slipp D. Thompson
13
Não tenho certeza de por que isso é tão votado, não parece ser pertinente à pergunta de forma alguma. Certamente não fornece as informações que o autor da postagem estava procurando.
Chris Rasys de
2
Esta resposta pode não ser perfeita. Mas é simples e certamente funciona até certo ponto. Acho útil adicionar o nome do branch - ou seja, filtrar todos os commits pertencentes a um determinado branch:git log --first-parent --no-merges | grep <branch_name>
artm
29

Cortesia do meu querido amigo Redmumba :

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

... onde origin/merge-onlyestá o nome do seu branch apenas de mesclagem remota. Se estiver trabalhando em um repositório git somente local, substitua refs/remotes/originpor refs/headse substitua o nome do branch remoto pelo nome do origin/merge-onlybranch local merge-only, ou seja:

git log --no-merges merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/heads |
    grep -Fv refs/heads/merge-only)
Jimmyorr
fonte
2
Espero que outra pessoa possa fornecer uma solução sem grep usando apenas git, mas se não, isso parece muito elegante.
Jimmyorr,
1
Sim, elegante. Use git for-each-refpara listar cada nome de referência na origem e grep -vpara omitir o branch somente de mesclagem. git logpega uma --notopção, para a qual passamos nossa lista de todos os refs (exceto o branch merge-only). Se você tem uma resposta mais elegante para o problema, vamos ouvi-la.
Jimmyorr,
2
Oh, tenho certeza que é a resposta mais elegante. Estou apenas argumentando que é um pouco "prolixo / complexo" para a verdadeira elegância. :-) Não quis menosprezar a sua abordagem, senhor!
Chris K,
1
O acompanhamento /*dos git for-each-refscomandos depende de não corresponder a algum arquivo existente e de não ter failglobou nullglobdefinido ( opções do bash , outros shells variam). Você deve citar / escapar os asteriscos ou apenas deixar o rastro /*(os git for-each-refpadrões podem corresponder “do início até uma barra”). Talvez use grep -Fv refs/remotes/origin/foo( refs/heads/foo) para ser mais rígido sobre quais referências são eliminadas.
Chris Johnsen de
3
Pode ser simplificado se você quiser apenas ver os commits presentes em um branch e não em outro git log --no-merges B1 --not B2:, onde B1 é o branch no qual você está interessado, e B2 é o branch com o qual você deseja comparar B1. Ambos B1 e B2 podem ser ramos locais ou remotos, portanto, você pode especificar git log --no-merges master --not origin/master, ou mesmo especificar dois ramos remotos.
sr.b
21
git log origin/dev..HEAD

Isso mostrará todos os commits feitos em seu branch.

Prakash
fonte
2
@Prakash origin/branchNameapontará para o chefe do branch remoto E HEADapontará para o commitid do último commit local naquele branch. Portanto, isso não funcionará quando você tiver usado o git push.
Bharat,
Você pode usar isso para comparar outra filial local. O sinalizador --no-merges também pode ser útil para resolver a questão original do OP.
Paul Whipp
15

A resposta @Prakash funciona. Apenas para maior clareza ...

git checkout feature-branch
git log master..HEAD

lista os commits no branch-feature, mas não no branch upstream (normalmente seu master).

Bryan
fonte
12

Talvez isso possa ajudar:

git show-branch

Grzuy
fonte
2
Embora isso possa teoricamente responder à pergunta, seria preferível incluir as partes essenciais da resposta aqui e fornecer o link para referência.
Vladimir Panteleev
Na verdade, isso é muito útil. Consulte stackoverflow.com/a/7623339/874188 para um exemplo mais elaborado e algumas respostas relacionadas.
tripleee
7

Experimente isto:

git rev-list --all --not $(git rev-list --all ^branch)

Basicamente, git rev-list --all ^branchobtém todas as revisões que não estão no branch e então você todas as revisões no repositório e subtrai a lista anterior que é as revisões apenas no branch.

Após os comentários de @Brian:

Da documentação do git rev-list:

List commits that are reachable by following the parent links from the given commit(s)

Portanto, um comando como git rev-list Aonde A é um commit listará os commits que podem ser acessados ​​por A inclusive A.

Com isso em mente, algo como

git rev-list --all ^A

irá listar commits não alcançáveis ​​de A

Então git rev-list --all ^branchirá listar todos os commits não alcançáveis ​​da ponta do branch. O que removerá todos os commits no branch, ou em outras palavras, os commits que estão apenas em outros branches.

Agora vamos para git rev-list --all --not $(git rev-list --all ^branch)

Isso vai ser como git rev-list --all --not {commits only in other branches}

Então, queremos listar allque não são acessíveis a partir deall commits only in other branches

Qual é o conjunto de commits que estão apenas em branch. Vamos dar um exemplo simples:

             master

             |

A------------B

  \

   \

    C--------D--------E

                      |

                      branch

Aqui, o objetivo é obter D e E, os commits não em qualquer outro branch.

git rev-list --all ^branch dê apenas B

Agora, git rev-list --all --not Bé aonde chegamos. O que também é git rev-list -all ^B- queremos todos os commits inacessíveis de B. Em nosso caso, é D e E. O que é o que queremos.

Espero que isso explique como o comando funciona corretamente.

Editar após o comentário:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"

Após os passos acima, se você fizer um git rev-list --all --not $(git rev-list --all ^merge-only), receberá o commit que estava procurando - "bad commit directly on merge-only"aquele.

Mas, depois de realizar a etapa final em suas etapas, git merge mastero comando não fornecerá a saída esperada. Porque a partir de agora não há commit que não esteja lá apenas no merge, já que o commit extra no master também foi mesclado para merge-only. Portanto, git rev-list --all ^branchdá um resultado vazio e, portanto git rev-list -all --not $(git rev-list --all ^branch), fornecerá todos os commits apenas em fusão.

manojlds
fonte
1
Hm ... não sei por que, mas isso não funciona muito bem. Canalizando a saída do seu comando para xargs -L 1 -t git branch -a --containsmostrar muitos falsos positivos (commits que estão de fato em outros branches). Tentei com e sem --no-merges. Obrigado por responder!
Jimmyorr de
Parece funcionar bem para mim, pelo que posso ver em um repositório git fictício.
manojlds de
Eu adicionei etapas para criar um repositório git fictício para ajudar a demonstrar o problema com sua resposta.
Jimmyorr de
Ah, opa. Votei a favor antes de pensar no assunto. git rev-list --all ^branchdará a você todos os commits que não estão em branch. Você está então subtraindo isso da lista que está em branch; mas, por definição, todos os commits que não branchestão em não estão branch, então você não está subtraindo nada. O que Jimmyorr está procurando são commits que estão em, branchmas não estão master, nem em qualquer outro branch. Você não quer subtrair os commits que não estão branch; você deseja subtrair os commits que estão em qualquer outro branch.
Brian Campbell,
1
@manojlds "(todas as revisões) - (todas as revisões não no ramo) = revisão no ramo." Sim, isso funciona para incluir todas as revisões branch, mas também funciona git rev-list branch. Você está apenas escrevendo git rev-list branchde uma forma mais complicada (e mais lenta). Não funciona responder a questão, que é como encontrar todos os commits branch que não estão em nenhum outro branch .
Brian Campbell de
2

Outra variação das respostas aceitas, para usar com master

git log origin/master --not $(git branch -a | grep -Fv master)

Filtre todos os commits que acontecem em qualquer branch diferente do master.

JaimeJorge
fonte
0

Esta não é exatamente uma resposta real, mas preciso acessar a formatação e muito espaço. Tentarei descrever a teoria por trás do que considero as duas melhores respostas: a aceita e a (pelo menos atualmente) melhor colocada . Mas, na verdade, eles respondem a perguntas diferentes .

Commits no Git estão frequentemente "em" mais de um branch por vez. Na verdade, é disso que se trata. Dado:

...--F--G--H   <-- master
         \
          I--J   <-- develop

onde as letras maiúsculas representam os hash IDs reais do Git, geralmente procuramos apenas commitH ou apenas commitsI-J em nossa git logsaída. Os commits até Gestão em ambas as ramificações, portanto, gostaríamos de excluí-los.

(Observe que em gráficos desenhados assim, os commits mais recentes estão à direita. Os nomes selecionam o único commit mais à direita nessa linha. Cada um desses commits tem um commit pai, que é o commit à sua esquerda: o pai de Hé G, e o pai de Jé I. O pai de Ié Gnovamente. O pai de Gé Fe Ftem um pai que simplesmente não é mostrado aqui: faz parte da ...seção.)

Para este caso particularmente simples, podemos usar:

git log master..develop    # note: two dots

para ver I-J, ou:

git log develop..master    # note: two dots

para ver Hapenas. O nome do lado direito, após os dois pontos, diz ao Git: sim, esses commits . O nome do lado esquerdo, antes dos dois pontos, diz ao Git: não, não esses commits . Git começa no final - em commit Hou commit J- e funciona de trás para frente . Para (muito) mais sobre isso, consulte Think Like (a) Git .

Da forma como a pergunta original é formulada, o desejo é encontrar commits que sejam acessíveis a partir de um nome em particular, mas não de qualquer outro nome na mesma categoria geral. Ou seja, se tivermos um gráfico mais complexo:

               O--P   <-- name5
              /
             N   <-- name4
            /
...--F--G--H--I---M   <-- name1
         \       /
          J-----K   <-- name2
           \
            L   <-- name3

poderíamos escolher um desses nomes, como name4ou name3, e perguntar: quais commits podem ser encontrados por esse nome, mas não por qualquer um dos outros nomes? Se escolhermos, name3a resposta é cometer L. Se escolhermos name4, a resposta é nenhum commit: o commit que name4names é commit Nmas commit Npode ser encontrado começando em name5e trabalhando para trás.

A resposta aceita funciona com nomes de rastreamento remoto, em vez de nomes de ramificações, e permite que você designe um - aquele escrito origin/merge-only- como o nome selecionado e observe todos os outros nomes naquele namespace. Também evita a exibição de mesclagens: se escolhermos name1como o "nome interessante" e dissermos mostre os commits que podem ser acessados, name1mas não com qualquer outro nome , veremos o commit de mesclagem Massim como o commit regular I.

A resposta mais popular é bem diferente. É tudo sobre percorrer o gráfico de commit sem seguir as duas pernas de uma mesclagem e sem mostrar nenhum dos commits que são mesclagens. Se começarmos com name1, por exemplo, não mostraremos M(é um merge), mas assumindo que o primeiro pai de merge Mé commit I, nem mesmo olharemos para commits Je K. Vamos acabar mostrando cometer I, e também se compromete H, G, F, e assim por diante-nenhuma delas é commits mesclagem e todos são acessíveis pela partir de Me trabalhando para trás, visitando apenas o primeiro pai de cada merge cometer.

A resposta mais popular é bastante adequada, por exemplo, para ver masterquando masterse destina a ser um branch somente de mesclagem. Se todo o "trabalho real" foi feito nas ramificações laterais que foram posteriormente mescladas master, teremos um padrão como este:

I---------M---------N   <-- master
 \       / \       /
  o--o--o   o--o--o

onde todos os ocommits un-letter-named são commits comuns (não-merge) e Me Nsão commits de mesclagem. Commit Ié o commit inicial: o primeiro commit já feito, e o único que deveria estar no master que não é um merge commit. Se o git log --first-parent --no-merges mastermostrar qualquer commit diferente de I , temos uma situação como esta:

I---------M----*----N   <-- master
 \       / \       /
  o--o--o   o--o--o

onde queremos ver o commit *feito diretamente master, não por meio da fusão de algum branch de recurso.

Resumindo, a resposta popular é ótima para saber masterquando masterdeve ser somente mesclagem, mas não é tão boa para outras situações. A resposta aceita funciona para essas outras situações.

Os nomes de rastreamento remoto são como nomes de origin/master agências ?

Algumas partes do Git dizem que não são:

git checkout master
...
git status

diz on branch master, mas:

git checkout origin/master
...
git status

diz HEAD detached at origin/master. Prefiro concordar com git checkout/ git switch: origin/masternão é um nome de branch porque você não pode "ativá-lo".

A resposta aceita usa nomes de rastreamento remoto origin/*como "nomes de agências":

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

A linha do meio, que invoca git for-each-ref, itera sobre os nomes de rastreamento remoto para o remoto nomeado origin.

O motivo pelo qual esta é uma boa solução para o problema original é que estamos interessados ​​aqui nos nomes de branch de outra pessoa , e não nos nomes de nosso branch. Mas isso significa que definimos branch como algo diferente de nossos nomes de branch . Tudo bem: apenas esteja ciente de que você está fazendo isso, quando fizer isso.

git log atravessa alguma (s) parte (s) do gráfico de confirmação

O que estamos realmente procurando aqui são séries do que chamei de daglets: veja o que exatamente queremos dizer com "galho"? Ou seja, estamos procurando fragmentos em algum subconjunto do gráfico de confirmação geral .

Sempre que fazemos o Git olhar para um nome de branch como master, um nome de tag como v2.1, ou um nome de rastreamento remoto como origin/master, tendemos a querer que o Git nos diga sobre esse commit e cada commit que podemos obter a partir desse commit: começando aí e trabalhando para trás.

Em matemática, isso é conhecido como gráfico de caminhada . O gráfico de commit do Git é um Directed Acyclic Graph ou DAG , e esse tipo de gráfico é particularmente adequado para caminhadas. Ao percorrer esse gráfico, visitaremos cada vértice do gráfico que pode ser alcançado através do caminho que está sendo usado. Os vértices no gráfico Git são os commits, com as arestas sendo arcos - links unilaterais - indo de cada filho para cada pai. (É aqui que entra o Think Like (a) Git . A natureza unilateral dos arcos significa que o Git deve trabalhar de trás para frente, do filho para o pai.)

Os dois comandos principais do Git para caminhar no gráfico são git loge git rev-list. Esses comandos são extremamente semelhantes - na verdade, eles são construídos principalmente a partir dos mesmos arquivos de origem - mas sua saída é diferente: git logproduz saída para humanos lerem, enquanto git rev-listproduz saída para outros programas Git lerem. 1 Ambos os comandos fazem esse tipo de caminhada no gráfico.

A caminhada no gráfico que eles fazem é especificamente: dado algum conjunto de commits de ponto de partida (talvez apenas um commit, talvez um monte de IDs de hash, talvez um monte de nomes que resolvem em IDs de hash), ande no gráfico, visitando commits . Diretivas específicas, como --notou um prefixo ^, ou --ancestry-path, ou --first-parent, modificam a caminhada do gráfico de alguma forma.

Enquanto fazem a caminhada do gráfico, eles visitam cada commit. Mas eles imprimem apenas alguns subconjuntos selecionados dos commits percorridos. Diretivas como --no-mergesou --before <date>informam o código do gráfico que se compromete a imprimir .

Para fazer esta visita, um commit de cada vez, esses dois comandos usam uma fila prioritária . Você executa git logou git rev-liste dá a ele alguns commits de ponto de partida. Eles colocam esses commits na fila de prioridade. Por exemplo, um simples:

git log master

transforma o nome masterem um ID de hash bruto e coloca esse ID de hash na fila. Ou:

git log master develop

transforma ambos os nomes em IDs de hash e - supondo que sejam dois IDs de hash diferentes - coloca ambos na fila.

A prioridade dos commits nesta fila é determinada por ainda mais argumentos. Por exemplo, o argumento --author-date-orderinforma git logou git rev-listpara usar o carimbo de data / hora do autor , em vez do carimbo de data / hora do committer. O padrão é usar o carimbo de data / hora do committer e escolher o commit mais recente por data: aquele com a data numérica mais alta. Assim master develop, assumindo que estes resolvam dois commits diferentes, o Git mostrará o que vier depois primeiro, porque estará na frente da fila.

Em qualquer caso, o código de passeio de revisão agora executa em um loop:

  • Enquanto houver commits na fila:
    • Remova a primeira entrada da fila.
    • Decida se deseja imprimir este commit. Por exemplo --no-merges: print nothing se for um commit de mesclagem; --before: não imprime nada se sua data não for anterior à hora designada. Se a impressão não for suprimida, imprima o commit: for git log, mostre seu log; para git rev-listimprimir seu ID de hash.
    • Coloque alguns ou todos os commits pais deste commit na fila (contanto que não esteja lá agora, e ainda não tenha sido visitado 2 ). O padrão normal é incluir todos os pais. Usar --first-parentsuprime tudo, exceto o primeiro pai de cada mesclagem.

(Ambos git loge git rev-listpodem fazer a simplificação do histórico com ou sem a reescrita dos pais neste ponto também, mas vamos pular isso aqui).

Para uma cadeia simples, como começar em HEADe trabalhar para trás quando não há commits de mesclagem, a fila sempre tem um commit no topo do loop. Há um commit, então nós o retiramos e imprimimos e colocamos seu (único) pai na fila e contornamos novamente, e seguimos a cadeia de trás para frente até chegarmos ao primeiro commit, ou o usuário se cansa da git logsaída e sai o programa. Nesse caso, nenhuma das opções de pedido importa: há apenas um commit para mostrar.

Quando há fusões e nós seguimos ambos os pais - ambas as "pernas" da fusão - ou quando você dá git logou git rev-listmais de um commit inicial, as opções de classificação são importantes.

Por último, considere o efeito de --notou ^na frente de um especificador de confirmação. Eles têm várias maneiras de escrevê-los:

git log master --not develop

ou:

git log ^develop master

ou:

git log develop..master

todos significam a mesma coisa. O --noté como o prefixo, ^exceto que se aplica a mais de um nome:

git log ^branch1 ^branch2 branch3

significa não branch1, não branch2, sim branch3; mas:

git log --not branch1 branch2 branch3

significa não branch1, não branch2, não branch3, e você tem que usar um segundo --notpara desligá-lo:

git log --not branch1 branch2 --not branch3

o que é um pouco estranho. As duas diretivas "não" são combinadas via XOR, então, se você realmente quiser, pode escrever:

git log --not branch1 branch2 ^branch3

para significar não branch1, não branch2, sim branch3 , se você quiser ofuscar .

Todos eles funcionam afetando a caminhada do gráfico. Conforme git logou git rev-listpercorre o gráfico, ele se certifica de não colocar na fila de prioridade qualquer confirmação que seja alcançável de qualquer uma das referências negadas . (Na verdade, eles afetam a configuração inicial também: commits negados não podem ir para a fila de prioridade diretamente da linha de comando, então git log master ^masternão mostra nada, por exemplo.)

Toda a sintaxe extravagante descrita na documentação do gitrevisions faz uso disso, e você pode expor isso com uma simples chamada para git rev-parse. Por exemplo:

$ git rev-parse origin/pu...origin/master     # note: three dots
b34789c0b0d3b137f0bb516b417bd8d75e0cb306
fc307aa3771ece59e174157510c6db6f0d4b40ec
^b34789c0b0d3b137f0bb516b417bd8d75e0cb306

A sintaxe de três pontos significa commits acessíveis do lado esquerdo ou direito, mas excluindo commits alcançáveis ​​de ambos . Neste caso, o próprio origin/mastercommit,, b34789c0bpode ser alcançado a partir de origin/pu( fc307aa37...), então o origin/masterhash aparece duas vezes, uma vez com uma negação, mas na verdade o Git atinge a sintaxe de três pontos colocando duas referências positivas - os dois IDs de hash não negados - e um negativo, representado pelo ^prefixo.

Simiarly:

$ git rev-parse master^^@
2c42fb76531f4565b5434e46102e6d85a0861738
2f0a093dd640e0dad0b261dae2427f2541b5426c

A ^@sintaxe significa todos os pais do commit fornecido , e master^ela mesma - o primeiro pai do commit selecionado por branch-name master- é um commit de mesclagem, então tem dois pais. Estes são os dois pais. E:

$ git rev-parse master^^!
0b07eecf6ed9334f09d6624732a4af2da03e38eb
^2c42fb76531f4565b5434e46102e6d85a0861738
^2f0a093dd640e0dad0b261dae2427f2541b5426c

O ^!sufixo significa o próprio compromisso, mas nenhum de seus pais . Nesse caso, master^é 0b07eecf6.... Já vimos ambos os pais com o ^@sufixo; aqui estão eles de novo, mas desta vez, negados.


1 Muitos programas Git literalmente rodam git rev-listcom várias opções, e lêem sua saída, para saber quais commits e / ou outros objetos Git usar.

2 Como o gráfico é acíclico , é possível garantir que nenhum já foi visitado, se adicionarmos a restrição nunca mostrar um pai antes de mostrar todos os seus filhos à prioridade. --date-order, --author-date-ordere --topo-orderadicione esta restrição. A ordem de classificação padrão - que não tem nome - não tem. Se os carimbos de data / hora de commits são complicados - se, por exemplo, alguns commits foram feitos "no futuro" por um computador cujo relógio estava desligado - isso poderia em alguns casos levar a uma saída de aparência estranha.


Se você chegou até aqui, agora sabe muito sobre git log

Resumo:

  • git log é sobre mostrar alguns commits selecionados enquanto percorre parte ou toda parte do gráfico.
  • O --no-mergesargumento, encontrado em ambas as respostas aceitas e atualmente no topo da classificação, suprime a exibição de alguns commits que são percorridos.
  • O --first-parentargumento, da resposta atualmente no topo da classificação, suprime a caminhada de algumas partes do gráfico, durante a própria caminhada do gráfico.
  • O --notprefixo para os argumentos da linha de comando, conforme usado na resposta aceita, elimina a visita a algumas partes do gráfico, desde o início.

Obtemos as respostas que gostamos, para duas perguntas diferentes, usando esses recursos.

Torek
fonte