Учитывая идентификатор фиксации, как определить, содержит ли текущая ветвь фиксация?

То, что я пытаюсь сделать, это проверка версии. Я хочу, чтобы код оставался на вершине минимальной версии. Таким образом, мне нужен способ узнать, содержит ли текущая ветвь указанная фиксация.

Ответ 1

Есть несколько способов достижения этого результата. Первый наивный вариант - использовать git log и искать конкретный коммит, используя grep, но это не всегда точно

git log | grep <commit_id>

Вам лучше использовать git branch напрямую, чтобы найти все ветки, содержащие данный COMMIT_ID, используя

git branch --contains $COMMIT_ID

Следующим шагом является поиск текущей ветки, которую можно сделать, начиная с git 1.8.1, используя

git symbolic-ref --short HEAD

И объединены вместе как

git branch $(git symbolic-ref --short HEAD) --contains $COMMIT_ID

Но приведенная выше команда не возвращает true или false, и существует более короткая версия, которая возвращает код выхода 0, если commit находится в текущей ветки, ИЛИ код выхода 1, если нет

git merge-base --is-ancestor $COMMIT_ID HEAD

Выходной код - это хорошо, но если вы хотите использовать строку true или false в качестве ответа, вам нужно добавить немного больше, а затем объединить с if из bash, и вы получите

if [ 0 -eq $(git merge-base --is-ancestor $COMMIT_ID HEAD) ]; then echo "true"; else echo "false"; fi

Ответ 2

Получить список ветвей, которые содержат конкретный коммит.

# get all the branches where the commit exists
$ git branch --contains <commit-id>

Проверьте, есть ли у ветки конкретный коммит.

# output the branch-name if the commit exists in that branch
$ git branch --contains <commit-id> | grep <branch-name>

Поиск ветки (скажем, feature) с точным соответствием.

$ git branch --contains <commit-id> | grep -E '(^|\s)feature$'

Например, если у вас есть 3 локальных ветки, которые называются feature, feature1, feature2 то

$ git branch --contains <commit-id> | grep 'feature'

# output
feature
feature1
feature2

$ git branch --contains <commit-id> | grep -E '(^|\s)feature$'

# output
feature     

Вы также можете выполнять поиск как в local и в remote ветвях (используйте -a) или только в remote ветвях (используйте -r).

# search in both 'local' & 'remote' branches  
$ git branch -a --contains <commit-id> | grep -E '(^|\s)feature$'

# search in 'remote' branches  
$ git branch -r --contains <commit-id> | grep -E '(^|\s)feature$'

Ответ 3

Извлеченный комментарий @torek в качестве ответа:

См. предлагаемый дубликат, чтобы узнать, как найти все ветки, содержащие указанный коммит.

Чтобы выяснить, содержит ли текущая ветвь коммит C, используйте команду "сантехника" git merge-base --is-ancestor. Текущая ветвь содержит C, если C является предком HEAD, поэтому:

if git merge-base --is-ancestor $hash HEAD; then
    echo I contain commit $hash
else
    echo I do not contain commit $hash
fi

(Примечание: в сценариях оболочки команда, которая выходит из нуля, имеет значение "истина", а команда, которая выходит из ненулевого значения, - "ложь".)

Ответ 4

Да, другая альтернатива:

git rev-list <branch name> | grep 'git rev-parse <commit>'

Это работает лучше всего для меня, поскольку оно также будет работать с локально кэшированными удаленными ветвями, такими как remotes/origin/master, на которых не работает git branch --contains.

Это охватывает больше, чем просто вопрос об "текущей ветке", но я нахожу глупым задавать вариант "любой ветки" этого вопроса, поэтому я все равно решаю опубликовать здесь.

Ответ 5

git branch --contains <commit-id> --points-at <target branch name>

Он вернет имя целевой ветки, если в этой ветки существует идентификатор фиксации. В противном случае команда потерпит неудачу.

Ответ 6

Поскольку на этот вопрос есть несколько хороших ответов, я добавляю свои любимые.

Этот покажет вам, за последние $n коммитов в $br ветвях которых есть каждый:

br=mybranch
n=10
git log --oneline -n$n $br | awk '{print; system("git branch --contains "$1)}'

Этот похож, но делает то же самое для списка веток:

br="mybranch yourbranch herbranch"
n=4
for br in $brs; do git log --oneline -n$n $br | awk '{print; system("git branch --contains "$1)}'; done