如何git cherrypick在特定分支中引入的所有更改

时间:2016-02-16 16:01:29

标签: git merge git-cherry-pick

背景信息:

由于现有系统的工作流程受到限制,我们需要设置一个有点非正统的git进程。

(patch)    A-B---F
             |   |
(hotfix)     C-D-E
                 |
(dev)      1-2-3-G

在补丁分支上,有一些提交。这里的文件与dev上的文件类似但不完全相同(同步脚本按照许多文件中的设置顺序切换,使它们在功能上相同时显示为已更改)。

此分支上需要修复,因此会创建并处理修补程序分支。然后,这个分支合并回补丁,到目前为止,非常好。

需要将相同的修补程序部署到dev分支,以便它与patch保持相对同步,但是尝试合并修补程序分支会导致git尝试合并来自A和B的所有不相关和“未更改”的文件而不仅仅是C,D和E.

问题:

看起来cherry-pick做了我们想要的只是从选定的提交中获得更改,但我真的想要一种方法来一次性地挑选给定分支中的所有提交,而不必查找提交ids每次。

9 个答案:

答案 0 :(得分:31)

  

似乎cherry-pick做了我们想要的只是从选定的提交中获得更改,但我真的想要一种方法来一次性地挑选给定分支中的所有提交,而不必查找每次提交ID。

使用cherry-pick

git cherry-pick允许您选择在任何分支中对任何其他分支进行的任何提交。在您的情况下,您可以简单地签出master分支,然后cherry-pick来自任何分支的所有提交(cherry-pick支持范围,这样您就可以指定开始和结束提交而不是列出所有提交。)< / p>

这样您就可以控制提交在所需分支中的显示方式。

例如:

git cherry-pick ebe6942..905e279
# Find the range of commits you wish to re-add to your branch.
# then use cherry-pick to add them back to the branch
git cherry-pick start..end

# If you wish to include the start commit as well add the ^
# This will result in a cherry-pick of the start commit included as well 
git cherry-pick start^..end

如何找到分支的第一次提交?

git log

 # print out the latest commit (first one) of the given branch
 git log  --oneline | tail -1

merge-base

使用merge-base命令查找分支从原始分支拆分的位置:

git merge-base A B

答案 1 :(得分:3)

假设您知道希望从分支中选择的提交数,则可以使用相对提交表示法。

git cherry-pick BRANCH_A~10^..BRANCH_A

这将挑选所有从({{1)}之前(~10)BRANCH_A的HEAD之前的10次提交开始的所有提交,并获得范围({{1} })到BRANCH_A的HEAD。

答案 2 :(得分:3)

一个班轮是:

git cherry-pick $(git merge-base master my/branch)..my/branch

您还可以将其转换为git别名或bash函数。我更喜欢这样使用它,所以我只更改一个地方:

BRANCH=my/branch; git cherry-pick $(git merge-base master ${BRANCH})..${BRANCH}

答案 3 :(得分:1)

签出您的分支(目标分支)并执行

git cherry-pick -m 1 hashCode

答案 4 :(得分:1)

根据接受的答案中的讨论,这里是一线。运行此命令时当前位于哪个分支(可能是一些非默认分支)都没有关系。假设devel是默认分支,并且您想从分支B分支出来之后,从分支devel挑选所有提交。

git cherry-pick $(git log devel..B --pretty=format:"%h" | tail -1)^..$(git log B -n 1 --pretty=format:"%h")

命令语法为first..last,但是我们在这里使用的变体更像first-1^..last

命令git log devel..B --pretty=format:"%h" | tail -1devel分支中获取提交,该分支是B分支中第一次提交的父级。这有点笨拙,但是git merge-base命令没有所需的格式设置选项。

命令git log B -n 1 --pretty=format:"%h"仅获得该分支中的最后一次提交。

这将使您处于交互式的樱桃选择环境。因此,如果运行不正常,请务必中止。

答案 5 :(得分:0)

如果您想从分支dev中挑选所有提交。

尝试:

git cherry-pick ..dev

答案 6 :(得分:0)

这也应该起作用。我们将HEAD(在本例中为master)与分支之间的分歧点称为转移点,并将其传递给Cherry-pick。

git merge-base origin/dev_single_doc_fit HEAD | xargs git cherry-pick {}..HEAD^

答案 7 :(得分:0)

快速前进的另一种方式。

情况:

您启动了 newBranch ,进行了首次提交,并重置了 Hard

结果您得到了空的 newBranch ,没有那个较晚的提交和git树在HEAD上是干净的。您位于分支 newBranch (可以与git分支联系)。

这是两步操作:

  • 通过
  • 获取“已删除邮件”中的提交列表

git fsck --lost-found

  • 使用以下命令将错过的提交提交回您的分支机构:

git cherry-pick --ff 43a7a2d

答案 8 :(得分:0)

我发现rebase上的这篇文章对相同的用例很有帮助。

让我们说您有如下承诺

commit 6 [my-feature-branch] | merged onto master commit
commit 5
commit 4 [master]
commit 3
commit 2 [production]
commit 1

您只希望在生产中包含6个。

git checkout my-feature-branch
git rebase production 5

这里5是您要从中提交的哈希值(不包括5)进行更改并放在生产分支上。