Suponha que eu execute o seguinte comando em um repositório git:
git rev-list --objects HEAD^..HEAD
Este comando me fornece apenas objetos que são referenciados por HEAD e não referenciados por HEAD^.
Entretanto, se houver um objeto referenciado por HEAD^^
e também por HEAD
, mas não por HEAD^
, esse objeto aparecerá na saída?
Com base na experimentação, parece que a resposta é sim.
Entretanto, a documentação não parece especificar a intenção, então não tenho certeza se meus resultados experimentais são acidentais ou não.
Atualização sobre meu entendimento atual para esclarecer a questão:
- Entendo que isso
<old>..<new>
é equivalente a^<old> <new>
, o que significa pegar todos os commits que podem ser acessados de<new>
, mas não podem ser acessados de<old>
. - (Implementação A1) Filosoficamente, se expandíssemos essa noção literalmente para "árvores e blobs referenciados por commits", então o comportamento "semanticamente correto"
git rev-list --objects ^<old> <new>
seria "encontrar todos os objetos (commits, árvores e blobs) que são acessíveis a partir<new>
dos quais não são acessíveis a partir de<old>
. - Levando isso ao pé da letra, isso implicaria que um blob X com as seguintes propriedades NÃO deveria aparecer em
git rev-list --objects HEAD^..HEAD
, porque o conjunto completo de objetos acessíveis a partir deHEAD^
inclui o blob X.- referenciado pela árvore de propriedade de
HEAD^^
- referenciado pela árvore de propriedade de
HEAD
- não referenciado diretamente pela árvore de propriedade de
HEAD^
- referenciado pela árvore de propriedade de
- Entretanto, meus experimentos indicam que o blob X aparece na saída de
git rev-list --objects HEAD^..HEAD
, o que implica na seguinte implementação alternativa (chame-o de A2) :- Pegue todos os objetos referenciados pelos commits no intervalo
<old>..<new>
. - Remova SOMENTE os objetos referenciados pelo commit
<old>
e NÃO todos os seus ancestrais e retorne este conjunto.
- Pegue todos os objetos referenciados pelos commits no intervalo
Portanto, minha pergunta pode ser reformulada como: O comportamento de é git rev-list --objects <old>..<new>
equivalente a A1, A2 ou algo completamente diferente que às vezes se comporta como A1 e às vezes como A2?
Há duas leituras sobre isso, sim, mas uma é muito mais útil na prática.
A ideia é encontrar eficientemente objetos que precisam ser enviados para busca ou envio, o que significa negociar o custo da busca exaustiva, que é feita sempre, com o custo de, às vezes (muito raramente, na prática) enviar objetos já possuídos.
É mais fácil ver se você disser
git rev-list --boundary @^..
: rev-list para de procurar quando atinge (identifica) o limite de confirmações, esteja ou não também fazendo--objects
processamento.Ambas as formas têm custos. Ambas as formas alcançam o mesmo resultado. A forma mais barata no geral também é mais segura, porque o outro repositório pode ser superficial e não ter todo o histórico que você acabou de verificar. É melhor apenas olhar o que o outro repositório disse que tem, os marcadores de limite fetch/push que ele forneceu.
edição: algumas verificações rápidas dizem
--objects
que não presume a posse de nenhum objeto além daqueles em commits de limite explicitamente listados. O que, novamente, só faz sentido do ponto de vista da segurança, o remoto não disse que tem o histórico mais profundo, não confie neles para tê-lo.