Dado um ID de confirmação, como determinar se a ramificação atual contém a confirmação?
156
O que estou tentando fazer é uma verificação de versão. Quero garantir que o código fique no topo de uma versão mínima. Então, eu preciso de uma maneira de saber se o ramo atual contém um commit especificado.
Consulte a duplicata proposta para saber como encontrar todas as ramificações que contêm uma confirmação especificada. Para descobrir se a ramificação atual contém confirmação C , use o comando "encanamento" git merge-base --is-ancestor. O ramo de corrente contém C , se C é um antepassado de HEAD, assim:if git merge-base --is-ancestor $hash HEAD; then echo I contain commit $hash; else echo I do not contain commit $hash; fi
Torek
1
Olá, envie isso como uma resposta para que ele possa ser selecionado como a resposta correta =) #
212 Ben Ben
1
@ Ben - eu adicionei como uma resposta wiki da comunidade.
Zitrax
1
@Remover: em scripts de shell, zero é verdadeiro, diferente de zero é falso: o inverso da convenção C. /bin/truefoi originalmente implementado como exit 0e /bin/falsecomo exit 1. (Conchas modernos têm, em seguida, construído em.)
Torek
Respostas:
220
Existem várias maneiras de alcançar esse resultado. A primeira opção ingênua é usar git loge procurar um commit específico usando grep, mas isso nem sempre é preciso
git log | grep <commit_id>
É melhor usar git branchdiretamente para encontrar todos os ramos que contêm dados COMMIT_IDusando
git branch --contains $COMMIT_ID
O próximo passo é descobrir o ramo atual que pode ser feito desde o git 1.8.1uso
Mas o comando acima não retorna verdadeiro ou falso e existe uma versão mais curta que retorna o código de saída 0 se a confirmação estiver na ramificação atual OU o código de saída 1 se não houver
git merge-base --is-ancestor $COMMIT_ID HEAD
O código de saída é bom, mas como você deseja string trueou falseresposta, você precisa adicionar um pouco mais e, em seguida, combinado com o ifbash, obtém
if [ 0 -eq $(git merge-base --is-ancestor $COMMIT_ID HEAD) ]; then echo "true"; else echo "false"; fi
Isso não está correto; o greppoderia resultar em falsos positivos se git logmencionar o SHA de confirmação por outros motivos, por exemplo, é mencionado em uma mensagem de confirmação como resultado de uma porta de outra ramificação.
O grepaqui também pode resultar em falsos positivos se houver outros ramos que contenham o commit cujos nomes também contenham <branch-name>como substring.
Adam Spiers
1
Sim @AdamSpiers, Actualizado a resposta com correspondência exata do nome de filial porgrep -E '(^|\s)branchname$'
Sajib Khan
1
Por esse comentário sobre a pergunta relacionada , pode ser útil adicionar a opção -r("remote") ou -a("all") git branchpara procurar ramificações que podem não ser replicadas no repo clone local.
Sxc731 23/05
Isso não funcionou para mim, eu precisava git branch --all --contains <commit-id>
Arthur Tacca
7
Comentário extraído por @torek como resposta:
Consulte a duplicata proposta para saber como encontrar todas as ramificações que contêm uma confirmação especificada.
Para descobrir se a ramificação atual contém confirmação C, use o comando "encanamento" git merge-base --is-ancestor. O ramo atual contém C se C é um ancestral de HEAD, portanto:
if git merge-base --is-ancestor $hash HEAD; then
echo I contain commit $hash
else
echo I do not contain commit $hash
fi
(Observação: em scripts de shell, um comando que sai zero é "verdadeiro", enquanto um que sai diferente de zero é "falso".)
Isso funciona melhor para mim, pois também funcionaria em ramificações remotas armazenadas em cache localmente, como remotes/origin/master, nas quais git branch --containsnão funcionará.
Isso cobre mais do que a pergunta do OP sobre apenas "ramo atual", mas acho idiota pedir uma versão "qualquer ramo" dessa pergunta, então decido postar aqui de qualquer maneira.
Você pode obter esse erro em 2 casos 1. Quando o <nome da filial> fornecido não contiver o <ID de confirmação> 2. O checkout <nome da filial> não é o <nome da filial>
especificado
0
Como esta pergunta tem algumas respostas legais, estou adicionando meus favoritos.
Este mostrará a você, para os últimos $ncommits nos $brquais os branches contêm cada um:
git merge-base --is-ancestor
. O ramo de corrente contém C , se C é um antepassado deHEAD
, assim:if git merge-base --is-ancestor $hash HEAD; then echo I contain commit $hash; else echo I do not contain commit $hash; fi
/bin/true
foi originalmente implementado comoexit 0
e/bin/false
comoexit 1
. (Conchas modernos têm, em seguida, construído em.)Respostas:
Existem várias maneiras de alcançar esse resultado. A primeira opção ingênua é usar
git log
e procurar um commit específico usandogrep
, mas isso nem sempre é precisoÉ melhor usar
git branch
diretamente para encontrar todos os ramos que contêm dadosCOMMIT_ID
usandoO próximo passo é descobrir o ramo atual que pode ser feito desde o
git 1.8.1
usoE combinados juntos como
Mas o comando acima não retorna verdadeiro ou falso e existe uma versão mais curta que retorna o código de saída 0 se a confirmação estiver na ramificação atual OU o código de saída 1 se não houver
O código de saída é bom, mas como você deseja string
true
oufalse
resposta, você precisa adicionar um pouco mais e, em seguida, combinado com oif
bash, obtémfonte
grep
poderia resultar em falsos positivos segit log
mencionar o SHA de confirmação por outros motivos, por exemplo, é mencionado em uma mensagem de confirmação como resultado de uma porta de outra ramificação.--format=format:%H
agit log
.Obtenha uma lista de ramificações que contêm o commit específico.
Verifique se uma ramificação possui o commit específico.
Pesquise o ramo (digamos
feature
) com a correspondência exata .por exemplo, se você tem 3 filiais locais chamados
feature
,feature1
,feature2
em seguida,Você também pode pesquisar em ramos
local
eremote
(uso-a
) ou apenas emremote
ramos (uso-r
).fonte
grep
aqui também pode resultar em falsos positivos se houver outros ramos que contenham o commit cujos nomes também contenham<branch-name>
como substring.grep -E '(^|\s)branchname$'
-r
("remote") ou-a
("all")git branch
para procurar ramificações que podem não ser replicadas no repo clone local.git branch --all --contains <commit-id>
Comentário extraído por @torek como resposta:
Consulte a duplicata proposta para saber como encontrar todas as ramificações que contêm uma confirmação especificada.
Para descobrir se a ramificação atual contém confirmação C, use o comando "encanamento"
git merge-base --is-ancestor
. O ramo atual contém C se C é um ancestral de HEAD, portanto:(Observação: em scripts de shell, um comando que sai zero é "verdadeiro", enquanto um que sai diferente de zero é "falso".)
fonte
Para listar ramificações locais que contêm commit:
git branch --contains <commit-id>
e para listar todas as ramificações, incluindo apenas remotas, contendo commit:
git branch -a --contains <commit-id>
Da mesma forma, para verificar se o commit está em particular branch:
git log <branch> | grep <commit_id>
e se a filial não existir, prefixe localmente o nome da filial com
origin/
fonte
-a
. Obrigado por esse conselho!Sim outra alternativa:
Isso funciona melhor para mim, pois também funcionaria em ramificações remotas armazenadas em cache localmente, como
remotes/origin/master
, nas quaisgit branch --contains
não funcionará.Isso cobre mais do que a pergunta do OP sobre apenas "ramo atual", mas acho idiota pedir uma versão "qualquer ramo" dessa pergunta, então decido postar aqui de qualquer maneira.
fonte
Ele retornará o nome do ramo de destino se o ID de confirmação existir nesse ramo. Caso contrário, o comando falhará.
fonte
error: malformed object name 'branch-name'
Como esta pergunta tem algumas respostas legais, estou adicionando meus favoritos.
Este mostrará a você, para os últimos
$n
commits nos$br
quais os branches contêm cada um:Este é semelhante, mas faz o mesmo para uma lista de ramos:
fonte