‘ git add-patch’来包含新文件?

当我运行 git add -p时,是否有一种方法可以让 git 选择新创建的文件作为块来进行选择?

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

31087 次浏览

当我在一个新文件(一个未跟踪的文件)上尝试 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 你想要编辑这个大块,它就会把你放到你选择的编辑器中,这样你就可以进行修改了。所有行都应该以 +作为前缀,git 在文件末尾有一些解释性注释(以 #作为前缀)。只需删除在初始提交文件时不需要的任何行。然后保存并退出编辑器。

Git 对其大块选项的解释:

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

还有一个非常类似的方法,利用 --cached标志..。

1) 将非阶段性更改转换为阶段性更改,就像添加的文件一样。

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

2)查看 diff (注意: 您可以同时包含编辑和新文件)。

git diff --cached

3) 创建补丁。

git diff --cached > my_patch_file.patch

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

git add -N .
git add -p

如果你想经常使用它,你可以在你的 ~/.bashrc中创建一个别名:

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

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

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

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

实际上,git add -iPatch 命令的作用与 git add -p相同,所以第二个命令是第一个命令的子集(尽管我承认我喜欢 add -p,也讨厌 add -i!).

猫鞋的回答包括:

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

git add -N someNewFile.txt
git add -p

Git 2.29(2020年第四季度)很快就会改变这一点。

最新版本的“ git diff-files(< a href = “ https://git-scm.com/docs/git-diff-files”rel = “ nofollow norefrer”> man )显示了索引和作为“新文件”补丁的“意图添加”路径的工作树之间的区别;
git apply --cached(< a href = “ https://git-scm.com/docs/git-application # Documents/git-applicy.txt--cached”rel = “ nofollow noReferrer”> man )应该能够采取“ git diff-files”,并应作为等效的“ git add”的路径,但命令未能这样做的路径。

第四季,第25集提交 e3cc41b(2020年8月8日)和 提交7cfde3f(2020年8月6日)。
(由 朱尼奥 · C · 哈马诺 gitster提交 ca81676合并,2020年8月17日)

apply : 在 i-t-a 条目上允许“ new file”补丁

帮助者: Junio C Hamano
结束,雷蒙德 · E · 帕斯科

diff-files最近发生了变化,将对索引中标记为“意图添加”的路径的更改视为新文件不同于而不是不同于空的 blob。

但是,除了重命名以外,apply拒绝在现有索引条目之上应用新的文件差异。
这导致“ git add -p(< a href = “ https://git-scm.com/docs/git-add # Document/git-add.txt-p”rel = “ nofollow noReferrer”> man )(使用 application)在尝试从文件中暂存数据块时失败,因为已经记录了添加的意图。

这改变了 check_to_create()中检查索引中是否已经存在条目的逻辑:

  • 首先,如果 ok_if_exists为 false,我们只搜索索引条目;
  • 其次,我们检查找到的所有索引条目的 CE_INTENT_TO_ADD标志,如果设置了该标志,则允许应用程序继续运行。

还有:

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

犯下75a009d(2020年9月9日) by 菲利普 · 伍德(phillipwood)
(由 朱尼奥 · C · 哈马诺 gitster提交458205f合并,2020年9月22日)

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

签名: 菲利普 · 伍德
报道: Thomas Sullivan
英宇琛报道

部分暂存新文件的一种流行方法是运行 git add -N <path>(< a href = “ https://git-scm.com/docs/git-add # Document/git-add.txt-N”rel = “ nofollow noReferrer”> man ),然后使用 git add -p(< a href = “ https://git-scm.com/docs/git-add # Document/git-add.txt-p”rel = “ nofollow noReferrer”> man )的大块编辑来选择用户希望暂存的文件部分。

自从 85953a3187(“ diff-files —— raw: show right post-image of Italy-to-add files”,2020-07-01,Git v2.28.0-rc0—— 第七批中列出的 合并)以来,这已经停止工作,因为意图添加路径现在显示为新文件,而不是更改为空的 blob,而且 git apply(< a href = “ https://git-scm.com/docs/git-Apply”rel = “ nofollow noReferrer”> man )拒绝为标记为意图添加的路径应用创建补丁。7cfde3fa0f(“ application: allow“ new file”patch on i-t-a entry”,2020-08-06)修复了 application 的问题,但仍然无法正确编辑添加的块。

2c8bd8471a (“ checkout -p: 正确处理新文件”,2020-05-27,Git v2.28.0-rc0—— 第二批中列出的 合并)之前已经更改了 add -p以处理新文件,但是它没有正确地实现补丁编辑。
Perl 版本简单地禁止编辑,而 C 版本用完全差异打开编辑器,而不是只打开大块,这意味着用户必须手动编辑大块标题才能使其工作。

问题的根本原因是添加的文件将 diff 头与块数据存储在一起,而不是像对待其他更改那样将两者分开。修改添加的文件来单独存储 diff 头文件可以解决编辑问题,代价是必须使用特殊大小写的空添加,因为它们不再有任何与之相关的块,只有 diff 头文件。

这些更改将一些现有代码移动到一个条件更改缩进,最好使用 --color-moved-ws=allow-indentation-change查看(或者使用 --ignore-space-change可以很好地获得更改的概述)


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

犯下7a14acd(2021年4月27日) by 彼得 · 奥利弗(mavit)
(由 朱尼奥 · C · 哈马诺 gitster于2021年5月7日在 第六季,第9集合并)

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

签名: Peter Oliver

在用与 diff 相关的命令生成补丁文本的文档中,请参考 diff 属性的文档。

这个属性影响补丁的生成方式,但是这在之前的 git-diff(< a href = “ https://git-scm.com/docs/git-diff”rel = “ nofollow noReferrer”> man )手册中没有提到。

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

  1. 大块标头提到大块所指向的函数的名称 中的“定义自定义大块头” gitattributes 详细了解如何适应这种情况 特定语言。

您可以使用 git add --intent-to-add -p .在一行中完成此操作 行为是相同的,但避免重复。