2

我是 Git 新手。

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

我怎样才能做到这一点?

4

3 回答 3

1
git checkout new_branch
git log old_branch

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

git cherry-pick <commit hash>

对于您想要的每个提交。我建议按时间顺序进行(从底部开始处理日志)。

于 2013-07-30T11:03:33.057 回答
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”。

于 2013-07-30T12:00:25.817 回答
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添加标签。这实际上真的很容易。不要在提交 C 处创建分支new_branch,而是在提交 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

实际上,您只需两个命令(上面的 3 条)就可以完成所有这些操作,git branch就像new_branchold_branch. 此外,您很可能想要到任何分支rebase -i尖端,即,而不是变基,--onto devel~1您只想变基到 (the tip of) 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创建一个新的,然后稍微清理一下。经过一次之后,我可能会决定再次修改它,所以我重命名为并在与 相同的地方创建一个新的,然后再等等。如果我想要的话,我所有的旧刺仍然存在,直到我决定不想要它们;然后我删除所有 -0 -1 -2 ... 名称。reviserebase -ireviserevise-1reviserevise-1rebase -i


脚注:上面标记为“已放弃”的提交仍然存在——它们通过 reflog 阻止垃圾收集——但最终 reflog 条目过期并且它们在git gc. 在那之前,它们大多是不可见的:例如git log --allgitk --all不会显示它们。您可以使用 运行这些命令--reflog,但即便如此,如果没有分支标签,它们仍然很难找到。我喜欢坚持一段时间,因此上面的多个分支名称工作流程。

于 2013-07-30T12:30:32.930 回答