当前位置: 首页 > news >正文

git 变基:git rebase

Rebase(变基)

Rebase 是将一个分支的所有更改重新应用到另一个分支的最新状态上。使你的分支看起来像是在目标分支的最新提交之后创建的。
在这里插入图片描述


[应用举例] (heads/dev) git rebase master 详细工作原理
1、Git 会检查是否有未提交的更改,如果你有未提交的修改,Git 会尝试保留它们,如果这些修改与即将 rebase 的内容冲突,则会提示错误并中止。
2、Git 首先会找到devmaster分支的最近共同祖先提交。把共同祖先提交dev最新提交的每个提交都换为一个补丁,并将这些补丁依次应用到master最新提交上。如果某个补丁应用失败(如冲突),Git 会暂停 rebase 并提示你解决冲突。解决冲突后,使用 git add . 标记解决,然后运行 git rebase --continue 继续;也可以选择跳过某次提交(–skip)或中止整个 rebase(–abort)。
3、所有补丁成功应用后,Git 会更新dev的指针(HEAD),使其指向新的提交。
4、由于提交历史已改变,远程仓库上的 dev 分支与本地不一致,必须使用强制推送。推荐使用 git push --force-with-lease,而不是 git push --force

(heads/dev) git rebase origin/release          将某分支的提交移到新基础上
● (heads/dev) git rebase -i origin/release       交互式地rebase
● (heads/dev) git rebase -i HEAD~3                  交互式整理最近3个提交

git rebase -i 详解
git rebase发生冲突时 ☞ 撤销rebase,git rebase --abort
git rebase发生冲突时 ☞ 解决冲突,git add . && git rebase --continue
github上基于rebase的一次PR提交
rebase导致源分支修改丢失


参数说明Git 引入年份 / 最低版本
--exec "echo hahah"在交互式变基过程中,对每个提交应用后执行指定命令(如测试、lint),确保提交质量2005 / Git v1.0
--ignore-date用当前时间覆盖原提交时间2005 / Git v1.0
--onto <newbase>自定义变基的目标基准(指定新基底)2005 / Git v1.0
--abort中断变基,回退到变基前状态2005 / Git v1.0
--continue解决冲突后继续变基流程2005 / Git v1.0
--skip跳过当前冲突提交,继续后续变基2005 / Git v1.0
--keep-empty保留空提交(默认跳过空提交)2007 / Git v1.5.0
--signoff给每个提交添加 Signed-off-by: 签名行2007 / Git v1.5.0
--interactive / -i进入交互模式,手动编排提交2007 / Git v1.5.4
--committer-date-is-author-date让提交者时间与作者时间一致,统一时间戳2008 / Git v1.6.0
--no-ff变基时禁用快进合并(保留合并提交)无独立版本,继承merge --no-ff逻辑,Git v1.0 + 支持
--autosquash / -a自动识别、合并标记过的 fixup 提交2010 / Git v1.7.0
--rebase-merges / -r保留原分支合并结构,重放合并提交2012 / Git v1.8.5
--preserve-merges在变基时尝试保留分支合并结构(通过重新创建合并提交),但不保留原合并提交的元数据(如提交信息、时间戳) ⚠️ 注意:此参数在 Git v2.0 后已被标记为 deprecated(不推荐使用),推荐使用 --rebase-merges 替代,后者能更完整地保留合并历史2010 / Git v1.7.0(引入) 2012 / Git v1.8.5(被 --rebase-merges 替代) 2014 / Git v2.0(标记为 deprecated)
--force-rebase强制对已有推送的分支执行变基(需谨慎)无独立版本,依赖push --force-with-lease逻辑,Git v1.8.5+ 后更安全

–exec

git rebase -i HEAD~3 --exec "echo hahah"pick be04f1b update
exec echo hahah
pick ddd538d update
exec echo hahah
pick a1c019c update
exec echo hahah# $ git rebase -i HEAD~3 --exec "echo hahah"
# hint: Waiting for your editor to close the file... Can't find filter element
# Can't find filter element
# Executing: echo hahahhahah
# Executing: echo hahahhahah
# Executing: echo hahahhahah
# Successfully rebased and updated refs/heads/dev.

–ignore-date

git rebase 会更新 committer date,不会更新 author date(作者时间)。 而 --ignore-date 不仅更新 committer date,还会覆盖 author date,让整个提交的时间看起来就像“现在写的”。

# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s"
# 6ed3bac    | HEAD -> dev          | 2025-06-28 14:43:54 +0800 | 2025-06-28 14:43:54 +0800 | update 5# zhang@zhangziwa MINGW64 /d/gitPrac/ckck (dev)
$ git rebase release --ignore-date
# Current branch dev is up to date, rebase forced.
# Successfully rebased and updated refs/heads/dev.# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s"
# e3f5262    | HEAD -> dev          | 2025-06-28 14:53:19 +0800 | 2025-06-28 14:53:19 +0800 | update 5

–onto

git rebase --onto main develop feature,将 feature 分支中从 develop 到 feature 的所有提交,重新应用到 main 上

–skip,–continue,–abort

git rebase 过程中用于处理冲突或中断操作时,有如下3个操作

git rebase --skip      跳过当前正在处理的提交,不将其应用到新的基础上
git rebase --continue  解决冲突并继续
git rebase --abort     中止整个变基

–keep-empty

在进行以下操作时,Git 默认会忽略所有空提交,加上 --keep-empty 参数后,Git 在重写历史时会 保留这些空提交,不会自动跳过它们。

git rebase
git rebase -i

–signoff

给每个提交添加 Signed-off-by: 签名行

# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s"
# 6ed3bac    | HEAD -> dev  | 2025-06-28 14:43:54 +0800 | 2025-06-28 14:43:54 +0800 | update 5
$ git rebase release --signoff
# Current branch dev is up to date, rebase forced.
# Successfully rebased and updated refs/heads/dev.# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s - %b"
# 405bb6c    | HEAD -> dev  | 2025-06-28 14:43:54 +0800 | 2025-06-28 15:03:48 +0800 | update 5 - Signed-off-by: zhangziwa <zhangziwa@qq.com>

–committer-date-is-author-date

# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s"
# 6ed3bac    | HEAD -> dev          | 2025-06-28 14:43:54 +0800 | 2025-06-28 14:43:54 +0800 | update 5$ git rebase release --signoff  # git rebase 会更新 committer date,不会更新 author date(作者时间)
# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s"
# 815ac13    | HEAD -> dev          | 2025-06-28 14:43:54 +0800 | 2025-06-28 15:15:58 +0800 | update 5$ git rebase release --committer-date-is-author-date  # 让提交者时间与作者时间一致,统一时间戳
# $ git log --pretty=format:"%<(10)%h | %<(20)%D | %<(20)%ai | %<(20)%ci | %s"
# 6ed3bac    | HEAD -> dev          | 2025-06-28 14:43:54 +0800 | 2025-06-28 14:43:54 +0800 | update 5

–no-ff

变基时禁用快进合并(保留合并提交)

–autosquash

当你使用 git commit --fixupgit commit --squash <commit> 创建了“修复提交”后,使用 git rebase -i --autosquash 自动识别并合并 fixup/squash 提交。

–preserve-merges(已废弃), --rebase-merges

–rebase-merges 的作用是:让 Git 在变基时记住你以前是怎么合并分支的,避免历史变得混乱或丢失重要信息。–preserve-merges 也是相同思路,但是已弃用。

原始结构如下:
A---B---C---D <-- main\E---F---M <-- featuregit rebase main
A---B---C---D <-- main\E'--F'--M' <-- feature   E'相对于E表示sha变了git rebase --preserve-merges main(已废弃)
A---B---C---D <-- main\        \E'---F'---M' <-- feature         M'是对原始M的“复制”,可能无法准确反映合并逻辑,已废弃git rebase --rebase-merges main
A---B---C---D <-- main\        \E'---F'---M' <-- feature         M'是通过重新执行合并生成的新提交git merge main
A---B-----C----D <-- main\           \D---E---M---N <-- featuregit merge feature
A---B---C---D---N <-- main\         /E---F---M <-- feature

–force-rebase

–force-rebase 的作用是:即使提交已经存在于目标分支中,也强制重新 apply 所有提交。

原始结构:
A---B---C <-- main\D---E <-- featuregit rebase main
A---B---C <-- main\D---E <-- feature (无变化)git rebase --force-rebase main
A---B---C <-- main\D'---E' <-- feature
http://www.lqws.cn/news/557713.html

相关文章:

  • 使用cmake+vs2022编译win环境下grpc(不建议拉取最新版本grpc(注意本文时间是2025/6/28))
  • 解决clion远程编程发现不了部分头文件问题
  • 如何在FastAPI中打造坚不可摧的Web安全防线?
  • 前端打印计算单位 cm、mm、px
  • COLT_CMDB_linux_zookeeperInfo_20250628.sh
  • JavaScript正则表达式之正向先行断言(Positive Lookahead)深度解析
  • MCPA2APPT:基于 A2A+MCP+ADK 的多智能体流式并发高质量 PPT 智能生成系统
  • 数字孪生技术赋能UI前端:实现虚拟与现实的无缝对接
  • InfluxDB 3 Core数据库管理指南:从概念到实操的完整流程
  • 单元测试和集成测试的区别
  • 正交视图三维重建 笔记 2d线到3d线
  • 【Python练习】017. 导入math模块并使用其sqrt函数计算平方根
  • ReactNative【实战系列教程】我的小红书 2 -- 快捷登录、手机号密码登录
  • 一站式了解SPI机制
  • NVIDIA 开源高性能语音识别模型:Parakeet TDT 0.6B V2 登顶 OpenASR 榜单
  • 【算法深练】单调栈:有序入栈,及时删除垃圾数据
  • 代理与反射
  • 基于LQR控制器的六自由度四旋翼无人机模型simulink建模与仿真
  • 微软人工智能证书AI-102 | 如何快速通过?
  • 桌面小屏幕实战课程:DesktopScreen 16 HTTP
  • 【软考--软件设计师】11 关系型数据库
  • WebRTC(十二):DTLS
  • 关于前端页面上传图片检测
  • 暑假复习篇之运算与逻辑
  • UI前端大数据可视化创新:利用AR/VR技术提升用户沉浸感
  • 什么是集中刷新,分散刷新,和异步刷新
  • 从 AJAX 到 axios:前端与服务器通信实战指南
  • 2023国赛linux的应急响应-wp
  • Re--攻防世界-基础android
  • C++ vector 完全指南:从入门到精通