例如,我有一个dev
分支和一个stable
分支。
dev
以防我从to中挑选了几个提交stable
。
有什么方法可以让 Git 知道樱桃挑选的提交,并避免双重合并它,如果我以后合并、变基或挑选重叠的范围,从dev
back 到stable
? (这是 SVN 中的基本合并跟踪功能)
例如,我有一个dev
分支和一个stable
分支。
dev
以防我从to中挑选了几个提交stable
。
有什么方法可以让 Git 知道樱桃挑选的提交,并避免双重合并它,如果我以后合并、变基或挑选重叠的范围,从dev
back 到stable
? (这是 SVN 中的基本合并跟踪功能)
同样值得注意的是,该-x
标志cherry-pick
将原始提交的 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>
git cherry-pick
是git rebase
而不是的一个有趣的例子git merge
,所以它实际上重写了你选择的提交,所以它会将相同的更改应用到你选择的分支的顶部。由于 git 的提交 id 基于提交的内容,因此新提交具有不同的 id,因此被 git 视为完全不同的提交。
git merge
,另一方面,创建一个合并提交;这是 git 实现合并跟踪的方式。合并提交标志着两个(或更多)不同的历史汇聚的点。调用git merge [commit-id]
而不是git cherry-pick [commit-id]
显式创建合并提交是可以接受的,但这不仅会带来单个精选提交的效果,还会带来该分支不同历史记录中的整个更改集。
尽管如此,“双重合并”在 git 中通常不是问题。如果您尝试与包含已经存在的变更集的历史合并,那么当历史粘合在一起时,它将变成无操作;git 真的只关心每次提交中树的状态,而不关心使它进入该状态的更改。
实际上有一个名为 git cherry的命令会打印两个分支之间未合并的每个提交。
对于每个打印的提交,“+”号表示您可以合并它,“-”号表示您已经挑选了该提交。
输出远非漂亮。
对于那些来自 SVN 并且习惯于svnmerge.py的人,我为 git 制作了一个“svnmergeavail -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
假设您在一个分支上,并且您想列出可以从 master 分支合并的内容,只需运行:
gitavail --name-status
你会得到一个非常类似于“svnmergeavail -l”的输出。
我猜不能手动修改 cherry-pick 提交(冲突呢?),如果补丁 id更改,git cherry 不会意识到提交已经被挑选过。