代码之家  ›  专栏  ›  技术社区  ›  jpswain

hg:如何像git的rebase那样进行rebase

  •  205
  • jpswain  · 技术社区  · 15 年前

    在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
    

    这是不好的,因为它留下了本地的,不需要的提交,应该删除。

    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。

    5 回复  |  直到 6 年前
        1
  •  230
  •   Community CDub    8 年前

    VonC有 the answer you're looking for ,rebase扩展。然而,值得花一两秒钟思考一下为什么mq和rebase在mercurial中默认都不启用:因为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,看看它们最初是针对什么编写的,以及我在整个工作中对主线中的更改的反应。不是每个人都认为这有价值,但我坚信,源代码控制的工作不是向我们展示我们希望发生的事情,而是实际发生的事情——每个死区和每个重构都应该留下不可磨灭的痕迹,而重新调整和其他历史编辑技术隐藏了这一点。

    现在我把肥皂盒收起来,去选冯克的答案。:)

        2
  •  99
  •   VonC    6 年前

    你可能在找 Rebase Extension . (作为 SummerOfCode 2008 )

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

    Getting from :

    alt text

    到:

    alt text


    AS commented below 通过 steprobe :

    如果您没有提取更改,并且您的回购协议中有两个分支,则可以( using keepbranches ):

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

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

    Mojca 提到:

    我喜欢使用 hg rebase --source {L1's-sha} --dest {R2's-sha} ,但我不知道我能加上 --保留牧场 最后。

    AS illustrated below 通过 Jonathan Blackburn :

     hg rebase -d default --keepbranches
    
        3
  •  43
  •   sblom    15 年前

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

    [extensions]
    rebase = 
    

    给某人写信。

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

        4
  •  21
  •   Richard Dingwall    10 年前

    我认为上面的答案并没有达到OP的目标,即维护他的任务分支,只是相对于父分支的稍后一点重新调整。

    假设我从这个图开始(使用graphlog扩展生成)。严肃的极客喜欢画图)。

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

    如果我在Feature3分支上,并且想将其从Againagainagainagain提交中移除,我知道我会运行 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分支上的提交在Againagainagainagainagainagainagainagainagainagainagainagainagainagainagainagainagainagainagain上时, 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分支上,默认情况下不可见。如果不保留任务分支,我看不出这在功能上与合并有什么不同。

    更新 :我发现了 --keepbranches 由hg rebase支持的标志,我很高兴地报告一切正常。使用 hg rebase -d default --keepbranches ,我完全复制了我渴望的git行为。几次化名之后,我就开始变卦了。

        5
  •  3
  •   Peter Cordes    10 年前

    因为有些人已经附和说他们认为保持每一个迭代都是好的,我将指出对于更大的开源项目来说,接受充满合并和开发迭代的变更将导致一个混乱的主线修订历史,并且使修订历史减少我们我很想看看现在的版本是怎么做到的。

    当提交的更改在被接受之前由未编写更改的人进行审阅时,这种方法可以很好地工作,因此进入主线的更改通常会被调试和工作。当你回溯到一条直线的原点时,你会看到它所伴随的所有变化,而不是它所参与的变化发展过程中的某个点。

    这个 x265 contributors 页面说明 如何重新提交正在处理的一组更改,以使它们准备好提交 到X265项目。(包括使用tortoisehg提交单个文件中的一些但不是所有更改,如git gui的stage/unstage diff hunk for commit)。

    这个过程是将hg更新到上游提示,然后在工作目录中获得所有未提交的更改。搁置不属于您要提交的内容的任何内容,然后将其余内容拆分为适当的多个单独提交,并提供漂亮的提交消息。

    我想您应该复制/粘贴,然后编辑您正在修改的补丁集以前迭代的提交消息。或者您可以移植旧的提交(git语言中的cherry pick),然后逐个修改它们,以获取旧的提交消息作为编辑的起点。