Pergunta

Estou escrevendo um script que faz algumas mudanças triviais e depois as compromete com o Git. Porque essas são mudanças triviais, eu quero fazer git commit --amend Sempre que posso me safar - especificamente, quando uma emenda não "bagunçará" a história de outras filiais. Se uma emenda estragaria outro ramo, eu quero fazer um padrão git commit em vez de.

Por exemplo, se meus galhos pareciam assim (a la "Visualize toda a história do ramo" em Git GUI):

* [experimental branch] Added feature.
* [master branch] Trivial change from script
* ...

E estou executando esse script no ramo principal, então não quero fazer uma emenda, porque substituiria parte da história do ramo experimental. Tecnicamente, isso não vai quebrar nada-o compromisso original ainda fará parte da história do Experimental e ainda será referenciado para que não seja coletado com lixo-mas tendo cometidos quase não idênticos em Dois ramos diferentes dificultam a vida quando quero rebaixar ou mesclar mais tarde, por isso é uma situação que quero evitar.

Como posso fazer meu script detectar automaticamente se uma confirmação tem algo ramificado dele?

Se simplificar as suposições ajudarem, eu sempre executo esse script na cabeça do mestre e só uso o Git como um repositório local - não empurro nem puxo as alterações em nenhum lugar.

Esse script está em Ruby, para que eu possa gastar para a linha de comando Git, ou posso usar o Ruby Bindings para Git - o que tornaria essa tarefa mais fácil.

Foi útil?

Solução

Apenas corra git branch --contains HEAD Para obter uma lista de ramificações que "contêm" esse compromisso. Se a lista estiver vazia, esse compromisso deve ser seguro para ampliar. Você também pode querer incluir o -a Sinalizador para listar ramificações locais e remotas.

Como alternativa, você pode comparar a saída de git rev-parse HEAD com git merge-base HEAD other-branch. Se esses IDs de comprometimento são idênticos, o comprometimento atual está no histórico de comprometimentos de outro ramo.

Outras dicas

O gráfico de comprometimento é unidirecional: dado um compromisso, você conhece todos os seus ancestrais, mas não qualquer um de seus filhos. Você terá que começar nos pontos de extremidade e voltar até chegar ao (s) comprometimento (s) que deseja.

Usar git rev-list [some commit] --children (Head é o padrão):

$ git rev-list HEAD --children
6edbee61c87fb063700751815f0ad53907d0b7a4
aee452860ecd772b8bdcd27227e6a72e6f4435fd 6edbee61c87fb063700751815f0ad53907d0b7a4
ef8a1487b03256a489d135e76d1f0b01872f2349 aee452860ecd772b8bdcd27227e6a72e6f4435fd
6910dc5833f6cd26133e32bef40ed54cf9337017 ef8a1487b03256a489d135e76d1f0b01872f2349
bbef0da56efe048f70293bd20bad0cb37b5e84f0 6910dc5833f6cd26133e32bef40ed54cf9337017
[...]

A coluna esquerda é uma lista de SHA-1s de compromisso em ordem cronológica reversa. Qualquer coisa para o direito desse compromisso são as crianças (--children) desse compromisso. O comando principal é a cabeça e, portanto, não tem filhos.

Assim, se você grep para o seu sha-1 nesta lista e ela tem algo à sua direita, ele tem pelo menos um filho:

$ git rev-list --children | grep '^6910'
6910dc5833f6cd26133e32bef40ed54cf9337017 ef8a1487b03256a489d135e76d1f0b01872f2349

No exemplo acima, cometer 6910... tem um filho, ef8a....

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top