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

将历史移植到*当前*分支

git
  •  1
  • Raman  · 技术社区  · 7 年前

    git rebase --onto 移植历史。然而,我经常发现自己想把历史从另一个分支移植到我的电脑上 现在的 分支,没有中间分离的头部状态。

    换句话说:

    git checkout foo
    git rebase --onto foo A^ B
    # results in a detached HEAD
    # how to avoid this last step?
    git checkout -B foo
    
    2 回复  |  直到 7 年前
        1
  •  5
  •   torek    7 年前

    太长,读不下去了

    git cherry-pick ,以及(稍后), git reset git branch -f

    请耐心听我说一会儿,我复习一下你已经知道的东西,因为它们会使答案更清楚。

    按工程重设基础 提交。也就是说,给定以下形式的提交图:

    ...--o--*--I   <-- mainline
             \
              F--G--H   <-- branch (HEAD)
    

    我们经常发现自己想要拥有提交序列 F-G-H I git checkout branch && git rebase mainline ,其中 提交 F-G-H公司 当前分行名称 指向最后一份副本:

                 F'-G'-H'  <-- branch (HEAD)
                /
    ...--o--*--I   <-- mainline
             \
              F--G--H   [abandoned, sort of]
    

    如您所知,我们可以将要复制的提交集与它们应该使用的点分开 git rebase --onto . 例如,不是复制所有 F-G-H公司 ,我们可能想离开 F 后面,仅复制 G H

                 G'-H'  <-- branch (HEAD)
                /
    ...--o--*--I   <-- mainline
             \
              F   <-- ???
               \
                G--H   [abandoned, sort of]
    

    当我们这样做时,最好给我们留下的提交加上一些名字 我们让Git把名字移走 branch . 我们可以用 git branch git checkout -B 或者别的什么。然而,关键是我们使用 --onto 目标commit,在它之后拷贝将被复制,另一个参数限制哪些提交被复制。政府承诺 之后 我们放弃的论点,包括 HEAD

    关于这个的论点 --上

    git rebase --onto $target $stop
    

    哪里 $stop .

    rebase实现这一点的方法非常简单:

    1. 它记住当前分支(或对于分离的头,哈希ID): saved_branch=$(git symbolic-ref -q --short HEAD) ,或多或少。

    2. 它列出要复制的提交的哈希ID。它使用 git rev-list $stop..HEAD .

    3. 它运行 git checkout --detach $onto (或差不多相等的东西)。

    4. 它运行 git cherry-pick <saved list> ,即。, git cherry-pick $stop..$saved_branch .

    5. 一旦所有的选择都完成,包括任何解决冲突的站点,由humanit runs处理 git branch -f $saved_branch HEAD 使保存的分支名称指向上次复制的提交。(这个特别的名字也有点乱 ORIG_HEAD .)

    在你的情况下,你已经在 部分。也就是说,第一步是不相关的,第二步不可能以完全相同的方式发生。步骤3不应该发生在所有我们希望新的承诺,以扩大目前的分支!

    这就只剩下第4步和第5步了。

    步骤4在任何现代Git中都特别简单,其中 吉特樱桃采摘 可以处理一个序列:我们只是运行:

    git cherry-pick $stop..$branch
    

    $停止 是在提交时的停止(我们所做的提交) 不要 $branch 我想要复制。如果我们在 mainline 现在,这是 git cherry-pick <hash-of-F>..branch git cherry-pick branch~2..branch ,以复制提交 小时

    $分支 指向后退以提交 F级 完成后,我们可以运行:

    git checkout $branch && git reset --hard $stop
    

    或:

    git branch -f $branch $stop
    

    主线

        2
  •  0
  •   Raman    7 年前

    git cherry-pick A..B

    @torek回答的关键信息当然是 cherry-pick 接受范围。