乐闻世界logo
搜索文章和话题

How to cherry pick multiple commits

2个答案

1
2

When using Git for version control, cherry-pick is a feature that allows developers to select one or more commits from one branch and apply them to the current branch. This is particularly useful when you want to apply specific commits to your branch instead of merging the entire branch's content.

To pick multiple commits individually, you can repeatedly use the git cherry-pick command followed by the commit hashes you want to select. For example:

sh
git cherry-pick commit_hash1 git cherry-pick commit_hash2 git cherry-pick commit_hash3

Each time you run cherry-pick, it applies the specified commit to the current branch.

If you want to pick a series of consecutive commits at once, you can use the following command:

sh
git cherry-pick commit_hash1^..commit_hash3

In this example, commit_hash1^ refers to the parent commit of commit_hash1, and commit_hash3 is the last commit you want to pick. The above command will pick all commits between commit_hash1 and commit_hash3 (including both).

If you want to pick non-consecutive commits, you can list all the commit hashes you want to select in a single git cherry-pick command, separated by spaces. For example:

sh
git cherry-pick commit_hash1 commit_hash3 commit_hash5

This will apply the commits commit_hash1, commit_hash3, and commit_hash5 individually.

When performing a cherry-pick operation, conflicts may occur. If conflicts arise, Git will stop applying the commit and prompt you to resolve them. After resolving the conflicts, you need to mark the conflicted files as resolved using git add, and then use git cherry-pick --continue to proceed with applying the selected commits. If you decide not to continue with the cherry-pick operation, you can use git cherry-pick --abort to discard the changes and revert to the state before the operation.

2024年6月29日 12:07 回复

如何挑选单个提交、多个提交或一系列提交

...到您当前签出的分支:

1. 挑选一个名为的_分支_或提交commit

shell
git cherry-pick commit

例子:

shell
git cherry-pick my_branch # by branch name git cherry-pick 1e038f108a130831f108329b1083a8139813fabc # by full hash git cherry-pick 1e038f10 # by partial hash

2. 挑选_多个_提交

请注意,您可以按您想要的任何顺序一次挑选_任意数量的提交哈希值__。_它们只会按照您指定的顺序一次应用一个。如果出现任何冲突,您必须一次解决一个问题,然后在完成后使用git add my_filethengit cherry-pick --continue继续挑选过程。

shell
git cherry-pick commit1 commit2 commit3 commit4 commit5

3. 挑选_一系列_提交

我最初是从@Eric Darchis 在这里获得最多支持的答案中学习了这种风格的基础知识。

请注意,要挑选一系列_提交_,您必须指定开始和结束提交哈希,以及..它们之间的值。但是,在一系列提交中,不包括开始提交。因此,要包含它,您必须在开始提交_之前_指定提交。_指定前面_提交的语法是在提交_之后_放置~~1或 ,如: ,这意味着^:“之前的提交”。beginning_commit~``beginning_commit

shell
# A. INCLUDING the beginning_commit git cherry-pick beginning_commit~..ending_commit # OR (same as above) git cherry-pick beginning_commit~1..ending_commit # OR (same as above) git cherry-pick beginning_commit^..ending_commit # B. NOT including the beginning_commit git cherry-pick beginning_commit..ending_commit

注意: commit~commit~1和all 表示“之前的commit^一次提交”,或者换句话说:“之前的提交”。 commit``commit

要指定之前的_两次_commit提交,您可以使用如下语法:

shell
commit~~ commit~2 # my preferred syntax commit^^

要指定之前的_三个_commit提交,您可以执行以下操作:

shell
commit~~~ commit~3 # my preferred syntax commit^^^

这不起作用:

shell
commit^3 # INVALID syntax

这_确实_有效,但这是一个非常特殊的情况。另请参阅我的问答:git merge-style 工作流程中,仅显示合并之前某人在其 PR(拉取请求)功能分支中拥有的唯一提交

shell
# valid on **merge commits** only commit^2 # this is the immediate **right** parent of the two parents # involved in the merge (which made commit `commit`) # valid on any commits (gets the left parent of a merge commit, or # the only parent of a non-merge commit) commit~ # and this is the immediate **left** parent of the two # parents involved in the merge (which made commit `commit`)

要自己测试上述“先前提交语法”概念,最简单的方法是使用git log命令。前任:

shell
git log commit git log commit~ git log commit~1 git log commit^ git log commit~~ git log commit~5 # etc.

4. 挑选一系列同行的提交到您的分支上

...当他们的分支peer_branch从您的分支的早期版本中分叉出来时my_branch

快速总结

shell
# you cherry-pick all of their extra commits from their `peer_branch` onto # your `my_branch` (note: the 3 dots below are very important!) git fetch origin peer_branch # get their latest changes from the remote git checkout my_branch # ensure you're on your branch # cherry-pick their range of commits git cherry-pick my_branch...origin/peer_branch git log # review the commits you just chery-picked git push # push your changes to the remote

提交范围内 2 点和 3 点之间的差异非常显着。git diff branch1...branch2相当于git diff $(git merge-base branch1 branch2) branch2. branch2当您想要查看自 偏离 以来所做的更改branch1,而不是两个分支在当前状态下的差异时,这非常有用。请参阅此处和此处的评论以及此处的答案:What are the Differences between double-dot ".." and Triple-dot "..." in Git diff commit Ranges?

完整的详细信息和工作流程演练

假设您正在开发功能分支my_branch,而您的同事希望帮助您进行一些更改以帮助您完成功能。您已经推my_branch送到名为 的远程origin。因此,他们将获取名为my_branch其本地计算机的远程分支,从中分叉出自己的名为 的分支peer_brach,然后推送到自己名为 的分支peer_branch。一旦他们这样做了,你就可以立即挑选他们添加的所有内容。该过程的第一部分如下所示:

shell
# **your peer** does this # peer fetches your branch named `my_branch` and forks their `peer_branch` # off of it # they fetch your latest work from remote `my_branch` into their locally-stored # remote-tracking "hidden" branch named `origin/my_branch` # (note: you can see all locally-stored remote-tracking "hidden" branches # with `git branch -r`) git fetch origin my_branch # create `peer_branch` as a fork off of `origin/my_branch`, and check it out git checkout -b peer_branch origin/my_branch # Now they can add their changes and commits and `git push` to remote `origin` # as their own `peer_branch` when done.

现在他们已经将所有更改推送到远程origin作为他们自己的名为 的分支peer_branch,您可以挑选他们添加到您的工作之上的_所有提交,如下所示:_

shell
# **you** do this to cherry-pick your peer's helpful changes they added to # your work # you fetch their latest work from their branch named `peer_branch` on remote # `origin` into your locally-stored remote-tracking "hidden" branch named # `origin/peer_branch` # (note: you can see all locally-stored remote-tracking "hidden" branches # with `git branch -r`) git fetch origin peer_branch # ensure you are on `my_branch` (if you aren't already) git checkout my_branch # you cherry-pick all of their extra commits from their `peer_branch` onto # your `my_branch` (note: the 3 dots here are very important!) git cherry-pick my_branch...origin/peer_branch git log # review the commits you just chery-picked git push # push your changes to the remote

为了您的理解,cherry-pick上面那个带有 3 个点的命令_完全等同_于这个更长的命令:

shell
git cherry-pick $(git merge-base my_branch origin/peer_branch)..origin/peer_branch

该部分查找branch和branchgit merge-base my_branch origin/peer_branch之间的公共父提交哈希。这是他们从你的你的. 然后,您当然会挑选从该点到 ( ) 的最终提交_的提交范围_。my_branch``origin/peer_branch``peer_branch``my_branch``..``origin/peer_branch

要了解有关 3 点语法的更多信息,请参阅此处:Git diff 提交范围中双点“..”和三点“...”之间的区别是什么?[复制]。有关 的帮助git checkout -b new_branch from_branch,请参阅我的答案:从另一个分支在 git 中创建分支的各种方法

官方 Git 文档

  1. https://git-scm.com/docs/gitrevisions - 提到 git commit 3 点 ( ...) 与 2 点范围语法、^commit("not" commit)、commit^( 的父级commit) 等。

更进一步

  1. 还有一点需要知道: agit rebase只是一堆连续的git cherry-picks。请参阅我的其他答案(根据 Git,谁是“我们”,谁是“他们”?),其中我展示了我制作的 ASCII 绘图,其中显示了 a 的git rebase工作原理及其正在执行的操作。
  2. Git diff 提交范围中的双点“..”和三点“...”有什么区别?[复制]
  3. 我对从另一个分支在 git 中创建分支的各种方法的回答
  4. 我的问答:git merge风格的工作流程中,仅显示合并之前某人在其 PR(拉取请求)功能分支中的唯一提交
2024年6月29日 12:07 回复

你的答案