Как да добавите файл към индекса в git pre-commit hook

Огледах се за дубликати и въпреки че някои от тях имат подобни заглавия, не намерих никой да има същия проблем като мен, така че ето.

Написах скрипт, който работи на 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
Можете ли да разкажете повече за това? Потърсих малко в Google и намерих малко информация за 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