git rebase

447 阅读5分钟
  • 什么是rebase?
  • rebase(变基)是将一系列提交从一个分支转移到另一个分支的过程,通过重新应用提交来创建线性的项目历史
  • 与merge的区别
    • merge: 保留原始分支结构,创建合并提交
    • rebase: 重写提交历史,创建线性历史
  • 基本语法
git rebase <目标分支> [<特性分支>]
//如果不指定特性分支,默认对当前分支进行变基
  • 常见使用场景
  1. 将特性分支变基到主分支
git checkout feature
git rebase main

这样把feature分支的提交重新应用到main分支的最新提交之后 2. 交互式变基(修改提交历史)

git rebase -i HEAD~3

允许你编辑最近的3个提交: * 重新排序顺序提交 * 合并提交 * 修改提交信息 * 拆分提交 3.继续变基(解决冲突后)

git rebase --continue
  1. 跳过当前提交
git rebase --skip
  1. 中止变基
git rebase --abort
  • 高级用法
  1. 只变基部分提交
git rebase --onto <新基> <旧基> <分支>
    * 场景描述
    假设你有一下提交历史
    A---B---C---D---E  main
         \
          F---G---H---I  feature
             \
              J---K  bugfix
    现在你行:
    1.只把bugfix分支的J和K提交(不包括F和G)
    2. 变基到main的最新提交E上

2. 保留合并提交

git rebase -p
  1. 自动解决简单冲突
git rebase -X theirs|ours
  1. 自动解决简单冲突
git rebase -autostash
  • 交互式变基操作指南 执行git rebase -i后会打开编辑器,显示可用的操作命令: 可用的命令:
  • pick(p):保留提交
  • reword(r):保留提交但暂停以修改提交信息
  • edit(e):保留提交以修改内容
  • squash(S):将提交合并到前一个提交
  • fixup(f):类似squash但丢弃提交信息
  • drop(d):删除提交
  • 总结
指令缩写作用
pickp保留该提交(不做修改)
rewordr保留提交内容,但修改提交信息
edite暂停以修改提交内容(可增删文件),可增加一个提交,或者修改提交的代码内容
squashs将提交合并到前一个提交中(保留多个提交信息),也可以有机会重新编辑合并之后的提交信息
fixupf类似squash,但丢弃当前提交信息, 提交仅合并到其上方的提交中,并且较早提交的消息用于描述这两个更改
dropd完全删除该提交
execx执行Shell命令(高级用法)[经典用法是用于运行测试:npm test、pytest;自动化格式化代码、执行自定义检查(如禁止某些关键字、文件校验)]

最佳实践

  1. 不要在公共分支上变基:只对本地未推送的提交使用 rebase
  2. 保持变基范围小:频繁变基比一次性变基大量提交更安全
  3. 备份重要分支:变基前创建备份分支
  4. 团队协作时沟通:如果必须变基已推送的分支,确保团队知晓

git rebase后使用git rebase --abort后不能终止rebase状态的解决方案

  1. 首先确认没有其他Git进程在运行
    • 关闭所有Git客户端(如Git Bash、SourceTree、VSCode等)
    • 确保你的IDE或编辑器没有在后台运行Git操作
  2. 手动删除index.lock文件
rm -f .git/index.lock
  1. 如果删除后问题仍然存在,可能是权限问题:
    • 确保你有关文件的删除权限
    • 尝试以管理员身份运行命令
  2. 检查是否有其他锁定文件
ls -la .git/*.lock

删除所有找到的锁定文件 5.重置Git索引(如果问题持续)

git reset
  • 终极解决方案(会丢失未暂存的更改)
git rm -r --cached .
git reset --hard
  • 预防措施

    • 避免在多个终端同时执行Git命令
    • 确保在网络文件系统(如果有)稳定
    • 定期维护仓库: Git gc
  • Git gc资料补充

    git gc是Git的垃圾回收命令,它通过优化Git仓库的内部结构来提升性能并减少磁盘占用,主要执行以下操作:

    1. 压缩对象:将多个松散对象打包成更高效的包文件(.pack)
    2. 清理无效对象: 删除违背引用的对象
    3. 优化仓库结构:充足和压缩仓库数据
    4. 修剪旧引用:清理过时的引用和日志
    • 何时需要运行git gc
    • Git通常会自动在需要时运行垃圾回收,但在以下情况下手动运行会有帮助:
      • 仓库体积异常增大时
      • 执行了大量提交、合并或重置操作后
      • 准备将仓库推送到远程服务器前
      • 发现Git操作变慢时
    • 基本用法
    git gc
    

    这会执行标准的垃圾回收操作,适用于大多数情况。

    • 更彻底的清理
    git gc --aggressive
    

    这会进行更深入的优化,但耗时更长(适合大型仓库或长期未维护的仓库

    • 查看统计信息
    git gc --auto --stat
    
    • 强制运行
    git gc --force
    
    • 实际案例:假设你有一个长期开发的项目,执行以下操作
      • du -sh .git:首先执行该命令查看仓库当前大小
      • git gc: 运行垃圾回收
      • 再次检查当前项目大小