git 可以在 rebase 上提示我每个文件吗?

Can git prompt me for each file on rebase?

我最近 运行 在一个网络项目中加入了这个:

git branch new-feature
git checkout new-feature

哈克哈克哈克...

"Bossman: hey, there's a bug in master that needs fixing, pronto!"

git commit -a -m "Partially completed migration changes"
git checkout master
git branch bugfix
git checkout bugfix

哈克哈克哈克... 测试测试测试...

"OK, fixed!"

git checkout master
git merge bugfix

关于完成功能,但我们不要重新引入错误...

git checkout new-feature
git rebase master

First, rewinding head to replay your work on top of it...
Applying: some commit info
Using index info to reconstruct a base tree...
...
Auto-merging /some/buggy/file
CONFLICT (content): /some/buggy/file
Auto-merging /some/buggy/file
CONFLICT (content): /some/buggy/file2
Auto-merging /some/buggy/file
CONFLICT (content): /some/buggy/file3
...

如果我碰巧知道特定文件与新功能无关,我该如何交互式强制文件从变基源复制?

有没有办法告诉 git 提示我像这样的东西:

copy /some/buggy/file master? y/n
copy /some/buggy/file2 master? y/n
...

Rebase 由重复的 git cherry-pick 操作组成(或者在某些情况下是一次整体选择,但这相当于同一件事):它需要您的 rebase 规范选择的所有提交(基本上 <upstream>..HEAD) 并将它们复制到新提交中,新链在 --onto 参数上增长(默认为 <upstream> 参数的尖端)。

进行挑选需要稍微改变一下视角:rebase 首先在 --onto 点检出一个匿名(分离的 HEAD)分支,然后遍历它之前保存的提交 ID从 <upstream>..HEAD 分离 HEAD 之前。正是这些精心挑选的步骤导致了合并冲突(这就是为什么您经常需要反复解决合并冲突,每次提交都经过精心挑选)。

这意味着除了 git rebase 文档外,我们可能还需要查看 the git cherry-pick documentation 来回答您的问题。在那里,我们发现:

When it is not obvious how to apply a change, the following happens:

  1. The current branch and HEAD pointer stay at the last commit successfully made.

  2. The CHERRY_PICK_HEAD ref is set to point at the commit that introduced the change that is difficult to apply.

这意味着在这种状态下,我们可以使用git checkout HEAD -- <em>path/to/file</em> (这里实际上不需要--,而是a good habit)或者git checkout CHERRY_PICK_HEAD -- <em>path/to/file </em>.

因为我们现在是在挑选,而不是变基(变基 仍在进行,我们只是在挑选 阶段 在这一点上),HEAD 指的是最近的成功提交。如果冲突发生在第一次提交时,HEAD 指的是与您的特定示例中的 master 相同的提交,而 CHERRY_PICK_HEAD 指的是从原始 new-feature 复制的提交] 分支。如果冲突更进一步,HEAD 指的是在从(再次使用您的示例)master 通往未来的匿名分支上增长的新提交之一。无论哪种情况,这都是您真正想要的,在这里。

(旁注:如果您知道您没有触及该文件,那么在本例中,CHERRY_PICK_HEAD 提交 master 提交,因此您可以使用 git 结账大师 -- <em>path/to/file</em>,这更容易输入。但是,这假设您要重新定位到 master 的尖端,而使用名称 CHERRY_PICK_HEAD 使其独立于目标提交。)

一旦 cherry-picking 阶段完成,git rebase 再次接管并通过更改 rebased 分支名称(在本例中为 new-feature)来完成 rebase,以指向 tip-most提交新的匿名分支。旧的(预变基)分支提示,在所有这些挑选之前,保留在 new-feature 的 reflog 中(如 new-feature@{1} 或任何其他命名方式)。它也可以在 ORIG_HEAD 中使用,直到你 运行 覆盖 ORIG_HEAD 的东西(各种 git 命令,包括 git amgit merge、和 git reset,也写入 ORIG_HEAD)。如果您不小心搞砸了 rebase,这将特别方便。