我想选择一组特定的提交,以选择性地选择到一个新分支。
main-branch
* commit8
* commit7
* commit6
* commit5
* commit4
* commit3
* commit2
* commit1
我只想创建一个带有选定提交的发布分支。
release-branch
* commit7
* commit6
* commit4
* commit2
* commit1
是否可以为所需的提交关联一个标记,并编写一个脚本来挑选与特定标记的提交?
tl;dr:可能最好使用git rebase -i
我想我看不出你期望从标记中得到什么。避免说
git cherry-pick commit
对于每个提交,你会说
git tag my_tag commit
然后仍然需要实际运行脚本来复制提交。。。这比手动操作要多得多。(此外,上面的标记命令不能按您的意愿工作,因为给定的标记正好指向一个对象;因此您必须使用许多标记,并让您的樱桃采摘脚本找到所有这些标记…(
这并不是说手工采摘樱桃是最好的方式。樱桃采摘的目的是抓住"我需要的一个改变";如果您需要处理整个分支,那么使用git rebase
可能更容易。rebase
操作经常被误解;它复制提交,很像cherry-pick。(人们似乎经常认为它"取代"了提交,删除了原始文件;这并不完全正确。它可以改变引用的历史,但这就是范围。(
例如,如果你从开始
A -- B -- C -- D -- E -- F -- G -- H <--(main-branch)
你可以
git checkout main-branch
git checkout -b release-branch
git rebase -i master~6
(我之所以使用master~6
,是因为它是一个引用B
的表达式;B
的对象ID(hash(也可以。我选择B
是因为C
是您不想保留的第一个提交,所以重写在B
之后开始。如果要删除A
,如果A
有父级,则可以使用解析为A
的父级的表达式;如果A
没有父级,可以使用--root
。(
现在git将打开一个编辑器,并向您显示一个"todo"列表,分支中的每个提交都有一行返回(但不包括(B
。对于要删除的提交,将该提交行上的第一个单词从pick
更改为drop
(或者只删除该行(。
当您退出编辑器时,rebase操作将开始"复制"提交(即,在新的基础上进行应用相同更改的新提交(。在每一步中,都可能存在冲突(如果稍后提交中的更改取决于您删除的先前提交中的变更(;系统将提示您解决这些问题并继续重新设置基础操作。
当它完成后,你会有
A -- B -- C -- D -- E -- F -- G -- H <--(main-branch)
D' -- F' -- G' <--(release-branch)
其中D'
应用与D
等相同的改变。
这并非没有潜在的缺点(尽管rebase
的缺点与cherry-pick
的缺点相同(;这真的取决于你将如何处理这里的树枝。如果release-branch
只是一个你会释放并忘记的终端状态,那么它可能很好。如果您可能需要对发布进行修补,您会发现release-branch
和main-branch
之间的合并可能很困难;因此,您可能必须使用cherry-pick
或rebase
在发布版和您的主要开发线之间共享修复程序。