在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一样简单。
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的答案。 :)
你可能正在寻找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
假设你有一个现代的Hg安装,你可以简单地添加:
[extensions]
rebase =
〜/。
然后你可以使用命令hg rebase
,hg pull --rebase
或hg help rebase
。
我不认为上面的答案达到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分支上,默认情况下不可见。在不保留任务分支的情况下,我看不出它在功能上与合并有何不同。
更新:我发现hg rebase支持的--keepbranches
标志,我很高兴报告一切都是okey-dokey。使用hg rebase -d default --keepbranches
,我完全复制了我渴望的Git行为。后来有几个别名,我像任何人的业务一样反对。
由于有些人已经说过他们认为保持所有内容的每次迭代都是好的,我会指出,对于更大的开源项目,接受充满合并和开发迭代的变化会导致主线修订历史混乱,并使修订历史对于查看当前版本是如何到达那样有用。
如果提交的更改由未编写它们的人在被接受之前进行审核,那么这种方法很有效,因此进入主线的更改通常会被调试并正常工作。然后,当您回溯到一条线的原点时,您会看到所有随之而来的变化,而不是它所发生的变化发展过程中的某些点。
x265 contributors页面解释了如何重新提交您正在进行的一组更改,以使它们准备好提交到x265项目。 (包括使用TortoiseHG来提交单个文件中的一些但不是所有更改,例如git gui的stage / unstage diff hunk for commit)。
该过程是将hg更新到上游提示,然后在工作目录中未提交所有更改。保留任何不属于您想要提交的内容的内容,然后将其余内容分解为适当的多个单独提交,并提供良好的提交消息。
我想你会复制/粘贴然后编辑你正在修改的补丁集的先前迭代中的提交消息。或许你可以移植你的旧提交(用git语言挑选),然后逐个修改它们,以便将旧的提交消息作为编辑的起点。