变基时,为什么 git 添加 --patch 不起作用?

When rebasing, why doesn't git add --patch work?

在 git 存储库中,我有一个包含大型提交的文件,我想将其分成多个提交。我正在尝试按照 this answer 中的说明进行操作,但我遇到了 运行 的问题。 git status 显示 file.js 未被跟踪,但 git add -p file.js 响应 "No changes." 我做了一个 github reposiotry 来说明我的意思。

在这个特定的存储库中,我想将提交 92cc4839abe2bfe54981d8227c17acf07c24c84b 分成几个提交,每个添加一个函数到 file.js。但是,我发现的唯一有用的说明失败了。

如何重现:

  1. git clone https://github.com/jgibbons94/rebase-error.git
  2. cd rebase-error/
  3. git rebase -i HEAD~2 并标记提交 92cc483 以进行编辑。保持其他一切不变。
  4. git reset HEAD~
  5. git status 列表 file.js 未被跟踪。
  6. git diff file.js 显示没有变化。
  7. git add -p file.js 回复 "No changes."

这是已知解决方法的已知问题吗?我误会了什么吗?我们将不胜感激。

问题出在这里:

  1. git reset HEAD~
  2. git status lists file.js is not tracked.

提交 92cc483 添加 文件,因此当您执行 git reset 来撤消 92cc483 的副本时,此 从 Git 的索引中删除了 文件。

提醒:indexstaging area(两个术语表示同一事物)包含将进入的每个文件的副本下一个 提交。它最初是 当前提交 的副本。所以 git reset HEAD~1(或任何等价物)意味着 取出索引中的所有内容,然后放入 HEAD~1 中的所有内容。文件 file.js 不在 之前的提交中,所以现在它 也不在索引 中。

git add -p 命令需要在索引中有一些内容来修补。索引中的一个空文件就足够了,git add -N 创建这样一个条目,所以:

git add -N file.js

会让你运行git add -p file.js.

这并不是那么有用,因为整个 file.js 现在都会显示为补丁。您不妨在编辑器中打开 file.js,将其中的大部分剪掉,写回去,然后——在编辑器仍处于打开状态时——运行 git add file.js,然后撤消剪断-去掉一部分,这样你就拥有了全部。您现在在索引中有您想要的 file.js 的副本:

$ vi file.js        # open file.js in editor
[snip]
:w
^Z                  # suspend editor - or, open another window to run git add
$ git add file.js
$ fg                # resume editor
[undo snippage]
:x                  # write and exit

所有这一切的结果是:

$ git status
interactive rebase in progress; onto 85aa6aa
Last command done (1 command done):
   edit 92cc483 A really big commit
Next command to do (1 remaining command):
   pick 3891479 Add description.txt
  (use "git rebase --edit-todo" to view and edit)
You are currently splitting a commit while rebasing branch 'master' on '85aa6aa'.
  (Once your working directory is clean, run "git rebase --continue")

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   file.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   file.js

我现在可以git commit,恢复我的编辑器,截图(这次少了),写,暂停,git addgit commit,恢复编辑器和撤消截图等,直到我完成了每个函数的所有提交。无需为笨重的 git add -p.

而烦恼