我想在git pre-commit钩子中整理文件,然后提交整理版本。
预提交钩子伪代码
for ($file in modified_files) {
tidy($file)
git add $file
}
此工作流程按预期整理和提交文件:
git add $file
git commit -m "foo"
此工作流程会整理并提交文件,但仍会暂停版本:
git add $file
git commit -m "foo" $file
问题
为什么后一个工作流程仍然会暂停文件,即使整理后的版本已经提交了?这几乎就像存在重复一样。我正在使用git版本2.7.3。
答案 0 :(得分:0)
几乎就像存在重复一样。
存在重复的 。
具体来说,鉴于当前提交(HEAD
或@
),每个文件有三个版本可用。一个是只读的,是存储在HEAD
提交本身的一个。另外两个是索引中的一个,它通过运行git add $file
来更新,而工作树中的一个是普通文本格式(而不是提交和索引版本的特殊Gitty格式) ),以便您和您的所有程序都可以使用它。
到目前为止,这并没有解释这个问题。真正的解释与git commit $file
影响--only
的{{1}} vs --include
选项的方式有关。它还与以下事实有关:虽然有 索引 - 一个特殊的,与工作树相关联的区别索引-Git也能够与某些其他 index,暂时。
我们现在需要更多的事实:
git commit
的默认操作与git commit
的默认操作相同,但git commit --include
的默认操作与git commit $file
的默认操作相同。 / p>
将git commit --only $file
与文件列表一起使用时,Git会构建临时,第二个索引。
git commit --only
成功后,Git希望索引与提交匹配。但是等等...... 我们在第3点讨论哪个索引?
索引是Git用于构建每个提交的索引。换句话说,现在索引中的内容是你和Git建议你应该在 next 提交中提出的内容。
当您使用 (普通)索引,或使用git commit
将其额外文件添加到 索引时,Git可以从进行新提交em> 索引,然后,当前(--include
或HEAD
)提交与索引匹配,因为Git只是从索引提交了,所以一切都很好。
但是当你使用一些其他索引时,Git会从临时索引中的文件中进行新的提交。然后,新提交将成为@
提交,Git会丢弃临时索引。这意味着 (普通)索引将恢复到其合法的宝座,从工作树中的普通rabble文件守护Git城堡(或者它是地牢?)的入口。 / p>
但是,如果原始的“索引”(即将要恢复的那个)具有这些文件,那些特定提交的文件,即您使用HEAD
命名的文件,采用旧版本{{{ 1}}提交,然后你非常明确地告诉Git更新和提交的文件将全部恢复到他们旧的,有臭味的,特殊前荣誉 - --only
- 形式。那么Git在抛出临时索引之前做的是将它复制回 (常规)索引。
HEAD
时,你才会看到这种效果,然后发现你的仔细分期已被删除。