如何挑选选定的提交集?

Gop*_*lki 2 git github cherry-pick

我想选择特定的提交集来挑选到新分支。

main-branch
* commit8
* commit7
* commit6
* commit5
* commit4
* commit3
* commit2
* commit1
Run Code Online (Sandbox Code Playgroud)

我只想创建一个包含选定提交的发布分支。

release-branch
* commit7
* commit6
* commit4
* commit2
* commit1
Run Code Online (Sandbox Code Playgroud)

是否可以为所需的提交关联一个标签,并编写一个脚本来用特定标签挑选提交?

Mar*_*ger 5

tl;dr:可能更好用git rebase -i


我想我不明白你希望从标记中得到什么。为了避免说

git cherry-pick commit
Run Code Online (Sandbox Code Playgroud)

对于每个提交你会说

git tag my_tag commit
Run Code Online (Sandbox Code Playgroud)

然后仍然需要实际运行脚本来复制提交...这比手动执行更多工作。(另外,上述标签命令不会按您想要的方式工作,因为给定的标签恰好指向一个对象;因此您必须使用许多标签,并让您的cherry-pick脚本找到所有这些标签...)

这并不是说手动挑选是最好的方法。择优挑选的要点是抓住“我需要的那个改变”;如果您需要处理整个分支,那么使用git rebase. 该rebase操作经常被误解;它复制提交,很像cherry-pick。(人们似乎常常认为它“替换”了提交,删除了原始提交;这并不完全正确。它可以改变引用的历史,但仅此而已。)

例如,如果您从

A -- B -- C -- D -- E -- F -- G -- H <--(main-branch)
Run Code Online (Sandbox Code Playgroud)

你可以

git checkout main-branch
git checkout -b release-branch
git rebase -i master~6
Run Code Online (Sandbox Code Playgroud)

(我之所以使用它,是因为它是一个引用;的对象 ID(哈希)master~6的表达式。我选择它是因为它是您不想保留的第一个提交 - 所以重写是在 ; 之后开始的。如果您想删除,如果有父级,则可以使用解析为 的父级的表达式,如果没有父级,则可以使用解析为的父级。)BBBCBAAA--rootA

现在 git 将打开一个编辑器并显示一个“待办事项”列表,其中分支中的每个提交都一行一行返回(但不包括)B。对于要删除的提交,将该提交行的第一个单词从 更改为pickdrop或直接删除该行)。

当您退出编辑器时,变基操作将开始“复制”提交(即在新基础上进行相同更改的新提交)。在每个步骤中,都可能存在冲突(如果稍后提交中的更改取决于您删除的早期提交中的更改);系统将提示您解决这些问题并继续变基操作。

完成后你将拥有

A -- B -- C -- D -- E -- F -- G -- H <--(main-branch)
      \
       D' -- F' -- G' <--(release-branch)
Run Code Online (Sandbox Code Playgroud)

其中应用与等D'相同的更改。D

这并非没有潜在的缺点(尽管缺点与 的缺点相同rebasecherry-pick;这实际上取决于您将如何处理这里的分支。如果release-branch只是一个最终状态,您将释放它并忘记,那可能没问题。如果您可能需要修复版本,您会发现release-branch和之间的合并main-branch可能很困难;因此,您可能必须使用cherry-pickrebase共享发行版和主要开发线之间的修复程序。