git 如何挑选多个提交
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1670970/
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
How to cherry-pick multiple commits
提问by tig
I have two branches. Commit a
is the head of one, while the other has b
, c
, d
, e
and f
on top of a
. I want to move c
, d
, e
and f
to first branch without commit b
. Using cherry pick it is easy: checkout first branch cherry-pick one by one c
to f
and rebase second branch onto first. But is there any way to cherry-pick all c
-f
in one command?
我有两个分支。Commita
是一个的头部,而另一个有b
, c
, d
,e
和f
在 之上a
。我想移动c
,d
,e
和f
第一支没有提交b
。使用cherry pick很容易:一个一个c
地结帐第一个分支cherry-pickf
并将第二个分支重新设置到第一个上。但有什么办法可以摘樱桃所有c
-f
在一个命令?
Here is a visual description of the scenario (thanks JJD):
这是场景的视觉描述(感谢JJD):
回答by Eric Darchis
Git 1.7.2 introduced the ability to cherry pick a range of commits. From the release notes:
Git 1.7.2 引入了挑选一系列提交的能力。从发行说明:
git cherry-pick
learned to pick a range of commits (e.g.cherry-pick A..B
andcherry-pick --stdin
), so didgit revert
; these do not support the nicer sequencing controlrebase [-i]
has, though.
git cherry-pick
学会了选择一系列提交(例如cherry-pick A..B
和cherry-pick --stdin
),也是如此git revert
;但是,这些不支持更好的排序控制rebase [-i]
。
To cherry-pick all the commits from commit A
to commit B
(where A
is older than B
), run:
要从提交A
到提交B
(A
比 更早的地方B
)挑选所有提交,请运行:
git cherry-pick A^..B
If you want to ignoreA itself, run:
如果要忽略A 本身,请运行:
git cherry-pick A..B
(Credit goes to damian, J. B. Rainsberger and sschaef in the comments)
(在评论中归功于 damian、JB Rainsberger 和 sschaef)
回答by CB Bailey
The simplest way to do this is with the onto
option to rebase
. Suppose that the branch which current finishes at a
is called mybranch and this is the branch that you want to move c
-f
onto.
要做到这一点,最简单的方法是使用onto
选项rebase
。假设在支路电流结束a
被称为mybranch,这是你要移动的分支c
-f
到。
# checkout mybranch
git checkout mybranch
# reset it to f (currently includes a)
git reset --hard f
# rebase every commit after b and transplant it onto a
git rebase --onto a b
回答by wolfc
Or the requested one-liner:
或要求的单线:
git rebase --onto a b f
回答by JJD
You can use a serial combination of git rebase
and git branch
to apply a group of commits onto another branch. As already posted by wolfcthe first command actually copies the commits. However, the change is not visible until you add a branch name to the top most commit of the group.
您可以使用的串联组合git rebase
,并git branch
申请一集团承诺的到另一个分支。正如wolfc已经发布的那样,第一个命令实际上复制了提交。但是,在将分支名称添加到组的最顶部提交之前,更改是不可见的。
Please open the picture in a new tab ...
请在新标签页中打开图片...
To summarize the commands in text form:
以文本形式总结命令:
- Open gitkas a independent process using the command:
gitk --all &
. - Run
git rebase --onto a b f
. - Press F5in gitk. Nothing changes. But no
HEAD
is marked. - Run
git branch selection
- Press F5in gitk. The new branch with its commits appears.
- 开放gitk如使用所述命令的独立的过程:
gitk --all &
。 - 运行
git rebase --onto a b f
。 - 按F5在gitk。没有什么改变。但没有
HEAD
被标记。 - 跑
git branch selection
- 按F5在gitk。带有提交的新分支出现。
This should clarify things:
这应该澄清一些事情:
- Commit
a
is the new root destination of the group. - Commit
b
is the commit before the first commit of the group (exclusive). - Commit
f
is the last commit of the group (inclusive).
- Commit
a
是组的新根目标。 - Commit
b
是组的第一次提交之前的提交(独占)。 - Commit
f
是组的最后一次提交(包括)。
Afterwards, you could use git checkout feature && git reset --hard b
to delete the commits c
till f
from the feature
branch.
之后,你可以使用git checkout feature && git reset --hard b
删除提交c
,直到f
从feature
分支。
In addition to this answer, I wrote a blog postwhich describes the commands in another scenario which should help to generally use it.
除了这个答案,我还写了一篇博客文章,描述了另一个场景中的命令,这应该有助于普遍使用它。
回答by Andy
To apply J. B. Rainsberger and sschaef's comments to specifically answer the question... To use a cherry-pick range on this example:
要应用 JB Rainsberger 和 sschaef 的评论来专门回答这个问题......在这个例子中使用樱桃挑选范围:
git checkout a
git cherry-pick b..f
or
或者
git checkout a
git cherry-pick c^..f
回答by Shrikant Wandhare
If you have selective revisions to merge, say A, C, F, J from A,B,C,D,E,F,G,H,I,J commits, simply use below command:
如果您有选择性的修订要合并,例如来自 A、B、C、D、E、F、G、H、I、J 提交的 A、C、F、J,只需使用以下命令:
git cherry-pick A C F J
git 挑选 ACFJ
回答by Dustin
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
回答by ut9081
To cherry pick from a commit id up to the tip of the branch, you can use:
要从提交 id 中挑选到分支的尖端,您可以使用:
git cherry-pick commit_id^..branch_name
git cherry-pick commit_id^..branch_name
回答by Nick F
Another variant worth mentioning is that if you want the last n
commits from a branch, the ~
syntax can be useful:
另一个值得一提的变体是,如果您想要n
来自分支的最后一次提交,则~
语法可能很有用:
git cherry-pick some-branch~4..some-branch
In this case, the above command would pick the last 4 commits from a branch called some-branch
(though you could also use a commit hash in place of a branch name)
在这种情况下,上面的命令将从名为的分支中选择最后 4 个提交some-branch
(尽管您也可以使用提交哈希代替分支名称)
回答by ealfonso
Actually, the simplest way to do it could be to:
实际上,最简单的方法可能是:
- record the merge-base between the two branches:
MERGE_BASE=$(git merge-base branch-a branch-b)
- fast-forward or rebase the older branch onto the newer branch
rebase the resulting branch onto itself, starting at the merge base from step 1, and manually remove commits that are not desired:
git rebase ${SAVED_MERGE_BASE} -i
Alternatively, if there are only a few new commits, skip step 1, and simply use
git rebase HEAD^^^^^^^ -i
in the first step, using enough
^
to move past the merge-base.
- 记录两个分支之间的合并基:
MERGE_BASE=$(git merge-base branch-a branch-b)
- 将旧分支快进或变基到新分支上
从步骤 1 的合并基础开始,将生成的分支重新绑定到自身,并手动删除不需要的提交:
git rebase ${SAVED_MERGE_BASE} -i
或者,如果只有几个新提交,请跳过步骤 1,只需使用
git rebase HEAD^^^^^^^ -i
在第一步中,使用足够
^
的移动通过合并基础。
You will see something like this in the interactive rebase:
您将在交互式 rebase 中看到类似的内容:
pick 3139276 commit a
pick c1b421d commit b
pick 7204ee5 commit c
pick 6ae9419 commit d
pick 0152077 commit e
pick 2656623 commit f
Then remove lines b (and any others you want)
然后删除行 b (以及您想要的任何其他行)