Как добавить файл в индекс с помощью git pre-commit hook - PullRequest
16 голосов
/ 24 февраля 2012

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

Я написал скриптработает на pre-commit и использует вывод git status --porcelain для компиляции любого файла LESS в моем проекте, который изменился.Эта часть отлично работает.Но я хочу, чтобы файлы .css были включены в текущий коммит.Таким образом, в дополнение к запуску компилятора, мой скрипт запускает git add <filename>.И вот тут все становится сложнее.

Файл добавляется к индексу , но это не индекс текущего коммита.Поэтому, если я изменю style.less и запусту git commit -a (или вручную git add style.less), компилятор должен сгенерировать style.css и style.min.css и добавить их в текущий коммит.Но я заметил, что поведение фиксируется только style.less, несмотря на то, что два файла .css добавляются в индекс для следующей фиксации.

Поэтому мой вопрос: есть ли способ добавить файлы?сделать коммит в хуке предварительной фиксации, чтобы он вступил в силу для этой фиксации?Обратите внимание, что до запуска ловушки перед фиксацией эти два файла .css не изменяются, поэтому я не могу просто добавить их до этого.Я также знаю, что могу выйти из ловушки с ненулевым статусом, поэтому коммит отменяется, но файлы добавляются, но я надеюсь избежать этого.Есть идеи получше?

Ответы [ 4 ]

12 голосов
/ 28 февраля 2012

Я не могу воспроизвести вашу проблему.Первоначально я предполагал, что переменная окружения GIT_INDEX_FILE была отменена вашей pre-commit ловушкой.Однако, когда я попытался сбросить GIT_INDEX_FILE с pre-commit, у меня возникла другая проблема (Git пожаловался, что .git/index заблокирован).

Вот пример сценария, который показывает, что Git функционирует так, как вы ожидаете, и что-тоостальное должно быть не так.Этот скрипт инициализирует новый тестовый репозиторий, создает хук pre-commit, который имитирует то, что делает ваш хук, и делает несколько тестовых коммитов:

#!/bin/sh

# initialize the test repository
rm -rf testrepo
git init testrepo
cd testrepo

# create the pre-commit hook
cat <<\EOF >.git/hooks/pre-commit
#!/bin/sh
git status --porcelain | while IFS= read -r line; do
    # todo: handle renames and deletions of a *.less file
    f=${line#???}
    case ${f} in
        *.less)
            fb=${f%.less}
            echo bar >>"${fb}".css
            echo baz >>"${fb}".min.css
            git add "${fb}".css "${fb}".min.css
            ;;
    esac
done
EOF
chmod +x .git/hooks/pre-commit

# create foo.less, commit it
echo foo >foo.less
git add foo.less
git commit -m "add foo.less"

# modify foo.less, commit it
echo foo2 >>foo.less
git commit -a -m "modify foo.less"

Если вы запустите git log -p в тестовом репозитории и посмотрите наВ результате коммитов вы увидите, что foo.css и foo.min.css изменялись при каждом изменении foo.less.

Вот почему я подумал, что ваша проблема была вызвана изменением / отменой установки переменной среды GIT_INDEX_FILE:

Когда запускается git commit -a, Git создает временный индексный файл и использует его вместо значения по умолчанию .git/index для создания фиксации.Чтобы операции типа git add работали из ловушки pre-commit, Git устанавливает переменную окружения GIT_INDEX_FILE в качестве имени временного индекса, созданного до запуска pre-commit.Если ваш хук сбрасывает GIT_INDEX_FILE или устанавливает его на .git/index, то все операции Git из вашего хука будут пытаться изменить исходный индекс, а не временный индекс, который используется для генерации фиксации.

Однако временный индексный файл также действует как блокировка исходного индексного файла.Если ловушка пытается изменить исходный индекс, а временный индекс существует, Git прервет работу с ошибкой.

0 голосов
/ 04 марта 2012

Почему вы хотите сделать это в первую очередь? Вы стараетесь включить сгенерированные файлы в систему управления версиями, что в общем-то не очень хорошая идея. Если вам нужно, чтобы style.min.css присутствовал при оформлении заказа, почему вы не можете сгенерировать его после оформления на этапе сборки?

0 голосов
/ 27 февраля 2012

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

0 голосов
/ 26 февраля 2012

Мне приходит в голову, что у вас может быть атрибут git 'clean', который будет скриптом, который обновляет сгенерированные файлы.Обычно этот хук может запустить скрипт, чтобы привести в порядок ваш исходный код, но я думаю, что он может быть использован для «очистки» вашего сгенерированного вывода.Этот атрибут срабатывает, когда вы делаете 'git add', и вы можете заставить скрипт сделать еще одну 'git add' для сгенерированного файла.

...