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

我可以在不显式指定父级的情况下在分支的分叉点上重新设置基础吗?

git
  •  3
  • Andrew  · 技术社区  · 6 年前

    git rebase -i 在出版之前整理一下我的历史。通常我想编辑提交回当前分支分叉的位置,而不更改其分叉点。我是这样做的: git rebase -i $(git show-branch --merge-base $PARENT_BRANCH HEAD)

    这是一个丑陋的命令,我正试图找到一个更好的方法。只要我还在做,我希望git能自动找出正确的父级。

    认为 我想要的是一个 git rebase -i --fork-point $(something) 哪里 something 查找具有当前分支的最新共同祖先的分支。它不需要防弹。如果它适用于线性主题分支,那就足够了。

    2 回复  |  直到 6 年前
        1
  •  5
  •   VonC    3 年前

    使用Git 2.24(2019年第4季度),不再 git rebase -i --onto @{upstream}...HEAD

    git rebase --keep-base <upstream> “试图找到主题的原始基础,然后 在同一底座上重新设置底座 ,在运行 git rebase -i git rebase -x

    该命令还学会了在更多情况下快速前进,在这种情况下,它可以代替重放来重新创建相同的提交。

    commit 414d924 , commit 4effc5b commit c0efb4c , commit 2b318aa (2019年8月27日),以及 commit 793ac7e commit 359eceb (2019年8月25日) Denton Liu ( Denton-L )
    帮助者: Eric Sunshine ( sunshineco ) , Junio C Hamano ( gitster ) , Ævar Arnfjörð Bjarmason ( avar ) ,和 Johannes Schindelin ( dscho ) .
    commit 6330209 , commit c9efc21 commit 4336d36 (2019年8月25日) 瓦阿恩夫比亚马森( ) .
    帮助者: 埃里克阳光( 阳光公司 ) , 朱尼奥哈马诺( 吉斯特 ) , 阿瓦尔 ) ,和 约翰内斯·辛德林( ) .
    Junio C Hamano -- gitster -- 在里面 commit 640f9cd

    rebase:教rebase --keep-base

    一个常见的场景是,如果用户正在处理一个主题分支,并且他们希望对中间提交或autosquash进行一些更改,那么他们将运行以下操作

    git rebase -i --onto master... master
    

    为了保留合并基
    这在向Git邮件列表提供修补程序系列时非常有用,通常从当前邮件列表的顶部开始 master '.

    git rebase -x ./test.sh master... master
    

    由于在分支和上游的合并基础上重新调整是一种常见的情况,因此引入 --守住基地 选项作为快捷方式。

    这使我们可以重写上述内容

    git rebase -i --keep-base master
    

    以及:

    git rebase -x ./test.sh --keep-base master
    

    git rebase man page now includes

    :

    设置创建新提交到的合并基的起始点 <upstream> <branch> .
    git rebase --keep-base <upstream> <branch> '相当于跑步' git rebase --onto <upstream>... <upstream>


    在处理该特性的同时,上游分支可能会前进,保持在上游分支之上的再平衡可能不是最好的主意,但是保持基本提交的原样。

    尽管这个选项和 --fork-point <upstream> and <branch> ,此选项使用合并基作为 起点 --分叉点 使用合并基来确定 提交的集合


    mvds 暗示 in the comments 将此与 git rebase --reapply-cherry-picks

    在我的工作流程中,要为用C编写的固件开发一个最小的二进制补丁,我需要返回到某个提交散列,创建一个分支,执行修改,并在生成的二进制文件中找到差异。

    在那次提交之后,我们的编译器得到了升级,变得更加智能,将代码库变成了非编译代码。


    那些樱桃树会弄乱你的魔法 --reapply-cherry-picks 已使用。

    这个 debate is on the Git mailing-list

        2
  •  4
  •   torek    6 年前

    --fork-point 用于远程跟踪名称。它的工作方式是对所提供的上游使用reflog。有关这方面的更多信息,请参见,例如。, Git rebase - commit select in fork-point mode

    第二,但也许更重要的是你能跑 git rebase upstream , git rebase --onto newbase upstream git rebase . 使用双参数形式时,您可以获得很多自由:

    • 这个 upstream 参数限制将要复制的提交。我们一会儿会有更多的话要说。

    • 这个 newbase

    也就是说,当你 使用 --onto ,您必须为 --上 新基地 论点但是当你 不要 使用 --上 上游 习惯于 两个目的 参数是一个需要非常仔细的精确性。一个目的是自由的,另一个不是。

    号码

    (由于问题的更新,下一部分的结构很奇怪。)

    git show-branch --merge-base X Y = git merge-base X Y

    这个 git show-branch 命令现在生效 --merge-base --independent 当给出多个参数时。只有两个参数,它的作用与 git合并基X Y ,即查找修订的合并基 X Y . ( git merge-base --独立的

    我更喜欢 git合并基

    没有任何争论 上游

    每个分支可以有一个(但只能有一个)上游设置。

    任何分支的上游设置 B 通常是 origin/ B ,因为我们倾向于将它们推送到GitHub、Bitbucket或某个公司的web服务器上,我们会将它们的URL放在名称下面 origin 这样我们就不用一直打出来了。如果你已经用光了 origin/ ,并想有一个 第二 git再基 会自动使用,你有点不走运(但请继续阅读)。但是如果你 没有 git再基 自动使用。例如,如果你在 feature-X 现在,我想让它重新定位 develop

    $ git branch --set-upstream-to=develop
    

    现在呢 feature 发展 作为它的上游。跑步 git再基 -i )将重新设置基础,就好像您对 发展 上游

    如果您已经用完了上游的别名,您可以创建自己的别名:

    alias.name = !git rebase "$@" $(git config --get branch.$(git symbolic-ref --short HEAD).base) #
    

    (选择一些名称):这允许您使用 git config ,一个额外的名字, branch.feature-X.base 发展 . 这个 $(git symbolic-ref --short) 提取当前分支名称 git config --get

    这里的缺点是,给定以下形式的图表:

                 o--o   <-- develop
                /
    ...--o--o--o
                \
                 A--B--C   <-- feature-X (HEAD)
    

    你最后得到的副本是

                      A'-B'-C'  <-- feature-X (HEAD)
                     /
                 o--o   <-- develop
                /
    ...--o--o--o
                \
                 A--B--C   [abandoned]
    

    当你想把副本放在同一个地方时,只需对它们的提交文本大惊小怪,或者把两个文本挤在一起或者其他什么:

                 o--o   <-- develop
                /
    ...--o--o--o--A'-B'-C'  <-- feature-X (HEAD)
                \
                 A--B--C   [abandoned]
    

    --上

    --上 参数选择目标提交:

                 o--o   <-- develop or whatever
                /
    ...--o--o--*    [pick this commit as target]
                \
                 A--B--C   <-- feature-X (HEAD)
    

    副本现在将在 * . 要复制的提交集实际上是通过使用, upstream ..feature-X 和向后工作,但不包括从 上游

    现在你只需要找到 * . 如果你有两个名字,比如 特征-X 发展 gitrevisions three-dot syntax , develop...feature-X feature-X...develop (当只有一个这样的合并基时,语法是对称的),以指定提交 * . 这只适用于Git的全新版本:在旧版本中,使用 git show分支 git合并基 (对于两个提交哈希ID,它们的行为方式相同)。

    指定提交的 * 作为 目标,您可以再次允许分支的上游作为限制器工作。也就是说,可以省略显式 因为它默认为实际的上游。既然你能用 @{upstream} @{u} 在语法方面,您可以创建一个非常简短的别名,就像您在自己的答案中所做的那样。

    如果你想保持一个独立的上游( origin/feature-X

    #! /bin/sh
    # git-base - rebase on the current branch's base setting
    . git-sh-setup
    branch=$(git symbolic-ref --short HEAD) || exit
    base=$(git config --get branch.$branch.base) || die "branch.$branch.base is not set"
    mbase=$(git merge-base $base HEAD) || die "there is no merge base"
    git rebase --onto $mbase "$@" $base
    

    git-base ,把它放在你的路径上,你现在可以跑了 git base

        3
  •  2
  •   Andrew    6 年前

    如果

    $ git rebase -i --onto @{upstream}...HEAD
    

    这些三个点的作用与git log和类似命令中的不同。从 git-rebase documentation :

    作为特例,您可以使用“a…B”作为合并基的快捷方式

    所以这是说“找到头部和它自己的上游的合并基础,并根据它重新调整基准”。通常本地分支没有上游,但是可以设置它,并且有一个gitconfig选项(autoSetupMerge)可以为新分支自动执行此操作。因此:

    $ git config --global branch.autoSetupMerge always
    $ git config --global alias.fixup 'rebase -i --onto @{upstream}...HEAD'
    $ git branch childbranch -u parentbranch  # Repeat for other branches as needed.
    

    git fixup
    

    它适用于所有未来的分支机构。

    torek's answer