Com o Git, como posso saber se um commit no meu ramo é descendente de outro commit?
--is-ancestorsolução.
Com o Git, como posso saber se um commit no meu ramo é descendente de outro commit?
--is-ancestorsolução.
Respostas:
Se você deseja verificar isso programaticamente (por exemplo, no script), pode verificar se git merge-base A Bé igual a git rev-parse --verify A(então A é acessível a partir de B), ou se é git rev-parse --verify B(então B é acessível a partir de A). git rev-parseaqui é necessário para converter do nome de confirmação para confirmar o ID SHA-1 / commit.
Usar git rev-listcomo na resposta do VonC também é possível.
Edit: no Git moderno, há suporte explícito para esta consulta na forma de git merge-base --is-ancestor.
Se um dos commits que você está perguntando for uma dica de ramificação , então git branch --contains <commit>ou git branch --merged <commit>pode ser uma solução não programática melhor.
git checkout -b quickcheck <more-recent-commit-ID>e depois git branch --contains <older-commit-ID>(e git branch -D quickcheckpara se livrar do ramo temporário).
git merge-base --is-ancestorpor 2 anos.
git branch --contains <commit>e git merge-base --is-ancestor ...: 3m40s vs 0.14s
No Git 1.8.0, isso é suportado como uma opção para merge-base:
git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>
Na página do manual:
--é-ancestral
Verifique se o primeiro é um ancestral do segundo e saia com o status 0, se verdadeiro, ou com o status 1, se não for. Os erros são sinalizados por um status diferente de zero que não é 1.
Por exemplo:
git merge-base --is-ancestor origin/master master; echo $?
git merge-base THING --is-ancestor OF_THING && echo yes || echo nopor exemplo:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit committrabalha com hashes ao meu lado com git2.1.4 (Debian / Devuan 7.10 jessie) e 1.9.1 (Ubuntu 14.04 confiável), que são bastante antigos agora. Funciona mesmo para o Debian wheezy, se você o fizer sudo apt-get install git/wheezy-backports.
Esse tipo de operação baseia-se na noção de intervalo de revisões detalhadas na pergunta SO: " Diferença em 'origem do git log / mestre' vs 'origem do git log / mestre ..' ".
git rev-list deve poder voltar de um commit, até outro, se possível.
Então, eu tentaria:
git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20
(Confirmações de limite são prefixadas -)
Se o último commit exibido for o mesmo que o primeiro commit no git rev-listcomando, será um commit acessível a partir do segundo commit.
Se o primeiro commit não estiver acessível a partir do segundo, git rev-listnada retornará.
git rev-list --boundary A..B
terminaria por A, se Aestiver acessível a partir de B.
É o mesmo que:
git rev-list --boundary B --not A
, com Buma referência positiva e Auma referência negativa .
Ele inicia Be volta ao gráfico até encontrar uma revisão acessível a partir dele A.
Eu diria que, se Afor diretamente acessível B, ele encontrará (e será exibido, devido à --boundaryopção) em Asi.
-85e54e2...o snippet tem um sinal de menos? também um possível erro de digitação: "... é o mesmo que o primeiro cometer ..."
-significa que é um commit de limite. Editei a resposta para torná-la mais clara, além de atualizar os links dos documentos e corrigir o erro de digitação desta resposta de 5 anos.
Outra maneira seria usar git loge grep.
git log --pretty=format:%H abc123 | grep def456
Isso produzirá uma linha de saída se a confirmação def456 for um ancestral da confirmação abc123, ou nenhuma saída de outra forma.
Geralmente, você pode omitir o --prettyargumento, mas é necessário se você quiser ter certeza de que apenas pesquisa através de hashes de confirmação reais e não através de comentários de log e assim por diante.
--prettyusar --oneline: git log --oneline ce2ee3d | grep ec219ccworks great
https://stackoverflow.com/a/13526591/895245 menciona, agora para torná-lo mais amigável ao ser humano:
git-is-ancestor() (
if git merge-base --is-ancestor "$1" "$2"; then
echo 'ancestor'
elif git merge-base --is-ancestor "$2" "$1"; then
echo 'descendant'
else
echo 'unrelated'
fi
)
alias giia='git-is-ancestor'
git show-branch branch-sha1 commit-sha1
Onde:
Se você estiver usando git merge-base --is-ancestor, certifique-se de usar o Git 2.28 (terceiro trimestre de 2020)
Com o Git 2.28 (terceiro trimestre de 2020), alguns campos " struct commit" que nem sempre precisam estar presentes foram movidos para confirmar lajes.
Consulte commit c752ad0 , commit c49c82a , commit 4844812 , commit 6da43d9 (17 de junho de 2020) por Abhishek Kumar ( abhishekkumar2718) .
(Incorporado por Junio C Hamano - gitster- in commit d80bea4 , 06 de julho de 2020)
commit-graph: introduzircommit_graph_data_slabAssinado por: Abhishek Kumar
O commit da estrutura é usado em muitos contextos. No entanto, os membros
generationegraph_possão usados apenas para operações relacionadas a commit-graph e, de outra forma, desperdiçam memória.Esse desperdício teria sido mais pronunciado na transição para o número de geração v2, que usa o número de geração de 64 bits em vez dos atuais 32 bits.
Como eles geralmente são acessados juntos, vamos apresentar o struct
commit_graph_datae movê-los para umacommit_graph_datalaje.Enquanto o conjunto de testes geral é executado tão rápido quanto
master(séries: 26m48s,:master27m34s, mais rápido em 2,87%), alguns comandos comogit merge-base --is-ancestorforam retardados em 40%, conforme descoberto por Szeder Gábor .
Depois de minimizar o acesso à laje de consolidação, a desaceleração persiste, mas está mais próxima de 20%.Derrick Stolee acredita que a desaceleração é atribuível ao algoritmo subjacente, e não à lentidão do acesso de commit-slab, e faremos o acompanhamento em uma série posterior.
Desenvolvendo a resposta do itub, caso você precise fazer isso para todas as tags no repositório:
for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done