Git的cherry picking如何进行合并跟踪?

29
例如,我有一个 dev 分支和一个 stable 分支。
假设我从 dev 分支挑选了几个提交合并到了 stable 分支。
是否有一种方法让 Git 感知到这些挑选的提交,并在以后从 dev 合并、变基或挑选重叠范围时避免二次合并呢?(而这是 SVN 中的基本合并跟踪功能)

虽然您可能有充分的理由这样做,但是将太多的提交挑选到一个分支中通常是不明智的。 - Noufal Ibrahim
3个回答

15

值得注意的是,对于cherry-pick命令,-x选项会将原始提交的SHA添加到提交消息的末尾。

我也喜欢在提交摘要的末尾添加简短的SHA,以便在查看日志时更容易将挑选的提交与原始提交关联起来。使用-s签名选项指示谁进行了挑选也可能很有帮助。

例如:

> git cherry-pick -sex 27d4985

#333: fixes all the things (27d4985)

- how it fixes all the things

(cherry picked from commit 27d49855238364d0184ad344884a366b5b16e)

Signed-off-by: Chuck Norris <chuck@example.com>

12
git cherry-pick 是一个有趣的案例,它实际上是 git rebase 而不是 git merge,因此它会重写你挑选的提交,以便将相同的更改应用于你挑选的分支顶部。由于 git 提交的 id 是基于提交内容的,所以新提交具有不同的 id,因此 git 将其视为完全不同的提交。
另一方面,git merge 则创建一个合并提交;这是 git 实现合并跟踪的手段。合并提交标记了两个(或多个)分叉历史汇聚的点。可以调用 git merge [commit-id] 而不是 git cherry-pick [commit-id] 显式地创建一个合并提交,但这不仅带来了单个挑选的提交的影响,还带来了该分支分叉历史中的整个更改集。
总之,在 git 中,“双重合并”通常不是问题。如果尝试合并包含已经存在的变更集的历史记录,则在将历史记录粘合在一起时它将成为 no-op;git 真正关心的只是每个提交中树的状态,而不是将其置于该状态的更改。

1
仅仅做个结论:无法追踪精选的提交。但是在GIT中双重合并通常不是问题,对吗?我对后面这个说法感到有些不确定。我没有看到GIT设计中有什么特别之处,可以使双重合并比其他版本控制系统(如SVN)更少出现问题。 - Adrian Shum
@Adrian:同意双重合并。如果在两次(相同的)合并之间合并目标发生了变化,就会存在潜在的问题。 - schoetbi

5

实际上有一个名为git cherry的命令,它会打印出在两个分支之间未合并的每个提交。

对于每个打印的提交,“+”符号表示您可以合并它,“-”符号表示您已经挑选了该提交。

输出结果远非美观。

对于那些来自SVN并习惯于svnmerge.py的人,我为git制作了一个“svnmerge avail -l”等效的bash脚本,我称之为gitavail:

#!/bin/bash

# get current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

# get tracked branch (1st argument), if no arg or arguments are only options, assume master
if test -z $1 || grep -q '^-' <<< $1;
then TRACKED_BRANCH=master
else TRACKED_BRANCH=$1; shift
fi

# Log commits available for merge from tracked branch
LOG_OPTIONS=$*
for i in $(git cherry $CURRENT_BRANCH $TRACKED_BRANCH | egrep '^\+' | awk '{print $2}'); do git --no-pager log -n1 $i ${LOG_OPTIONS}; echo; done

假设你正在一个分支上,并且想要列出可以从主分支合并的内容,只需运行以下命令:
gitavail --name-status

您将获得与 "svnmerge avail -l" 非常相似的输出。

我猜测cherry-pick提交不能手动修改(冲突怎么办?),如果 patch id 发生变化,git cherry 将无法意识到该提交已被cherry-pick。


虽然我还没有机会尝试这个,但它似乎正好符合我的要求。 :) +1 和采纳答案给你 :) - Adrian Shum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接