2013-07-30 112 views
2

我是Git的新手。在分支中合并提交

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

我该怎么做?

+0

你想从old_branch中选择所有提交到new_branch吗?如果是这样,只要做“git checkout new_branch; git合并old_branch” – naomi

+0

不,我不想挑选所有提交,但其中一些。 – Joy

回答

1
git checkout new_branch 
git log old_branch 

的记录会显示在old_branch每次提交,有长长的一串像“cf5e845a13866239eb87f2593d6edc6e273decc5”,就在提交信息上面。这是提交哈希。你可以做

git cherry-pick <commit hash> 

你想要的每个提交。我会建议按照时间顺序进行操作(从底部开始处理日志)。

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'。

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)的顶部“移动它”,你只是做:

$ 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)和做同样的事情,但不“撕下标签” old_branch。此外,您要挑选E,F,G和H中的哪一个去那里。完成全部工作后,您需要添加标签new_branch。这其实很简单。而不是创建分支new_branch在提交C,创建它在提交H,的old_branch头:

$ git checkout old_branch; git checkout -b new_branch 

现在new_branchold_branch相同内容明智的,但有不同的名称。

现在你可以简单地rebase -i(互动,让你挑选)new_branch到你想要的点。我一直在假设犯C在这里,这是我一直在假设是从名为devel分支尖退一万步,所以我会与运行:你挑选后

$ git rebase -i --onto devel~1 devel new_branch 

和选择的方式rebase -i允许(并解决删除某些提交和git rebase --continue解决后继续任何冲突),你会拥有这样的事情,这取决于你承诺采取和删除。我假设你删除F,但保持休息:

A --- B --- C --- D     <-- devel 
     \  \ 
     \  E' - G' - H'   <-- new_branch 
     \ 
      E - F - G - H    <-- old_branch 

实际上,你可以做到这一切,只有两个命令(VS以上3),作为git branch可以在相同的点old_branch创建new_branch。此外,它很可能要rebase -i尖任何分支,即,而不是重订--onto devel~1你只是想变基到devel(尖)。在这种情况下,你并不需要在所有的--onto部分:

$ git branch new_branch old_branch 
$ git rebase -i devel new_branch 

这里的结果几乎与以前一样,除了现在提交E”脱落d,而不是C:

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,并在与revise-1相同的位置创建新的revise,然后再次rebase -i等等。我所有的旧东西都在那里刺伤如果我想要他们,直到我决定我不想要他们;然后我删除所有的-0 -1 -2 ...名称。


脚注:在犯下标有“抛弃”上面仍通过引用日志,但最终进入reflog了对垃圾收集关押在那里 - 他们会过期,走在git gc。直到这时他们大多是无形的:git log --allgitk --all不会告诉他们,例如。你可以用--reflog运行这些命令,但即使是这样,无分支的标签,他们仍然有点棘手找到。我喜欢挂在他们上面一段时间,因此上面的多分支名称工作流程。

+0

我不会说这很容易,但对于像我们这样的聪明才智的人来说更令人满意。对于git初学者来说,阅读和理解它涉及的概念需要一到几个小时,所以naomi的实际上更容易 – CharlesB

相关问题