Запуск перехвата после команды "git checkout -b"

Один и тот же вопрос задавался здесь раньше, однако оба ответа мне не сильно помогли.

Я не мог получить post-checkout крюк, чтобы отличаться git checkout от git checkout -b команда как $1 (sha1 предыдущей HEAD) и $2 (sha1 новой HEAD) одинаковы для обоих вызовов.

Вот мой сценарий после оформления заказа:

#!/bin/bash

echo "old HEAD: $1"
echo "new HEAD: $2"
echo "checkout type: $3"

Я выполнил следующие команды:

> ozgur@ozgurv:~/project (master)$ git checkout -b new_branch
old HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
new HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
checkout type: 1

> ozgur@ozgurv:~/project (new_branch)$ git checkout my_branch
old HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
new HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
checkout type: 1

То, что я пытаюсь достичь, это выполнить логику в post-checkout перехватывать только при создании новой локальной ветки, а не при ее извлечении.

1 ответ

Решение

Вы не можете заметить разницу в крючке после оформления заказа. 1 В любом случае вы можете не захотеть пытаться заметить разницу. Рассматривать:

$ git branch newbr     # make a new branch
$ git checkout newbr   # and now check it out

Вероятно, имеет смысл делать то, что вы бы сделали для git checkout -b newbr здесь, и если это так, проверка на -b Флаг (если вы можете заставить его работать), вероятно, контрпродуктивно. (Рассмотрим также git checkout feature когда origin/feature существует и местный филиал feature нет, что создает feature как новая ветка, которая отслеживает origin/feature хотя опять нет -b флаг.)

Давайте посмотрим на это еще раз, и я предложу другой подход:

только когда создается новая локальная ветка

Что если в вашем хуке вы сохранили список "всех увиденных до сих пор локальных ветвей", сохраненных в файле? (Может быть, .git/ozgur/branchlist было бы разумным местом, чтобы сохранить это. Мы хотим что-то, что следует за репозиторием, которое вряд ли будет использовать сам git.) Затем, если извлечение является извлечением в стиле ветки ($3 является 1), сравните текущую ветку со списком:

git_dir=$(git rev-parse --git-dir) || exit 1
branchlist=$git_dir/ozgur/branchlist
if [ "$3" = 1 ]; then
    # Checked out a branch - what branch are we on now?
    # (Skip rest of code if we're on a detached HEAD.)
    curbranch=$(git symbolic-ref --short HEAD) || return
    # Is $curbranch in our branch list?  Create empty
    # branch list first if needed.  Can just "touch" but
    # this avoids changing the mod-time unnecessarily.
    [ -f $branchlist ] || : > $branchlist
    if ! grep "^$curbranch$" $branchlist > /dev/null; then
        echo "switching to as-yet-unvisited-branch $curbranch"
        echo $curbranch >> $branchlist  # now we've visited it
    fi
fi

Это все еще имеет небольшой недостаток: если вы удалите ветку, она может остаться в файле списка ветвей. Мы могли бы исправить это, отфильтровывая удаленные ветви довольно регулярно (сравните $branchlist содержание, чтобы соответствовать git for-each-ref refs/heads вывод), возможно, в дополнительных git-хуках. Но это может быть достаточно для ваших целей как есть.


На самом деле, есть способ рассказать, по крайней мере, о системах, которые позволят вам взглянуть на дерево процессов и посмотреть на аргументы их команд. С крючка найдите своего родителя git checkout обработать и посмотреть, есть ли у него -b флаг. Но тогда это не работает на двухступенчатом git branch ...; git checkout Последовательность, ни на ветвях, автоматически созданных из восходящей ветки.

Другие вопросы по тегам