如何挑选选定的一组提交?

How to cherry-pick selected set of commits?

我想 select 特定的一组提交被挑选到一个新分支。

main-branch
* commit8
* commit7
* commit6
* commit5
* commit4
* commit3
* commit2
* commit1

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

release-branch
* commit7
* commit6
* commit4
* commit2
* commit1

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

tl;dr:使用 git rebase -i

可能更好

我想我没有看到您希望从标记中得到什么。为了避免说

git cherry-pick commit

对于每次提交,您会说

git tag my_tag commit

then 实际上仍然需要 运行 脚本来复制提交......这比手动完成更多的工作。 (另外,上面的标签命令不会像你想要的那样工作,因为给定的标签正好指向 one 对象;所以你必须使用很多标签,并且让你的 cherry-选择脚本找到所有这些...)

这并不是说手动挑选是最好的方法。 cherry-pick的要点就是抢"that one change I need";如果你需要处理整个分支,使用 git rebase 可能更容易。 rebase 操作经常被误解;它复制提交,很像 cherry-pick。 (人们似乎常常认为它 "replaces" 提交,删除原件;这不完全正确。它可以改变 ref 的历史,但仅此而已。)

例如,如果您从

开始
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(散列)也可以。我选择了 B 因为 C 是您不想保留的第一个提交 - 所以重写在 B 之后开始。如果您想删除 A,您可以使用解析为 [=如果 A 有父代,则为 24=] 的父代;如果 A 没有父代,则使用 --root。)

现在 git 将打开一个编辑器并向您显示一个 "todo" 列表,其中一行表示您分支中返回(但不包括)B 的每个提交。对于要删除的提交,将该提交行上的第一个单词从 pick 更改为 drop(或者只删除该行)。

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

完成后您将拥有

A -- B -- C -- D -- E -- F -- G -- H <--(main-branch)
      \
       D' -- F' -- G' <--(release-branch)

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

这并非没有潜在的缺点(尽管 rebase 的缺点与 cherry-pick 的缺点相同);这真的取决于你将如何处理这里的分支。如果 release-branch 只是您将释放并忘记的最终状态,那可能没问题。如果您可能需要修补该版本,您会发现 release-branchmain-branch 之间的合并可能很困难;那么您可能必须使用 cherry-pickrebase 来在版本和您的主要开发线之间共享修复。