首页 > 解决方案 > 变基时,为什么 git add --patch 不起作用?

问题描述

在 git 存储库中,我有一个包含大型提交的文件,我想将其分成多个提交。我正在尝试按照此答案中的说明进行操作,但遇到了问题。git status显示 file.js 未被跟踪,但git add -p file.js响应“无更改”。我制作了一个github 存储库来准确说明我的意思。

在这个特定的存储库中,我想将提交 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回答“没有变化”。

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

标签: gitgit-rebasegit-diffgit-add

解决方案


问题在这里:

  1. git重置头~
  2. git status 列出 file.js 不被跟踪。

提交92cc483 添加了文件,因此当您执行 agit reset以退出 的副本时92cc483,这会从 Git 的索引中删除该文件。

提醒:索引暂存区域(同一事物的两个术语)保存将进入下一次提交的每个文件的副本。它最初是当前提交的副本。所以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 add,,,git commit恢复编辑器和撤消剪断等,直到我为每个功能完成所有提交。没有必要为笨重的东西而烦恼git add -p


推荐阅读