简体   繁体   English

Git 挑选语法并合并分支

[英]Git cherry-pick syntax and merge branches

So I have done countless cherry picks before and it seems that I must fail at life with this right now, I am trying to cherry pick from one branch to another which should be easy, how ever I get an error about it being a merge but not -m was given?所以我以前做过无数次挑选,看来我现在必须在生活中失败,我试图从一个分支挑选到另一个应该很容易,但我怎么会收到关于它是合并的错误,但是不是 -m 给出的?

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0
error: Commit a8c5ad438f6173dc34f6ec45bddcef2ab23285e0 is a merge but no -m option was given.
fatal: cherry-pick failed

That looks wrong.......it should be:看起来不对……应该是:

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0

Since when do I have to supply a -m function?从什么时候开始我必须提供 -m 函数?

You have to supply -m if the commit is a merge commit , ie a commit with more than one parent.如果提交是合并提交,即具有多个父项的提交,则必须提供-m

Normally, what git cherry-pick REV does can be described as:通常, git cherry-pick REV所做的可以描述为:

  1. Take the changes between rev and its parent.采取rev与其父级之间的更改。

  2. Apply these changes to the current HEAD and commit the result with rev 's commit message.将这些更改应用于当前 HEAD 并使用rev的提交消息提交结果。

A merge commit joins two lines of development.合并提交加入了两条开发线。 For example, one line implements widget, and the other line removes clutter.例如,一行实现小部件,另一行消除杂乱。 The merge gives you the code with the widget, sans the clutter.合并为您提供带有小部件的代码,避免混乱。

Now consider step #1 of the cherry-pick process: git can't guess whether you want to remove the clutter or to implement the widget.现在考虑挑选过程的第 1 步:git 无法猜测您是要消除混乱还是要实现小部件。 Nor can you do both, because the information on how to do both is not contained inside a single merge commit, only the content of the resultant merged tree is.你也不能两者都做,因为关于如何做这两者的信息不包含在单个合并提交中,只有结果合并树的内容。

The -m option allows you to tell git how to proceed. -m选项允许您告诉 git 如何继续。 For example, if clutter removal happened on master and the merge commit was created using git merge WIDGET , then git cherry-pick -m 1 merged-commit will cherry-pick the new widget because diff between the merged tree and parent 1 (the last of clutter-removing commits) will have been exactly the widget addition.例如,如果master发生了杂乱删除并且使用git merge WIDGET创建了合并提交,那么git cherry-pick -m 1 merged-commit将优先选择新的小部件,因为合并的树和父级 1(最后一个)之间存在差异。杂乱删除提交)将完全是小部件的添加。 On the other hand, git cherry-pick -m 2 merge-commit will delete the clutter, because the difference between parent 2 (the last of the widget-adding commits) and merge-commit is exactly the clutter-removal missing from the widget branch.另一方面, git cherry-pick -m 2 merge-commit将删除杂乱,因为 parent 2(添加小部件的最后一个提交)和merge-commit之间的区别正是小部件中缺少的杂乱去除分支。

The git is requesting you to specify parent number ( -m ), because your merge commit has two parents and git do not know which side of the merge should be considered the mainline. git 要求您指定父编号( -m ),因为您的合并提交有两个父级,而 git 不知道合并的哪一侧应该被视为主线。 So using this option you can specify the parent number (starting from 1) of the mainline and cherry-pick in order to replay the change relative to the specified parent.因此,使用此选项,您可以指定主线的父级编号(从 1 开始)并进行挑选,以便重播相对于指定父级的更改。

To find out your commit parents, try either:要找出您的承诺父母,请尝试:

git show --pretty=raw <merge_commit>

or:要么:

git cat-file -p <merge_commit>

or even for better GUI visibility, try:甚至为了更好的 GUI 可见性,请尝试:

gitk <merge_commit>

As result, you should get something like:结果,你应该得到类似的东西:

commit fc70b1e9f940a6b511cbf86fe20293b181fb7821
tree 8d2ed6b21f074725db4f90e6aca1ebda6bc5d050 
parent 54d59bedb9228fbbb9d645b977173009647a08a9 = <parent1_commit>
parent 80f1016b327cd8482a3855ade89a41ffab64a792 = <parent2_commit>

Then check your each parent details by:然后通过以下方式检查您的每个父母的详细信息:

git show <parent1_or_2_commit>

Add --stat to see list of modified files.添加--stat以查看修改后的文件列表。

Or use the following command to compare the changes (based on the above parent):或者使用以下命令来比较更改(基于上述父级):

git diff <parent1_or_2_commit>..<commit>

Add --stat to see list of modified files.添加--stat以查看修改后的文件列表。

or use the combined diff to compare the two parents by:或使用组合差异通过以下方式比较两个父母:

git diff --cc <parent1_commit>
git diff --cc <parent2_commit>

Then specify the parent number starting from 1 for your cherry-pick, eg然后为您的挑选指定从 1 开始的父编号,例如

git cherry-pick -m 1 <merge_commit>

Then run git status to see what's going on.然后运行git status看看发生了什么。 If you don't want to commit the changes yet, add -n option to see what happens.如果您还不想提交更改,请添加-n选项以查看会发生什么。 Then when you're not happy, reset to HEAD ( git reset HEAD --hard ).然后当你不开心时,重置为 HEAD ( git reset HEAD --hard )。 If you'll get git conflicts, you'll probably have to solve them manually or specify merge strategy ( -X ), see: How to resolve merge conflicts in Git?如果您遇到 git 冲突,您可能必须手动解决它们或指定合并策略 ( -X ),请参阅:如何解决 Git 中的合并冲突?

就我个人而言,我通常做的是,由于合并合并了 2 个提交,例如,如果我有由 2 个父级组成的合并提交 C,例如在 master 中提交 A 并从另一个分支提交 B 被合并,如果我需要挑选合并我不会打扰令人困惑的命令来挑选合并提交本身,而是我只会分别挑选每个父母 A 和 B,这在您只想挑选提交 B 的情况下也很有帮助在合并发生之前,来自 master 的 case 提交 A 已经被挑选到了一个正在挑选的分支。

The syntax from the man pages is as follows:手册页的语法如下:

git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...

The parent-number refers to:父编号是指:

-m parent-number, --mainline parent-number, Usually you cannot cherry-pick a merge because you do not know which side of the merge should be considered the mainline. -m parent-number, --mainline parent-number, 通常你不能挑选合并,因为你不知道合并的哪一边应该被认为是主线。 This option specifies the parent number (starting from 1) of the mainline and allows cherry-pick to replay the change relative to the specified parent.此选项指定主线的父级编号(从 1 开始),并允许cherry-pick 重播相对于指定父级的更改。

So I would double check to make sure you have the correct commit hash.所以我会仔细检查以确保你有正确的提交哈希。 It might be that you want one that isn't from a merge but rather the commit before it.可能您想要的不是来自合并而是之前的提交。 Otherwise, you need to use this flag and point to the correct side of the merge to disambiguate your request.否则,您需要使用此标志并指向合并的正确一侧以消除您的请求的歧义。

Try to merge result: 尝试合并结果:

git cherry-pick ....
git mergetool
git cherry-pick --continue

parent1 commit change widget parent1 提交更改小部件

parent2 commit change clutter parent2 提交更改混乱

merge commit (contains both changes) widget clutter合并提交(包含两个更改)小部件混乱

git cherry-pick -m 1 merge-commit diff of merge and parent1(master) merge - master= widget git cherry-pick -m 1 merge-commit 合并和 parent1(master) 合并的差异 - master= widget

git cherry-pick -m 2 merge-commit diff of merge and parent2(WIDGET) merge - WIDGET= clutter git cherry-pick -m 2 合并提交和 parent2(WIDGET) 合并的合并提交差异 - WIDGET= 杂乱

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM