git - 使用 git add -N 后文件没有进入提交

标签 git

我想提交一个 Python 模块的 __init__.py 文件,该文件在我的磁盘上已经包含代码。但是,对于当前提交,我想将其添加为空,因为这部分代码尚待测试。因此,我使用了

$ git add -N __init__.py

该文件在 git status 的输出中,但是如果我发出 git commit,除了 __init__.py,它又根据 git status 保留在索引中。

git-add 的手册页对 -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.

有没有办法绕过这个 will be added later 部分,即添加空文件而不临时删除其内容?

编辑当前 (2.2.0) Git 会发生这种情况。使用 1.7.1 和一个小的测试 repo,我得到一个错误:

$ 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 2.5(2015 年第 2 季度)中修复,这意味着 git commit 不会尝试包含“打算稍后添加”的新文件。
参见 commit d95d728作者:Nguyễn Thái Ngọc Duy ( pclouds )( merge 于 d0c692263 )

diff-lib.c: adjust position of i-t-a entries in diff

问题:

Entries added by "git add -N" are reminder for the user so that they don't forget to add them before committing. These entries appear in the index even though they are not real.
Their presence in the index leads to a confusing "git status" like this:

On branch master
Changes to be committed:
        new file:   foo

Changes not staged for commit:
        modified:   foo

If you do a "git commit", "foo" will not be included even though "status" reports it as "to be committed".

解决方案:

This patch changes the output to become

On branch master
Changes not staged for commit:
        new file:   foo

no changes added to commit

换句话说:

  • Treat such paths as "yet to be added to the index but Git already know about them";
  • "git diff HEAD" and "git diff --cached HEAD" should not talk about them, and
  • "git diff" should show them as new files yet to be added to the index.

2016 年第四季度更新:

commit: fix empty commit creation when there's no changes but ita entries

(itai-t-a 是“意图添加”)

参见 commit 2c49f7f , commit 018ec3c , commit b42b451 , commit 425a28e (2016 年 10 月 24 日)Nguyễn Thái Ngọc Duy (pclouds) .
(由 Junio C Hamano -- gitster -- merge 于 commit 6503602 ,2016 年 10 月 27 日)

When new paths were added by "git add -N" to the index, it was enough to circumvent the check by "git commit" to refrain from making an empty commit without "--allow-empty".
The same logic prevented "git status" to show such a path as "new file" in the "Changes not staged for commit" section.

git diff man page现在包括:

--ita-invisible-in-index:

By default entries added by "git add -N" appear as an existing empty file in "git diff" and a new file in "git diff --cached".
This option makes the entry appear as a new file in "git diff" and non-existent in "git diff --cached".

This option could be reverted with --ita-visible-in-index.

Both options are experimental and could be removed in future.


更新Q1 2018 (Git 2.16.x/2.17),git status再次改进。
git status”,在工作树中移动路径后(因此使 它显示为“已删除”),然后添加 -N 选项(因此 使其显示为“已添加”)将其检测为重命名,但没有 正确报告新旧路径名。

参见 commit 176ea74 , commit 5134ccd , commit ea56f97 , commit 98bc94e , commit 06dba2b , commit 6de5aaf (2017 年 12 月 27 日)Nguyễn Thái Ngọc Duy (pclouds) .
帮助:Igor Djordjevic (boogisha) .
(由 Junio C Hamano -- gitster -- merge 于 commit bc3dca0 ,2018 年 1 月 23 日)

注意:i-t-aita 是“意在添加”。

wt-status.c: handle worktree renames

Before 425a28e (diff-lib: allow ita entries treated as "not yet exist in index" - 2016-10-24, Git 2.11.0-rc0) there are never "new files" in the index, which essentially disables rename detection because we only detect renames when a new file appears in a diff pair.

After that commit, an i-t-a entry can appear as a new file in "git diff-files".
But the diff callback function in wt-status.c does not handle this case and produces incorrect status output.


使用 Git 2.20 更新 2018 年第四季度,git status 避免在同一目标上显示多个重命名。

参见 commit 3e73cc6 (2018 年 9 月 27 日)Elijah Newren (newren) .
(由 Junio C Hamano -- gitster -- merge 于 commit 98f3f00 ,2018 年 10 月 16 日)

commit: fix erroneous BUG, 'multiple renames on the same target? how?'

builtin/commit.c:prepare_to_commit() can call run_status() twice if using the editor, including status, and the user attempts to record a non-merge empty commit without explicit --allow-empty.
If there is also a rename involved as well (due to using 'git add -N'), then a BUG in wt-status.c is triggered:

BUG: wt-status.c:476: multiple renames on the same target? how?

The reason we hit this bug is that both run_status() calls use the same struct wt_status * (named s), and s->change is not freed between runs. Changes are inserted into s with string_list_insert, which usually means that the second run just recomputes all the same results and overwrites what was computed the first time.

关于git - 使用 git add -N 后文件没有进入提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28066351/

相关文章:

git - 如何将原始 GitHub 项目的分支克隆到您的复刻中?

git - Xcode 4 git 集成

git - 高级 git 场景

git - 'Git push heroku master' 命令出错

git - 为所有子文件夹设置 git 配置值

git - 如何将文件重置或还原为特定修订版?

git - 如何在 Mac OS 中安装 GitExtensions?

git - 如何查看一个分支中的哪些提交不在另一个分支中?

ruby-on-rails - 通过gitbash命令行推送到Bitbucket远程仓库

java - Gradle:如何通过gradle执行git pull?