Git | 变基操作

基本概念

将当前分支的提交移动到另一个基端 base 上,从而重新组织提交历史

merge 不同,rebase 会创建新提交来替代旧提交,使得提交历史呈现线性结构

适用场景
  • 整理本地提交历史 ------ 在推送前用 rebase 整理杂乱的分支提交,使其更清晰
  • 避免不必要的合并提交 ------ 希望提交历史是线性结构时(如开源项目的 PR
  • 同步上游代码 ------ 将当前分支基于上游最新代码重新应用更改(如 git pull --rebase
原理
初始状态
  • 初始时,master 分支与 feature 分支均有提交,HEAD 当前分支在 feature ,此时执行指令:

    shell 复制代码
    git rebase master	# feature分支上执行,将当前分支feature变基到目标分支master上
找到共同祖先
  • 找到当前分支 feature 和目标分支 master 的最近共同祖先 common ancestor,即两个分支分叉处的提交
提取当前分支独有提交
  • 从共同祖先开始,提取当前分支 feature 之后的所有提交更改,保存为临时补丁
应用提交到目标分支
  • 移动 feature 分支的指针到 master 的最新提交(新基端)

    此时 feature 的提交历史没有指针指向,暂时丢失游离(可以通过 git reflog 找回)

  • 将之前提取的补丁应用到 master 新基端,生成新提交(内容相同,提交哈希值不同)

    如果遇到冲突,Git 暂停 rebase 过程,解决冲突后继续

    shell 复制代码
    git add
    git rebase --continue
对比 merge(合并)与 rebase(变基)
示意图
  • 变基 ------ 在当前分支 feature 执行 git rebase master,将 feature 的提交嫁接到 master上,重写历史,保持线性
  • 合并 ------ 在当前分支 feature 执行 git merge master,将 master 的提交合并到 feature上,生成合并提交,保留历史
关键区别
  • rebase 重写历史,merge 保留历史
    • rebasefeature 的提交看起来基于 master 的最新提交开发(线性历史)
    • merge 会保留分支的分叉和合并记录(非线性的历史)
  • merge 会生成新提交,rebase 不会
    • merge 一定会生成合并提交,即使没有冲突
    • rebase 只是重新应用提交,不会额外生成提交
  • rebase 更适合本地整理,merge 更适合公共分支
    • 如果在开发本地分支,并希望提交历史清晰,用 rebase
    • 如果在合并公共分支(如团队协作的 develop),用 merge 更安全

指令介绍

变基分支 git rebase
  • 语法

    sh 复制代码
    git rebase [选项] <目标分支>
    参数 说明
    -i / --interactive 进入交互式变基(可修改提交)
    --continue 解决冲突后继续变基
    --abort 终止变基,恢复到变基前的状态
    --skip 跳过当前提交(冲突无法解决时使用)
    --onto <新基端> 将提交移动到另一个基端(复杂变基场景)
    -p / --preserve-merges 保留合并提交(默认会丢弃)
    --autostash 自动暂存未提交的更改(防止变基失败)
  • 具体示例

    • 基本变基 ------ 将当前分支 feature 变基到目标分支 master

      shell 复制代码
      $ git checkout feature
      $ git rebase master
      shell 复制代码
      # 初始状态
      A---B---C (master)
      \
      D---E (feature)
      
      # 执行 git rebase master 后
      A---B---C (master)
         \
          D'---E' (feature)
    • 交互式变基(修改提交)

      shell 复制代码
      $ git rebase -i HEAD~3  # 修改最近3个提交

      进入交互式界面后,可以:

      方法 说明 方法 说明
      pick 保留提交(默认) squash 合并到前一个提交
      reword 修改提交信息 drop 删除提交
      edit 修改提交内容 --- ---
      shell 复制代码
      pick 1a2b3c Commit 1
      reword 4d5e6f Commit 2
      squash 7g8h9i Commit 3
    • 变基过程中遇到冲突

      sh 复制代码
      $ git add <冲突文件>			  # 手动解决冲突后添加文件
      sh 复制代码
      $ git rebase --continue			# 继续变基
      shell 复制代码
      $ git rebase --abort			# 放弃变基
    • 部分提交移动到另一个分支 ------ 把当前分支 topicGH)移动到目标分支 main

      shell 复制代码
      git rebase --onto main feature topic
      shell 复制代码
      # 初始状态
      A---B---C (main)
      \
      D---E---F (feature)
           \
            G---H (topic)
      
      # 把 topic 分支(G 和 H)移动到 main 分支的最新提交 C 上
      A---B---C (main)
      \   \
      \   G'---H' (topic)
       \
        D---E---F (feature)

变基

相关指令
  • git rebase ------ 将当前分支的提交变基到指定分支,重新组织提交历史
场景一:基本变基
  1. 切换分支 ------ 从 master 分支切换到 feature 分支

    shell 复制代码
    $ git checkout feature
  2. 变基 ------ 将当前分支 feature 变基到目标分支 master

    shell 复制代码
    $ git rebase master

    效果:

    shell 复制代码
    # 初始状态
    A---B---C (master)
      \
       D---E (feature)
    
    # 执行 git rebase master 后
    A---B---C (master)
          \
           D'---E' (feature)
场景二:变基时冲突
  1. 变基时报错

    shell 复制代码
    $ git rebase
    Auto-merging main.py
    CONFLICT (content): Merge conflict in main.py
    error: could not apply 2264188... add function_a
    hint: Resolve all conflicts manually, mark them as resolved with
    hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
    hint: You can instead skip this commit: run "git rebase --skip".
    hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
    Could not apply 2264188... add function_a

    冲突文件main.py 存在内容冲突

    冲突原因 :在变基过程中,提交 2264188 的修改与当前代码存在冲突

  2. 查看冲突文件 ------ 输出未合并的路径 Unmerged paths

    shell 复制代码
    $ git status
    Unmerged paths:
      (use "git add <file>..." to mark resolution)
            both modified:   main.py
  3. 手动解决冲突 ------ 打开 main.py,保留正确的代码,并添加到暂存区

    shell 复制代码
    <<<<<<< HEAD
    当前分支的代码(HEAD指向的版本)
    =======
    要应用的提交代码(2264188的修改)
    >>>>>>> 2264188... add function_a
    shell 复制代码
    $ git add main.py
  4. 继续变基

    shell 复制代码
    $ git rebase --continue
  5. 放弃变基 ------ 回到 rebase 前的状态

    shell 复制代码
    $ git rebase --abort
  6. 跳过当前提交 ------ 该提交的修改将被丢弃

    shell 复制代码
    $ git rebase --skip
场景三:检测到存在未完成的变基
  1. 检测到存在未完成的变基操作

    shell 复制代码
    fatal: It seems that there is already a rebase-merge directory, and
    I wonder if you are in the middle of another rebase.  If that is the
    case, please try
            git rebase (--continue | --abort | --skip)
    If that is not the case, please
            rm -fr ".git/rebase-merge"
    and run me again.  I am stopping in case you still have something
    valuable there.

    问题原因 ------ Git.git/rebase-merge 目录保存未完成的变基状态,可能由于:

    • 之前的 git rebase 被意外中断(如关闭终端)
    • 冲突未完全解决就停止了操作
    • 系统崩溃或强制退出
  2. 解决方案

    • 继续未完成的变基:git rebase --continue
    • 放弃当前变基:git rebase --abort
    • 跳过当前提交:git rebase --skip
    • 手动清理(仅当确认无价值内容时):rm -fr ".git/rebase-merge"

参考文献

更多内容可以参考以下文章:

相关推荐
siqiangming4 小时前
将SVN项目迁移到Git,保留提交记录
git·svn
CCPC不拿奖不改名4 小时前
两种完整的 Git 分支协作流程
大数据·人工智能·git·python·elasticsearch·搜索引擎·自然语言处理
南方者4 小时前
【Sourcetree】【Git】提交后无法推送,优雅回滚
git·版本管理·sourcetree·回滚·贮藏
ccino .5 小时前
【将更改从 GitHub Desktop 推送到 GitHub】
github
lpfasd1236 小时前
PyGithub用法详解
git·python·github
一品威客网7 小时前
版本控制(Git):APP协同开发的四大核心基石
大数据·git
沉淀の沙8 小时前
1-20[IDEA远程链接GitHub失效问题]
github
007张三丰8 小时前
git中的SSH 公钥配置详细指南(GitHub、GitLab、Gitee平台适用)
git·ssh·github
Xiaok10188 小时前
解决GitHub双重认证问题:使用Chrome插件Authenticator
chrome·github·2fa
CoderJia程序员甲8 小时前
GitHub 热榜项目 - 日榜(2026-01-20)
开源·大模型·llm·github·ai教程