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

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

问题描述

我有以下存储库布局:

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

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

解决方案

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

正如下面提到的Keith Kim,Git 1.7.2+ 引入了挑选一系列提交的能力(但你仍然需要注意 为未来合并而挑选的结果)

<块引用>

git 樱桃挑选"学会了选择一系列提交
(例如cherry-pick A..B"和cherry-pick --stdin"),git revert";这些不支持更好的排序控制rebase [-i]";不过有.

damian 评论 并警告我们:

<块引用>

cherry-pick A..B"中形式,A 应该比 B 旧.
如果它们的顺序错误,命令将无声地失败.

如果你想选择范围BD(包括B),那就是B^..D(而不是 B..D).
请参阅Git 从先前提交的范围创建分支?"作为说明.

正如 Jubobs 提到的 在评论中:

<块引用>

这里假设 B 不是根提交;你会得到一个unknown revision";否则错误.

注意:从 Git 2.9.x/2.10(2016 年第三季度)开始,您可以直接在孤儿分支(空头)上挑选一系列提交:参见 "如何在 git 中使现有分支成为孤儿》.


原始答案(2010 年 1 月)

rebase --onto 会更好,您可以在集成分支上重放给定的提交范围,如 此处描述的查尔斯·贝利.
(另外,在 git rebase 手册页,查看git rebase --onto)

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

# 在当前位置检出一个新的临时分支git checkout -b tmp# 将集成分支移动到新补丁集的头部git branch -f 集成 last_SHA-1_of_working_branch_range# 将补丁集重新定位到 tmp,旧的集成位置git rebase --onto tmp first_SHA-1_of_working_branch_range~1 集成

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

  • 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"; 分支 + 所有重放的提交)

使用cherry-picking 或rebase --onto,不要忘记它对后续合并有影响,如此处描述.


纯粹的cherry-pick"解决方案是在此处讨论,并且将涉及以下内容:

<块引用>

如果你想使用补丁方法,那么git format-patch|git am";和git樱桃"是你的选择.
目前,git cherry-pick 只接受一次提交,但如果你想选择 BD 的范围,那就是 B^..D 在 git 术语中,所以

git rev-list --reverse --topo-order B^..D |在阅读 rev 时做git 樱桃选择 $rev ||休息完毕

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

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'm 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 (including B) that would be B^..D (instead of 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天全站免登陆