Проверить, существует ли фиксация

Как проверить, существует ли фиксация с данным sha в текущей ветке?

Есть много способов синтаксического анализа выходных данных, но мне нужен оптимальный способ, который возвращает логическое значение (для использования в сценарии bash).

e.g.

sha=$1
if [ -z `git magic --validate $sha` ]; then
  echo "Invalid commit sha: $sha"
  exit 1
fi

person takeshin    schedule 08.11.2010    source источник
comment


Ответы (6)


Метод rev-list | grep работает нормально; есть крошечные накладные расходы, потому что git должен распечатать все SHA1, чтобы grep мог их увидеть, но на самом деле это не имеет большого значения.

Вы также можете сделать это с помощью git merge-base, если хотите - если база слияния целевой фиксации и ветка является целевой фиксацией, ветвь будет содержать целевую фиксацию:

if [ "$(git merge-base $commit $branch)" = "$commit" ]; then
    ...
fi

В любом случае обратите внимание, что rev-list и merge-base будут распечатывать SHA1, поэтому, если коммит, который вы тестируете для включения, назван веткой или тегом, вы захотите использовать git rev-parse, чтобы превратить его в SHA1 первый.

person Cascabel    schedule 08.11.2010
comment
Небольшое примечание: оператор равенства строки POSIX - =, а не ==. bash в любом случае примет оба. - person Sven Marnach; 10.11.2010
comment
@Sven: Спасибо, я всегда об этом забываю. - person Cascabel; 10.11.2010
comment
Для небольшой оптимизации полезно использовать git rev-list -qn1 <commit> 2>/dev/null, который не будет проходить через все дерево фиксации и завершится с ненулевым кодом выхода, если данная фиксация не существует. - person nvie; 15.11.2012
comment
@nvie Если вы пытаетесь проверить существование фиксации, я думаю, что каноническим способом является git rev-parse --quiet --verify <commit>. - person Cascabel; 15.11.2012

git rev-parse --quiet --verify <commit>

Фактически не проверяет, существует ли фиксация (я предполагаю, что имеется в виду SHA1). Он проверяет наличие объекта в базе данных, соответствующего предоставленному SHA1. То есть, если есть объект blob или дерева, который соответствует SHA1, он сообщит, что он существует, даже если это не фиксация.

git rev-parse --quiet --verify <sha1>^{commit}

Это подтвердит, что объект существует и что это объект, который можно использовать как фиксацию (фиксация или аннотированный тег).

person Janne    schedule 19.02.2014
comment
Но это не ограничивает выводы текущей веткой, как того требует OP. - person sschuberth; 27.02.2017

Вы можете посмотреть результат

git rev-list HEAD..$sha

Если эта команда завершится неудачно, потому что sha1 вообще не существует в репозитории, код выхода будет отличным от нуля. Если вывод пуст, фиксация находится в текущей ветке, а если она не пуста, это не так. Итак, ваш сценарий будет выглядеть так

if revlist=`git rev-list HEAD..$sha 2>/dev/null` && [ -z "$revlist" ]; then
    :
fi

Если вы уже знаете, что $sha действительно называет фиксацию (как хэш SHA1 или как-то иначе), это упрощает

if [ -z "`git rev-list HEAD..$sha`" ]; then
    :
fi
person Sven Marnach    schedule 08.11.2010

git cat-file печатает информацию об объектах в репозитории. "-e" проверяет, действителен ли объект и завершает работу со статусом 0, а когда недопустимый существует, с 1.

git cat-file -e 3d68db1028afe27a0055c2234f98fc945b1958f5
echo $?
1
person Earle    schedule 18.08.2015

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

Это проверяет, является ли $sha фиксацией предка для текущей ветки (HEAD), и успешно завершает работу, если это так.

В вашем примере

sha=$1
if ! git merge-base --is-ancestor $sha HEAD; then
  echo "Invalid commit sha: $sha"
  exit 1
fi
person Paul Draper    schedule 07.09.2015
comment
Эта опция доступна, начиная с Git 1.9.0. - person Palec; 08.09.2015
comment
Верный. На момент написания этой статьи v1.9 существовала около полутора лет. - person Paul Draper; 08.09.2015
comment
Debian имеет двухлетний цикл выпуска, и, как ни странно, старая стабильная версия нередко используется в производственной среде. Вот почему я считаю необходимым указать версию Git, в которую была включена эта функция. - person Palec; 08.09.2015

git rev-list branch-youre-interested-in | grep -q sha-youre-interested-in

Вы можете использовать код выхода из grep в условных выражениях.

Для текущей ветки

 git rev-list HEAD | grep -q sha-youre-interested-in
person Ken Bloom    schedule 08.11.2010