如何挑选一系列提交并合并到另一个分支? [英] How to cherry pick a range of commits and merge into another branch?

查看:164
本文介绍了如何挑选一系列提交并合并到另一个分支?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下存储库布局:

  • 主分支(生产)
  • 整合
  • 工作

我想要实现的是从工作分支中挑选一系列提交并将其合并到集成分支中.我对git很陌生,我不知道如何准确地做到这一点(在一个操作中选择合并范围而不是合并中的提交范围)而不弄乱存储库.有任何指示或想法吗?谢谢!

解决方案

当涉及到一系列提交时,挑选 是不切实际的. >

挑选樱桃的后果,以供将来合并)

git cherry-pick"学会了选择一系列提交
(例如"cherry-pick A..B"和"cherry-pick --stdin"),"git revert"也是如此;但是,这些不支持更好的排序控件"rebase [-i]".

达米安 评论并警告我们:

在"cherry-pick A..B"表格中, A应该早于B .
如果顺序错误,该命令将自动失败.

如果您要选择范围BD(包括),则该范围将为 B^..D .
请参见"是否从以前的提交范围创建Git创建分支?".

Jubobs 提到unknown revision"错误.

注意:从Git 2.9.x/2.10(2016年第三季度)开始,您可以直接在孤儿分支(空头)上挑选一系列提交:请参阅"


原始答案(2010年1月)

rebase --onto更好,您可以在集成分支顶部重播给定的提交范围,如 git rebase手册页,以查看git rebase --onto)

的实际示例

如果您当前的分支是集成:

 # Checkout a new temporary branch at the current location
git checkout -b tmp

# Move the integration branch to the head of the new patchset
git branch -f integration last_SHA-1_of_working_branch_range

# Rebase the patchset onto tmp, the old location of integration
git rebase --onto tmp first_SHA-1_of_working_branch_range~1 integration
 

这将重播之间的所有内容:

  • first_SHA-1_of_working_branch_range的父项之后(因此是~1):您要重播的第一个提交
  • 直到"integration"(指向您要从working分支重播的最后一个提交)

到"tmp"(指向integration之前指向的位置)

如果重播这些提交之一时有任何冲突:

  • 要么解决它,然后运行"git rebase --continue".
  • 或跳过此补丁,而是运行"git rebase --skip"
  • 或使用"git rebase --abort"取消所有操作(并将integration分支放回tmp分支上)

rebase --onto之后,integration将返回到集成分支的最后一次提交(即"tmp"分支+所有重播的提交)

选择樱桃或rebase --onto时,请不要忘记它会对后续合并产生影响,例如此处已讨论,并且涉及到以下内容:

如果您想使用补丁方法,则可以选择"git format-patch | git am"和"git cherry".
当前,git cherry-pick仅接受一次提交,但是如果您要选择BD的范围,则在git lingo中应为B^..D,因此

 git rev-list --reverse --topo-order B^..D | while read rev 
do 
  git cherry-pick $rev || break 
done 
 

但是无论如何,当您需要重播"一系列提交时,重播"一词应促使您使用Git的"rebase"功能.

I have the following repository layout:

  • master branch (production)
  • integration
  • working

What I want to achieve is to cherry pick a range of commits from the working branch and merge it into the integration branch. I pretty new to git and I can't figure out how to exactly do this (the cherry picking of commit ranges in one operation not the merging) without messing the repository up. Any pointers or thoughts on this? Thanks!

解决方案

When it comes to a range of commits, cherry-picking is was not practical.

As mentioned below by Keith Kim, Git 1.7.2+ introduced the ability to cherry-pick a range of commits (but you still need to be aware of the consequence of cherry-picking for future merge)

git cherry-pick" learned to pick a range of commits
(e.g. "cherry-pick A..B" and "cherry-pick --stdin"), so did "git revert"; these do not support the nicer sequencing control "rebase [-i]" has, though.

damian comments and warns us:

In the "cherry-pick A..B" form, A should be older than B.
If they're the wrong order the command will silently fail.

If you want to pick the range B through D (inclusive) that would be B^..D.
See "Git create branch from range of previous commits?" as an illustration.

As Jubobs mentions in the comments:

This assumes that B is not a root commit; you'll get an "unknown revision" error otherwise.

Note: as of Git 2.9.x/2.10 (Q3 2016), you can cherry-pick a range of commit directly on an orphan branch (empty head): see "How to make existing branch an orphan in git".


Original answer (January 2010)

A rebase --onto would be better, where you replay the given range of commit on top of your integration branch, as Charles Bailey described here.
(also, look for "Here is how you would transplant a topic branch based on one branch to another" in the git rebase man page, to see a practical example of git rebase --onto)

If your current branch is integration:

# Checkout a new temporary branch at the current location
git checkout -b tmp

# Move the integration branch to the head of the new patchset
git branch -f integration last_SHA-1_of_working_branch_range

# Rebase the patchset onto tmp, the old location of integration
git rebase --onto tmp first_SHA-1_of_working_branch_range~1 integration

That will replay everything between:

  • after the parent of first_SHA-1_of_working_branch_range (hence the ~1): the first commit you want to replay
  • up to "integration" (which points to the last commit you want to replay, from the working branch)

to "tmp" (which points to where integration was pointing before)

If there is any conflict when one of those commits is replayed:

  • either solve it and run "git rebase --continue".
  • or skip this patch, and instead run "git rebase --skip"
  • or cancel the all thing with a "git rebase --abort" (and put back the integration branch on the tmp branch)

After that rebase --onto, integration will be back at the last commit of the integration branch (that is "tmp" branch + all the replayed commits)

With cherry-picking or rebase --onto, do not forget it has consequences on subsequent merges, as described here.


A pure "cherry-pick" solution is discussed here, and would involve something like:

If you want to use a patch approach then "git format-patch|git am" and "git cherry" are your options.
Currently, git cherry-pick accepts only a single commit, but if you want to pick the range B through D that would be B^..D in git lingo, so

git rev-list --reverse --topo-order B^..D | while read rev 
do 
  git cherry-pick $rev || break 
done 

But anyway, when you need to "replay" a range of commits, the word "replay" should push you to use the "rebase" feature of Git.

这篇关于如何挑选一系列提交并合并到另一个分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆