如何将某些提交基于git中的另一个分支?


381

情况:

  • 师父在X
  • quickfix1在X + 2次提交时

这样:

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)

然后我开始研究quickfix2,但是偶然地将quickfix1作为要复制的源分支,而不是master。现在quickfix2是X + 2提交+ 2相关的提交。

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

现在,我想拥有一个带有quickfix2的分支,但不包含属于quickfix1的2个提交。

      q2a'--q2b' (quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

我试图从quickfix2中的某个修订版本创建补丁,但该补丁不保留提交历史记录。有没有一种方法可以保存我的提交历史记录,但是有一个分支没有在quickfix1中进行任何更改?



8
@Kevin该问题仅询问有关将提交从一个分支移动到另一分支的问题,该问题还有包括on上的提交的附加要求quickfix1。(还请注意答案的差异。)
Scott Weldon

Answers:


372

这是一个典型的案例rebase --onto

 # let's go to current master (X, where quickfix2 should begin)
 git checkout master

 # replay every commit *after* quickfix1 up to quickfix2 HEAD.
 git rebase --onto master quickfix1 quickfix2 

所以你应该从

o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

至:

      q2a'--q2b' (new quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

最好在干净的工作树上完成此操作。
请参阅git config --global rebase.autostash true,尤其是在Git 2.10之后


24
请注意,这些步骤将修改quickfix2的历史记录,因此,如果您已经共享了该分支,请改用选择樱桃(请参阅以下答案)。
Max Chernyak

仅作记录:使用SmartGit的日志将其q2a拖到X并从发生的对话框的选项中选择Rebase 2 commits
Thomas S.

1
@ThomasS。有趣。那是一个不错的GUI实现git rebase --onto
VonC

1
我必须承认,我确实做了一些愚蠢的事情,例如我确实应该更频繁地提交到错误的分支,SmartGit日志视图GUI在相同情况下为我节省了很多时间。
2015年

1
@Cosine同意。我已经编辑了答案,添加了对rebase.autostash配置的引用:这样可以避免在进行重新设置基准时丢失工作树中正在进行的工作。
VonC

155

您可以git cherry-pick用来仅选择要复制的提交。

最好的方法可能是在master之外创建分支,然后在该分支中使用git cherry-pick所需的quickfix2的2次提交。


如果只想移动一次提交,这也是最佳选择。谢谢。
亚历克斯

142

您可以做的最简单的事情就是挑选一个范围。它的功能与相同,rebase --onto但对眼睛更容易:)

git cherry-pick quickfix1..quickfix2

6
另外,它不会丢失原始提交,即IIUC,因此对于像我这样的“安全游戏”而言似乎更可取;)还是rebase --onto还保留了原始更改?
akavel 2013年

6
两者,rebasecherry-pick为您提供新的SHA密钥。这是因为每次提交都是存储库的唯一快照。
Christoph

6
@akavel的意思是Cherry-pick将原始提交保留在其分支中,这是正确的
Mr_and_Mrs_D 2014年

4
无论值多少,我都尝试cherry-pick在此答案中找到一个范围,这使我的回购感到困惑。cherry-pick对于每次提交,我都必须进行个人操作。(也许不用说,但是如果有人在挣扎,您必须cherry-pick按照提交的时间顺序排列。)
carmenism

3
git checkout在这里至关重要。你的头是什么:)?
斯瓦沃米尔Lenart

28

我相信是:

git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2

3
cherry-pick可与提交哈希一起使用,因此,如果您只想从某个地方获取一个提交并将其放在其他位置,这就是方法。只要确保您checkout <branch>首先对正确的分支进行操作即可。
约翰·莱德格伦

-1
// on your branch that holds the commit you want to pass
$ git log
// copy the commit hash found
$ git checkout [branch that will copy the commit]
$ git reset --hard [hash of the commit you want to copy from the other branch]
// remove the [brackets]

其他更有用的命令,并附有说明:Git指南

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.