我是Git的新手。
我创建了一个新分支new_branch
。我已完成所有更改并在另一个分支old_branch
中提交。现在我想通过old_branch
从分支new_branch
到git cherry-pick
选择一些提交。为此我首先需要知道哪个提交在该分支中,然后选择它们并与new_branch
合并。
我该怎么做?
答案 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-1
和rebase -i
不会显示它们。您可以使用git gc
运行这些命令,但即使这样,没有分支标签,它们仍然有点难以找到。我喜欢暂时搁置它们,因此上面有多个分支名称工作流程。