第四章:Git高级操作与技巧(git官网入口)

4.1 贮藏(Stash)

贮藏是Git中一个非常实用的功能,它可以暂时保存当前未提交的修改,让你可以切换到其他分支工作,之后再恢复这些修改。

核心场景

  • 正在进行中的工作需要中断,切换到其他任务
  • 分支切换前需要保存当前未完成的修改
  • 尝试一些实验性修改,不想提交

基本操作

# 保存当前工作区和暂存区的修改
git stash save "临时保存工作"

# 查看贮藏列表
git stash list

# 应用最近一次贮藏
git stash apply

# 应用并删除贮藏
git stash pop

# 删除最近一次贮藏
git stash drop

# 删除所有贮藏
git stash clear

案例

# 在feature分支上工作,尚未完成
git add file1.txt
git status  # 显示已暂存和未暂存的修改

# 突然需要切换到master分支处理紧急问题
git stash save "未完成的功能"  # 保存当前修改
git checkout master           # 切换到master分支

# 处理完紧急问题后,回到feature分支
git checkout feature
git stash pop                 # 恢复并删除贮藏

高级用法

# 保存工作区修改但不保存暂存区
git stash push -k

# 应用指定的贮藏
git stash apply stash@{1}

# 查看贮藏的差异
git stash show -p stash@{0}

4.2 重置(Reset)与回退

Git的reset命令可以让你回退到历史的某个状态,但使用时需要谨慎,因为它可能会丢失未提交的修改。

三种重置模式

  1. --soft:只移动HEAD指针,不改变暂存区和工作区
  2. --mixed(默认):移动HEAD指针并重置暂存区,但不改变工作区
  3. --hard:移动HEAD指针、重置暂存区和工作区,彻底丢弃未提交的修改

案例1:回退到上一个提交

# 回退到上一个提交,保留工作区修改
git reset HEAD^

# 回退到上一个提交,彻底丢弃修改
git reset --hard HEAD^

案例2:撤销错误的提交

# 错误地提交了一些内容
git commit -m "错误提交"

# 回退到上一个正确的提交,但保留修改
git reset HEAD^

# 重新提交正确的内容
git add .
git commit -m "正确提交"

找回丢失的提交
如果不小心使用了git reset --hard,可以通过reflog找回丢失的提交:

# 查看引用日志
git reflog

# 恢复到指定的提交
git reset --hard <commit-hash>

4.3 变基(Rebase)

变基是将一个分支的修改应用到另一个分支的另一种方式,与merge不同,它会创建一个线性的提交历史。

基本操作

# 在feature分支上
git rebase master  # 将master的修改应用到feature分支

# 等价于
git checkout feature
git rebase master

变基 vs 合并

  • 合并(Merge):创建一个新的"合并提交",保留分支历史
  • 变基(Rebase):将提交历史重新排列,创建线性历史

案例

# 在feature分支上开发
git checkout -b feature

# 此时master分支有了新提交
git checkout master
git pull

# 将feature分支变基到最新的master
git checkout feature
git rebase master

# 推送到远程(第一次推送到新分支需要-f)
git push -f origin feature

交互式变基

# 修改最近3个提交
git rebase -i HEAD~3

变基注意事项

  • 不要对已经推送到远程的分支进行变基(会导致提交历史混乱)
  • 变基过程中可能会出现冲突,需要手动解决

4.4 子模块(Submodule)

子模块允许你在一个Git仓库中包含另一个Git仓库,适合管理大型项目中的独立组件。

基本操作

# 添加子模块
git submodule add <repository-url> <path>

# 克隆包含子模块的仓库
git clone --recursive <repository-url>

# 初始化和更新子模块
git submodule init
git submodule update

# 更新子模块到最新版本
git submodule update --remote

案例

# 添加子模块
git submodule add https://github.com/example/library.git lib/library

# 克隆包含子模块的项目
git clone --recursive https://github.com/example/main-project.git

# 更新子模块
cd main-project
git submodule update --remote

4.5 高级日志查看

Git的日志命令非常强大,可以通过各种参数定制输出格式。

常用参数

# 简洁的单行输出
git log --oneline

# 显示文件改动
git log -p

# 统计改动
git log --stat

# 图形化输出
git log --graph --oneline --decorate

# 按作者过滤
git log --author="张三"

# 按日期过滤
git log --since="2023-01-01" --until="2023-12-31"

# 查看文件历史
git log --follow -p -- file.txt

自定义日志格式

git log --format="%h %ad | %s%d [%an]" --date=short

4.6 别名与配置

Git允许你创建自定义命令别名,提高工作效率。

全局配置

# 设置常用别名
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

# 自定义日志命令
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

# 使用vim作为默认编辑器
git config --global core.editor "vim"

案例

# 使用别名
git co feature/branch  # 相当于 git checkout feature/branch
git lg                 # 查看美观的日志

4.7 钩子(Hooks)

Git钩子是在特定事件发生前或发生后自动执行的脚本,可用于自动化工作流程。

常见钩子

  • pre-commit:提交前执行,可用于代码检查
  • commit-msg:提交信息验证
  • pre-push:推送前执行,可用于运行测试
  • post-merge:合并后执行,可用于安装依赖

案例:创建pre-commit钩子检查代码格式

# 进入.git/hooks目录
cd .git/hooks

# 创建pre-commit文件
touch pre-commit
chmod +x pre-commit

# 编辑pre-commit文件,添加检查逻辑
#!/bin/sh
echo "正在检查代码格式..."
# 这里可以添加代码格式化或测试命令

4.8 总结

通过本章的学习,你已经掌握了Git的高级操作:

  1. 使用贮藏(Stash)临时保存未完成的工作
  2. 重置(Reset)和回退到历史状态
  3. 变基(Rebase)创建线性提交历史
  4. 子模块(Submodule)管理项目中的外部依赖
  5. 高级日志查看和自定义
  6. 配置别名提高效率
  7. 使用钩子自动化工作流程

在下一章中,我们将学习Git在团队协作中的最佳实践,包括工作流程、代码评审和常见问题解决。

原文链接:,转发请注明来源!