128

当我运行时git add -p,git有没有办法选择新制作的文件作为选择?

因此,如果我创建一个名为 的新文件foo.java,然后运行 ​​git add -p,git 不会让我选择要添加到索引中的文件内容。

4

6 回答 6

125

当我尝试git add -p someNewFile.txt一个新文件(一个未跟踪的文件)时,git 会简单地输出No changes.并停止。我不得不告诉 git 我打算先跟踪新文件。

git add -N someNewFile.txt
git add -p

然而,由于该文件未被跟踪,它会显示为一个无法拆分的巨大块(因为它是全新的!)。所以,然后我需要将大块编辑成更小的位。如果您对此不熟悉,请查看此参考以开始使用。

更新 - 大块编辑信息 我想更新它以防上述参考消失。因为新文件未跟踪,所以git add -p将文件中的每一行显示为一个大块中的新行。然后它会问你想用那个大块做什么,给你以下提示:

Stage this hunk [y,n,q,a,d,/,e,?]?

假设您不想提交整个大块(因此,整个文件;因为我不确定您为什么要git add -p在这种情况下使用?),您将需要指定选项e来告诉 git 您要编辑大块头。

一旦你告诉 git 你想编辑大块,它应该让你进入你选择的编辑器,这样你就可以进行更改。所有行都应以 a 为前缀,并且 git在文件末尾+有一些解释性注释(以 a 为前缀)。#只需在文件的初始提交中删除您不想要的任何行。然后保存并退出编辑器。

Git对git的hunk选项的解释:

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
于 2013-07-31T20:38:04.380 回答
106

要包含每个新文件,您可以运行:

git add -N .
git add -p

如果你想经常使用它,你可以在你的~/.bashrc:

alias gapan='git add --intent-to-add . && git add --patch'

注意:如果你将它与一个空的新文件一起使用,git 将无法修补它并跳到下一个。

于 2017-08-11T17:44:32.297 回答
8

Catshoes的回答包括:

当我尝试git add -p someNewFile.txt一个新文件(一个未跟踪的文件)时,git 会简单地输出 No changes。并停下来。
我不得不告诉 git 我打算先跟踪新文件。

git add -N someNewFile.txt
git add -p

Git 2.29(2020 年第四季度)应该会很快改变这种情况。

最新版本的 " git diff-files" ( man )显示了索引和工作树之间的差异,作为“新文件”补丁的“intent-to-add”路径;
" git apply --cached" ( man )应该能够采用 " git diff-files" 并且应该作为路径的 " git add" 等效项,但是对于这样的路径,该命令未能这样做。

请参阅Raymond E. Pasco ( ) 的提交 4c025c6提交 e3cc41b(2020 年 8 月 8 日)和提交 7cfde3f(2020 年 8 月 6 日(由Junio C Hamano 合并 -- --ca81676 提交中,2020 年 8 月 17 日)juped
gitster

apply:允许 ita 条目上的“新文件”补丁

帮助者:Junio C Hamano
签字者:Raymond E. Pasco

diff-files最近更改为将对索引中标记为“intent to add”的路径的更改视为新文件差异,而不是来自空 blob 的差异。

但是,apply拒绝在现有索引条目之上应用新的文件差异,除非是重命名。
这会导致使用 apply 的 " git add -p" ( man )在记录添加意图时尝试从文件暂存大块时失败。

check_to_create()这改变了以两种方式检查索引中是否已存在条目的逻辑:

  • 首先,如果ok_if_exists为假,我们只搜索索引条目;
  • 其次,我们检查CE_INTENT_TO_ADD找到的任何索引条目上的标志,如果已设置,则允许应用程序继续进行。

和:

在 Git 2.29(2020 年第四季度)中,“ add -p”现在允许编辑仅在意图中添加的路径。

请参阅Phillip Wood ( ) 的提交 75a009d(2020 年 9 月 9 日(由Junio C Hamano 合并 -- --提交 458205f中,2020 年 9 月 22 日)phillipwood
gitster

add -p:修复意图添加路径的编辑

签字人:Phillip Wood
报道人:Thomas Sullivan
报道人:Yuchen Ying

部分暂存新文件的一种流行方法是运行( man ),然后使用 (man) 的大块编辑选择用户希望暂存的文件部分。git add -N <path>git add -p

85953a3187(“diff-files --raw:显示意图添加文件的正确后图像”,2020-07-01,Git v2.28.0-rc0 --批处理 #7中列出的合并)以来,这已停止工作因为意图添加路径现在显示为新文件,而不是对空 blob 的更改,并且( man )拒绝为标记为意图添加的路径应用创建补丁。7cfde3fa0f(“应用:允许 ita 条目上的“新文件”补丁”,2020-08-06)修复了应用的问题,但仍然无法正确编辑添加的块。git apply

2c8bd8471a(“ checkout -p:正确处理新文件”,2020-05-27,Git v2.28.0-rc0 -批次 #2中列出的合并)之前已更改为处理新文件,但未正确实现补丁编辑。 perl 版本简单地禁止编辑,而 C 版本打开编辑器时会显示完整的差异,而不仅仅是 hunk,这意味着用户必须手动编辑 hunk 标头才能使其工作。add -p

问题的根本原因是添加的文件将差异标头与大块数据一起存储,而不是像我们对其他更改所做的那样将两者分开。更改添加的文件以单独存储 diff 标头修复了编辑问题,但代价是必须进行特殊情况下的空添加,因为它们不再具有与它们关联的任何块,只有 diff 标头。

这些更改将一些现有代码移动到有条件的更改缩进中,最好查看它们--color-moved-ws=allow-indentation-change(或--ignore-space-change很好地了解更改的概述)


Git 2.32(2021 年第二季度)增加了一些清晰度:

请参阅Peter Oliver ( ) 的提交 7a14acd(2021 年 4 月 27 日(由Junio C Hamano 合并 -- --提交 e60e9cc中,2021 年 5 月 7 日)mavit
gitster

doc: 指向补丁格式文档中的差异属性

签字人:彼得·奥利弗

从使用 diff 相关命令生成补丁文本的文档中,请参阅 diff 属性的文档。

该属性影响生成补丁的方式,但之前在( man )手册页中没有提到这一点。git-diff

diff-generate-patch现在在其手册页中包含:

  1. 大块标题提到大块应用的函数的名称。gitattributes有关如何针对特定语言进行定制的详细信息,请参阅“定义自定义 hunk-header” 。
于 2020-08-26T21:18:47.667 回答
7

git add -p实际上是关于向已跟踪的文件添加更改。

交互式选择要添加的文件的命令是git add -i. 例如:

$ git add -i

*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
What now> a
  1: another-new.java
  2: new.java
Add untracked>> 2
  1: another-new.java
* 2: new.java
Add untracked>> 
added one path

*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
What now> q
Bye.
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   new.java

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        another-new.java

(真正的命令有我无法在这里剪切和粘贴的颜色,所以它比看起来更好)

实际上,patch 命令的作用与 相同,所以第二个是一个的子集(尽管我承认我爱自己也恨自己!)。git add -igit add -padd -padd -i

于 2017-08-23T14:07:49.940 回答
6

还有一种非常相似的方法利用--cached标志......

1)将您未暂存的更改转换为暂存,就像您添加的文件一样。

git add edited-file.txt
git add new-file.txt
git add directory-of-changes/

2)查看差异(注意:您可以包括编辑和新文件)。

git diff --cached

3)创建补丁。

git diff --cached > my_patch_file.patch
于 2016-09-16T20:52:48.623 回答
-4

您可以在一行中使用git add --intent-to-add -p . The behavior is the same,但避免重复。

于 2021-08-02T18:20:31.913 回答