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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35437253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 03:55:53  来源:igfitidea点击:

How to git cherrypick all changes introduced in specific branch

gitmergegit-cherry-pick

提问by Valyrion

Background info:

背景资料:

Due to restrictions in workflow with out existing systems, we need to set up a somewhat unorthodox git process.

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

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

On the patch branch, there are some commits. The files here are similar but not identical to the ones on dev (sync scripts switch around the order of settings in many of the files, making them appear changed while they are functionally the same).

在补丁分支上,有一些提交。此处的文件与 dev 上的文件相似但不完全相同(同步脚本在许多文件中切换设置顺序,使它们在功能相同的情况下看起来已更改)。

A fix is needed on this branch so a hotfix branch is created and worked on. This branch is then merged back into patch, so far, so good.

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

This same fix needs to be deployed to the dev branch so it stays relatively in sync with patch, but trying to merge the hotfix branch leads to git trying to merge all the unrelated and 'unchanged' files from A and B as well, rather than only C,D and E.

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

Question:

题:

It seems that cherry-pick does what we want in terms of only getting changes from selected commits, but I would really like a way to cherry-pick all commits in a given branch at once, without having to look up the commit ids every time.

似乎cherry-pick 只从选定的提交中获取更改就完成了我们想要的操作,但我真的很喜欢一种方法来一次对给定分支中的所有提交进行cherry-pick,而不必每次都查找提交 id .

回答by CodeWizard

It seems that cherry-pickdoes what we want in terms of only getting changes from selected commits, but I would really like a way to cherry-pick all commits in a given branch at once, without having to look up the commit ids every time.

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



Using cherry-pick

使用 cherry-pick

git cherry-pickallows you to pick any commits you made in any branch to any other branch. In your case you can simply checkout master branch and then cherry-pickall the commits from any branch that you wish (cherry-picksupports ranges so you can specify start and end commit instead of listing all the commits).

git cherry-pick允许您选择您在任何分支中所做的任何提交到任何其他分支。在您的情况下,您可以简单地检出 master 分支,然后检查cherry-pick您希望的任何分支的所有提交(cherry-pick支持范围,因此您可以指定开始和结束提交,而不是列出所有提交)。

This way you can control the way your commits will appear in the desired branch.

通过这种方式,您可以控制提交在所需分支中的显示方式。

For example:

例如:

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


How to find first commit of branch?

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

git log

git log

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

merge-base

merge-base

Use the merge-basecommand to find where the branch was split from the original branch:

使用该merge-base命令查找分支从原始分支中分离出来的位置:

git merge-base A B

回答by Josh

Assuming you know the number of commits you wish to pick from the branch you can use the relative commit notation.

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

git cherry-pick BRANCH_A~10^..BRANCH_A

git cherry-pick BRANCH_A~10^..BRANCH_A

This will cherry pick all commits starting at 10 commits before (~10) BRANCH_A's HEAD, inclusive of the starting commit (^), and will get all commits in the range (..) through to BRANCH_A's HEAD.

这将~10优先选择从 ( ) BRANCH_A 的 HEAD之前的 10 个提交开始的所有提交,包括起始提交 ( ^),并将获取范围 ( ..) 到 BRANCH_A 的 HEAD 的所有提交。

回答by Linji

If you want to cherry-pick all commits from branch dev.

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

Try:

尝试:

git cherry-pick ..dev

git 樱桃选择 ..dev

回答by nimcap

A one liner would be:

一个班轮将是:

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

You can also convert this into a git alias or bash function. I prefer using it like this so I only change single place:

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

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

回答by AlanSE

Following from discussion in the accepted answer, here is a one-liner. It should not matter what branch you are currently on when you run this (presumably some non-default branch). This assumes that develis the default branch, and that you want to cherry pick all commits from branch B, after it diverged from the develbranch.

根据已接受答案中的讨论,这里是一个单行。运行它时,您当前所在的分支(大概是某个非默认分支)应该无关紧要。这假设这devel是默认分支,并且您希望在分支脱离分支B后从分支中挑选所有提交devel

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

The command syntax goes first..last, but we are using a variant here which is more like first-1^..last.

命令语法是这样first..last,但我们在这里使用了一个更像first-1^..last.

The command git log devel..B --pretty=format:"%h" | tail -1gets the commit in the develbranch which is a parent of the first commit in the Bbranch. This is a little clunky, but the git merge-basecommand did not have the needed formatting options.

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

The command git log B -n 1 --pretty=format:"%h"just gets the last commit in that branch.

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

This will put your in an interactive cherry-pick context. So make sure to abort if it's not going well.

这将使您处于交互式的挑选环境中。因此,如果进展不顺利,请务必中止。

回答by David Beauchemin

This should also work. We call the point of divergence between the HEAD (master in this case) and the branch and pass it to cherry-pick.

这也应该有效。我们将 HEAD(在本例中为 master)和分支之间的分歧点称为分支并将其传递给cherry-pick。

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

回答by AlexNikonov

one more way with fast-forward.

快进的另一种方式。

The case:

案子:

you started newBranch, commited first commit and did reset Hard.

您启动了newBranch,提交了第一次提交并重置了Hard

As a result you got empty newBranch, no that late commit and git tree is clean at the HEAD. You are at the branch newBranch(may check with git branch).

结果你得到了空的newBranch,没有那个延迟提交,并且 git 树在 HEAD 上是干净的。你在分支newBranch(可以检查 git branch)。

Here is two steps action:

这是两步操作:

  • get the list of commits in 'trash' by
  • 通过以下方式获取“垃圾箱”中的提交列表

git fsck --lost-found

git fsck --lost-found

  • commit the missed commit back to your branch with:
  • 使用以下命令将错过的提交提交回您的分支:

git cherry-pick --ff 43a7a2d

git cherry-pick --ff 43a7a2d

回答by Alwin

checkout your branch(target branch) and do

结帐您的分支(目标分支)并执行

git cherry-pick -m 1hashCode

gitcherry-pick -m 1hashCode