【问题标题】:Rebase only part of a branch仅对分支的一部分进行变基
【发布时间】:2016-04-27 20:18:18
【问题描述】:

我有两个分支(和主分支)。 Branch 2 基于 Branch 1 基于 master。我已经提交了 Branch 1 进行审核,它有一些更改,我将其中一些更改重新设置为历史记录并将结果合并到 master。

现在我需要在 master 之上 rebase 分支 2 以准备审查/合并。

问题是分支 2 仍然包含分支 1 的原始提交,它们不再存在,所以 git 会感到困惑。我尝试 rebase -i 删除分支 1 的原始提交,但分支 2 的提交不基于 master-before-branch-1。

我需要做的是采用分支 2,删除一些提交,并在一次操作中将剩余的提交重新设置在 master 之上。但我只知道如何在两个不同的步骤中完成这两个操作。

如何将我的部分分支重新定位到另一个分支,删除所有不属于共同祖先的提交,除了我指定的提交(例如从 HEAD~2 开始)?

这是当前状态:

master                     new branch 1
- - - - - - - - - - - | - - - - - - - - -
    \
     \   branch 1
      \ _ _ _ _ _ _ _
                     \
                      \     branch 2
                       \ _ _ _ _ _ _ _

我想得到什么:

master            new branch 1    
- - - - - - - | - - - - - - - - - -
                                   \
                                    \
                                     \
                                      \    branch 2
                                       - - - - - - - - - 

【问题讨论】:

  • 一个代表你的仓库状态的 ASCII 图表会有所帮助。乍一看,我会说您正在寻找git rebase --onto。看看这是否有帮助:stackoverflow.com/questions/28715619/…
  • git rebase --onto 几乎为我工作。我做了git rebase --onto master --root HEAD~1,但由于某种原因,它选择了三个提交给我,而不是只有HEAD~1 及更高版本。此外,我现在不是重新设置分支,而是处于分离的 HEAD 状态。

标签: git


【解决方案1】:

实际的命令是:

git rebase --onto newbranch1 branch1 branch2

这将在new_branch1 之上重播所有提交之后 branch1 直到branch2 HEAD。

正如Joshua Goldberg 所说的in the comments

 git rebase --onto <place-to-put-it> <last-change-that-should-NOT-move> <change to move>

正如Denis Sivtsovthe comments 中说明的那样:

如果您只需要从分支重放最后一次提交,在这种情况下工作:

git rebase --onto newbranch1 HEAD~1

【讨论】:

  • 确实如此(我自己也打算发同样的)。顺便说一句,git help rebase 涵盖了这个案例。
  • @TomFenech 甚至比 git help rebase 更好:stackoverflow.com/a/2369516/6309(我在 2010 年的旧答案);)
  • 对我来说棘手的事情是理解帮助中的“上游”意味着保持不变的变化。 git rebase —onto &lt;place-to-put-it&gt; &lt;last-change-that-should-NOT-move&gt; &lt;change to move&gt;
  • @JoshuaGoldberg 是的:这就是我所说的“所有提交之后 branch1”。我已将您的命令包含在答案中以获得更多可见性。
  • 如果您只需要从分支重播最后一次提交,在这种情况下工作 git rebase --onto newbranch1 HEAD~1
【解决方案2】:

解决方案比我预期的要简单得多。事实证明,您可以将-i 提供给更多种类的变基命令(我认为这只是为了将分支变基到自身以更改历史记录)。所以我只是运行git rebase -i master 并放弃了那些额外的提交。

【讨论】:

  • 为了澄清 @Puppy 所做的是从分支 2 到新分支 1 的交互式变基(git rebase -i new_branch_1 在分支 2 上)并使用交互式控制台删除所有分支 1 提交,因此只有分支 2提交已播放。
  • 是的,执行git checkout branch-to-move &amp;&amp; git rebase -i new-parent-branch 并仅保留与您要保留的补丁匹配的行可以正常工作。只是要非常小心,不要丢弃任何您不想丢失的补丁。
【解决方案3】:
git rebase --onto master HEAD~2
  • master - 你要变基的分支
  • 2 - 您需要重新定位的当前分支的最后 n 次提交

Source

【讨论】:

  • 正是我需要的,谢谢!
【解决方案4】:

我发现您的 ASCII 图有点模棱两可,因为分支并不真正代表一系列提交 - 分支指向特定提交。我认为你的意思是像

H (new-branch-1)
G
| F (HEAD -> branch-2)
| E
| D (branch-1)
| C
|/
B (master)
A

在这种情况下,VonC's answergit rebase --onto new-branch-1 branch-1 branch-2 的目标和结果是

F' (HEAD -> branch-2)
E'
H (new-branch-1)
G
| D (branch-1)
| C
|/
B (master)
A

但是your answer git rebase -i master 没有意义。当然你的意思是git rebase -i new-branch-1 并在编辑器中写

drop C
drop D
pick E
pick F

这将实现上述目标。

(您的答案将导致):

F' (HEAD -> branch-2)
E'
| H (new-branch-1)
| G
|/ 
| D (branch-1)
| C
|/
B (master)
A

【讨论】:

    【解决方案5】:

    如已回答,您可以使用 --onto 执行此操作。

    我发现git rebase --onto 语法很混乱。所以我创建了这个脚本来重新定位“嵌套”分支:Github Gist

    在您的示例中,您会调用:

    moveBranch newBranch2 from newBranch1 to master

    #!/bin/bash
    
    ## Places a branch to a new base. 
    ## Useful when splitting a long branch to multiple pull requests.
    ##
    ##   ---+--------master 
    ##       \
    ##         --- A ---- B
    ## 
    ## git-moveBranch.sh B from A to master
    ##
    ##   ---+-------- master ---- B
    ##       \
    ##         --- A 
    
    
    function printUsageAndExit() {
        echo "Usage: moveBranch <branch> from <previous-base> to <new-base>";
        exit 1;
    }
    
    if [ 5 != $# ] ; then printUsageAndExit; fi
    if [ "$2" != "from" ] ; then printUsageAndExit; fi
    if [ "$4" != "to" ] ; then printUsageAndExit; fi
    
    WHAT="$1"
    FROM="$3"
    ONTO="$5"
    
    echo "Running:   git rebase —-onto=\"$ONTO\" \"$FROM\" \"$WHAT\""
    # git rebase —-onto <place-to-put-it> <last-change-that-should-NOT-move> <change to move>
    git rebase --onto "$ONTO" "$FROM" "$WHAT"
    

    【讨论】:

      猜你喜欢
      • 2021-10-16
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2014-05-22
      • 2016-09-20
      相关资源
      最近更新 更多