cra*_*yte 599 git git-merge git-cherry-pick
我有以下存储库布局:
我想要实现的是从工作分支中挑选一系列提交并将其合并到集成分支中.我是git的新手,我无法弄清楚如何正确地做到这一点(在一次操作中不提取合并的樱桃选择提交范围)而不会弄乱存储库.关于这个的任何指针或想法?谢谢!
Von*_*onC 767
当涉及到一系列的提交,采摘樱桃 是 是不实际的.
正如Keith Kim 在下面提到的,Git 1.7.2+引入了挑选一系列提交的能力(但是你仍然需要知道未来合并的挑选的结果)
git cherry-pick"学会选择一系列提交
(例如"cherry-pick A..B
"和"cherry-pick --stdin
"),所以"git revert
";这些不支持更好的排序控制"rebase [-i]
".
在"
cherry-pick A..B
"形式,A
应该比年龄大B
.
如果它们的顺序错误,命令将无声地失败.
如果你想挑选范围B
通过D
(含),这将是B^..D
.
请参阅" Git从先前提交范围创建分支? "作为示例.
这假设
B
不是root提交;unknown revision
否则你会得到一个" "错误.
注意:从Git 2.9.x/2.10(2016年第3季度)开始,您可以直接在孤儿分支(空头)上挑选一系列提交:请参阅" 如何在git中使现有分支成为孤儿 ".
原始答案(2010年1月)
A rebase --onto
会更好,你可以在集成分支上重放给定的提交范围,正如Charles Bailey在这里所描述的那样.
(另外,在git rebase手册页中查找"以下是如何将基于一个分支的主题分支移植到另一个分支" ,以查看实际示例git rebase --onto
)
如果您当前的分支是集成:
# Checkout a new temporary branch at the current location
git checkout -b tmp
# Move the integration branch to the head of the new patchset
git branch -f integration last_SHA-1_of_working_branch_range
# Rebase the patchset onto tmp, the old location of integration
git rebase --onto tmp first_SHA-1_of_working_branch_range~1 integration
Run Code Online (Sandbox Code Playgroud)
这将重播之间的一切:
first_SHA-1_of_working_branch_range
(因此~1
)的父项之后:您要重播的第一个提交integration
"(指向您要重播的最后一次提交,来自working
分支)到" tmp
"(integration
指向之前指向的位置)
如果重播其中一个提交时有任何冲突:
git rebase --continue
".git rebase --skip
"git rebase --abort
" 取消所有东西(并将integration
分支放回tmp
分支)之后rebase --onto
,integration
将返回到集成分支的最后一次提交(即" tmp
"分支+所有重放的提交)
选择樱桃,或者rebase --onto
不要忘记它会对后续合并产生影响,如此处所述.
这里讨论一个纯粹的" cherry-pick
"解决方案,它将包含以下内容:
如果你想使用补丁方法,那么"git format-patch | git am"和"git cherry"是你的选择.
目前,git cherry-pick
只接受单一的承诺,但如果你想选择的范围内B
通过D
,这将是B^..D
在git的行话,所以
git rev-list --reverse --topo-order B^..D | while read rev
do
git cherry-pick $rev || break
done
Run Code Online (Sandbox Code Playgroud)
但无论如何,当你需要"重放"一系列提交时,"重放"一词应该会促使你使用rebase
Git 的" "特性.
小智 134
从git v1.7.2开始,cherry pick可以接受一系列提交:
git cherry-pick
学会了选择一系列提交(例如cherry-pick A..B
和cherry-pick --stdin
),也是如此git revert
; 但是,这些不支持更好的测序控制rebase [-i]
.
Kos*_*asA 32
假设你有2个分支,
"branchA":包括要复制的提交(从"commitA"到"commitB")
"branchB":您希望从"branchA"传输提交的分支
1)
git checkout <branchA>
Run Code Online (Sandbox Code Playgroud)
2)获取"commitA"和"commitB"的ID
3)
git checkout <branchB>
Run Code Online (Sandbox Code Playgroud)
4)
git cherry-pick <commitA>^..<commitB>
Run Code Online (Sandbox Code Playgroud)
5)如果您有冲突,请解决并输入
git cherry-pick --continue
Run Code Online (Sandbox Code Playgroud)
继续樱桃采摘过程.
djs*_*djs 26
你确定你不想真正合并分支吗?如果工作分支有一些你不想要的最近提交,你可以在你想要的位置创建一个带有HEAD的新分支.
现在,如果你真的想要挑选一系列提交,无论出于何种原因,一个优雅的方法是只需要一个补丁集并将其应用到你的新集成分支:
git format-patch A..B
git checkout integration
git am *.patch
Run Code Online (Sandbox Code Playgroud)
这基本上就是git-rebase正在做的事情,但不需要玩游戏.您可以添加--3way
到git-am
,如果你需要合并.如果您逐字按照说明操作,请确保在您执行此操作的目录中没有其他*.patch文件...
Sai*_*pta 26
例如git cherry-pick 3a7322ac^..7d7c123c
假设您位于要从branchA
中选择提交的位置(给出了范围的开始和结束提交 SHA,而左侧提交 SHA 较旧)branchB
。整个提交范围(包括两者)都将在branchA
.
官方文档中给出的例子非常有用。
我将VonC的代码包装成一个简短的bash脚本git-multi-cherry-pick
,以便于运行:
#!/bin/bash
if [ -z $1 ]; then
echo "Equivalent to running git-cherry-pick on each of the commits in the range specified.";
echo "";
echo "Usage: $0 start^..end";
echo "";
exit 1;
fi
git rev-list --reverse --topo-order $1 | while read rev
do
git cherry-pick $rev || break
done
Run Code Online (Sandbox Code Playgroud)
我正在使用这个,因为我重建了一个项目的历史,该项目的第三方代码和自定义在同一个svn主干中混合在一起.我现在将核心第三方代码,第三方模块和自定义分离到他们自己的git分支上,以便更好地理解未来的自定义.git-cherry-pick
在这种情况下有用,因为我在同一个存储库中有两棵树,但是没有共享的祖先.
git cherry-pick FIRST^..LAST
仅适用于简单场景。
为了实现像样的“将其合并到集成分支”,同时具有通常的舒适度,例如自动跳过已经集成的选择、移植钻石合并、交互式控制......)最好使用变基。这里的一个答案指出了这一点,但是该协议包含了一个冒险git branch -f
和与临时分支的杂耍。这是一个直接的稳健方法:
git rebase -i FIRST LAST~0 --onto integration
git rebase @ integration
Run Code Online (Sandbox Code Playgroud)
允许-i
交互式控制。~0
如果 LAST 是分支名称,则可确保分离的变基(不移动/另一个分支)。否则可以省略。第二个 rebase 命令只是integration
以安全的方式将分支引用移动到中间分离头 - 它不会引入新的提交。要使用合并菱形等对复杂结构进行变基,请在第一个变基中考虑--rebase-merges
或 。--rebase-merges=rebase-cousins
几天前,在阅读了 Vonc 非常清晰的解释后,我对此进行了测试。
dev
: ABCDEFGHIJtarget
: ABCDE
也不H
dev_feature_wo_E_H
git checkout dev
git checkout -b dev_feature_wo_E_H
git rebase --interactive --rebase-merges --no-ff D
我放在变基编辑器drop
前面E
和里面的地方H
commit
dev_feature_wo_E_H
。git checkout target
git merge --no-ff --no-commit dev_feature_wo_E_H
commit
cherry-pick
我这样做是因为前几天做了太多事
git cherry-pick
功能强大且简单,但是
merge
我必须解决初始提交和重复提交的冲突,因此对于一两个cherry-pick
,“择优挑选”是可以的,但对于更多,它太冗长了,分支将变得太复杂 归档时间: |
|
查看次数: |
322351 次 |
最近记录: |