Git 挑选语法并合并分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12626754/
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
Git cherry-pick syntax and merge branches
提问by TheWebs
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 函数?
回答by user4815162342
You have to supply -m
if the commit is a merge commit, i.e. a commit with more than one parent.
-m
如果提交是合并提交,即具有多个父项的提交,您必须提供。
Normally, what git cherry-pick REV
does can be described as:
通常,git cherry-pick REV
可以将其描述为:
Take the changes between revand its parent.
Apply these changes to the current HEAD and commit the result with rev's commit message.
采取rev与其父级之间的更改。
将这些更改应用于当前 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. 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.
现在考虑挑选过程的第 1 步:git 无法猜测您是要消除混乱还是要实现小部件。你也不能两者都做,因为关于如何做这两者的信息不包含在单个合并提交中,只有结果合并树的内容。
The -m
option allows you to tell git how to proceed. 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. 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-commitis exactly the clutter-removal missing from the widgetbranch.
该-m
选项允许您告诉 git 如何继续。例如,如果发生了杂乱删除master
并且使用创建了合并提交git merge WIDGET
,那么git cherry-pick -m 1 merged-commit
将挑选新的小部件,因为合并树和父级 1(最后一个杂乱删除提交)之间的差异将恰好是小部件的添加。另一方面,git cherry-pick -m 2 merge-commit
将删除杂乱,因为父 2(添加小部件的最后一个提交)和合并提交之间的区别正是小部件分支中缺少的杂乱去除。
回答by kenorb
The git is requesting you to specify parent number (-m
), because your merge commit has two parentsand git do not know which side of the merge should be considered the mainline. 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.
git 要求您指定父编号 ( -m
),因为您的合并提交有两个父级,而 git 不知道合并的哪一侧应该被视为主线。因此,使用此选项,您可以指定主线的父级编号(从 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, e.g.
然后为您的挑选指定从 1 开始的父编号,例如
git cherry-pick -m 1 <merge_commit>
Then run git status
to see what's going on. If you don't want to commit the changes yet, add -n
option to see what happens. Then when you're not happy, reset to 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 status
过去看看发生了什么。如果您还不想提交更改,请添加-n
选项以查看会发生什么。然后当你不开心时,重置为 HEAD ( git reset HEAD --hard
)。如果您遇到 git 冲突,您可能必须手动解决它们或指定合并策略 ( -X
),请参阅:如何解决 Git 中的合并冲突?
回答by Wyclif
Personally what i normally do is that since a merge combines 2 commits, for instance if i have merge commit C which is composed of 2 parents e.g commit A in master and commit B from the other branch getting merged, if i need to cherry pick the merge i wouldn't bother with the confusing command to cherry pick the merge commit itself but instead i would just cherry each of the parents A and B individually, this is also helpful in a situation where you only want to cherry pick commit B only in case commit A from master was already cherry-picked to the branch one is cherry picking to before the merge happened.
就我个人而言,我通常做的是,由于合并合并了 2 个提交,例如,如果我有由 2 个父级组成的合并提交 C,例如在 master 中提交 A 并从另一个分支提交 B 合并,如果我需要挑选合并我不会理会令人困惑的命令来挑选合并提交本身,而是我只会分别挑选每个父母 A 和 B,这在您只想挑选提交 B 的情况下也很有帮助在合并发生之前,来自 master 的 case 提交 A 已经被挑选到了一个正在挑选的分支。
回答by Magikhead
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. 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.
-m parent-number, --mainline parent-number, 通常你不能挑选合并,因为你不知道合并的哪一边应该被认为是主线。此选项指定主线的父级编号(从 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.
所以我会仔细检查以确保你有正确的提交哈希。可能您想要的不是来自合并而是之前的提交。否则,您需要使用此标志并指向合并的正确一侧以消除您的请求的歧义。
回答by Knase
Try to merge result:
尝试合并结果:
git cherry-pick ....
git mergetool
git cherry-pick --continue