你可以在 git commit 期间更改文件内容吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16831536/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can you change a file content during git commit?
提问by jjmerelo
One of the things I keep in my open novel in GitHubis a list of wordsI would like to set automatically the first line, which is the number of words in the dictionary. My first option is to write a pre-commit hook that reads the file, counts the words, rewrites the first line and writes it back again. Here's the code
有一个问题我一直在我的东西在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 );
}
}
};
However, since the file has already been staged, I get this error
但是,由于文件已经暂存,我收到此错误
error: Your local changes to the following files would be overwritten by checkout: text/words.dic Please, commit your changes or stash them before you can switch branches. Aborting
错误:您对以下文件的本地更改将被检出覆盖: text/words.dic 请提交您的更改或将它们隐藏,然后才能切换分支。中止
Might it be better to do it as a post-commit hook and have it changed for the next commit? Or do something completely different altogether? The general question is: if you want to process and change the contents of a file during commit, what's the proper way of doing it?
将其作为提交后挂钩并在下一次提交时进行更改可能会更好吗?或者做一些完全不同的事情?一般的问题是:如果您想在提交期间处理和更改文件的内容,那么正确的做法是什么?
采纳答案by torek
The actual commit stuck in by git commit
is whatever is in the index once the pre-commit hook finishes. This means that you canchange files in the pre-commit hook, as long as you git add
them too.
git commit
一旦预提交钩子完成,实际提交的内容就是索引中的任何内容。这意味着您可以更改预提交挂钩中的文件,只要您也更改git add
它们。
Here's my example pre-commit hook, modified from the .sample:
这是我的示例预提交钩子,从 .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
and then:
进而:
$ git commit -m dink
updated zorg to 3
[master 76eeefc] dink
1 file changed, 1 insertion(+), 1 deletion(-)
But note a minor flaw (won't apply to your case):
但请注意一个小缺陷(不适用于您的情况):
$ 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
Basically, because the pre-commit hook updates and git add
s, the file keeps incrementing even though I'm not actually doing the commit, here.
基本上,因为 pre-commit 钩子更新和git add
s,即使我实际上并没有在这里进行提交,文件也会不断增加。
回答by LeGEC
It turns out you can run "hooks" - they are actually handled by another mechanism - when stagingfiles (at git add
time) :
事实证明,您可以运行“钩子”——它们实际上是由另一种机制处理的——当暂存文件时(在git add
时间):
https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion
https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion
(scroll down a bit to the "smudge" and "clean" diagrams)
(向下滚动到“污迹”和“清洁”图表)
Here is what I understood :
这是我的理解:
edit the
.gitattributes
, and create rules for the files which should trigger a dictionary update:novel.txt filter=updateDict
Then, tell Git what the
updateDict
filter does on smudge(git checkout) and clean(git add):$ git config --global filter.updateDict.clean countWords.script
$ git config --global filter.updateDict.smudge cat
编辑
.gitattributes
, 并为应该触发字典更新的文件创建规则:novel.txt filter=updateDict
然后,告诉 Git
updateDict
过滤器对smudge(git checkout) 和clean(git add) 的作用:$ git config --global filter.updateDict.clean countWords.script
$ git config --global filter.updateDict.smudge cat