如何使用git只播放新文件的一部分?

aug*_*tin 212 git

喜欢 git add --interactive.它现在是我日常工作流程的一部分.

问题似乎是它不适用于未跟踪的文件.我想要做的是跟踪一个新文件,但只添加它的一部分,即这个新文件的某些部分尚未准备好上演.

例如,使用git add -i,我可以选择补丁选项,甚至可以编辑单个磁盘以暂存新代码的部分,从而使调试代码注释保持未分级状态.我喜欢这种方式工作,因为它显然我目前正在处理的大型补丁的哪些位置仍然需要工作.

不幸的是,我似乎无法对未跟踪的文件做同样的事情.要么我暂存整个文件,要么没有.我一直在使用的解决方法是在新文件为空时暂存或提交新文件,然后以通常的方式暂存各个更改.但是这个解决方案感觉就像一个肮脏的黑客,当我忘记或改变主意时,它会造成比应有的麻烦.

所以问题是:如何仅仅暂存新文件的一部分,以便跟踪这个新文件但是将其全部或部分内容保持未分级?

Ric*_*sen 390

哇,所有这些update-indexhash-object业务似乎过于复杂.怎么样呢:

git add -N new_file
git add -i
Run Code Online (Sandbox Code Playgroud)

来自git help add:

-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.
Run Code Online (Sandbox Code Playgroud)

  • ++ 1!应得的信用.我确实相信有点太多了,我现在知道这些联机帮助...."</ shame>` (8认同)
  • 精彩的`-N`发现,谢谢!虽然在这种情况下我更喜欢将它与`-p`结合起来.`gid add -N the_file`&`git add -p`.应该补充一点,`-N`也适用于`-A` (6认同)
  • 不知道为什么git-gui不会在内部使用它来从新文件中分段线. (3认同)
  • 很好找到。我应该进一步滚动手册页。也许我应该归还 Git Pro 徽章。 (2认同)

seh*_*ehe 6

git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
git add --interactive newfile
Run Code Online (Sandbox Code Playgroud)

简单演示:

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

echo hello > newfile
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
Run Code Online (Sandbox Code Playgroud)
  • 提示如果您确定git对象数据库中已经存在'空'blob,则可以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
Run Code Online (Sandbox Code Playgroud)

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


Chr*_*ial 6

最简单的方法(和imho交互式升级一般)是git gui.它与git捆绑在一起,几乎可以在git支持的所有平台上运行.

只需运行git gui并打开一个gui即可打开和取消暂停状态,甚至单行跟踪和未跟踪文件.

Git Gui截图

  • 请注意,并非所有git发行版都包含`git gui`.例如,在Debian中,它位于一个名为"git-gui"的独立包中. (3认同)
  • 对我来说,`git gui`中单行未跟踪文件的分段从未奏效.实际上,它[禁用这些菜单选项](http://i.imgur.com/PhSHm7D.png). (2认同)
  • @Deiwin我必须在问题中错过了这个 - 我的屏幕截图显示了一个已经跟踪过的文件.如果你想使用`git gui`来获取新文件,你必须首先运行`git add -N new_file` - 参见Richard Hansen的回答. (2认同)