我在open novel in GitHub中保留的一件事是list of words我想自动设置第一行,即字典中的字数。我的第一个选择是编写一个预提交钩子,它读取文件,计算单词,重写第一行并再次写回。这是代码
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 );
}
}
};
但是,由于该文件已经暂存,我收到此错误
错误:您对以下文件的本地更改将被覆盖 结帐时: 文/ words.dic 请提交您的更改或存储它们 在你可以切换分支之前。 中止
可能最好将它作为一个post-commit钩子并将其更改为下一次提交?或者做一些完全不同的事情?一般的问题是:如果你想在提交过程中处理和更改文件的内容,那么这样做的正确方法是什么?
答案 0 :(得分:21)
git commit
中的实际提交是预提交挂钩完成后索引中的任何内容。这意味着只要您git add
,就可以更改预提交挂钩中的文件。
这是我的示例预提交钩子,从.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
基本上,因为预提交钩子更新了git add
,所以即使我实际上没有在这里进行提交,文件也会继续递增。
答案 1 :(得分:10)
事实证明你可以运行“钩子” - 它们实际上是由另一种机制来处理的 - 当登台文件时(git add
时间):
https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion
(向下滚动到“涂抹/清洁”图表)
以下是我的理解:
编辑.gitattributes
,并为应触发字典更新的文件创建规则:
novel.txt updateDict
然后,告诉Git“updateDict”过滤器在涂抹(git checkout)和清理(git add)时做了什么:
$ git config --global filter.updateDict.clean countWords.script
$ git config --global filter.updateDict.smudge cat