因为文件还没有被暂存
实际上,这并不完全正确。但也不完全错误。
下面是一个(愚蠢的,仅用于示范)pre-commit钩子来演示这个问题:
$ cat .git/hooks/pre-commit
echo \$GIT_INDEX_FILE = $GIT_INDEX_FILE
git diff-index --cached --name-only HEAD
exit 1
这个钩子使用了可靠性较高的命令
git diff-index --cached HEAD
来查找暂存文件的名称。但首先,它会打印出用于提交文件的索引名称。(最后,它会阻止提交,因为我并不想提交任何更改。)
我在Git自身的存储库中将其设置为可执行文件,并修改了一些文件,但没有使用
git add
添加它们。
$ git status --short
M Makefile
M wt-status.c
(请注意,
M
在第二列。然后:)
$ git commit
$GIT_INDEX_FILE = .git/index
$ git commit -a
$GIT_INDEX_FILE = [redacted]/.git/index.lock
Makefile
wt-status.c
第一次钩子调用的“echo”告诉我们正在使用真实(主)索引,其“git diff-index”没有产生任何输出。
第二次调用告诉我们正在使用备用索引文件,名为“.git/index.lock”(我已经删除了源路径)。它显示了两个暂存文件。
让我们再做一件事情:我将“git add”修改后的“Makefile”,并对“Makefile”进行第二次更改。现在我们有:
$ git status --short
MM Makefile
M wt-status.c
第一行告诉我们,在提交中(已冻结),HEAD:Makefile
与暂存区(已提交)的:Makefile
不同,它们又与工作目录(未提交)的Makefile
不同。实际上,我们可以看到这三个文件是不同的:
$ git show HEAD:Makefile | head -2
all::
$ git show :Makefile | head -2
$ head -2 Makefile
运行
git commit
和
git commit -a
现在会产生以下结果:
$ git commit
$GIT_INDEX_FILE = .git/index
Makefile
$ git commit -a
$GIT_INDEX_FILE = [redacted]/.git/index.lock
Makefile
wt-status.c
如果我没有阻止非
-a
版本的
git commit
,那么
git commit
将提交的是(主要/真实/
.git/index
)索引中Makefile的版本,而不是工作树中的版本。因此,如果您想检查将要提交的文件,请查看索引。您可以使用
git checkout-index
从索引中提取文件,但要小心不要破坏可能不同的工作树版本。
git commit -a
将提交的是工作树中Makefile的版本,Git已将其添加到(非标准的临时)
.git/index.lock
索引中。一旦
git commit -a
完成,该非标准临时索引将成为真正的索引,破坏了我中间的特殊暂存副本
Makefile
。同样,要检查将要提交的文件,请查看索引-使用重定向的索引,因为Git会自动为
git diff-index
和
git checkout-index
。
(由于我不知道您的脚本需要什么,因此无法为如何使用
git checkout-index
提取感兴趣的文件提供具体建议。考虑使用
--work-tree=
和临时目录。)
(另请参见我的答案:
Skip past (full) staging area and commit file or patch directly?,其中讨论了
-a
、
--only
和
--include
在内部实际上是做什么的。)