Как добавить файл в индекс в ловушке git pre-commit

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

Я написал сценарий, который запускается на 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 не изменяются, поэтому я не могу просто добавить их перед этим. Я также знаю, что могу выйти из ловушки с ненулевым статусом, поэтому фиксация отменяется, но файлы добавляются, но я надеюсь этого избежать. Есть идеи получше?


person Jimmy Sawczuk    schedule 24.02.2012    source источник


Ответы (4)


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

person plaugg    schedule 03.03.2012
comment
Поскольку файлы CSS не являются двоичными файлами, это просто статические текстовые файлы. Сгенерированные файлы не помещаются в систему контроля версий, потому что они обычно вызывают конфликты слияния, когда у вас действительно нет хорошего способа их разрешить (двоичные файлы), но для файлов CSS такая проблема возникает редко. Я не хотел устанавливать LESS-компилятор на наших веб-серверах, чтобы делать это после слияния / обновления. Однако, несмотря на все сказанное, это оказался более простой способ выполнить то, что я пытался сделать, хотя он и не был идеальным. - person Jimmy Sawczuk; 04.03.2012
comment
Почему это принятый ответ? Это вообще не решает проблемы. - person frhd; 01.10.2014
comment
Думаю, он принял мой отказ от вашего ответа, потому что в этом случае он решил его проблему (возможно, не ответив на его вопрос). Если он в первую очередь не проверит файлы LESS, проблема с фиксацией исчезнет. - person plaugg; 15.10.2014

Я не могу воспроизвести вашу проблему. Мое первоначальное предположение заключалось в том, что переменная среды 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 завершит работу с ошибкой.

person Richard Hansen    schedule 28.02.2012
comment
Я запустил ваш скрипт, и он сработал, как ожидалось, в отличие от моего реального репозитория. Я подробнее рассмотрю это чуть позже и вернусь к вам, если я что-нибудь угадаю. Спасибо! - person Jimmy Sawczuk; 29.02.2012
comment
Назначил вам награду из-за усилий, хотя я все еще не мог понять, что происходит. Спасибо еще раз! - person Jimmy Sawczuk; 04.03.2012

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

person jarodeells    schedule 26.02.2012
comment
Не могли бы вы подробнее рассказать об этом? Я немного погуглил и нашел некоторую информацию об атрибутах Git, но ничего о том, как прикрепить к ним скрипт или как можно разместить атрибут add. - person Jimmy Sawczuk; 27.02.2012

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

person Xobb    schedule 27.02.2012
comment
Я рассматривал этот вариант, но надеюсь его избежать. Он включает в себя выполнение фиксации, запуск ловушки, затем завершение исходной фиксации, а затем запуск второй фиксации (если я чего-то не упускаю), что кажется сложным для выполнения вручную и своего рода нелепым делать автоматически с использованием хуков. - person Jimmy Sawczuk; 27.02.2012
comment
Хотя, когда он автоматически запускается крючком, он будет выполнять свою работу безупречно. - person Xobb; 28.02.2012