在 Git 中,rebase 可以做一些骚操作。这篇就来讲讲 rebase 中的 --onto 选项。
    先来看例1:

    1. // 例1
    2. A---B---C---D (HEAD, master)
    3. \
    4. E---F---G

    使用 git rebase C F ,会形成下面的提交记录:

    1. A---B---C---D (master)
    2. \
    3. E'---F' (HEAD)

    但,如果是 git rebase --onto C F ,会形成这样的提交记录:

    1. A---B---C---D (master)
    2. \
    3. G' (HEAD)

    可以看到,加上 --onto 之后,与之前的不加的提交记录全变了。我们来看一下 --onto 的选项。

    1. git rebase --onto <newparent> <oldparent> <until>

    其中,until 不是必须的选项。

    1. // 例2
    2. A---B---C---D (HEAD, master)
    3. \
    4. E---F---G---H---I

    在例2中,使用 git rebase C F H 后的提交记录为:

    1. A---B---C---D (master)
    2. \
    3. G'---H' (HEAD)

    可以看到,他是以 C 结点为根,在 C 之上进行变基,变基的基础是 oldparentuntil 的共同父节点(不包括父节点)到 until 结点之间的历史。上述就是 FH 的父节点 FH 的历史,也就是 G---H ,变基到 C 上。
    如果,对例2使用 git rebase C F 那么提交会变成这样。

    1. A---B---C---D (master)
    2. \
    3. G'---H'---I' (HEAD)

    可以看到,如果没有加 until 他会一直到 oldparent 的结尾。
    在例3中,可以让你看出 until 的实用性:

    1. // 例3
    2. A---B---C---D (HEAD, master)
    3. \
    4. E---F---G (server)
    5. \
    6. H---I (client)

    在例3中,使用 git rebase --onto master server client ,就会形成这样的提交:

    1. A---B---C---D (master)---H'---I' (HEAD, client)
    2. \
    3. E---F---G (server)
    4. \
    5. H---I

    可以看到,它可以截取 server 分支中的 client 分支的提交,变基到 master 分支上。从上面的命令中可看,他是截取 serverclient 的父节点 Eclient 结点之间的提交。