Hg:如何像git's rebase那样做一个rebase

在Git中,我可以这样做:

1. Start working on new feature:
$ git co -b newfeature-123  # (a local feature development branch)
do a few commits (M, N, O)


master A---B---C
\
newfeature-123   M---N---O


2. Pull new changes from upstream master:
$ git pull
(master updated with ff-commits)


master A---B---C---D---E---F
\
newfeature-123   M---N---O


3. Rebase off master so that my new feature
can be developed against the latest upstream changes:
(from newfeature-123)
$ git rebase master


master A---B---C---D---E---F
\
newfeature-123               M---N---O

< br / >

我想知道如何在Mercurial中做同样的事情,我在网上搜索了一个答案,但我能找到的最好的是:Git rebase - hg能做到吗

该链接提供了两个示例:
. 1. 我承认这:(用我自己的例子替换例子中的修订)

hg up -C F
hg branch -f newfeature-123
hg transplant -a -b newfeature-123

不是很糟糕,除了它留下了预重基M-N-O作为未合并的头,并创建了3个新的提交M',N',O',代表它们从更新的主线分支。

基本上问题是这样的:

master A---B---C---D---E---F
\           \
newfeature-123   \           M'---N'---O'
\
newfeature-123     M---N---O

这并不好,因为它会留下应该丢弃的本地、不需要的提交。

  1. 来自同一链接的另一个选项是
hg qimport -r M:O
hg qpop -a
hg up F
hg branch newfeature-123
hg qpush -a
hg qdel -r qbase:qtip

这就得到了我们想要的图:

master A---B---C---D---E---F
\
newfeature-123               M---N---O

但是这些命令(总共6个!)似乎比

$ git rebase master

我想知道这是否是Hg中唯一等效的方法,或者是否有其他简单的方法,如Git。

83768 次浏览

你可能在找变基扩展。(作为SummerOfCode 2008的一部分实现)

在这种情况下,“分离”本地更改,将存储库与主流存储库同步,然后将私有更改附加在新的远程更改之上是很有用的。这个操作称为rebase。

:

alt text

:

alt text


As 下面的评论 by steprobe:

在你没有拉入变更的情况下,你在你的回购中有两个分支,你可以这样做(using keepbranches):

hg up newfeature-123
hg rebase -d master --keepbranches

(--keepbranches:继承原来的分支名称。)

Mojca提到:

我喜欢使用hg rebase --source {L1's-sha} --dest {R2's-sha},但我不知道我可以在结尾添加--keepbranches

As 所示的 by 乔纳森·布莱克本:

 hg rebase -d default --keepbranches

假设你有一个现代化的Hg安装,你可以简单地添加:

[extensions]
rebase =

~ / . hgrc。

然后你可以使用命令hg rebasehg pull --rebase,或hg help rebase

VonC有你想要的答案, Rebase扩展名。但是,值得花一秒钟或两秒钟思考一下为什么在mercurial中默认情况下既不启用mq也不启用rebase:因为mercurial都是关于不可删除的更改集。当我以你描述的方式工作时,我几乎每天都在工作,下面是我采取的模式:

1. Start working on a new feature:
$ hg clone mainline-repo newfeature-123
do a few commits (M, N, O)


master A---B---C
\
newfeature-123   M---N---O


2. Pull new changes from upstream mainline:
$ hg pull


master A---B---C---D---E---F
\
newfeature-123   M---N---O


3. merge master into my clone so that my new feature
can be developed against the latest upstream changes:
(from newfeature-123)
$ hg merge F


master A---B---C---D---E---F
\           \
newfeature-123   M---N---O---P

这就是所有需要做的。我最终得到了一个新的功能123克隆,当我对它感到满意时,我可以轻松地将它推回到主线中。然而,最重要的是,我从未改变历史。有人可以查看我的cset,并了解它们最初是针对什么编写的,以及我在整个工作过程中如何对主线中的变化做出反应。不是每个人都认为这有价值,但我坚信源代码控制的工作不是告诉我们我们希望发生什么,而是告诉我们实际发生了什么——每个死胡同和每个重构都应该留下不可磨灭的痕迹,而重基和其他历史编辑技术会掩盖这一点。

我把我的临时演讲台收起来,你去帮我选冯克的答案。:)

我不认为上面的答案达到了OP的目标,也就是维护他的任务分支,只是基于父分支的后面一个点。

假设我从这个图开始(使用graphlog扩展名生成)。极客对graphlog的热爱)。

@  9a4c0eb66429 Feature 3 commit 2 tip feature3
|
| o  af630ccb4a80 default againagainagain
| |
o |  98bdde5d2185 Feature 3 branch commit 1  feature3
|/
o  e9f850ac41da foo

如果我在feature3分支上,并且想要将它从againagainagain提交上重新赋基,我知道我会运行hg rebase -d default。这有以下结果:

@  89dada24591e Feature 3 commit 2 tip
|
o  77dcce88786d Feature 3 branch commit 1
|
o  af630ccb4a80 default againagainagain
|
o  e9f850ac41da foo

任务完成了?我不这么想。问题是当feature3分支上的提交一次又一次地基于删除feature3分支时。我的提交已经移动到默认分支,这是我首先要避免的。

在Git中,结果看起来是这样的:

@  9a4c0eb66429 Feature 3 commit 2 tip
|
o  98bdde5d2185 Feature 3 branch commit 1 **feature3**
|
o  af630ccb4a80 default againagainagain
|
o  e9f850ac41da foo

注意,feature3分支仍然存在,两次提交仍然在feature3分支上,默认情况下不可见。如果不保留任务分支,我看不出这在功能上与合并有什么不同。

更新:我发现hg rebase支持--keepbranches标志,我很高兴地报告一切都很好。使用hg rebase -d default --keepbranches,我完全复制了我渴望的Git行为。换了几个化名之后,我就改换基地了。

由于有些人附和说,他们认为保留所有东西的每个迭代是好的,我要指出的是,对于较大的开源项目,接受充满合并和开发迭代的更改将导致混乱的主线修订历史,并使修订历史对于查看当前版本是如何实现的用处较小。

当提交的更改在被接受之前由非编写更改的人进行审查时,这种方法效果很好,因此进入主线的更改通常会被调试并工作。然后,当你回溯到一条线的原点时,你会看到所有与之相关的变化,而不是它所在的变化发展过程中的某个点。

x265贡献者页面向x265项目解释了如何重新提交您正在处理的一组更改,以便为提交做好准备。(包括使用TortoiseHG在一个单独的文件中提交一些但不是全部的更改,比如git gui的stage/unstage diff块用于提交)。

这个过程是将hg更新到上游提示,然后在工作目录中获得未提交的所有更改。搁置那些不是你想要提交的内容,然后将剩下的内容分解成尽可能多的独立提交,并使用漂亮的提交消息。

我猜您会复制/粘贴,然后编辑来自您正在修改的补丁集以前迭代的提交消息。或者您可以移植您的旧提交(在git语言中选择),然后逐个修改它们,以获得您的旧提交消息作为编辑的起点。