Git 将历史记录移植到*当前*分支
我知道如何使用Git 将历史记录移植到*当前*分支,git,Git,我知道如何使用git-rebase--on移植历史。然而,我经常发现自己想要把历史从一个不同的分支移植到我现在的分支上,而不需要中间分离的头部状态 换言之: git checkout foo git rebase --onto foo A^ B # results in a detached HEAD # how to avoid this last step? git checkout -B foo TL;博士 根据需要使用git cherry pick,以及(稍后),git reset或g
git-rebase--on
移植历史。然而,我经常发现自己想要把历史从一个不同的分支移植到我现在的分支上,而不需要中间分离的头部状态
换言之:
git checkout foo
git rebase --onto foo A^ B
# results in a detached HEAD
# how to avoid this last step?
git checkout -B foo
TL;博士
根据需要使用git cherry pick
,以及(稍后),git reset
或git branch-f
长的
在我回顾你已经知道的事情时,请容忍我一点,因为它们会让答案更清楚
重基通过复制提交来工作。也就是说,给定以下形式的提交图:
...--o--*--I <-- mainline
\
F--G--H <-- branch (HEAD)
正如您已经知道的,我们可以使用git-rebase--to
将要复制的提交集从它们应该到达的点分离出来。例如,与其复制所有的F-G-H
,我们可能希望将F
留在后面,只复制G
和H
:
G'-H' <-- branch (HEAD)
/
...--o--*--I <-- mainline
\
F <-- ???
\
G--H [abandoned, sort of]
其中,$stop
是,例如,commitF
rebase如何在内部工作
rebase实现这一点的方法非常简单:
saved\u branch=$(git symbolic ref-q——short HEAD)
,或多或少git rev list
和许多新奇的选项来处理所有困难的情况,但对于简单的情况,我们可以使用$stop..HEAD
git checkout——将$detach分离到(或类似的东西)
git cherry pick
,即git cherry pick$stop..$saved_分支
git branch-f$saved_branch HEAD
(或类似的东西),使保存的分支名称指向上次复制的提交。(还有一个特殊的名字ORIG_HEAD
)也有点混乱。)--on
部分。也就是说,第1步是不相关的,第2步不可能以完全相同的方式发生。第3步根本不应该发生,我们希望新的提交能够扩展当前分支
这就给我们留下了实现目标的第4步和第5步
步骤4在任何现代Git中都特别容易,其中Git cherry pick
可以处理一个序列:我们只需运行:
git cherry-pick $stop..$branch
其中,$stop
是提交时的停止(我们不希望复制的提交),而$branch
是指向我们确实希望复制的最后一次提交的分支。如果我们现在在mainline
上,那就是git cherry pick..branch
或git cherry pick branch~2..branch
,复制提交G
和H
为了实现第5步——使$branch
指向提交F
——我们将在复制完成后将此留待以后。完成这些复制后,我们可以运行:
git checkout $branch && git reset --hard $stop
或:
当我们在主线上时
TL;博士
根据需要使用git cherry pick
,以及(稍后),git reset
或git branch-f
长的
在我回顾你已经知道的事情时,请容忍我一点,因为它们会让答案更清楚
重基通过复制提交来工作。也就是说,给定以下形式的提交图:
...--o--*--I <-- mainline
\
F--G--H <-- branch (HEAD)
正如您已经知道的,我们可以使用git-rebase--to
将要复制的提交集从它们应该到达的点分离出来。例如,与其复制所有的F-G-H
,我们可能希望将F
留在后面,只复制G
和H
:
G'-H' <-- branch (HEAD)
/
...--o--*--I <-- mainline
\
F <-- ???
\
G--H [abandoned, sort of]
其中,$stop
是,例如,commitF
rebase如何在内部工作
rebase实现这一点的方法非常简单:
saved\u branch=$(git symbolic ref-q——short HEAD)
,或多或少git rev list
和许多新奇的选项来处理所有困难的情况,但对于简单的情况,我们可以使用$stop..HEAD
git checkout——将$detach分离到(或类似的东西)
git cherry pick
,即git cherry pick$stop..$saved_分支
git branch-f$saved_branch HEAD
(或类似的东西),使保存的分支名称指向上次复制的提交。(还有一个特殊的名字ORIG_HEAD
)也有点混乱。)--on
部分。也就是说,第1步是不相关的,第2步不可能以完全相同的方式发生。第3步根本不应该发生,我们希望新的提交能够扩展当前分支
这就给我们留下了实现目标的第4步和第5步
步骤4在任何现代Git中都特别容易,其中Git cherry pick
可以处理一个序列:我们只需运行:
git cherry-pick $stop..$branch
其中,$stop
是提交时的停止(我们不希望复制的提交),而$branch
是指向我们确实希望复制的最后一次提交的分支。如果我们现在在mainline
上,那就是git cherry pick..branch
或git cherry pick branch~2..branch
,复制提交G
和H
为了实现第5步——使$branch
指向提交F
——我们将在复制完成后将此留待以后。完成这些复制后,我们可以运行:
git checkout $branch && git reset --hard $stop
或:
当我们在
主线上时
@torek的回答非常好,但是