Як вказати ідентифікатор фіксації, як визначити, чи містить поточна гілка фіксацію?


156

Я намагаюся зробити перевірку версій. Я хочу забезпечити, щоб код залишався поверх мінімальної версії. Тому мені потрібен спосіб дізнатись, чи містить поточна гілка вказану комітку.



10
Див. Запропонований дублікат щодо того, як знайти всі гілки, які містять вказаний коміт. Щоб дізнатись, чи містить поточна гілка фіксацію С , скористайтеся командою "сантехніка" 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
torek

1
Привіт, будь ласка, подайте це як відповідь, щоб його можна було вибрати як правильну відповідь =)
Бен

1
@Ben - я додав це як відповідь у вікі спільноти.
Zitrax

1
@Remover: у скриптах оболонки нуль є істинним, ненульове значення - помилковим: зворотний бік конвенції 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використання

git symbolic-ref --short HEAD

І разом поєднані як

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

Але наведена вище команда не повертає true чи false, і є більш коротка версія, яка повертає код виходу 0, якщо фіксація знаходиться в поточній гілці АБО код виходу 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

9
Це не правильно; це grepможе призвести до помилкових позитивних результатів, якщо git logзгадується про комісію SHA з інших причин, наприклад, це згадується у повідомленні про фіксацію як результат порту з іншої гілки.
Адам Шпіерс

1
Виправлено (вірніше, додано інший варіант).
JiriS

3
Будь ласка, дивіться коментар до питання, в якому використовується вбудований набір інструментів git. stackoverflow.com/questions/43535132/…
Бен

2
Я , як перший варіант, але , щоб виключити заперечення Адама, я хотів би додати опцію --format=format:%Hдо git log.
PJSCopeland

71

Отримайте список філій (ів), що містять конкретні коміти.

# 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$'

1
grepТут також може привести до помилкових спрацьовувань , якщо є інші гілки , що містять Комміт , чиї імена містять в <branch-name>якості підрядка.
Адам Шпіерс

1
Так @AdamSpiers, оновив відповідь точною відповідністю назвою філії відgrep -E '(^|\s)branchname$'
Саджіб Хан

1
Відповідно до цього коментаря до пов'язаного питання, може бути корисним додати параметр -r("віддалений") або -a("всі"), git branchщоб шукати гілки, які не можуть бути повторені в локальному клоні репо.
sxc731

Це не спрацювало для мене, мені потрібно git branch --all --contains <commit-id>
Артур Такка

7

Витягнутий коментар від @torek як відповідь:

Див. Запропонований дублікат щодо того, як знайти всі гілки, які містять вказаний коміт.

Щоб дізнатись, чи містить поточна гілка фіксацію С, скористайтеся командою "сантехніка" 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

(Побічна примітка: в скриптах оболонки команда, яка виходить з нуля, є "true", тоді як у випадку, що виходить з нуля, є "false".)


4

Щоб перелічити місцеві відділення, що містять коміти:

git branch --contains <commit-id>

і перелічити всі гілки, включаючи лише віддалені, що містять фіксацію:

git branch -a --contains <commit-id>

Аналогічно, щоб перевірити, чи виконувати комісію в конкретній галузі:

git log <branch> | grep <commit_id>

і якщо відділення не існує локального префіксу, назва гілки з origin/


Голосували за зауваження о -a. Дякую за ту пораду!
Thorkil Værge

3

Так, ще одна альтернатива:

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

Це найкраще працює для мене, оскільки він також буде працювати на локально кешованих віддалених гілках, таких як remotes/origin/master, на яких git branch --containsне буде працювати.

Це охоплює більше, ніж питання ОП про лише "поточну галузь", але мені здається, що це нерозумно задавати "будь-яку галузь" версію цього питання, тож я все-таки вирішу публікувати тут.


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

Він поверне ім'я цільової гілки, якщо ідентифікатор комісії існує в цій гілці. Інакше команда не вдасться.


nope ...error: malformed object name 'branch-name'
bbodenmiller

1
Ви можете отримати цю помилку у 2 випадках 1. Коли вказане <ім'я гілки> не містить вказаного <ідентифікатор фіксації> 2. Замовлення <ім'я гілки> не дане <ім'я філії>
DreamUth

0

Оскільки на це запитання є кілька приємних скрипт-відповідей, я додаю своїх улюблених.

Це покаже вам, для останніх $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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.