Можете ли вы изменить содержимое файла во время 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 =~ /sws+(S+)/g);
     if ( $words ~~ @changed_files ) {
       my @words_content = read_file( $words );
       say "I have $#words_content words";
       $words_content[0] = "$#words_contentn";
       write_file( $words, @words_content );
     }
   }
};

однако, так как файл уже был поставлен, я получаю эту ошибку

ошибка: локальные изменения в следующие файлы будут переписаны на кассе: текст/слова.ДВС-синдром Пожалуйста, внесите изменения или спрячьте их прежде чем вы сможете переключить ветви. Аборт

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

2 ответов


фактическая фиксация застряла в git commit - это то, что находится в индексе после завершения крючка предварительной фиксации. Это означает, что вы can изменение файлов в крючке предварительной фиксации, пока вы git add их тоже.

вот мой пример предварительной фиксации крючка, измененный из .пример:

#!/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 adds, файл продолжает увеличиваться, хотя я на самом деле не делаю фиксацию здесь.


оказывается, вы можете запустить "крючки" - они фактически обрабатываются другим меканизмом-когда постановка файлы (at git add времени) :

https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion

(прокрутите немного вниз до диаграммы" smudge/clean")

вот что я понял :

  1. редактировать .gitattributes, и создать правила для файлов, которые должны вызвать словарь update:

    novel.txt updateDict

  2. затем скажите Git, что делает фильтр" updateDict " на smudge (git checkout) и clean (git add):

    $ git config --global filter.updateDict.clean countWords.script

    $ git config --global filter.updateDict.smudge cat