【问题标题】:Rebase single commit without replaying subsequent commits重新设置单个提交而不重播后续提交
【发布时间】:2019-11-20 10:36:37
【问题描述】:

我有两个分支,B1 和 B2,在以下设置中

          [B1]
-o-o-d1-d2-d3 
      \
       c1-c2-c3  
            [B2]

我想将提交 c1 切换到 B1 以实现以下设置

-o-o-d1-c1-d2-d3
         \
          c2-c3

我知道我可以将 c1 挑选到第一个分支上。但如果我只在分支 B1 上更改了 c1,我的历史记录会更清晰。 (我承认,这个问题可以看作是一个美学问题......但我希望 git 有一个很好的解决方案。)

【问题讨论】:

  • 这能回答你的问题吗? Git: How to rebase to a specific commit?
  • @TimBiegeleisen:谢谢。所以在第 2 步中,我仍然会写 pick 但使用 c2 的哈希?
  • 请注意,从提交d2 回到提交d1 的连接实际上是一部分 d2 本身。任何现有提交的任何部分都不能更改,因此为了达到您想要的结果,您必须将现有的d2 复制到其父级为c1 的新提交(具有不同的哈希 ID)。现有的c1 可以重复使用,但必须复制d2。我们可以将新改进的副本称为d2'。复制 d2 后,您还必须将 d3 换成新的和改进的副本,以便 d3' 引用 d2'。这样就完成了所有的复制,之后分支名称标签B1需要调整。
  • 整个过程——将一些提交复制到新的和改进的版本,然后调整分支标签以指向最终复制的提交——正是 git rebase 所做的。您可以手动将其拆分为一系列git cherry-pick 命令,每个命令复制一个提交,然后是git branch -f,这是RomainValeri's answer 中的内容,或者使用git rebase,如Phlippe's answer。跨度>

标签: git rebase


【解决方案1】:

你只需要这样做:

git checkout B1
git rebase c1

rebase 将重新应用到 c1 上来自提交 c1 和分支 B1 之间的最后一个共同祖先的所有提交,即来自 d1(最后一个共同祖先)的 B1 中的所有提交。

在你的情况下,d2 和 d3。

【讨论】:

    【解决方案2】:

    简答

    git checkout c1
    git cherry-pick d2 d3
    git branch -f B1 [HEAD]
    

    分步流程(为了清楚起见,使用临时分支)

    初步情况

    -o-o-d1-d2-d3 <<< B1
          \
           c1-c2-c3 <<< B2
    

    首先将临时分支指向c1

    git checkout -b B3 c1
    

    第二阶段

    -o-o-d1-d2-d3 <<< B1
          \
           c1 <<< B3
             \
              c2-c3 <<< B2
    

    然后你恢复d2d3

    git cherry-pick d2 d3
    

    第三阶段

    -o-o-d1-d2-d3 <<< B1
          \
           c1-d2'-d3' <<< B3
             \
              c2-c3 <<< B2
    

    你最终必须移动 B1 以指向我们的新构造 (B3)

    git checkout -B B1 B3
    # and destroy the temp branch
    git branch -d B3
    

    (当然,这意味着 B1 的重写历史。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-11
      • 2021-07-22
      • 2013-03-03
      • 1970-01-01
      • 2013-06-29
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多