tig*_*tig 779 git git-rebase cherry-pick
我有两个分支.提交a是一个头,而其他有b,c,d,e和f之上a.我想移动c,d,e和f第一支没有提交b.使用樱桃挑选很容易:结帐第一个分支樱桃 - 一个接一个c地挑选f第二个分支到第一个.但有没有办法挑选所有c- f一个命令?
这是场景的直观描述(感谢JJD):

Eri*_*his 1141
Git 1.7.2引入了一系列提交的能力.从发行说明:
git cherry-pick"学会了选择一系列提交(例如"cherry-pick A..B"和"cherry-pick --stdin"),"git revert"也是如此;这些不支持更好的排序控制"但是,rebase [-i]"有.
包括重要评论(各自作者的学分)
注1:在"cherry-pick A..B"形式中,A应该比B更旧.如果它们的顺序错误,命令将无声地失败. - 达米安
注2:此外,这不会选择A,而是A之后的所有内容,包括B. - JB Rainsberger
注3:要包括一个只是类型git cherry-pick A ^ .. B - sschaef
Gab*_*les 140
...到您当前签出的分支:
commitgit cherry-pick commit
Run Code Online (Sandbox Code Playgroud)
例子:
git cherry-pick my_branch # by branch name
git cherry-pick 1e038f108a130831f108329b1083a8139813fabc # by full hash
git cherry-pick 1e038f10 # by partial hash
Run Code Online (Sandbox Code Playgroud)
请注意,您可以按您想要的任何顺序一次挑选任意数量的提交哈希值。它们只会按照您指定的顺序一次应用一个。如果出现任何冲突,您必须一次解决一个问题,然后在完成后使用git add my_filethengit cherry-pick --continue继续挑选过程。
git cherry-pick commit1 commit2 commit3 commit4 commit5
Run Code Online (Sandbox Code Playgroud)
我最初是从@Eric Darchis 在这里获得最多支持的答案中学习了这种风格的基础知识。
请注意,要挑选一系列提交,您必须指定开始和结束提交哈希,以及..它们之间的值。但是,在一系列提交中,不包括开始提交。因此,要包含它,您必须在开始提交之前指定提交。指定前面提交的语法是在提交之后放置~、~1或 ,^如:,这意味着:“之前的提交”。beginning_commit~beginning_commit
# A. INCLUDING the beginning_commit
git cherry-pick beginning_commit~..ending_commit
# OR (same as above)
git cherry-pick beginning_commit~1..ending_commit
# OR (same as above)
git cherry-pick beginning_commit^..ending_commit
# B. NOT including the beginning_commit
git cherry-pick beginning_commit..ending_commit
Run Code Online (Sandbox Code Playgroud)
注意: commit~、commit~1和all 表示“之前的commit^一次提交”,或者换句话说:“之前的提交”。 commitcommit
要指定之前的两次commit提交,您可以使用如下语法:
commit~~
commit~2 # my preferred syntax
commit^^
Run Code Online (Sandbox Code Playgroud)
要指定之前的三个commit提交,您可以执行以下操作:
commit~~~
commit~3 # my preferred syntax
commit^^^
Run Code Online (Sandbox Code Playgroud)
这不起作用:
commit^3 # INVALID syntax
Run Code Online (Sandbox Code Playgroud)
这确实有效,但这是一个非常特殊的情况。另请参阅我的问答:在git merge-style 工作流程中,仅显示合并之前某人在其 PR(拉取请求)功能分支中拥有的唯一提交:
# valid on **merge commits** only
commit^2 # this is the immediate **right** parent of the two parents
# involved in the merge (which made commit `commit`)
# valid on any commits (gets the left parent of a merge commit, or
# the only parent of a non-merge commit)
commit~ # and this is the immediate **left** parent of the two
# parents involved in the merge (which made commit `commit`)
Run Code Online (Sandbox Code Playgroud)
要自己测试上述“先前提交语法”概念,最简单的方法是使用git log命令。前任:
git log commit
git log commit~
git log commit~1
git log commit^
git log commit~~
git log commit~5
# etc.
Run Code Online (Sandbox Code Playgroud)
...当他们的分支peer_branch从您的分支的早期版本中分叉出来时my_branch。
# you cherry-pick all of their extra commits from their `peer_branch` onto
# your `my_branch` (note: the 3 dots below are very important!)
git fetch origin peer_branch # get their latest changes from the remote
git checkout my_branch # ensure you're on your branch
# cherry-pick their range of commits
git cherry-pick my_branch...origin/peer_branch
git log # review the commits you just chery-picked
git push # push your changes to the remote
Run Code Online (Sandbox Code Playgroud)
提交范围内 2 点和 3 点之间的差异非常显着。git diff branch1...branch2相当于git diff $(git merge-base branch1 branch2) branch2. branch2当您想要查看自 偏离 以来所做的更改branch1,而不是两个分支在当前状态下的差异时,这非常有用。请参阅此处和此处的评论以及此处的答案:What are the Differences between double-dot ".." and Triple-dot "..." in Git diff commit Ranges?
假设您正在开发功能分支my_branch,而您的同事希望帮助您进行一些更改以帮助您完成功能。您已经推my_branch送到名为 的远程origin。因此,他们将获取名为my_branch其本地计算机的远程分支,从中分叉出自己的名为 的分支peer_brach,然后推送到自己名为 的分支peer_branch。一旦他们这样做了,你就可以立即挑选他们添加的所有内容。该过程的第一部分如下所示:
# **your peer** does this
# peer fetches your branch named `my_branch` and forks their `peer_branch`
# off of it
# they fetch your latest work from remote `my_branch` into their locally-stored
# remote-tracking "hidden" branch named `origin/my_branch`
# (note: you can see all locally-stored remote-tracking "hidden" branches
# with `git branch -r`)
git fetch origin my_branch
# create `peer_branch` as a fork off of `origin/my_branch`, and check it out
git checkout -b peer_branch origin/my_branch
# Now they can add their changes and commits and `git push` to remote `origin`
# as their own `peer_branch` when done.
Run Code Online (Sandbox Code Playgroud)
现在他们已经将所有更改推送到远程origin作为他们自己的名为 的分支peer_branch,您可以挑选他们添加到您的工作之上的所有提交,如下所示:
# **you** do this to cherry-pick your peer's helpful changes they added to
# your work
# you fetch their latest work from their branch named `peer_branch` on remote
# `origin` into your locally-stored remote-tracking "hidden" branch named
# `origin/peer_branch`
# (note: you can see all locally-stored remote-tracking "hidden" branches
# with `git branch -r`)
git fetch origin peer_branch
# ensure you are on `my_branch` (if you aren't already)
git checkout my_branch
# you cherry-pick all of their extra commits from their `peer_branch` onto
# your `my_branch` (note: the 3 dots here are very important!)
git cherry-pick my_branch...origin/peer_branch
git log # review the commits you just chery-picked
git push # push your changes to the remote
Run Code Online (Sandbox Code Playgroud)
为了您的理解,cherry-pick上面那个带有 3 个点的命令完全等同于这个更长的命令:
git cherry-pick $(git merge-base my_branch origin/peer_branch)..origin/peer_branch
Run Code Online (Sandbox Code Playgroud)
该部分查找branch和branchgit merge-base my_branch origin/peer_branch之间的公共父提交哈希。这是他们从你的你的. 然后,您当然会挑选从该点到 ( ) 的最终提交的提交范围。my_branchorigin/peer_branchpeer_branchmy_branch..origin/peer_branch
要了解有关 3 点语法的更多信息,请参阅此处:Git diff 提交范围中双点“..”和三点“...”之间的区别是什么?[复制]。有关 的帮助git checkout -b new_branch from_branch,请参阅我的答案:从另一个分支在 git 中创建分支的各种方法
...) 与 2 点范围语法、^commit("not" commit)、commit^( 的父级commit) 等。git rebase只是一堆连续的git cherry-picks。请参阅我的其他答案(根据 Git,谁是“我们”,谁是“他们”?),其中我展示了我制作的 ASCII 绘图,其中显示了 a 的git rebase工作原理和正在执行的操作。git merge风格的工作流程中,仅显示合并之前某人在其 PR(拉取请求)功能分支中的唯一提交CB *_*ley 94
最简单的方法是使用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
Run Code Online (Sandbox Code Playgroud)
小智 79
或者要求的单行:
git rebase --onto a b f
Run Code Online (Sandbox Code Playgroud)
JJD*_*JJD 65
您可以使用序列组合git rebase并将git branch一组提交应用到另一个分支.正如wolfc发布的那样,第一个命令实际上复制了提交.但是,在将分支名称添加到组的最顶层提交之前,更改不可见.
请在新标签页中打开图片...

以文本形式总结命令:
gitk --all &.git rebase --onto a b f.HEAD标记.git branch selection这应该澄清一些事情:
a是组的新根目标.b是第一次提交组(独占)之前的提交.f是该组的最后一次提交(包括).之后,你可以使用git checkout feature && git reset --hard b删除提交c,直到f从feature分支.
除了这个答案之外,我写了一篇博文,其中描述了另一种场景中的命令,这些命令应该有助于普遍使用它.
And*_*ndy 40
申请JB Rainsberger和sschaef的评论来专门回答这个问题...在这个例子中使用樱桃挑选范围:
git checkout a
git cherry-pick b..f
Run Code Online (Sandbox Code Playgroud)
要么
git checkout a
git cherry-pick c^..f
Run Code Online (Sandbox Code Playgroud)
Dus*_*tin 19
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
Run Code Online (Sandbox Code Playgroud)
Nic*_*k F 16
另一个值得一提的变体是,如果您想要n来自分支的最后一次提交,则~语法可能很有用:
git cherry-pick some-branch~4..some-branch
Run Code Online (Sandbox Code Playgroud)
在这种情况下,上面的命令将从名为的分支中选择最后 4 个提交some-branch(尽管您也可以使用提交哈希代替分支名称)
Ayu*_*pta 10
择优挑选多个提交:
签出到您想要挑选提交的分支
使用此命令:(通过部分哈希)
git cherry-pick 1e038f10 1e038f11 1e038f12 ...
Run Code Online (Sandbox Code Playgroud)
要从提交ID到分支的尖端进行挑选,可以使用:
git cherry-pick commit_id^..branch_name
| 归档时间: |
|
| 查看次数: |
392546 次 |
| 最近记录: |