git 如何使用git仅暂存新文件的一部分?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6436681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stage only part of a new file with git?
提问by augustin
I lovegit add --interactive. It is now part of my daily workflow.
我喜欢git add --interactive。它现在是我日常工作流程的一部分。
The problem seems that it does not work with untracked files. What I want to do is track a new file, but only add part of it, i.e. some parts of this new file are not yet ready to be staged.
问题似乎不适用于未跟踪的文件。我想要做的是跟踪一个新文件,但只添加它的一部分,即这个新文件的某些部分还没有准备好进行上演。
For example, with git add -i, I can chose the patch option and even edit individual hunks in order to stage parts of the new code, leaving debug code comments unstaged. I love working this way because it makes it obvious which places of the mega patch I am currently working on still need work.
例如,使用 git add -i,我可以选择补丁选项,甚至可以编辑单个大块以暂存部分新代码,而不暂存调试代码注释。我喜欢以这种方式工作,因为它清楚地表明我目前正在处理的大型补丁的哪些地方仍然需要工作。
Unfortunately, I don't seem to be able to do the same with an untracked file. Either I stage the whole file, or nothing. The workaround I have been using is staging or even committing a new file when it is empty, and then staging individual changes in the usual way. But this solution feels like a dirty hack and when I forget, or change my mind, it creates more troubles than there should be.
不幸的是,我似乎无法对未跟踪的文件执行相同的操作。要么我暂存整个文件,要么什么都不上。我一直在使用的解决方法是在新文件为空时暂存甚至提交一个新文件,然后以通常的方式暂存个别更改。但是这个解决方案感觉就像一个肮脏的黑客,当我忘记或改变主意时,它会产生比应有的更多的麻烦。
So the question is: How to stage only part of a new file, so that this new file gets tracked but leaving the whole or parts of its content unstaged?
所以问题是:如何仅暂存新文件的一部分,以便跟踪该新文件,但不暂存其全部或部分内容?
回答by Richard Hansen
Whoa, all that update-index
and hash-object
business seems overly complicated. How about this instead:
哇,所有这些update-index
和hash-object
业务似乎过于复杂。这个怎么样呢:
git add -N new_file
git add -i
From git help add
:
来自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.
回答by sehe
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
git add --interactive newfile
Simple demo:
简单演示:
mkdir /tmp/demo
cd /tmp/demo
git init .
echo hello > newfile
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
- HintIf you're sure the 'empty' blob already exists in your git object database, you could hardcode the hash
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
instead. I don't recommend doing that_ - HintIf you're on Windows, you probably can just use
NUL:
instead of/dev/null
. Otherwise, use something likeecho -n '' | git hash-object --stdin -w
- 提示如果您确定 git 对象数据库中已经存在“空” blob,则可以
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
改为对哈希进行硬编码。我不建议这样做_ - 提示如果您使用的是 Windows,您可能可以使用
NUL:
代替/dev/null
. 否则,使用类似echo -n '' | git hash-object --stdin -w
Now the index will contain newfile
as the empty blob, and the empty blob has been entered into the object database if it didn't exist yet:
现在索引将包含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
This should be precisely what you want. May I also recommend the vim fugitive plugin for very intelligent index management (see Better git add -p?)
这应该正是您想要的。我还可以推荐用于非常智能的索引管理的 vim fugitive 插件(请参阅Better git add -p?)
回答by Chronial
The easiest way to do this (and imho interactive staging in general) is git gui
. It comes bundled with git and should work on almost all platforms that are supported by git.
执行此操作的最简单方法(以及一般的 imho 交互式登台)是git gui
. 它与 git 捆绑在一起,几乎可以在 git 支持的所有平台上运行。
Simply run git gui
and a gui will open that allows staging and unstaging hunks and even single lines of tracked and untracked files.
只需运行git gui
并打开一个 gui,它允许暂存和取消暂存大块,甚至单行跟踪和未跟踪的文件。
回答by dave1010
Edit:this doesn't seem to be working now. I'm sure it was before (on git 1.7.1). In case it doesn't work, I suggest staging /dev/null
as sehe suggests above:
编辑:这现在似乎不起作用。我确定它是以前的(在 git 1.7.1 上)。如果它不起作用,我建议/dev/null
按照 sehe 上面的建议进行分期:
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
If you're on Windows (without /dev/null
) then you can replace it with the path to an empty file.
如果您使用的是 Windows(没有/dev/null
),那么您可以将其替换为空文件的路径。
Original answer
原答案
You want
你要
git add -p # (or --patch)
This adds untracked files for me. From the man page:
这为我添加了未跟踪的文件。从手册页:
Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to review the difference before adding modified contents to the index.
This effectively runs add --interactive, but bypasses the initial command menu and directly jumps to the patch subcommand. See “Interactive mode” for details.
在索引和工作树之间交互选择补丁块并将它们添加到索引中。这使用户有机会在将修改后的内容添加到索引之前查看差异。
这有效地运行 add --interactive,但绕过初始命令菜单并直接跳转到 patch 子命令。有关详细信息,请参阅“交互模式”。
回答by Pedro Adame Vergara
Just for the record of another possibility: I use
只是为了记录另一种可能性:我使用
git add -N file
git add -p file
And then you can stage hunks, or edit them in place.
然后你可以上演帅哥,或者就地编辑他们。