我喜欢git添加-交互式。现在这是我日常工作流程的一部分。

问题似乎是,它不能对未跟踪的文件工作。我想要做的是跟踪一个新文件,但只添加它的一部分,即这个新文件的某些部分还没有准备好登台。

例如,使用git add -i,我可以选择补丁选项,甚至可以编辑单独的块,以便阶段性地展示新代码的一部分,而不显示调试代码注释。我喜欢这种工作方式,因为它让我很明显地知道我目前正在制作的大型补丁中哪些地方还需要改进。

不幸的是,对于未跟踪的文件,我似乎无法做到这一点。要么我把文件全部放出来,要么什么都不放。我一直在使用的解决方法是在新文件为空时暂存,甚至提交新文件,然后以通常的方式暂存各个更改。但这个解决方案感觉像一个肮脏的hack,当我忘记,或改变我的想法,它创造了更多的麻烦比应有的。

因此,问题是:如何只显示新文件的一部分,以便跟踪这个新文件,而不显示其全部或部分内容?


当前回答

哇,所有更新索引和哈希对象的事情看起来都太复杂了。不如这样吧:

git add -N new_file
git add -i  # or 'git add -p' if you prefer

从git帮助添加:

-N, --intent-to-add
    Record only the fact that the path will be added later.  An entry
    for the path is placed in the index with no content.  This is useful
    for, among other things, showing the unstaged content of such files
    with git diff and committing them with git commit -a.

其他回答

最简单的方法是git gui。它与git捆绑在一起,应该可以在git支持的几乎所有平台上工作。

简单地运行git gui,一个gui将打开,允许分段和取消分段块,甚至单行跟踪和未跟踪文件。

哇,所有更新索引和哈希对象的事情看起来都太复杂了。不如这样吧:

git add -N new_file
git add -i  # or 'git add -p' if you prefer

从git帮助添加:

-N, --intent-to-add
    Record only the fact that the path will be added later.  An entry
    for the path is placed in the index with no content.  This is useful
    for, among other things, showing the unstaged content of such files
    with git diff and committing them with git commit -a.

编辑:这似乎不工作现在。我敢肯定是在git 1.7.1之前。如果它不起作用,我建议按照上面sehe的建议暂存/dev/null:

git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile

如果你在Windows上(没有/dev/null),那么你可以用一个空文件的路径替换它。

原来的答案

你想要的

git add -p # (or --patch)

这为我添加了未跟踪的文件。从手册页:

交互式地选择大块的补丁 在索引和工作树之间 并将它们添加到索引中。这给了 用户有机会审查 添加前差异已修改 索引的内容。 这有效地运行add ——交互,但绕过初始的命令菜单和直接 跳转到补丁子命令。看到 “互动模式”。

git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
git add --interactive newfile

简单的演示:

mkdir /tmp/demo
cd /tmp/demo
git init .

echo hello > newfile
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile

提示:如果你确定'empty' blob已经存在于你的git对象数据库中,你可以硬编码散列e69de29bb2d1d6434b8b29ae775ad8c2e48c5391。我不建议那样做 提示:如果你在Windows上,你可能只需要使用NUL:而不是/dev/null.否则,使用类似echo -n " | git hash-object——stdin -w

现在索引将包含newfile作为空blob,如果空blob还不存在,那么它已经被输入到对象数据库中:

$ find .git/objects/ -type f 
.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   newfile
#
# 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:   newfile
#

$ git diff
diff --git a/newfile b/newfile
index e69de29..ce01362 100644
--- a/newfile
+++ b/newfile
@@ -0,0 +1 @@
+hello

这应该正是你想要的。我还可以推荐vim逃犯插件,用于非常智能的索引管理(参见Better git add -p?)

顺便说一下另一种可能性 我使用

git add -N file
git add -p file

然后你就可以摆出大块头,或者就地编辑它们。