将一个分支基于另一个分支进行Git rebase

125
在我的 Git 仓库中,有一个 'Master' 分支。其中一位远程开发人员创建了一个名为 'Branch1' 的分支,并在其上进行了大量提交。我从 'Branch1' 分支创建了一个新的分支称为 'Branch2'(使用 'git checkout -b Branch2 Branch1' 命令),以便 'Branch2' 的头部指向添加到 'Branch1' 的最后一个提交:(看起来像这样)
Master---
         \
          Branch1--commit1--commit2
                                   \
                                    Branch2 (my local branch) 

Branch1有许多更改。另一位开发者压缩了他的提交,然后添加了几个新的提交。同时,我在我的分支中进行了许多更改,但还没有提交任何内容。当前结构如下:

  Master---
             \
             Branch1--squashed commit1,2--commit3--commit4
                                       \
                                        Branch2 (my local branch)

现在我想将我的更改基于Branch1重新定位。 我对如何进行此操作感到非常困惑。 我知道第一步将是使用git add .git commit -m "message"提交我的更改。 但是我接下来该怎么做呢?使用git push origin Branch2还是git push origin Branch2 Branch1?非常需要帮助并且会非常感激,如果我可以以某种方式创建分支的备份,那将非常好,以防出现问题。


3
可能是将特性分支变基到另一个特性分支上的重复问题。 - The Bearded Llama
这篇文章是我发现的关于Git rebase最好的教程之一。 - Gangula
4个回答

163

首先备份当前的Branch2

# from Branch2
git checkout -b Branch2_backup

然后将Branch2变基到Branch1上:

# from Branch2
git fetch origin           # update all tracking branches, including Branch1
git rebase origin/Branch1  # rebase on latest Branch1

变基后,您的分支结构应如下所示:

master --
         \
          1 -- 2 -- 3 -- 4 -- Branch2'

在上面的图表中,Branch2 上的撇号表示重置后的 Branch2 中从提交 4 之后的每个提交实际上都是一次重写。

请注意,您现在已经重写了 Branch2 的历史记录,如果该分支已经发布,则必须通过强制推送到远程来同步更新它:

git push --force origin Branch2

强制推送可能会给其他使用Branch2的人带来问题,因此在执行此操作时应小心。


如果有合并冲突怎么办?当我执行 git rebase Branch1 时,它们会显示出来吗?我假设任何冲突都应该阻止合并,然后我可以在合并分支之前解决它们。 - Beginner
在我进行变基之前,最后一个问题是 - 由于自从我从branch1分支出来后它已经发生了变化,那么我是执行git checkout branch1然后跟着执行git fetch还是git pull来更新本地的branch1副本。 - Beginner
尝试了 git rebase origin/Branch1,出现了 Cannot rebase: Your index contains uncommitted changes. Please commit or stash them 的错误提示。 - Beginner
1
所以这里有几种选择:如果你想要这些更改,那么对每个文件都执行git add然后提交(commit)。如果你不想要任何更改,可以执行git reset --hard来丢弃它们。如果你不确定,可以执行git stash,之后再处理。只有在你确定不需要这些更改的情况下才使用重置(reset)选项。 - Tim Biegeleisen
1
当然我想要这些更改。在执行变基之前,我会使用 git commit -m "commit message" 进行提交。 - Beginner
显示剩余7条评论

54

git rebase branch1 branch2 将把分支 branch2 变基到 branch1。这意味着仅存在于 branch2(而不在 branch1 中)的提交将在 branch1 之上重新应用,同时移动 branch2 指针。更多信息,请参见 git rebase --help,其中包括此操作的图示。

该操作可能会产生一些冲突,您需要手动解决。编辑受影响的文件,合并内容并删除任何失败的 hunks。然后,使用 git add <file> 标记文件已合并,继续使用 git rebase --continue 进行变基。重复此过程直到完成。

完成后,您无需执行其他操作。您不必推送。但是,如果您希望将新更改镜像到其他存储库(例如与他人共享或在另一个存储库中保存这些更改),请执行最终的 git push


4
警告:git rebase -i branch1 branch2 会自动切换到 branch2 分支,并修改其中的提交记录。branch1 分支不受影响。为避免误操作,请谨慎使用。 - Jason Moore
1
仅供未来读者参考:请注意,如果branch1仅存在于远程,则必须检出到“branch1”,这是“智能”git将动态创建并自动跟踪的(如果没有发生这种情况,则必须手动执行此过程),然后按照答案建议执行。 - Carmine Tambascia
我还想补充一点,检查您是否对起源(origin/branch1)进行了后续的变基,这可能会在第一次变基之后增加一些提交,否则您可能会一直更新但错过了那些提交。 - Carmine Tambascia

7

我想把我在本地分支branch2上的更改重新基于branch1

git checkout branch2   # Go to your local branch. Use -f to force the checkout.
git reset HEAD --hard  # Drop all non-committed changes.
git rebase branch1     # Rebase on top of branch1. Use -i for an interactive list.

注意:如果一个分支在远程,如origin,请在分支名称前加上origin/

故障排除

  • If you got stuck in the middle of rebase and you want to start over, run:

    rm -fr .git/rebase-merge # Abort a rebase-merge mode.
    git reset HEAD --hard    # Reset everything to the current HEAD.
    
  • If you're on the detached branch (run: git branch and look for the star symbol), run:

    git checkout branch2 -f # and start again.
    
  • If you get conflicts, you need to fix them, use different rebasing point.

  • If you'd like to do rebase manually step by step, use cherry-picking. E.g.

    git reflog              # Note hashes of for your commits.
    git checkout master     # Go to your base branch.
    git cherry-pick C0MM1T1 # Cherry pick first commit based on its hash.
    # Go to the next one or solve the conflicts.
    git cherry-pick C0MM1T2 # Cherry pick another commit and so on.
    
  • If your rebase showing too many commits on the interactive list after running git rebase branch1 -i, you can start your rebase given the specific commit just before your changes, e.g. git rebase pr3v1ios.


4

首先,您必须确保对Branch1的引用是最新的(尤其是因为它的历史已被修改)。

如果您喜欢使用本地副本,则可以执行以下操作:

git push origin Branch2 # this ensures you have at least one copy in your remote
git fetch origin
git checkout Branch1
git reset --hard origin/Branch1
git checkout Branch2
git rebase Branch1 # solve conflicts ... and check that everything is ok
git push -f origin Branch2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接