将提交合并到一个分支中

时间:2013-07-30 10:41:25

标签: git git-cherry-pick

我是Git的新手。

我创建了一个新分支new_branch。我已完成所有更改并在另一个分支old_branch中提交。现在我想通过old_branch从分支new_branchgit cherry-pick选择一些提交。为此我首先需要知道哪个提交在该分支中,然后选择它们并与new_branch合并。

我该怎么做?

3 个答案:

答案 0 :(得分:1)

git checkout new_branch
git log old_branch

日志将在old_branch中显示每个提交,并在提交消息上方显示一个长字符串,如“cf5e845a13866239eb87f2593d6edc6e273decc5”。这是提交哈希。然后你可以做

git cherry-pick <commit hash>

为您想要的每个提交。我建议按时间顺序执行它们(从底部处理日志)。

答案 1 :(得分:0)

有很多方法可以实现这一点,这里有一对提交列表:

git log --cherry new_branch..old_branch --oneline

将显示old_branch中无法通过old_branch访问的所有提交内容。

或另一种方式:

git checkout old_branch
git cherry new_branch --abbrev=6 -v

将显示old_branch内的提交(没有引入相同更改的提交),并将标记提交以指示他们是否有-,或者还没有'+'还是樱桃 - 选入new_branch例如:

+2bdcd1 1st commit     (Has not been cherry picked)
-8de6cc 2nd Commit     (Has been cherry picked)
+8ac1ee 3nd Commit     (Has not been cherry picked)

在任何一种情况下,您都可以使用

git cherry-pick <commit>

虽然您想要在第二种情况下签出'new_branch'。

答案 2 :(得分:0)

@naomi给出的方法可以正常工作,但有一种更简单的方法。你有old_branch分支从某个其他分支的提交开始,如下所示:

A --- B --- C --- D      <-- devel (let's say it's branch devel, anyway)
        \
          E - F - G - H  <-- old_branch

你已经做了一个分支new_branch从一些提交(也许是B或C或D),你想要挑选一些提交E,F,G和/或H(也许是更长的提交字符串,但这应该说明事情。)

通常情况下,如果你想要一个未发表的工作序列(也许old_branch就是这样一个序列)并在最新的(提交D)之上“移动它”,你只需要:< / p>

$ git checkout old_branch   # get onto old_branch
$ git rebase devel          # and rebase it onto commit D in "devel"

它的作用是使提交E到H的“副本”,在“D”之后添加每个提交。然后它剥离标签old_branch(用于命名提交H)并将其粘贴到H副本上,并给出:

A --- B --- C --- D                    <-- devel
       \           \
        \           E' - F' - G' - H'  <-- old_branch
         \
          E - F - G - H                    [abandoned, see footnote]

你想要的是选择一些提交,让我们说C(无论你在上面创建new_branch的地方)并做同样的事情,但“剥离标签”{{ 1}}。此外,您想要选择E,F,G和H中的哪一个去那里。完成所有操作后,您需要添加标签old_branch。这其实很简单。而不是在提交C处创建分支new_branch,而是在提交H处创建它,new_branch的头部:

old_branch

现在$ git checkout old_branch; git checkout -b new_branch new_branch内容相同,但名称不同。

现在,您只需old_branch(互动,允许您选择)rebase -i到您想要的点。我一直在这里假设提交new_branch,我一直假设它是从名为C的分支提示后退一步,所以我将使用它:

devel

在您选择$ git rebase -i --onto devel~1 devel new_branch 允许的方式(并解决因删除某些提交而导致的任何冲突,并在解析后继续rebase -i)之后,您最终会得到类似的内容,具体取决于哪个提交你采取和删除。我假设您删除F但保留其余部分:

git rebase --continue

实际上,您只需使用两个命令即可完成此操作(上述3个命令),因为A --- B --- C --- D <-- devel \ \ \ E' - G' - H' <-- new_branch \ E - F - G - H <-- old_branch 可以在git branch的同一点创建new_branch。此外,您可能希望old_branch进入任何分支的提示,即,而不是重新定位rebase -i,您只想重新绑定到({tip}){{1} }}。在这种情况下,您毕竟不需要--onto devel~1部分:

devel

这里的结果几乎和以前一样,除了现在提交E'脱离D而不是C:

--onto

这基本上是我在重新处理未发布的更改时所做的事情。如果我在(比方说)分支$ git branch new_branch old_branch $ git rebase -i devel new_branch ,我将其重命名为A --- B --- C --- D <-- devel \ \ \ E' - G' - H' <-- new_branch \ E - F - G - H <-- old_branch ,在同一位置创建一个新revise,然后revise-0并清理一下。在一次通过之后,我可能会决定再次修改它,因此我将revise重命名为rebase -i并在与revise相同的位置创建新的revise-1,然后{{如果我想要它们的话,我所有的旧的刺都仍在那里,直到我决定我不想要它们;然后我删除所有-0 -1 -2 ......名称。


脚注:上面标记为“废弃”的提交仍然存在 - 它们通过reflog进行垃圾收集 - 但最终reflog条目到期并且它们在revise中消失。在此之前,它们几乎是不可见的:revise-1rebase -i不会显示它们。您可以使用git gc运行这些命令,但即使这样,没有分支标签,它们仍然有点难以找到。我喜欢暂时搁置它们,因此上面有多个分支名称工作流程。