我最近在一个web项目上遇到了这个问题:
git branch new-feature
git checkout new-feature
破解破解破解
"Bossman:嘿,master中有一个错误需要立即修复!"
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
在完成该功能之前,我们不要重新引入这个bug。。。
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
...
如果我碰巧知道特定的文件与新功能无关,我如何以交互方式强制文件从rebase源复制?
有没有办法告诉git
用之类的东西提示我
copy /some/buggy/file master? y/n
copy /some/buggy/file2 master? y/n
...
Rebase由重复的git cherry-pick
操作组成(在某些情况下,也可以是一个单独的集体pick,但这相当于相同的东西):它接受Rebase规范(基本上是<upstream>..HEAD
)选择的所有提交,并将这些提交复制到--onto
参数上生长的新链的新提交中(默认为<upstream>
参数的尖端)。
进行挑选需要稍微改变一下视角:rebase首先在--onto
点签出一个匿名(分离的HEAD)分支,然后在分离HEAD之前迭代它之前从<upstream>..HEAD
保存的提交ID。正是这些精心挑选的步骤遇到了合并冲突(这就是为什么您经常需要重复解决合并冲突,每次提交都要经过精心挑选)。
这意味着,为了回答您的问题,除了git rebase
文档外,我们可能还需要查看git cherry-pick
文档。在那里,我们发现:
当不清楚如何应用更改时,会发生以下情况:
当前分支和
HEAD
指针停留在上次成功提交时。
CHERRY_PICK_HEAD
ref设置为指向引入难以应用的更改的提交。
这意味着在这种状态下,我们可以使用git checkout HEAD -- path/to/file
(这里实际上不需要--
,但这是一个好习惯)或git checkout CHERRY_PICK_HEAD -- path/to/file
。
由于我们现在正在进行樱桃采摘,而不是重新定基(重新定基仍在进行,此时我们正处于樱桃采摘阶段),HEAD
指的是最近成功的提交。如果冲突发生在第一次提交时,则HEAD
指的是与特定示例中的master
相同的提交,而CHERRY_PICK_HEAD
指的是从原始new-feature
分支复制的提交。如果冲突进一步发展,HEAD
指的是(再次使用您的示例)master
在通往未来的匿名分支上增长的一个新提交。无论哪种情况,这都是你真正想要的,在这里。
(附带说明:如果你知道你没有接触到文件,那么在这种情况下,CHERRY_PICK_HEAD
提交和master
提交都是一样的,所以你可以使用git checkout master -- path/to/file
,这更容易键入。但是,这假设你是在重新调整master
的顶端,而使用名称CHERRY_PICK_HEAD
使其独立于目标提交。)
一旦樱桃采摘阶段完成,git rebase
将再次接管并通过更改重新基础的分支名称(在本例中为new-feature
)来完成重新基础,以指向新匿名分支上最尖端的提交。在所有这些樱桃采摘之前,旧的(再基前)枝条尖端仍保留在new-feature
的reflog中(如new-feature@{1}
或任何其他命名方式)。此时,它在ORIG_HEAD
中也可用,直到您运行覆盖ORIG_HEAD
的东西(包括git am
、git merge
和git reset
在内的各种git命令也写入ORIG_HEAD
)。如果你不小心把重新基准搞砸了,这会特别方便。