使用git add -N命令后,文件没有进入提交中。

6

我想提交一个Python模块的__init__.py文件,但在我的磁盘上已包含代码。然而,在当前提交中,我想将它添加为空,因为这部分代码尚未经过测试。因此,我使用了以下方法:

$ git add -N __init__.py

git status的输出中,文件已经存在,但是如果我执行git commit,所有其他文件都会被提交,除了__init__.py,而它则仍然保留在索引中,根据git status

git-add的man页面对于-N说:

Record only the fact that the path will be added later. An entry for the path is placed in the index with no content.

有没有办法规避这个稍后添加的部分,即添加空文件而不暂时删除其内容?

编辑:这在当前(2.2.0)Git中发生。使用1.7.1和一个小测试存储库,我会得到错误:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   b
#
$ git commit -m 'test'
b: not added yet
error: Error building trees

这是不可行的,因为它将提交所有其他修改过的文件,无论我是否使用 git add 添加了它们。然而,未跟踪的文件仍将保持未跟踪状态。 - GergelyPolonkai
太搞笑了。当您仅使用“git add -N”然后提交时,可以创建一个完全为空的提交。只是想分享这个小技巧。 - Sascha Wolf
git add -N 之后,您可以使用 git add -p 命令,并简单地拒绝添加您被询问的单个差异块。有关更多信息,请参见此答案 - Sven Marnach
@SvenMarnach,我实际上已经尝试过了,在git 1.9.4中至少这并不能解决问题。 - Sascha Wolf
@SvenMarnach 谢谢,我的搜索技巧让我找不到那篇帖子,这使得我的问题有些重复。 - GergelyPolonkai
显示剩余3条评论
1个回答

6
这应该在Git 2.5(2015年第二季度)中得到解决,这意味着git commit将不会尝试包含新文件“intended to be added later”。 请参见Nguyễn Thái Ngọc Duy(pclouds)的commit d95d728(合并于d0c692263),调整i-t-a条目在diff中的位置。

diff-lib.c:调整diffi-t-a条目的位置

问题:

"git add -N" 命令添加的条目是为了提醒用户在提交前不要忘记将它们添加。尽管这些条目并不存在,但它们会出现在索引中。
它们存在于索引中会导致 "git status" 命令显示以下混淆信息:
On branch master
Changes to be committed:
        new file:   foo

Changes not staged for commit:
        modified:   foo

如果你执行"git commit",那么即使"status"报告它为"to be committed","foo"也不会被包含在内。
解决方案:
这个补丁改变了输出结果:
On branch master
Changes not staged for commit:
        new file:   foo

no changes added to commit

换句话说:
将这些路径视为“尚未添加到索引但 Git 已经知道它们的存在”;
git diff HEAD”和“git diff --cached HEAD”不应该提及它们,而且
git diff”应该将它们显示为尚未添加到索引的新文件。
更新 2016 年第四季度:

commit: 解决没有更改但存在 "ita" 条目时无法创建提交的问题

("ita" 或 "i-t-a" 代表 "意图添加")

查看 提交2c49f7f, 提交018ec3c, 提交b42b451, 提交425a28e(2016年10月24日)由Nguyễn Thái Ngọc Duy (pclouds)
(由Junio C Hamano -- gitster --提交6503602中合并,2016年10月27日) 当使用 "git add -N" 命令将新路径添加到索引中时,只需通过 "git commit" 命令规避检查即可避免未使用 "--allow-empty" 选项进行空提交。同样的逻辑也会防止 "git status" 将此类路径显示为 "Changes not staged for commit" 部分中的 "new file"。
现在 git diff man page 包括了这一说明。
--ita-invisible-in-index:

默认情况下,使用“git add -N”添加的条目在“git diff”中会显示为空文件,而在“git diff --cached”中会显示为新文件。
此选项可使条目在“git diff”中显示为新文件,在“git diff --cached”中则不存在。

此选项可以通过使用“--ita-visible-in-index”来撤销。

这两个选项都是实验性的,可能会在将来被删除。


2018年第一季度更新(Git 2.16.x / 2.17),git status再次改进。
在工作树中移动路径后(因此使其看起来像是“删除”),然后使用-N选项添加(因此使其看起来像是“添加”),“git status”检测到它是一个重命名,但没有正确报告旧路径和新路径的名称。
参见 提交 176ea74, 提交 5134ccd, 提交 ea56f97, 提交 98bc94e, 提交 06dba2b, 提交 6de5aaf (2017年12月27日) 由 Nguyễn Thái Ngọc Duy (pclouds) 提交。
协助者:Igor Djordjevic (boogisha)
(由 Junio C Hamano -- gitster --提交 bc3dca0 中合并,2018年1月23日) 注意:i-t-aita 的意思是“旨在添加”。

wt-status.c:处理工作树重命名

425a28e(diff-lib:允许将 ita 条目视为“尚未存在于索引中”- 2016-10-24,Git 2.11.0-rc0)之前,索引中从未有过“新文件”,这实际上禁用了重命名检测,因为只有在差异对中出现新文件时才会检测到重命名。

在那次提交之后,i-t-a 条目可以出现在 "git diff-files" 中作为一个新文件。
但是在 wt-status.c 中的差异回调函数没有处理这种情况,导致输出错误的状态。


使用 Git 2.20 更新Q4 2018,git status 现在避免在同一目标上显示多个重命名。

请参见提交记录3e73cc6 (2018年9月27日),由 Elijah Newren(newren 提交。
(由 Junio C Hamano -- gitster --合并于提交记录98f3f00,2018年10月16日)

提交:修正错误的 BUG,'同一目标上的多个重命名?怎么办?'
如果使用编辑器(包括状态)并且用户尝试记录一个非合并空提交而没有显式指定 '--allow-empty',则 builtin/commit.c:prepare_to_commit() 可能会调用两次 run_status()。如果还涉及重命名(由于使用 'git add -N'),则会触发 wt-status.c 中的 BUG:
BUG:wt-status.c:476:同一目标上的多个重命名?怎么办?
我们遇到这个 bug 的原因是两个 run_status() 调用使用相同的 struct wt_status * (命名为 s),并且在运行之间未释放 s->change。更改使用 string_list_insert 插入到 s 中,这通常意味着第二次运行只重新计算所有相同的结果并覆盖第一次计算的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接