简体中文 ▾ 主题 ▾ 最新版本 ▾ git-cherry-pick 最后更新于 2.54.0

名称

git-cherry-pick - 应用现有的提交所引入的变更

概要

git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]
		  [-S[<keyid>]] <commit>…​
git cherry-pick (--continue | --skip | --abort | --quit)

描述

给定一个或多个现有的提交,应用它们各自引入的变更,并为每一个变更记录一个新的提交。这要求您的工作树必须是干净的(不能有相对于 HEAD 提交的任何修改)。

当如何应用某个变更不明确时,会发生以下情况:

  1. 当前分支和 HEAD 指针会停留在最后一次成功创建的提交上。

  2. CHERRY_PICK_HEAD 引用被指向那个难以应用的变更所对应的提交。

  3. 成功应用变更的路径会同时在索引文件和工作树中得到更新。

  4. 对于存在冲突的路径,索引文件会记录多达三个版本,详见 git-merge[1] 中的“真正的合并”(TRUE MERGE)章节。工作树中的文件将包含冲突描述,并由常见的冲突标记 <<<<<<<>>>>>>> 包围。

  5. 不会进行其他任何修改。

请参阅 git-merge[1] 以获取解决此类冲突的建议。

选项

<commit>…​

要拣选(cherry-pick)的提交。关于指定提交方式的更完整列表,请参阅 gitrevisions[7]。可以传递一组提交,但默认情况下不会进行遍历(如同指定了 --no-walk 选项),详见 git-rev-list[1]。请注意,指定一个范围会将所有的 <commit>…​ 参数输入到单一的修订版本遍历中(参见后续使用 maint master..next 的示例)。

-e
--edit

使用此选项,git cherry-pick 会允许您在提交前编辑提交信息。

--cleanup=<mode>

此选项决定了在传递给提交机制之前如何清理提交信息。详细信息请参阅 git-commit[1]。特别地,如果 <mode> 的值被设为 scissors,则在发生冲突时,剪刀标记将被追加到 MERGE_MSG 中再进行传递。

-x

在记录提交时,在原始提交信息的末尾追加一行 "(cherry picked from commit …​)",以标明此变更源自哪个提交。这仅在没有冲突的拣选操作中执行。如果您是从私有分支进行拣选,请勿使用此选项,因为该信息对接收者毫无用处。另一方面,如果您是在两个公开可见的分支之间进行拣选(例如从开发分支向旧版本维护分支补齐修复),添加此信息则很有用。

-r

以前该命令默认执行上述的 -x,而 -r 是为了禁用它。现在默认不执行 -x,因此该选项现在是一个空操作(no-op)。

-m <parent-number>
--mainline <parent-number>

通常您无法拣选一个合并提交,因为您不知道合并的哪一边应被视为主线。此选项指定主线的父编号(从 1 开始),并允许 cherry-pick 相对于指定的父提交重放变更。

-n
--no-commit

通常该命令会自动创建一系列提交。此标志将拣选每个指定提交所需的变更应用到您的工作树和索引中,而不进行实际提交。此外,使用此选项时,您的索引不需要与 HEAD 提交匹配。拣选操作是针对您索引的初始状态进行的。

这在连续将多个提交的效果拣选到索引中时非常有用。

-s
--signoff

在提交信息的末尾添加一行 Signed-off-by 签名。详细信息请参阅 git-commit[1] 中的 signoff 选项。

-S[<keyid>]
--gpg-sign[=<keyid>]
--no-gpg-sign

GPG 签名提交。*keyid* 参数是可选的,默认为提交者身份;如果指定,则必须将其紧贴选项,中间无空格。*--no-gpg-sign* 对于抵消 *commit.gpgSign* 配置变量和先前的 *--gpg-sign* 非常有用。

--ff

如果当前 HEAD 与被拣选提交的父提交相同,则会执行到该提交的快进(fast-forward)。

--allow-empty

默认情况下,拣选一个空提交会失败,提示需要显式调用 git commit --allow-empty。此选项会覆盖该行为,允许在拣选中自动保留空提交。请注意,当启用 "--ff" 时,即使没有此选项,符合“快进”要求的空提交也会被保留。另请注意,此选项仅保留最初就是空的提交(即该提交记录的树与父提交相同)。由于先前的提交而变为空的提交会导致拣选失败。要强制包含这些提交,请使用 --empty=keep

--allow-empty-message

默认情况下,拣选一个信息为空的提交会失败。此选项覆盖该行为,允许拣选信息为空的提交。

--empty=(drop|keep|stop)

如何处理那些与当前历史中已有的变更重复的拣选提交。

drop

该提交将被丢弃。

keep

该提交将被保留。暗示使用 --allow-empty

stop

当应用该提交时,拣选操作将停止,允许您检查该提交。这是默认行为。

请注意,--empty=drop--empty=stop 仅指定如何处理原本非空但因先前的提交而变为空的提交。除非指定了 --empty=keep--allow-empty,否则最初就是空的提交仍会导致拣选失败。

--keep-redundant-commits

--empty=keep 的已弃用别名。

--strategy=<strategy>

使用指定的合并策略。应该只使用一次。有关详细信息,请参阅 git-merge[1] 中的“合并策略”部分。

-X<option>
--strategy-option=<option>

将合并策略特定的选项传递给合并策略。有关详细信息,请参阅 git-merge[1]

--rerere-autoupdate
--no-rerere-autoupdate

在 rerere 机制对当前冲突重用已记录的解决方案以更新工作区中的文件后,允许它同时使用解决方案的结果更新索引。--no-rerere-autoupdate 是在将结果提交到索引之前,通过单独的 git-add[1] 仔细检查 git-rerere[1] 所做操作并捕获潜在错误合并的好方法。

序列化器子命令

--continue

使用 .git/sequencer 中的信息继续正在进行的操作。可用于在解决拣选或还原(revert)失败产生的冲突后继续操作。

--skip

跳过当前提交,继续进行序列中的其余操作。

--quit

放弃当前正在进行的操作。可用于在拣选或还原失败后清除序列化器状态。

--abort

取消操作并返回到序列化之前的状态。

示例

git cherry-pick master

应用 master 分支尖端的提交所引入的变更,并创建一个包含此变更的新提交。

git cherry-pick ..master
git cherry-pick ^HEAD master

应用所有属于 master 的祖先但非 HEAD 的祖先的提交所引入的变更,以生成新提交。

git cherry-pick maint next ^master
git cherry-pick maint master..next

应用所有属于 maint 或 next 的祖先,但不属于 master 或其任何祖先的提交所引入的变更。注意,后者并不意味着 maintmasternext 之间的所有提交;特别地,如果 maint 包含在 master 中,则不会使用 maint

git cherry-pick master~4 master~2

应用由 master 指向的倒数第五个和倒数第三个提交所引入的变更,并为这些变更创建 2 个新提交。

git cherry-pick -n master~1 next

将 master 指向的倒数第二个提交以及 next 指向的最后提交所引入的变更应用到工作树和索引中,但不为这些变更创建任何提交。

git cherry-pick --ff ..next

如果历史是线性的且 HEAD 是 next 的祖先,则更新工作树并将 HEAD 指针前移以匹配 next。否则,将 next 中有而 HEAD 中没有的提交所引入的变更应用到当前分支,并为每个新变更创建一个新提交。

git rev-list --reverse master -- README | git cherry-pick -n --stdin

将 master 分支上所有修改了 README 的提交所引入的变更应用到工作树和索引中,以便可以对其进行检查,并在合适时合并为一个新的提交。

以下序列尝试向后移植(backport)补丁,由于补丁应用的代码变化过大而中断,然后再次尝试,这次更加注意匹配上下文行。

$ git cherry-pick topic^             (1)
$ git diff                           (2)
$ git cherry-pick --abort            (3)
$ git cherry-pick -Xpatience topic^  (4)
  1. 应用 git show topic^ 显示的变更。在此示例中,补丁未干净地应用,因此有关冲突的信息被写入索引和工作树,没有产生新提交。

  2. 总结需要协调的变更

  3. 取消拣选。换句话说,返回到拣选之前的状态,保留您在工作树中所做的任何本地修改。

  4. 再次尝试应用由 topic^ 引入的变更,花费额外时间以避免因错误匹配上下文行而导致的错误。

另请参阅

GIT

Git[1] 套件的一部分