在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
我想知道如何在Mercurial中做同样的事情,我在网上搜索答案,但我能找到的最好的是:git rebase - can hg do that
该链接提供了两个例子:
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
这不好,因为它留下了应该删除的本地不需要的提交。
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一样简单。
答案 0 :(得分:233)
VonC有the answer you're looking for,Rebase扩展。然而,值得花一两秒时间考虑为什么默认情况下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
这就是所有必要的。我最终得到了一个newfeature-123克隆,当我对它很满意时,我可以很容易地回到主线。但最重要的是,我永远不会改变历史。有人可以查看我的cset并查看它们最初编码的内容以及我在整个工作中对主线的变化的反应。不是每个人都认为它有价值,但我坚信,源代码控制的工作不是向我们展示我们希望发生的事情,而是实际发生的事情 - 每个deadend和每个重构都应该留下不可磨灭的痕迹,并且变基和其他历史编辑技术隐藏起来。
现在,当我把肥皂盒拿走时,选择VonC的答案。 :)
答案 1 :(得分:102)
您可能正在寻找Rebase Extension。 (作为SummerOfCode 2008)
的一部分实施在这些情况下,“分离”本地更改,将存储库与主流同步,然后在新的远程更改之上附加私有更改可能很有用。此操作称为rebase。
为:
如果您没有提取更改,并且您的回购中有两个分支,则可以执行( using
keepbranches
):
hg up newfeature-123
hg rebase -d master --keepbranches
(--keepbranches
:继承原始分支名称。)
Mojca提及:
我喜欢使用
hg rebase --source {L1's-sha} --dest {R2's-sha}
,但我不知道最后可以添加--keepbranches
。
illustrated below作为Jonathan Blackburn:
hg rebase -d default --keepbranches
答案 2 :(得分:44)
假设你有一个现代的Hg安装,你可以简单地添加:
[extensions]
rebase =
到〜/ .hgrc。
然后您可以使用命令hg rebase
,hg pull --rebase
或hg help rebase
。
答案 3 :(得分:21)
我不认为上面的答案达到了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分支上并且希望将其重新设置为再次提交,我知道我会运行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分支上,默认情况下不可见。在不保留任务分支的情况下,我看不出它在功能上与合并有何不同。
UPDATE :我发现hg rebase支持--keepbranches
标志,我很高兴报告所有内容都是okey-dokey。使用hg rebase -d default --keepbranches
,我完全复制了我渴望的Git行为。之后有几个别名,我就像没有人做生意一样反对。
答案 4 :(得分:3)
由于有些人说他们认为保持所有内容的每次迭代都很好,我会指出,对于更大的开源项目,接受充满合并和开发迭代的变化会使对于凌乱的主线修订历史记录,并使修订历史记录对于查看当前版本如何到达那里不太有用。
如果提交的更改在未被接受之前由未编写的人进行审核,则此方法很有效,因此进入主线的更改通常会进行调试并正常工作。然后,当你回溯到一条线的原点时,你会看到它所带来的所有变化,而不是它所发生变化的中间点。
x265 contributors页面解释了如何重新提交您正在进行的一系列更改,以便准备好提交到x265项目。 (包括使用TortoiseHG来提交单个文件中的一些但不是所有更改,例如git gui的stage / unstage diff hunk for commit)。
该过程是将hg更新到上游提示,然后在工作目录中未提交所有更改。保留任何不想提交的内容,然后将其余内容分解为适当的单独提交,并提供良好的提交消息。
我猜你要复制/粘贴然后编辑你之前正在修改的补丁集迭代中的提交消息。或许你可以移植你的旧提交(用git语言挑选),然后逐个修改它们,把你的旧提交消息作为编辑的起点。