Как я могу определить, существует ли данный git-хеш в данной ветви? - PullRequest
38 голосов
/ 15 марта 2010

Справочная информация: я использую автоматизированную систему сборки, которая принимает git-хэш в качестве входных данных, а также имя ветви, в которой существует этот хэш, и создает ее. Однако система сборки использует только хэш для проверки кода и его сборки - она ​​просто сохраняет имя ветви, как указано, в метаданных БД сборки.

Я беспокоюсь о том, что разработчики случайно указали неправильное имя ветки при запуске сборки, что вызывает путаницу, когда люди просматривают историю сборки.

Так, как я могу подтвердить, перед передачей имени хеша и ветви в систему сборки, что данный хеш действительно происходит из данной ветви?

Ответы [ 3 ]

120 голосов
/ 15 марта 2010

Вы можете напрямую спросить git branch, в каких ветвях содержится данный коммит:

% git branch -a --contains 4f08c85ad
* master
  remotes/origin/bug_872
  remotes/origin/bug_898
  remotes/origin/master
8 голосов
/ 15 марта 2010

Хм, это использование названия ветви кажется подозрительным. Как и в ответе Дастина, может быть несколько веток, содержащих коммит. Почему одно из этих названий веток лучше, чем другое для этой цели?


Если вам нужна только одна конкретная ветка, вы можете вычислить «базу слияния» между веткой и коммитом.

На следующих рисунках коммит для сборки равен C, кончик заявленной ветви - T, а основание объединения помечено M над ним.

  • Если M равно C равно T, то коммит для сборки является верхушкой заявленной ветви.

                   M
                   ↓
    o--o--o--o--o--x  branch  # x is both C and T
    
  • Если M равно C, то верхушка заявленной ветви является потомком коммита для сборки.

          M
          ↓
    o--o--C--o--o--T  branch
    
  • Если M равно T, то обязательство по созданию является потомком вершины заявленной ветви.

          M
          ↓
    o--o--T           branch
           \
            o--o--C
    
  • Если M равно чему-то другому, то C является потомком какого-то предка T.

          M
          ↓
    o--o--o--o--o--T  branch
           \
            o--o--C
    
  • Если нет M, то фиксация для сборки не связана с заявленной веткой.

    o--o--o--o--o--T branch
    
    o--o--o--o--C
    

Вы можете сделать эту проверку следующим образом:

#!/bin/sh

# Usage: is-ancestor-of <branch> <commit>

if test $# -ne 2; then
    echo "$0"': invalid arguments'
    exit 128
fi
claimed_branch="$1"
commit="$2"

merge_base="$(git merge-base "$commit" "$claimed_branch")" &&
  test -n "$merge_base" &&
  test "$merge_base" = "$(git rev-parse --verify "$commit")" &&
  exit 0

echo "$commit is not an ancestor of $claimed_branch" 1>&2
exit 1

Приведенный выше скрипт на самом деле не требует и не проверяет, является ли аргумент «ветвь» ветвью (это может быть любой коммит). Чтобы проверить, что что-то действительно является веткой, вы можете использовать что-то вроде этого:

#!/bin/sh

# Usage: is-branch <branch>

if test $# -ne 1; then
    echo "$0"': invalid arguments'
    exit 128
fi
branch="$1"

# check various branch hierarchies, adjust as needed
git show-ref --verify refs/heads/"$branch" ||
git show-ref --verify refs/remotes/"$branch" || {
    echo "not a branch name: $branch" 1>&2
    exit 1
}

Таким образом, вы можете использовать их вместе, чтобы убедиться, что что-то является ветвью и что в этой ветке находится определенный коммит:

is-branch "$claimed_branch" && is-ancestor-of "$claimed_branch" "$commit_to_build"
1 голос
/ 15 марта 2010

Одним из возможных нерешений будет разбор результата:

$ git reflog show myBranch

и посмотрите, есть ли в нем ваш хэш.

C:\Prog\Git\tests\rep\main>git reflog show patches
786a190 patches@{0}: rebase finished: refs/heads/patches onto 74630b983db476c323b1d3f6771e57484551240e
8448d0f patches@{1}: master~1: updating HEAD
74630b9 patches@{2}: commit: test2
1e73e36 patches@{3}: branch: Created from master

Я оставляю это как ответ сообщества Wiki, чтобы запомнить Игорь Зевака и Крис Джонсен комментарии:

Будет ли это работать после клона?
Уверен, ваш reflog начинается после того, как вы клонируете пульт. Таким образом, если ветка имела коммит до клона, он не будет отображаться в журнале ссылок.

Существуют также проблемы с выталкиванием, перебазированием, извлечением (для «удаленного отслеживания» ветвей) и извлечением (слияние или перебазирование), когда только новый коммит с подсказкой завершает рефлог.
Также рефлоги по умолчанию отключены в пустых репозиториях (наиболее распространенное назначение для толчков).
Кроме того, если «мошенничество» является проблемой, это просто вопрос редактирования текстового файла, чтобы добавить или удалить записи reflog, но это более сложное изменение самого графа истории.

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