git post commit hook - сторона сервера - PullRequest
0 голосов
/ 21 октября 2018

Мне нужно запустить обработчик git на стороне сервера после коммита, который должен был проверить si, чтобы проверить, произошло ли слияние, и выполнить некоторую автоматизацию, если было слияние.

Я попытался использовать git reflog -1, и этоотлично работает, но только на стороне клиента.

Я также пытался реализовать хук после слияния, но это не сработало.

когда я запускаю git reflog -1 на стороне сервера, я не получаю вывод.

есть идеи, как мне этого добиться?

1 Ответ

0 голосов
/ 21 октября 2018

Комментарий ElpieKay имеет ключ к ответу, но стоит немного подробнее.Поскольку сервер на самом деле не выполнял git commit, вы должны использовать ловушку после получения, чтобы следить за обновлениями ссылок.К сожалению, зацепки после получения не просты.Вот простой полезный каркас, выраженный в оболочке POSIX:

#! /bin/sh
# sample post-receive hook

# return true if the argument ($1) is the null hash (all-0s)
is_nullhash() {
    expr "$1" : '0*$' >/dev/null
}

while read oldhash newhash ref; do
    # If the old hash is all 0s, the reference was just created.
    # If the new hash is all 0s, the reference was just deleted.
    # Otherwise, the reference was updated, from $oldhash to $newhash.
    if is_nullhash $oldhash; then
        op=create
    elif is_nullhash $newhash; then
        op=delete
    else
        op=update
    fi

    # If the reference begins with refs/heads/, the rest of it is
    # a branch name.  If it starts with refs/tags, the rest is a tag.
    # Otherwise it's some other type of reference (not decoded here).
    case $ref in
    refs/heads/*) reftype=branch; shortref=${ref#refs/heads/};;
    refs/tags/*) reftype=tag; shortref=${ref#refs/tags/};;
    *) reftype=other; shortref=$ref;;  # NB: not shortened!
    esac

     ... insert code here ...
done

Код, указанный в разделе «вставить код здесь», должен:

  • определить, является ли этоэто операция, о которой вы заботитесь
  • , если это так, решите, что делать, основываясь на типе операции

Например, если вы хотите специально наблюдать толчок к master только:

if [ $reftype = branch -a $shortref = master ]; then
    if [ $op = update ]; then
        handle_master_update $oldhash $newhash
    else
        ... do something different if the op is create or delete ...
    fi
fi

, где handle_master_update - ваша функция для обновления до master.Если вы не хотите обрабатывать создание и удаление ветки master, вы можете еще больше упростить это до:

case $ref,$op in
refs/heads/master,update) handle_master_update $oldhash $newhash;;
esac

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

Теперь мы переходим к сути обработки обновлений:

# Do something with update to master branch.
# The old hash is $1 and the new hash is $2,
# so commits in $1..$2 now appear on `master` but
# were not part of `master` before (they may have
# been on some other branch, and may still be).
# Meanwhile, commits in $2..$1 used to be on `master`
# but have just been removed via force-push.  If this
# list is empty, the push did not have to be forced,
# and maybe was not.
handle_master_update() {
    local rev parents
    git rev-list $2..$1 | while read rev; do ...; done  # deal with removed commits

    git rev-list --parents $1..$2 | while read rev parents; do
        ...
    done
}

Первый раздел (посвященный удаленным коммитам), конечно, не является обязательным.Во втором разделе вы хотели обнаружить слияния, поэтому мы используем git rev-list (не git log - здесь более полезна рабочая лошадка), чтобы перечислить все добавленные коммиты вместе с их родительскими хэш-идентификаторами..read помещает все родительские хеши в переменную parents, поэтому мы можем легко сосчитать их в разделе ....Например:

        set -- $parents
        case $# in
        0) ...;; # $rev is a root commit
        1) ...;; # $rev is an ordinary commit
        *) ...;; # $rev is a merge, its parents are $1, $2, ... through $#
        esac

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

A--B--C   <-- master

до:

A--B--C--D--H   <-- master
           /
F---------G

В git rev-list, заданном C..H (ну, их хэш-идентификаторы), будут перечислены H, D, G и F в некоторыхпорядок.Хеш для H будет первым, но все после этого зависит от любых параметров сортировки, которые вы предоставляете для git rev-list.Используйте --topo-order, чтобы гарантировать получение топологической сортировки, если это важно для работы вашего кода (например, вам может потребоваться --reverse --topo-sort, чтобы всегда работать вперед , получая одно из D, F, G, Hили F, G, D, H в качестве входных данных).

Обратите внимание, что если вы используете POSIX-совместимый sh для реализации своей ловушки, то раздражает git rev-list ... | while read ...: цикл while выполняется в подоболочкеЭто означает, что любые переменные, установленные здесь, теряются при выходе из цикла.Вы можете обойти это несколькими способами;см. Дилемма подобъекта цикла цикла в Bash .

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