Можете ли вы изменить содержимое файла во время git commit?
Одна из вещей, которые я храню в своем открытом романе в GitHub, - это список слов, которые я хотел бы автоматически задать в первой строке, то есть количество слов в словаре. Мой первый вариант - написать хук перед фиксацией, который читает файл, считает слова, переписывает первую строку и записывает обратно. Вот код
PRE_COMMIT {
my ($git) = @_;
my $branch = $git->command(qw/rev-parse --abbrev-ref HEAD/);
say "Pre-commit hook in $branch";
if ( $branch =~ /master/ ) {
my $changed = $git->command(qw/show --name-status/);
my @changed_files = ($changed =~ /\s\w\s+(\S+)/g);
if ( $words ~~ @changed_files ) {
my @words_content = read_file( $words );
say "I have $#words_content words";
$words_content[0] = "$#words_content\n";
write_file( $words, @words_content );
}
}
};
Тем не менее, так как файл уже был поставлен, я получаю эту ошибку
ошибка: ваши локальные изменения в следующих файлах будут перезаписаны извлечением: text / words.dic Пожалуйста, передайте изменения или сохраните их, прежде чем вы сможете переключать ветки. Aborting
Может быть, лучше сделать это как хук после коммита, и изменился ли он для следующего коммита? Или сделать что-то совершенно другое? Общий вопрос: если вы хотите обрабатывать и изменять содержимое файла во время коммита, каков правильный способ сделать это?
2 ответа
Фактический коммит застрял в git commit
это то, что находится в индексе после завершения ловушки предварительной фиксации. Это означает, что вы можете изменять файлы в хуке предварительной фиксации, пока вы git add
их тоже.
Вот мой пример ловушки pre-commit, модифицированный из.sample:
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# [snipped much of what used to be in it, added this --
# make sure you take out the exec of git diff-index!]
num=$(cat zorg)
num=$(expr 0$num + 1)
echo $num > zorg
git add zorg
echo "updated zorg to $num"
exit 0
а потом:
$ git commit -m dink
updated zorg to 3
[master 76eeefc] dink
1 file changed, 1 insertion(+), 1 deletion(-)
Но обратите внимание на небольшой недостаток (не относится к вашему делу):
$ git commit
git commit
updated zorg to 4
# On branch master
# Untracked files:
[snip]
nothing added to commit but untracked files present (use "git add" to track)
$ git commit
updated zorg to 5
# Please enter the commit message for your changes. Lines starting
[snip - I quit editor without changing anything]
Aborting commit due to empty commit message.
$ git commit
updated zorg to 6
# Please enter the commit message for your changes. Lines starting
В основном, потому что обновления pre-commit hook и git add
s, файл продолжает увеличиваться, хотя я на самом деле не делаю коммит здесь.
Оказывается, вы можете запускать "крючки" - они фактически обрабатываются другим механизмом - при размещении файлов (в git add
время):
https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes
(прокрутите немного вниз к диаграмме "smudge / clean")
Вот что я понял:
редактировать
.gitattributes
и создайте правила для файлов, которые должны запускать обновление словаря:novel.txt updateDict
Затем скажите Git, что делает фильтр "updateDict" для smudge (git checkout) и clean (git add):
$ git config --global filter.updateDict.clean countWords.script
$ git config --global filter.updateDict.smudge cat