Git 高级协作技巧:储藏与变基实战指南🛠️

引言

Git 场景化实战指南:从菜鸟到高手的完整攻略中,我们学习了 Git 的基础操作和常见工作流程。现在让我们深入探讨两个高级但极其实用的 Git 功能:储藏(stash)变基(rebase) 。掌握这些技巧将显著提升你的 Git 工作流效率!

stash 储藏操作

场景:

你正在开发一个功能,但突然需要切换到另一个紧急任务。,这时就需要用到git stash操作来临时保存当前的工作进度了

具体操作步骤:

csharp 复制代码
# 1. 你要在 feature 分支上开发用户登录功能,首先切换到这个分支
git checkout feature
​
# 2. 你在login.js文件里面写了对应的登录验证代码
echo "// 登录验证代码" >> login.js
#把刚刚写的代码提交到暂存区
git add login.js
# 注意:还没有 git commit,因为功能没写完
​
# 3. 突然接到紧急任务:修复主分支的 bug
# 你不能提交,因为功能没写完
# 你也不能切换分支,因为有未提交的修改
​
# 4. 使用 git stash 临时保存
git stash  # 保存当前工作进度
​
# 5. 现在可以切换分支了
git checkout main
​
# 6. 修复紧急 bug
# ... 修复代码 ...
git add .
git commit -m "hotfix: fix critical bug"
​
# 7. 回到功能分支继续开发
git checkout feature
git stash pop  # 恢复之前的工作进度

❓为什么不能直接切换分支:

  • Git 不允许在有未提交修改时切换分支
  • 这是为了保护你的工作不被丢失
  • git stash 提供了一个安全的临时保存方案

rebase 变基操作

1.什么是变基(Rebase)?

变基(Rebase) 是 Git 中的一个重要操作,它的本质是**「重新基于最新代码来应用你的更改」**。

2.基本变基操作

bash 复制代码
git checkout feature  # 切换到 feature 分支
git rebase main       # 将当前分支feature变基到 main 分支

实际效果:

变基前:

css 复制代码
          A---B---C feature
         /
    D---E---F---G main

变基后:

css 复制代码
                  A'--B'--C' feature
                 /
    D---E---F---G main

3.git rebase main 详解

  • 将当前分支(feature)的提交"重新应用"到 main 分支的最新提交G之上

  • 这个过程会:

    • 找到两个分支的共同祖先E
    • 提取当前分支feature 的所有新提交A,B,C
    • 将这些提交F和G 逐个应用到 main 分支的顶端
    • 创建新的提交A',B',C'

注意: 变基操作是在代码提交后,是你已经把A,B,C执行了commit后的操作,它的作用是整理、修改和优化提交历史,使其更加清晰和有条理。

变基前的提交A,B,C 和变基后的提交A',B',C' 内容相同但用来标识每次提交的哈希值不同

4.rebase 的使用场景:

场景1:你的分支落后了,需要同步最新代码

bash 复制代码
# 情况:你一周前从主分支创建了功能分支
 # A---B---C feature
 #         /
 #  D---E---F---G main
# 现在主分支有了很多新更新,你的分支落后了
​
git log --oneline --graph
#log:显示提交历史
#--oneline:每个提交只显示一行(缩短的哈希值 + 提交信息)
#--graph:用 ASCII 图形显示分支和合并历史

显示出的提交历史示例:

解读这个图形:

  1. * 表示一个提交
  2. |/ 表示分支的分叉和合并关系
  3. (HEAD -> feature) 表示当前在 feature 分支
  4. (main) 表示 main 分支的位置

执行变基操作 git rebase main,这个命令的意思是: "将 当前feature 分支的提交重新应用到 main 分支的最新状态之上"

变基后的结果

现在的状态:

  • 变成了线性历史:没有分支分叉了

  • feature 分支现在基于最新的 main

    • 原来的提交 def5678 和 abc1234 被重新应用
    • 它们现在位于 main 分支的所有更新之后
  • 提交顺序(从新到旧):

    • abc1234 (feature的最新功能)
    • def5678 (feature的较旧功能)
    • xyz9999 (main的最新更新)
    • uvw8888 (main的另一个更新)
    • rst7777 (main的第三个更新)
    • mno7890 (一周前的共同基础)

场景2:你的提交历史太乱了,想整理一下

bash 复制代码
# 情况:你开发了一个功能,但提交了很多次,历史很乱
​
# 1. 查看最近的6个提交,一行显示一个
git log --oneline -6
# abc1234 修复按钮样式
# def5678 添加错误处理
# ghi9012 修复bug
# jkl3456 添加注释
# mno7890 优化性能
# pqr1234 实现登录功能

操作: 这时你输入git rebase -i HEAD~6 ,表示你要交互式(interactive )地对当前(HEAD所指向)的分支的这六个提交做变基操作,这时Git 会打开文本编辑器 (如 Vim、VSCode、Nano等),显示类似这样的内容:

复制代码
pick pqr1234 提交信息5
pick mno7890 提交信息4  
pick jkl3456 提交信息3
pick ghi9012 提交信息2
pick def5678 提交信息1
pick abc1234 提交信息0

你可以修改每行前的命令:

  • pick → 保留这个提交
  • reword → 修改提交信息
  • edit → 暂停并修改提交内容
  • squash → 合并到前一个提交
  • fixup → 合并但丢弃信息
  • drop → 删除这个提交

保存退出后,Git 会按照你的指示重新组织提交历史

💡 实用技巧

如果想操作所有提交:

css 复制代码
# 从第一个提交开始操作所有历史
git rebase -i --root

如果想操作特定数量的提交:

bash 复制代码
# 操作最近3个提交
git rebase -i HEAD~3

# 操作最近10个提交  
git rebase -i HEAD~10

如果想操作到某个特定提交:

bash 复制代码
# 操作直到提交abc1234(不包括abc1234)
git rebase -i abc1234^
# abc1234^ 表示 abc1234 的父提交
#相当于 abc1234 的前一个提交

⚠️ 重要提醒

只对尚未推送到远程仓库的本地提交使用交互式变基! 因为变基会重写提交历史,如果已经推送了,会给协作者带来麻烦。

特性 普通变基 (git rebase) 交互式变基 (git rebase -i)
操作方式 自动完成 手动交互选择
修改历史 通常不修改提交内容 可以修改提交内容和信息
使用场景 同步代码、整理分支 精细修改提交历史
风险等级 中等

场景3:你想修改某个提交的信息

bash 复制代码
# 情况:你发现某个提交的信息写错了

# 1. 查看提交
git log --oneline -3
# abc1234 修复登录bug
# def5678 添加用户注册
# ghi9012 初始化项目

# 2. 交互式 rebase
git rebase -i HEAD~3

# 3. 编辑器打开,按照时间顺序从上到下显示(和git log顺序不一样)
# pick ghi9012 初始化项目
# pick def5678 添加用户注册
# pick abc1234 修复登录bug

# 4. 你想修改第二个提交的提交信息,你就要把第二条提交记录前面的单词pick(保留这个提交)改成reword(修改提交信息),也就是你要这么写:

# pick ghi9012 初始化项目
# reword def5678 添加用户注册
# pick abc1234 修复登录bug

# 5. 保存后,Git 会让你重新编辑第二个提交的信息
# 你改为:"实现用户注册功能"

# 6. 结果:
git log --oneline -3
# abc1234 修复登录bug
# def5678 实现用户注册功能
# ghi9012 初始化项目

场景4:你想删除某个提交

bash 复制代码
# 情况:你提交了一个测试文件,现在想删除这个提交

# 1. 查看提交
git log --oneline -4
# abc1234 添加测试文件
# def5678 实现核心功能
# ghi9012 添加配置文件
# jkl3456 初始化项目

# 2. 交互式 rebase
git rebase -i HEAD~4

# 3. 编辑器打开:
# pick jkl3456 初始化项目
# pick ghi9012 添加配置文件
# pick def5678 实现核心功能
# pick abc1234 添加测试文件

# 4. 你想删除最后一个提交,改为:
# pick jkl3456 初始化项目
# pick ghi9012 添加配置文件
# pick def5678 实现核心功能
# drop abc1234 添加测试文件

# 5. 结果:测试文件的提交被删除了
git log --oneline -3
# def5678 实现核心功能
# ghi9012 添加配置文件
# jkl3456 初始化项目

为什么需要 Rebase?

问题:提交历史太乱

markdown 复制代码
# 没有 rebase 的历史(看起来像这样):
* abc1234 修复小bug         ← 琐碎的提交
* def5678 添加注释          ← 琐碎的提交  
* ghi9012 修复另一个bug      ← 琐碎的提交
* jkl3456 优化代码          ← 琐碎的提交
* mno7890 实现功能          ← 主要的提交

问题在于:

  • 5个提交其实都是为了完成同一个功能
  • 包含了很多琐碎的中间步骤
  • 历史记录冗长且难以阅读
  • 代码审查时需要看很多小提交

整理后的清晰历史

markdown 复制代码
# 使用 rebase 整理后:
* mno7890 实现完整功能       ← 一个清晰的提交

好处:

  • 一个提交代表一个完整的功能
  • 历史简洁明了
  • 更容易理解代码变更
  • 便于代码审查和问题排查

✅ 总结

Rebase 整理历史就像是:

  • 从"过程记录"到"成果展示"
  • 从"零散零件"到"完整产品"
  • 从"草稿笔记"到"正式文档"

让提交历史更有意义,而不仅仅是记录每一个微小的更改!

相关推荐
项目題供诗1 小时前
Hadoop(四)
大数据·hadoop·github
10岁的博客6 小时前
GitHub宕机自救指南技术文章大纲
github
花椒和蕊6 小时前
记录git报错ssh: connect to host github.com port 22: Connection timed out,已解决
git·ssh·github
CoderJia程序员甲7 小时前
GitHub 热榜项目 - 日榜(2025-08-28)
ai·github·开源项目·github热榜
atwednesday8 小时前
git提交规范
github
顾辰逸you8 小时前
git打包流程
前端·github
wayhome在哪9 小时前
Git 合并:Merge 还是 Rebase?
git·面试·github
掘金安东尼11 小时前
JavaScript 接下来要加啥新功能?9个特性!
前端·javascript·github
喷火龙8号1 天前
一次完整的 Git 提交撤销与代码恢复经历
github