【问题标题】:'git add --patch' to include new files?'git add --patch' 包含新文件?
【发布时间】:2013-01-07 15:23:36
【问题描述】:

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

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

【问题讨论】:

    标签: git shell git-add


    【解决方案1】:

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

    git add -N someNewFile.txt
    git add -p
    

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

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

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

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

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

    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
    

    【讨论】:

    • 请有人总结一下。
    • 总之,git add -N someNewFile.txt 后跟git add -p
    • 似乎在新的 git 版本中,行为发生了变化。它没有手动编辑当前块的选项。
    • 这似乎对我不起作用,当我接受git add -p filename 中的所有更改时(通过输入y),它退出时没有任何上演。当我尝试使用 e 进行编辑时,我收到“抱歉,无法编辑这个大块”
    • 如果我在 git push 说“一切都是最新的”之后这样做
    【解决方案2】:

    还有一种非常相似的方法利用--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
    

    【讨论】:

    • 不幸的是,这不会达到同样的目的。我喜欢git add -p 的一点是它不会添加所有内容,但让我挑选我想要添加的内容。此解决方案会盲目添加所有内容。
    • 您可以选择添加的内容!我会更新答案。
    • 谢谢 :allthethings: 这对我来说非常有用
    【解决方案3】:

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

    git add -N .
    git add -p
    

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

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

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

    【讨论】:

    • 对于任何想知道git add -N 做什么的人,它只是将指定的未跟踪文件添加到索引中,但没有内容。
    【解决方案4】:

    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 并且讨厌@ 987654327@我自己!)。

    【讨论】:

    • "我承认我喜欢 add -p 讨厌 add -i 我自己!"这就是为什么 git add then patch 是我喜欢的解决方案的原因:它仍然允许您检查正在添加的新文件的内容(因为您将它们与它们的空版本进行比较),以及您编辑的补丁文件!
    • 如果我错了请纠正我,但即使在交互模式下,补丁仍然会在新文件上输出No changes.。 OP 询问如何从新文件而不是整个文件中添加大块。我相信这里仍然需要--intent-to-add
    • add -p 单独是行不通的,但这个答案建议add -i,确实如此。
    • 我赞成,因为我不知道git add -i。但是,您可以使用 git add -N 以非交互方式执行相同的操作。
    【解决方案5】:

    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) 将“意图添加”路径的索引和工作树之间的差异显示为“新文件”补丁;
    "git apply --cached"(man) 应该能够采用 "git diff-files" 并且应该作为路径的 "git add" 的等效项,但该命令未能这样做对于这样的路径。

    参见Raymond E. Pasco (juped)@commit 4c025c6commit e3cc41b(2020 年 8 月 8 日)和commit 7cfde3f(2020 年 8 月 6 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit ca81676,8 月 17 日2020)

    apply:允许在 i-t-a 条目上添加“新文件”补丁

    帮助: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 (phillipwood)commit 75a009d(2020 年 9 月 9 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit 458205f,2020 年 9 月 22 日)

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

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

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

    由于85953a3187 ("diff-files --raw: 显示正确的意图添加文件的后图像", 2020-07-01, Git v2.28.0-rc0 -- merge 列在@ 987654346@) 这已停止工作,因为意图添加路径现在显示为新文件,而不是对空 blob 的更改,并且git apply(man) 拒绝为标记为意图添加的路径。 7cfde3fa0f ("apply: allow "new file" patch on i-t-a entries", 2020-08-06) 修复了 apply 的问题,但仍然无法正确编辑添加的块。

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

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

    这些更改将一些现有代码移动到有条件的更改缩进中,最好使用--color-moved-ws=allow-indentation-change(或--ignore-space-change 可以很好地了解更改)


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

    参见 Peter Oliver (mavit)commit 7a14acd(2021 年 4 月 27 日)。
    (由 Junio C Hamano -- gitster -- 合并到 commit e60e9cc,2021 年 5 月 7 日)

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

    签字人:彼得·奥利弗

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

    此属性会影响生成补丁的方式,但之前在 git-diff(man) 手册页中并未提及。

    diff-generate-patch 现在包含在其man page 中:

    1. Hunk 标头提到了该hunk 所在的函数的名称 适用。请参阅“定义自定义块头”中的 gitattributes 详细了解如何为此量身定制 特定语言。

    【讨论】:

    • 这个有什么更新吗?我正在使用 git 版本 2.28.0,它不适用于 git add -N + git add -p 手动编辑帅哥
    • @The.Wolfgang.Grimmer 还没有:2.29 将在几周后发布。
    • 是的!现在修复:)
    【解决方案6】:

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

    【讨论】:

      猜你喜欢
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 2013-07-17
      • 2021-11-11
      • 1970-01-01
      • 2013-07-23
      • 2011-07-17
      相关资源
      最近更新 更多