Git实战:从入门到精通的开发场景全指南
## 目录
1. [引言:为什么需要Git](#引言为什么需要git)
2. [Git核心概念快速回顾](#git核心概念快速回顾)
3. [开发场景一:日常开发流程](#开发场景一日常开发流程)
4. [开发场景二:分支管理最佳实践](#开发场景二分支管理最佳实践)
5. [开发场景三:合并分支的多种方式](#开发场景三合并分支的多种方式)
6. [开发场景四:冲突解决实战](#开发场景四冲突解决实战)
7. [开发场景五:团队协作流程](#开发场景五团队协作流程)
8. [开发场景六:回滚与恢复](#开发场景六回滚与恢复)
9. [开发场景七:紧急修复处理](#开发场景七紧急修复处理)
10. [Git高级技巧与工具](#git高级技巧与工具)
11. [常见问题与解决方案](#常见问题与解决方案)
12. [总结](#总结)
---
## 引言:为什么需要Git
在实际开发中,我们经常面临以下场景:
- 多人协作开发同一个项目
- 需要同时开发多个功能
- 代码出现bug需要快速修复
- 需要查看历史修改记录
- 需要对比不同版本的差异
Git作为分布式版本控制系统,完美解决了这些问题。本文将通过真实的开发场景,带你掌握Git的实战使用技巧。
---
## Git核心概念快速回顾
在深入实战之前,先快速回顾Git的核心概念:
### Git的三种状态
```
工作区(Working Directory)
↓ git add
暂存区(Staging Area/Index)
↓ git commit
本地仓库(Local Repository)
↓ git push
远程仓库(Remote Repository)
```
### Git的分支模型
```
主分支:main/master(稳定代码)
开发分支:develop(日常开发)
功能分支:feature/xxx(新功能)
修复分支:fix/xxx或hotfix/xxx(bug修复)
发布分支:release/xxx(版本发布)
```
### Git配置
```bash
# 配置用户信息
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
# 查看配置
git config --list
# 配置默认分支名称
git config --global init.defaultBranch main
# 配置别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
```
---
## 开发场景一:日常开发流程
### 场景描述
你是一名开发者,需要开发一个新功能。标准的开发流程如下:
### 完整流程
#### 1. 获取最新代码
```bash
# 克隆仓库(首次)
git clone https://github.com/your-repo/project.git
cd project
# 拉取最新代码(已有本地仓库)
git fetch origin
git pull origin main
# 或者直接pull(推荐)
git pull origin main
```
#### 2. 创建功能分支
```bash
# 创建并切换到新分支
git checkout -b feature/user-login
# 或者使用新语法
git switch -c feature/user-login
# 查看所有分支
git branch -a
# 查看当前分支
git branch
```
**命名规范:**
```
功能分支:feature/功能描述
例如:feature/user-login, feature/payment-api
修复分支:fix/问题描述
例如:fix/login-bug, fix/database-connection
热修复分支:hotfix/紧急问题
例如:hotfix/critical-security-fix
发布分支:release/版本号
例如:release/v1.0.0, release/v2.1.0
```
#### 3. 开发与提交
```bash
# 查看当前状态
git status
# 查看具体修改
git diff
# 添加文件到暂存区
# 方式1:添加单个文件
git add src/main/java/UserService.java
# 方式2:添加所有修改的文件
git add .
# 方式3:交互式添加
git add -i
# 提交代码
git commit -m "feat: 实现用户登录功能"
# 查看提交历史
git log --oneline
# 查看详细历史
git log
# 查看图形化历史
git log --graph --oneline --all
```
**提交信息规范(Conventional Commits):**
```
feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 重构
test: 测试相关
chore: 构建/工具相关
```
**示例:**
```bash
git commit -m "feat: 添加用户登录接口"
git commit -m "fix: 修复登录时的空指针异常"
git commit -m "docs: 更新API文档"
git commit -m "refactor: 重构用户服务层"
```
#### 4. 推送到远程
```bash
# 推送当前分支到远程
git push origin feature/user-login
# 首次推送设置上游分支
git push -u origin feature/user-login
# 查看远程分支
git branch -r
# 推送所有分支
git push --all origin
```
#### 5. 提交Pull Request/Merge Request
在GitHub/GitLab/Gitee等平台创建PR/MR,请求合并到主分支。
---
## 开发场景二:分支管理最佳实践
### 场景一:功能开发并行进行
**场景:** 你同时开发了两个功能,需要分别提交。
```bash
# 创建第一个功能分支
git checkout -b feature/login
# 开发login功能...
git add .
git commit -m "feat: 实现登录功能"
git push -u origin feature/login
# 创建第二个功能分支(基于main)
git checkout main
git pull origin main
git checkout -b feature/register
# 开发register功能...
git add .
git commit -m "feat: 实现注册功能"
git push -u origin feature/register
```
### 场景二:基于其他分支开发
```bash
# 当前在develop分支
git checkout develop
# 创建基于develop的功能分支
git checkout -b feature/feature-a
# 开发完成后,需要合并到develop
git checkout develop
git merge feature/feature-a
```
### 场景三:临时保存工作
```bash
# 正在开发,突然需要切换到其他分支
# 但当前代码还未完成,不能提交
# 方式1:使用stash保存
git stash
git stash save "开发登录功能到一半"
# 切换分支处理其他事情
git checkout fix/bug-123
# 处理完后回来
git checkout feature/login
# 恢复stash
git stash pop
# 或者应用但不删除stash
git stash apply
# 查看stash列表
git stash list
# 删除stash
git stash drop stash@{0}
# 清空所有stash
git stash clear
# 方式2:临时提交
git add .
git commit -m "WIP: 临时保存,未完成"
# 切换分支...
# 回来后撤销临时提交
git reset --soft HEAD~1
```
### 场景四:删除分支
```bash
# 删除本地分支
git branch -d feature/feature-a
# 强制删除未合并的分支
git branch -D feature/feature-a
# 删除远程分支
git push origin --delete feature/feature-a
# 或者使用冒号语法
git push origin :feature/feature-a
# 批量删除已合并的本地分支
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
# 批量删除远程已合并的分支
git branch -r --merged | grep -v main | sed 's/origin\///' | xargs -I {} git push origin --delete {}
```
### 场景五:重命名分支
```bash
# 重命名当前分支
git branch -m new-branch-name
# 重命名指定分支
git branch -m old-branch-name new-branch-name
# 重命名远程分支
git branch -m old-name new-name
git push origin :old-name
git push origin new-name
```
---
## 开发场景三:合并分支的多种方式
Git提供了多种合并方式,每种方式适用不同场景。
### 方式一:Merge合并
**特点:** 保留完整历史,创建合并提交
```bash
# 切换到目标分支
git checkout main
# 合并功能分支
git merge feature/login
# 查看合并历史
git log --graph --oneline
```
**合并策略:**
```bash
# 默认的递归合并
git merge feature/branch
# 章鱼合并(合并多个分支)
git merge feature/a feature/b feature/c
# 合并但自动提交
git merge --no-ff feature/branch # 总是创建合并提交
# 合并但不提交(用于检查冲突)
git merge --no-commit feature/branch
# 合并后提交
git commit
```
**使用场景:**
- 需要保留完整的历史记录
- 团队协作,需要明确的合并点
- 功能分支合并到主分支
### 方式二:Rebase合并
**特点:** 线性历史,重写提交历史
```bash
# 切换到功能分支
git checkout feature/login
# 变基到主分支
git rebase main
# 或者指定上游
git rebase origin/main
# 变基过程中交互式编辑
git rebase -i main
```
**交互式rebase示例:**
```bash
# 编辑最近3次提交
git rebase -i HEAD~3
# 会打开编辑器,显示:
pick abc1234 feat: 实现功能A
pick def5678 fix: 修复bug
pick ghi9012 refactor: 重构代码
# 可以修改pick为:
# pick - 保留该提交
# reword - 修改提交信息
# edit - 编辑提交内容
# squash - 合并到前一个提交
# drop - 删除该提交
# 例如,将后两个提交合并到第一个:
pick abc1234 feat: 实现功能A
squash def5678 fix: 修复bug
squash ghi9012 refactor: 重构代码
# 保存后,编辑合并后的提交信息
```
**使用场景:**
- 保持线性历史
- 整理提交历史
- 合并前同步最新代码
- 个人的功能分支
**注意事项:**
```bash
# 避免对已推送的分支进行rebase
# 如果必须rebase,需要强制推送
git push --force
# 或者更安全的强制推送
git push --force-with-lease
```
### 方式三:Cherry-pick合并
**特点:** 选择性地合并单个提交
```bash
# 查看提交历史,找到要cherry-pick的提交ID
git log --oneline
# 挑选单个提交
git cherry-pick abc1234
# 挑选多个提交
git cherry-pick def5678 ghi9012
# 挑选范围(不包含开始提交)
git cherry-pick abc1234^..ghi9012
# cherry-pick但自动解决冲突
git cherry-pick --continue
# 放弃cherry-pick
git cherry-pick --abort
# 跳过当前提交,继续下一个
git cherry-pick --skip
```
**使用场景:**
- 将某个bug修复应用到多个分支
- 选择性地合并某些提交
- 从其他分支提取特定功能
### 方式四:Squash合并
**特点:** 将多个提交压缩为一个
```bash
# 创建临时分支用于测试
git checkout -b feature/temp
# 多次提交
git commit -m "feat: 实现功能"
git commit -m "fix: 修复bug"
git commit -m "refactor: 优化代码"
# 回到主分支,压缩合并
git checkout main
git merge --squash feature/temp
git commit -m "feat: 完成新功能"
# 删除临时分支
git branch -d feature/temp
# 或者使用交互式rebase压缩
git checkout feature/temp
git rebase -i main
# 将所有pick改为squash
# 保存后,编辑合并信息
```
**使用场景:**
- 合并功能分支前整理提交
- 将多个小功能合并为一个完整功能
- 清理杂乱的提交历史
---
## 开发场景四:冲突解决实战
### 场景一:修改同一文件的不同行
```bash
# 场景:两个分支修改了同一文件的不同位置
# 这种情况下,Git通常会自动合并
# Branch A修改了UserService.java的第10行
git checkout main
git checkout -b feature/a
# 修改代码...
git add .
git commit -m "feat: 添加登录方法"
# Branch B修改了UserService.java的第20行
git checkout main
git checkout -b feature/b
# 修改代码...
git add .
git commit -m "feat: 添加注册方法"
# 合并时,Git会自动合并
git checkout main
git merge feature/a
git merge feature/b # 自动合并成功
```
### 场景二:修改同一文件的同一行
```bash
# 场景:两个分支修改了同一文件的同一行
# Git无法自动合并,需要手动解决冲突
# Branch A
git checkout main
git checkout -b feature/a
# 修改UserService.java第15行:
// public String getName() {
// return name; // Branch A的修改
// }
git add .
git commit -m "fix: 修复getName方法"
# Branch B
git checkout main
git checkout -b feature/b
# 修改UserService.java第15行:
// public String getName() {
// return this.name; // Branch B的修改
// }
git add .
git commit -m "refactor: 优化getName方法"
# 尝试合并
git checkout main
git merge feature/a
git merge feature/b
# 产生冲突:
# <<<<<<< HEAD
// return name;
// =======
// return this.name;
// >>>>>>> feature/b
```
**解决冲突步骤:**
```bash
# 1. 查看冲突文件
git status
# 2. 打开冲突文件,标记如下:
<<<<<<< HEAD
return name;
=======
return this.name;
>>>>>>> feature/b
# 3. 编辑文件,选择保留的代码
// 方案1:保留HEAD的修改
public String getName() {
return name;
}
// 方案2:保留feature/b的修改
public String getName() {
return this.name;
}
// 方案3:合并两者的修改
public String getName() {
return this.name != null ? name : ""; // 合并后更完善
}
# 4. 解决冲突后,标记为已解决
git add UserService.java
# 5. 继续合并
git commit -m "解决getName方法冲突"
```
### 场景三:删除文件与修改文件冲突
```bash
# Branch A删除了UserService.java
git checkout main
git checkout -b feature/a
git rm UserService.java
git commit -m "refactor: 删除旧的用户服务"
# Branch B修改了UserService.java
git checkout main
git checkout -b feature/b
# 修改UserService.java...
git add .
git commit -m "fix: 修复用户服务bug"
# 合并时产生冲突
git checkout main
git merge feature/a
git merge feature/b
# 冲突内容:
# <<<<<<< HEAD
# =======
# public class UserService {
# ...
# }
# >>>>>>> feature/b
```
**解决方式:**
```bash
# 方案1:删除文件(保留删除)
git rm UserService.java
git commit
# 方案2:保留文件(恢复文件)
git checkout feature/b -- UserService.java
git add UserService.java
git commit
```
### 场景四:Rebase过程中的冲突
```bash
# Rebase时遇到冲突
git checkout feature/a
git rebase main
# 冲突信息:
# CONFLICT (content): Merge conflict in UserService.java
# 解决冲突步骤:
# 1. 编辑冲突文件
# 2. 标记为已解决
git add UserService.java
# 3. 继续rebase
git rebase --continue
# 如果要放弃rebase
git rebase --abort
# 如果要跳过当前提交
git rebase --skip
```
### 场景五:复杂的多个文件冲突
```bash
# 当多个文件都有冲突时
# 1. 查看所有冲突文件
git status
# 2. 使用工具辅助解决冲突
# 使用mergetool配置图形化工具
git mergetool
# 3. 批量标记冲突已解决
git add .
# 4. 完成合并
git commit
# 或者使用IDE的Git集成(推荐)
# IntelliJ IDEA、VSCode等都有很好的冲突解决界面
```
### 冲突解决的最佳实践
```bash
# 1. 预先沟通
# 在合并前与团队成员沟通,避免大范围冲突
# 2. 小步快跑
# 频繁合并主分支,减少冲突积累
git pull origin main
# 3. 使用工具
# 配置图形化工具帮助解决冲突
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd "code --wait $MERGED"
# 4. 保持提交清晰
# 一个提交只做一件事,减少冲突范围
# 5. 代码审查
# 合并前进行代码审查,提前发现问题
# 6. 使用rebase整理
# 个人分支使用rebase保持线性历史
git pull --rebase origin main
```
---
## 开发场景五:团队协作流程
### 场景一:Git Flow工作流
```
main/master分支
↓
release分支(版本发布)
↓
develop分支(日常开发)
↓
feature分支(新功能)
↓
hotfix分支(紧急修复)
```
**完整流程:**
```bash
# 1. 创建develop分支
git checkout -b develop main
git push -u origin develop
# 2. 开发人员创建功能分支
git checkout -b feature/login develop
# 开发...
git push -u origin feature/login
# 3. 完成功能后合并到develop
git checkout develop
git merge --no-ff feature/login
git push origin develop
# 4. 创建release分支
git checkout -b release/v1.0.0 develop
# 发布准备...
git commit -m "chore: 准备v1.0.0发布"
git push -u origin release/v1.0.0
# 5. 发布完成,合并到main和develop
git checkout main
git merge --no-ff release/v1.0.0
git tag -a v1.0.0 -m "发布版本v1.0.0"
git push origin main
git push origin v1.0.0
git checkout develop
git merge --no-ff release/v1.0.0
git push origin develop
# 6. 紧急修复
git checkout -b hotfix/critical-bug main
# 修复...
git checkout main
git merge --no-ff hotfix/critical-bug
git tag -a v1.0.1 -m "紧急修复v1.0.1"
git push origin main v1.0.1
git checkout develop
git merge --no-ff hotfix/critical-bug
git push origin develop
```
### 场景二:GitHub Flow工作流
**简化版工作流,适合持续部署**
```
main分支(可部署)
↓
feature分支(新功能)
↓
Pull Request
↓
合并到main
↓
自动部署
```
**完整流程:**
```bash
# 1. 确保main分支是最新的
git checkout main
git pull origin main
# 2. 创建功能分支
git checkout -b feature/new-api
# 开发...
git push -u origin feature/new-api
# 3. 在GitHub上创建Pull Request
# 等待代码审查...
# 4. 审查通过后合并到main
# 通过GitHub界面合并
# 5. 删除功能分支
git branch -d feature/new-api
git push origin --delete feature/new-api
```
### 场景三:Fork与Pull Request
**场景:** 参与开源项目或外部项目
```bash
# 1. Fork项目到自己的GitHub账号
# 2. Clone自己的仓库
git clone https://github.com/your-username/project.git
cd project
# 3. 添加上游仓库
git remote add upstream https://github.com/original-owner/project.git
# 4. 查看远程仓库
git remote -v
# 5. 创建功能分支
git checkout -b feature/awesome-feature
# 6. 开发并提交
# 修改代码...
git add .
git commit -m "feat: 添加很酷的功能"
git push -u origin feature/awesome-feature
# 7. 在GitHub上创建Pull Request
# 选择从你的仓库的feature/awesome-feature到原仓库的main分支
# 8. 同步上游更新
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
# 9. 更新功能分支
git checkout feature/awesome-feature
git rebase main
git push --force-with-lease origin feature/awesome-feature
```
### 场景四:Code Review流程
```bash
# 1. 创建Review Request分支
git checkout -b review/user-auth
# 开发...
git push -u origin review/user-auth
# 2. 创建Pull Request/Merge Request
# 在平台上设置审核人
# 3. 根据反馈修改
# 修改代码...
git commit -am "fix: 根据review意见修改"
git push
# 4. 审核通过后合并
# 5. 或者需要重新Review
git reset --soft HEAD~1
# 修改代码...
git commit -m "refactor: 根据review重构"
git push --force-with-lease
```
---
## 开发场景六:回滚与恢复
### 场景一:撤销未提交的修改
```bash
# 撤销工作区的修改
git checkout -- filename
# 撤销所有修改
git checkout -- .
# 或者使用restore(新语法)
git restore filename
git restore .
# 撤销暂存区的修改
git reset HEAD filename
# 撤销所有暂存
git reset HEAD .
```
### 场景二:撤销已提交的修改
```bash
# 1. 查看提交历史
git log --oneline
# 输出:
# abc1234 feat: 实现功能C
# def5678 feat: 实现功能B
# ghi9012 feat: 实现功能A
# 2. 撤销最后一次提交(保留修改)
git reset --soft HEAD~1
# 3. 撤销最后一次提交(不保留修改)
git reset --hard HEAD~1
# 4. 撤销到指定提交
git reset --soft def5678
# 5. 撤销到指定提交并强制推送
git reset --hard def5678
git push --force-with-lease
```
### 场景三:回滚已推送的提交
```bash
# 场景:错误的提交已经推送到远程
git log --oneline
# 方法1:使用revert(推荐,安全)
git revert abc1234
git push
# 方法2:使用reset(危险,需要协调)
git reset --hard HEAD~1
git push --force-with-lease
# 注意:reset会改写历史,影响其他开发人员
# revert会创建新的提交,更安全
```
### 场景四:恢复删除的提交
```bash
# 场景:错误地reset了,需要找回删除的提交
# 1. 查看reflog(引用日志)
git reflog
# 输出:
# abc1234 HEAD@{0}: reset: moving to abc1234
# def5678 HEAD@{1}: commit: 实现功能A
# ghi9012 HEAD@{2}: checkout: moving from main to feature
# 2. 恢复到指定位置
git reset --hard def5678
# 或者创建新分支恢复
git branch recover-branch def5678
```
### 场景五:回滚到指定标签
```bash
# 1. 查看所有标签
git tag
# 2. 回滚到指定标签
git checkout v1.0.0
# 3. 创建新分支修复bug
git checkout -b hotfix/bug-from-v1.0.0
# 修复...
git push -u origin hotfix/bug-from-v1.0.0
```
### 场景六:清理历史
```bash
# 1. 删除未追踪的文件
git clean -fd
# 2. 删除所有未追踪的文件(包括.gitignore中的)
git clean -fdx
# 3. 清理reflog
git reflog expire --expire=now --all
# 4. 垃圾回收
git gc --prune=now --aggressive
# 5. 清理大文件
git filter-branch --tree-filter 'rm -f large-file.zip' HEAD
```
---
## 开发场景七:紧急修复处理
### 场景一:生产环境紧急bug
```bash
# 1. 确认当前分支
git branch
# 2. 切换到主分支
git checkout main
# 3. 拉取最新代码
git pull origin main
# 4. 创建hotfix分支
git checkout -b hotfix/critical-security-fix
# 5. 快速修复bug
# 修改代码...
# 6. 提交修复
git add .
git commit -m "hotfix: 修复严重安全漏洞"
# 7. 推送到远程
git push -u origin hotfix/critical-security-fix
# 8. 紧急合并到main
git checkout main
git merge --no-ff hotfix/critical-security-fix
git tag -a v1.0.1-hotfix -m "紧急修复v1.0.1"
git push origin main v1.0.1-hotfix
# 9. 合并到develop分支(如果有)
git checkout develop
git merge --no-ff hotfix/critical-security-fix
git push origin develop
# 10. 删除hotfix分支
git branch -d hotfix/critical-security-fix
git push origin --delete hotfix/critical-security-fix
```
### 场景二:开发过程中的紧急任务
```bash
# 1. 保存当前工作
git stash push -m "开发功能A,进行到一半"
# 2. 切换到main创建hotfix分支
git checkout main
git pull origin main
git checkout -b hotfix/urgent-bug
# 3. 快速修复
# 修改代码...
git add .
git commit -m "hotfix: 紧急修复bug"
# 4. 推送并合并
git push -u origin hotfix/urgent-bug
# 创建PR/MR快速审核并合并
# 5. 回到原来的工作
git checkout feature/feature-a
# 6. 恢复stash
git stash pop
# 7. 同步main的最新修改
git pull origin main
# 8. 继续原来的工作
# 开发...
```
---
## Git高级技巧与工具
### 1. Git别名配置
```bash
# 配置常用别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual 'log --graph --oneline --all'
# 使用别名
git st # git status
git co main # git checkout main
git ci -m "msg" # git commit -m "msg"
```
### 2. Git Hooks自动化
```bash
# 示例:提交前检查代码格式
# 创建pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# 运行代码格式检查
npm run lint
# 如果检查失败,阻止提交
if [ $? -ne 0 ]; then
echo "代码格式检查失败,请修复后再提交"
exit 1
fi
EOF
# 赋予执行权限
chmod +x .git/hooks/pre-commit
```
### 3. Git Bisect调试
```bash
# 场景:找到引入bug的提交
# 1. 开始bisect
git bisect start
# 2. 标记当前提交为坏的(有bug)
git bisect bad
# 3. 标记早期提交为好的(无bug)
git bisect good v1.0.0
# 4. Git会切换到中间的提交
# 测试代码...
# 5. 如果是好的,标记为good
git bisect good
# 6. 如果是坏的,标记为bad
git bisect bad
# 7. 重复测试,直到找到问题提交
# 8. 结束bisect
git bisect reset
```
### 4. Git Blame追溯
```bash
# 查看文件的每一行是谁在什么时候修改的
git blame filename
# 查看特定行
git blame -L 10,20 filename
# 查看特定作者
git blame --author="张三" filename
# 查看特定时间范围
git blame --since="2024-01-01" filename
```
### 5. Git忽略文件配置
```bash
# 创建.gitignore文件
cat > .gitignore << 'EOF'
# 编译产物
target/
build/
*.class
*.jar
# IDE配置
.idea/
.vscode/
*.iml
# 日志文件
*.log
# 临时文件
*.tmp
*.swp
# 敏感信息
config.properties
secrets.properties
# 操作系统
.DS_Store
Thumbs.db
EOF
# 提交.gitignore
git add .gitignore
git commit -m "chore: 添加.gitignore配置"
```
### 6. Git子模块管理
```bash
# 添加子模块
git submodule add https://github.com/example/library.git libs/library
# 克隆包含子模块的项目
git clone --recursive https://github.com/example/project.git
# 初始化子模块
git submodule init
# 更新子模块
git submodule update
# 或者一条命令
git submodule update --init --recursive
# 更新子模块到最新版本
cd libs/library
git pull
cd ../..
git add libs/library
git commit -m "chore: 更新子模块"
```
---
## 常见问题与解决方案
### 问题1:合并后后悔了
```bash
# 场景:合并后发现有问题,想撤销合并
# 查看合并前的commit ID
git reflog
# 回滚到合并前
git reset --hard HEAD@{1}
# 或者使用git revert
git revert -m 1 HEAD
```
### 问题2:Rebase后无法推送
```bash
# 场景:rebase后push失败
# 强制推送
git push --force
# 更安全的强制推送
git push --force-with-lease
# 如果其他人已经拉取了你的代码,需要协调
# 1. 告知团队成员不要基于旧版本开发
# 2. 或者放弃rebase,使用merge
```
### 问题3:大文件导致仓库体积过大
```bash
# 方案1:使用git filter-repo(推荐)
pip install git-filter-repo
git filter-repo --path big-file.zip --invert-paths
# 方案2:使用BFG Repo-Cleaner
java -jar bfg.jar --delete-files big-file.zip
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# 方案3:使用Git LFS(大文件存储)
git lfs track "*.zip"
git add .gitattributes
git commit -m "chore: 启用Git LFS"
```
### 问题4:忘记推送某个分支
```bash
# 场景:本地有分支忘记推送
# 查看未推送的分支
git branch -vv
# 推送指定分支
git push -u origin feature/feature-name
# 推送所有分支
git push --all origin
```
### 问题5:错误的提交到错误的分支
```bash
# 场景:在main分支上做了开发,应该在feature分支
# 1. 创建feature分支
git branch feature/feature-name
# 2. 回退main分支
git reset --hard HEAD~1
# 3. 切换到feature分支
git checkout feature/feature-name
# 4. 继续开发
```
---
## 总结
本文通过多个真实的开发场景,详细介绍了Git的实战使用技巧:
### 核心要点回顾
1. **日常开发流程**
- 创建功能分支
- 开发与提交
- 推送到远程
2. **分支管理**
- 遵循命名规范
- 合理使用分支策略
- 及时清理无用分支
3. **合并方式**
- Merge:保留完整历史
- Rebase:线性历史
- Cherry-pick:选择性合并
- Squash:压缩提交
4. **冲突解决**
- 识别冲突
- 手动解决
- 标记已解决
5. **团队协作**
- Git Flow工作流
- GitHub Flow工作流
- Fork与Pull Request
6. **回滚与恢复**
- 撤销未提交的修改
- 撤销已提交的修改
- 使用reflog恢复
### 最佳实践建议
1. **提交规范**
- 使用Conventional Commits规范
- 一个提交只做一件事
- 提交信息清晰明确
2. **分支策略**
- 选择适合团队的工作流
- 保持分支生命周期短
- 及时合并,减少冲突
3. **代码审查**
- 所有合并都经过Review
- 使用PR/MR机制
- 及时反馈和处理
4. **安全考虑**
- 敏感信息不提交
- 定期备份
- 使用强密码和SSH密钥
5. **工具使用**
- 配置Git别名
- 使用图形化工具
- 配置自动化Hook
### 学习资源推荐
- [Git官方文档](https://git-scm.com/doc)
- [Pro Git书籍](https://git-scm.com/book/zh/v2)
- [GitHub Learning Lab](https://lab.github.com/)
- [Atlassian Git教程](https://www.atlassian.com/git/tutorials)
掌握Git不是一蹴而就的,需要在实际项目中不断练习和积累经验。希望这篇实战指南能帮助你更好地使用Git!
如有任何问题或需要更深入的讲解,欢迎继续交流。