在 GIT 中提交除一个文件块以外的所有文件的命令行方式?

Command-line way to commit all but one chunk of a file in GIT?

对于个人项目,我开始更改代码,然后意识到我需要更复杂的东西,所以我没有提交它们并做了其他事情。

两个小时后,我有了一个彻底改变的想法。在这种情况下,它将 Inform 7 中的“touchable”一词替换为“fungible”,以加快速度。所以我很快做出了改变,没有隐藏当前代码。 (是的,这是一个过程中的错误。但它会再次发生。)

问题是,一个文件中有 250 个块文本被更改,只有一两个块与我开始处理的更改相关。我想在没有 2 的情况下提交 250。

一旦我跟踪行号(9100 到 9200)并使用 git add --patch story.ni 验证关键扇区之前的更改,这并不痛苦。我快速输入 y 直到我到达第 8800 行。然后我放慢速度并输入 a 以添加其余部分。

我想我也可以将文件缩减到 9100 行,添加,取消截断,然后键入 n 然后 a。但我不是在寻找技巧。我希望对 git 的内部运作更有信心,例如如果有命令行参数可以清理它,例如

git add --linechunk:1-9100 --linechunk:9200-30000

或者...

git add --linechunk:-9100 --linechunk:9200

虽然我的方法已经足够好了,但知道是否有比手动修补更多的方法会很巧妙。

对于 git 更敏捷的人来说,有没有办法提高效率?

这里最简单的方法是使用 git diff 制作补丁文件,编辑并应用它。

换句话说,你实际上是在做一个 git add --patch 但不是交互式的,从而避免了等待专线接通的单调乏味。

示例:

% git diff > ~/Desktop/mypatch.txt
# edit the patch file in your favorite editor, 
# undoing the part you don't want changed
# don't forget to save!
% git apply --cached -- ~/Desktop/mypatch.txt
% git commit

编辑: @root 在评论中指出 git add --edit(或简称 git add -e)更紧凑地做同样的事情。这是真的,所以值得一提。我喜欢在自己的时间处理自己的补丁文件,但如果您不介意在 Git 等待您关闭编辑器时处理补丁,这可能是一个更简单的选择。

git add -p 是一个方便的工具,可以了解减少的变更集,恕我直言,在您的情况下,您对它的期望有点高。
应该记住,目标结果只是能够将您想要的文件版本放入索引中。


这里有一些其他方法可以达到该结果:

  • 运行 git gui,将完整文件添加到暂存区,然后滚动暂存文件以取消暂存您正在寻找的两个块(根据我的经验: 虽然它的界面看起来很笨拙,git gui 是一个非常有用的工具,可以在提交之前查看和编辑您的更改,并且有一个“添加此 line/remove 此行”,适用于所有情况)

  • 将该文件重命名为 filename.tmp、运行 git checkout filename、应用搜索和替换、添加和提交,然后恢复您的初始文件(mv filename.tmp filename)

  • 隐藏您当前的更改,重新应用“搜索+替换”,提交该文件,运行 git stash pop(根据您的描述,看起来甚至不应该是一个冲突,但如果有解决办法可能是从存储中获取版本)

  • 撤消您的搜索和替换(您的 ctrl+Z 堆栈中仍然有它,或者只是以相反的方式替换),提交或存储该版本的文件,然后重新应用您的搜索和替换,并提交新版本(您现在有两个提交,您可以 rebase/cherry-pick ... )

  • 等...

作为 almost-comment,因为对于这种极端情况,马特的回答通常可能是最好的,但是 git reset 也有 --patch 选项(git checkout 也是如此) , 这样您就可以轻松清理错误。

此外:任何体面的程序员的编辑器都会有一个 Git 插件,可以直接从编辑缓冲区暂存和取消暂存大块,所以更容易的是添加整个东西并取消暂存你没有的部分那个意思git gui 可以为编辑无法做到的人做到这一点。