Учитывая идентификатор фиксации, как определить, содержит ли текущая ветвь фиксацию?
156
Я пытаюсь проверить версию. Я хочу, чтобы код оставался поверх минимальной версии. Поэтому мне нужен способ узнать, содержит ли текущая ветвь указанный коммит.
Смотрите предложенный дубликат, чтобы узнать, как найти все ветви, которые содержат указанный коммит. Чтобы узнать, содержит ли текущая ветвь коммит C , используйте команду «plumbing» 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
Торек
1
Привет, пожалуйста, отправьте это как ответ, чтобы он мог быть выбран как правильный ответ =)
Бен
1
@Ben - я добавил это как ответ сообщества вики.
Цитракс
1
@Remover: в сценариях оболочки ноль равен true, ненулевой - false: обратная сторона соглашения C /bin/trueизначально был реализован как exit 0и /bin/falseкак exit 1. (Современные раковины затем встраивается.)
Торек
Ответы:
220
Есть несколько способов достижения этого результата. Первый наивный вариант заключается в использовании git logи поиске определенного коммита с использованием grep, но это не всегда точно
git log | grep <commit_id>
Вам лучше использовать git branchнапрямую, чтобы найти все ветви, содержащие данные, COMMIT_IDиспользуя
git branch --contains $COMMIT_ID
Следующим шагом является выяснение текущей ветви, которая может быть сделана, так как git 1.8.1 использования
Но приведенная выше команда не возвращает true или false, и существует более короткая версия, которая возвращает код выхода 0, если commit находится в текущей ветви ИЛИ код выхода 1, если нет
git merge-base --is-ancestor $COMMIT_ID HEAD
Выходной код это хорошо, но если вам нужна строка trueили falseответ, вам нужно добавить немного больше, а затем в сочетании с ifbash, вы получите
if [ 0 -eq $(git merge-base --is-ancestor $COMMIT_ID HEAD) ]; then echo "true"; else echo "false"; fi
Это не правильно; Это grepможет привести к ложным срабатываниям, если git logупомянуть SHA о коммите по другим причинам, например, это упоминается в сообщении о коммите как результат порта из другой ветви.
grepЗдесь также может привести к ложным срабатываниям , если есть другие ветви , содержащие коммит , чьи имена содержат в <branch-name>качестве подстроки.
Адам
1
Да @AdamSpiers, Обновлен ответ с точным соответствием имени ветвиgrep -E '(^|\s)branchname$'
Саджиб Хан
1
В соответствии с этим комментарием к связанному вопросу может быть полезно добавить опцию -r(«удаленный») или -a(«все») git branchдля поиска ветвей, которые не могут быть реплицированы в клоне локального репо.
sxc731
Это не сработало для меня, мне нужно было git branch --all --contains <commit-id>
Артур Такка
7
Извлеченный комментарий @torek в качестве ответа:
Смотрите предложенный дубликат, чтобы узнать, как найти все ветви, которые содержат указанный коммит.
Чтобы узнать, содержит ли текущая ветвь коммит C, используйте команду «plumbing» 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
(Примечание: в сценариях оболочки команда, которая выходит из нуля, имеет значение «истина», а команда, которая выходит из нуля, - «ложь».)
Это работает лучше всего для меня, так как это также будет работать на локально кэшированных удаленных ветвях, таких как remotes/origin/master, на которых git branch --containsне будет работать.
Это охватывает больше, чем вопрос OP о «текущей ветке», но я нахожу глупым задавать вариант «любой ветви» этого вопроса, поэтому я все равно решил разместить здесь.
Нету ...error: malformed object name 'branch-name'
bbodenmiller
1
Вы можете получить эту ошибку в 2 случаях: 1. Когда указанное <имя ветви> не содержит указанного <идентификатора фиксации> 2. Оформление <имя ветви> не является указанным <имя ветви>
DreamUth
0
Поскольку на этот вопрос есть несколько хороших ответов, я добавляю в избранное.
Этот покажет вам, для последних $nкоммитов, в $brкоторых каждый содержит ветки:
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
/bin/true
изначально был реализован какexit 0
и/bin/false
какexit 1
. (Современные раковины затем встраивается.)Ответы:
Есть несколько способов достижения этого результата. Первый наивный вариант заключается в использовании
git log
и поиске определенного коммита с использованиемgrep
, но это не всегда точноВам лучше использовать
git branch
напрямую, чтобы найти все ветви, содержащие данные,COMMIT_ID
используяСледующим шагом является выяснение текущей ветви, которая может быть сделана, так как
git 1.8.1
использованияИ объединены как
Но приведенная выше команда не возвращает true или false, и существует более короткая версия, которая возвращает код выхода 0, если commit находится в текущей ветви ИЛИ код выхода 1, если нет
Выходной код это хорошо, но если вам нужна строка
true
илиfalse
ответ, вам нужно добавить немного больше, а затем в сочетании сif
bash, вы получитеисточник
grep
может привести к ложным срабатываниям, еслиgit log
упомянуть SHA о коммите по другим причинам, например, это упоминается в сообщении о коммите как результат порта из другой ветви.--format=format:%H
кgit log
.Получить список ветвей, которые содержат конкретный коммит.
Проверьте, есть ли у ветки определенный коммит.
Искать ветку (скажем,
feature
) с точным соответствием .например , если у вас есть 3 -х местные ветви называются
feature
,feature1
,feature2
тоВы также можете искать в обоих
local
иremote
ветвей (использование-a
) или только вremote
ветви (использование-r
).источник
grep
Здесь также может привести к ложным срабатываниям , если есть другие ветви , содержащие коммит , чьи имена содержат в<branch-name>
качестве подстроки.grep -E '(^|\s)branchname$'
-r
(«удаленный») или-a
(«все»)git branch
для поиска ветвей, которые не могут быть реплицированы в клоне локального репо.git branch --all --contains <commit-id>
Извлеченный комментарий @torek в качестве ответа:
Смотрите предложенный дубликат, чтобы узнать, как найти все ветви, которые содержат указанный коммит.
Чтобы узнать, содержит ли текущая ветвь коммит C, используйте команду «plumbing»
git merge-base --is-ancestor
. Текущая ветвь содержит C, если C является предком HEAD, поэтому:(Примечание: в сценариях оболочки команда, которая выходит из нуля, имеет значение «истина», а команда, которая выходит из нуля, - «ложь».)
источник
Для просмотра локальных веток, содержащих коммит
git branch --contains <commit-id>
и перечислить все ветви, включая только удаленные, содержащие коммит:
git branch -a --contains <commit-id>
Аналогично, чтобы проверить, есть ли коммит в конкретной ветке:
git log <branch> | grep <commit_id>
и если ветвь не существует, локально префикс имени ветки с
origin/
источник
-a
. Спасибо за этот совет!Да, другая альтернатива:
Это работает лучше всего для меня, так как это также будет работать на локально кэшированных удаленных ветвях, таких как
remotes/origin/master
, на которыхgit branch --contains
не будет работать.Это охватывает больше, чем вопрос OP о «текущей ветке», но я нахожу глупым задавать вариант «любой ветви» этого вопроса, поэтому я все равно решил разместить здесь.
источник
Он вернет имя целевой ветви, если в этой ветви существует идентификатор фиксации. В противном случае команда потерпит неудачу.
источник
error: malformed object name 'branch-name'
Поскольку на этот вопрос есть несколько хороших ответов, я добавляю в избранное.
Этот покажет вам, для последних
$n
коммитов, в$br
которых каждый содержит ветки:Этот похож, но делает то же самое для списка филиалов:
источник