05 - 版本控制¶
学习时间: 3-4小时 重要性: ⭐⭐⭐⭐⭐ 团队协作必备
🎯 学习目标¶
- 理解Git的核心概念和工作原理
- 掌握常用Git命令和工作流程
- 学会分支管理和冲突解决
- 了解GitHub/GitLab协作流程
- 掌握.gitignore配置
1. Git基础概念¶
1.1 什么是版本控制?¶
版本控制是一种记录文件变化,以便将来查阅特定版本修订情况的系统。
为什么需要版本控制?
场景1: 你正在写一个报告,保存了多个版本
- report_v1.docx
- report_v2_final.docx
- report_v3_final_final.docx
- report_v4_final_final_really.docx
问题: 不知道哪个是最新版,不知道改了什么
场景2: 团队协作
- 小明修改了第10行
- 小红同时修改了第10行
- 合并时不知道用谁的版本
Git解决方案: - ✅ 完整的历史记录 - ✅ 清晰的版本对比 - ✅ 自动合并(大部分情况) - ✅ 并行开发支持
1.2 Git核心概念¶
工作区 (Working Directory)
↓ git add
暂存区 (Staging Area / Index)
↓ git commit
本地仓库 (Local Repository)
↓ git push
远程仓库 (Remote Repository)
三个区域的含义: - 工作区: 你实际看到的文件 - 暂存区: 准备提交的更改 - 仓库: 永久保存的提交历史
2. Git基础命令¶
2.1 配置Git¶
# 设置用户名和邮箱(必须)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 设置默认编辑器
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim" # Vim
# 设置默认分支名
git config --global init.defaultBranch main
# 查看配置
git config --list
git config user.name
# 配置别名(快捷命令)
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 st 代替 git status
2.2 仓库操作¶
# 初始化新仓库
git init
# 克隆远程仓库
git clone https://github.com/username/repo.git
git clone https://github.com/username/repo.git my-folder # 指定目录名
# 查看远程仓库
git remote -v
# 添加远程仓库
git remote add origin https://github.com/username/repo.git
# 修改远程仓库URL
git remote set-url origin https://github.com/username/new-repo.git
2.3 基本工作流程¶
# 1. 查看状态
git status
# 2. 添加文件到暂存区
git add filename.txt # 添加单个文件
git add . # 添加所有更改
git add *.py # 添加所有Python文件
git add -A # 添加所有更改(包括删除)
# 3. 提交更改
git commit -m "描述性提交信息"
# 4. 推送到远程
git push origin main
# 完整示例
git add .
git commit -m "添加用户认证功能"
git push origin main
2.4 查看历史¶
# 查看提交历史
git log
git log --oneline # 简洁显示
git log --graph # 图形化显示分支
git log --oneline --graph --all # 组合使用
git log -5 # 最近5条
git log --author="username" # 按作者筛选
# 查看工作区与暂存区的差异
git diff
git diff filename.txt
# 查看暂存区与最后一次提交的差异
git diff --staged
git diff --cached
# 查看某次提交的详情
git show commit-hash
git show HEAD # 查看最新提交
git show HEAD~1 # 查看倒数第二次提交
2.5 撤销操作¶
# 撤销工作区的修改(未add)
git checkout -- filename.txt
git restore filename.txt # Git 2.23+
# 撤销暂存区的修改(已add未commit)
git reset HEAD filename.txt
git restore --staged filename.txt # Git 2.23+
# 修改最后一次提交
git commit --amend -m "新的提交信息"
# 回退到指定版本(保留修改)
git reset --soft HEAD~1
# 回退到指定版本(丢弃修改)
git reset --hard commit-hash
# 查看所有操作记录(用于恢复)
git reflog
3. 分支管理¶
3.1 分支基础¶
# 查看分支
git branch # 本地分支
git branch -r # 远程分支
git branch -a # 所有分支
# 创建分支
git branch feature-x # 创建分支
git checkout -b feature-x # 创建并切换
git switch -c feature-x # 新命令(Git 2.23+)
# 切换分支
git checkout main
git switch main # 新命令(Git 2.23+)
# 删除分支
git branch -d feature-x # 已合并的分支
git branch -D feature-x # 强制删除
# 重命名分支
git branch -m old-name new-name
3.2 合并分支¶
# 合并分支到当前分支
git checkout main
git merge feature-x
# 合并策略
# 1. Fast-forward(快进合并)
# main: A---B
# feature-x: A---B---C---D
# 合并后: A---B---C---D
# 2. Three-way merge(三方合并)
# main: A---B---C
# feature-x: A---B---D---E
# 合并后: A---B---C---F---D---E (F是合并提交)
# 禁用快进合并(保留分支历史)
git merge --no-ff feature-x
3.3 分支工作流示例¶
# 1. 从main创建功能分支
git checkout main
git pull origin main
git checkout -b feature-login
# 2. 开发功能
echo "开发代码..."
git add .
git commit -m "实现登录功能"
# 3. 开发过程中同步main的更新
git checkout main
git pull origin main
git checkout feature-login
git rebase main # 或者 git merge main
# 4. 完成功能,合并到main
git checkout main
git merge feature-login
git push origin main
# 5. 删除功能分支
git branch -d feature-login
git push origin --delete feature-login
4. 分支策略¶
4.1 Git Flow¶
Git Flow是一种经典的分支模型,适合有明确发布周期的项目。
分支说明: - main: 生产环境代码 - develop: 开发分支,集成所有功能 - feature/: 功能分支,从develop创建 - release/: 发布分支,从develop创建 - hotfix/*: 热修复分支,从main创建
# Git Flow初始化
git flow init
# 创建功能分支
git flow feature start my-feature
# 完成功能
git flow feature finish my-feature
# 创建发布分支
git flow release start 1.0.0
# 完成发布
git flow release finish 1.0.0
# 创建热修复
git flow hotfix start fix-bug
# 完成热修复
git flow hotfix finish fix-bug
4.2 GitHub Flow¶
GitHub Flow是一种简化的分支模型,适合持续部署的项目。
工作流程: 1. 从main创建分支 2. 提交更改 3. 创建Pull Request 4. 代码审查和讨论 5. 合并到main 6. 部署
4.3 Trunk-Based Development¶
所有开发都在main分支进行,使用特性开关控制功能。
# 短生命周期的特性分支(<1天)
git checkout -b quick-fix
git commit -am "Quick fix"
git checkout main
git merge quick-fix
5. 冲突解决¶
5.1 什么是冲突?¶
当两个人修改了同一文件的同一部分,Git无法自动合并时就会产生冲突。
5.2 解决冲突¶
# 尝试合并
git merge feature-x
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Automatic merge failed; fix conflicts and then commit the result.
# 查看冲突文件
git status
# 打开冲突文件,会看到类似这样的内容:
<<<<<<< HEAD
这是main分支的内容
=======
这是feature-x分支的内容
>>>>>>> feature-x
# 手动编辑,保留需要的代码,删除标记
# 例如:
这是合并后的内容
# 标记为已解决
git add file.txt
git commit -m "解决合并冲突"
# 或者放弃合并
git merge --abort
5.3 预防冲突¶
# 1. 经常同步主分支
git pull origin main
# 2. 使用rebase保持线性历史
git checkout feature-x
git rebase main
# 3. 小步提交,频繁推送
# 4. 沟通协作,避免同时修改同一文件
6. 远程协作¶
6.1 Pull Request / Merge Request¶
工作流程:
# 1. Fork仓库(如果是外部贡献者)
# 2. 克隆仓库
git clone https://github.com/your-username/repo.git
# 3. 创建分支
git checkout -b feature-awesome
# 4. 提交更改
git add .
git commit -m "添加 awesome 功能"
git push origin feature-awesome
# 5. 在GitHub/GitLab上创建Pull Request
# 6. 代码审查
# - 审查者提出意见
# - 作者修改代码
# - 再次推送,PR自动更新
# 7. 合并PR
# - 通过审查后合并到main
6.2 同步上游仓库¶
# 添加上游仓库
git remote add upstream https://github.com/original-owner/original-repo.git
# 获取上游更新
git fetch upstream
# 合并到本地main
git checkout main
git merge upstream/main
# 推送到自己的fork
git push origin main
6.3 代码审查清单¶
提交PR前自查: - [ ] 代码能正常运行 - [ ] 添加了必要的测试 - [ ] 更新了文档 - [ ] 遵循代码规范 - [ ] 提交信息清晰 - [ ] 没有调试代码(print, debugger等)
7. .gitignore配置¶
7.1 基本语法¶
# 注释
*.log # 忽略所有.log文件
temp/ # 忽略temp目录
build/ # 忽略build目录
!important.log # 不忽略important.log
*.py[cod] # 忽略.pyc, .pyo, .pyd
**/__pycache__/ # 忽略所有__pycache__目录
7.2 Python项目.gitignore¶
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
ENV/
env/
.venv
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
# Jupyter
.ipynb_checkpoints
# Environment variables
.env
.env.local
# Logs
*.log
# OS
.DS_Store
Thumbs.db
7.3 常用模板¶
GitHub提供了各种语言的.gitignore模板: https://github.com/github/gitignore
# 使用gitignore.io生成
curl -o .gitignore https://www.toptal.com/developers/gitignore/api/python,pycharm,windows,macos,linux <!-- ⚠️ 可能需要登录 -->
8. 高级技巧¶
8.1 储藏(Stash)¶
# 储藏当前更改
git stash
git stash push -m "描述信息"
# 查看储藏列表
git stash list
# 应用最近的储藏
git stash pop # 应用并删除
git stash apply # 应用但不删除
# 应用指定的储藏
git stash apply stash@{2}
# 删除储藏
git stash drop stash@{0}
git stash clear # 清空所有
8.2 拣选(Cherry-pick)¶
# 将某个提交应用到当前分支
git cherry-pick commit-hash
# 拣选多个提交
git cherry-pick A^..B # A到B的所有提交
# 拣选时解决冲突
git cherry-pick --continue
git cherry-pick --abort
8.3 变基(Rebase)¶
# 交互式变基
git rebase -i HEAD~3 # 最近3个提交
# 常用操作:
# p, pick = 使用提交
# r, reword = 修改提交信息
# e, edit = 修改提交内容
# s, squash = 合并到上一个提交
# d, drop = 删除提交
# 变基时解决冲突
git rebase --continue
git rebase --abort
# 不要对已经推送到远程的提交进行变基!
8.4 子模块¶
# 添加子模块
git submodule add https://github.com/user/repo.git path/to/submodule
# 克隆包含子模块的仓库
git clone --recurse-submodules https://github.com/user/main-repo.git
# 更新子模块
git submodule update --init --recursive
📝 练习¶
练习1: 基础操作¶
# 1. 创建一个新仓库
mkdir my-project
cd my-project
git init
# 2. 创建文件并提交
echo "Hello Git" > README.md
git add README.md
git commit -m "Initial commit"
# 3. 修改文件并查看差异
echo "World" >> README.md
git diff
git add .
git commit -m "Add world"
# 4. 查看历史
git log --oneline
练习2: 分支操作¶
# 1. 创建并切换到新分支
git checkout -b feature-1
# 2. 在新分支上提交更改
echo "Feature 1" > feature.txt
git add .
git commit -m "Add feature 1"
# 3. 切换回main分支
git checkout main
# 4. 合并分支
git merge feature-1
# 5. 删除分支
git branch -d feature-1
练习3: 解决冲突¶
# 1. 创建两个分支,修改同一文件
git checkout -b branch-a
echo "Branch A content" > conflict.txt
git add . && git commit -m "Branch A"
git checkout main
git checkout -b branch-b
echo "Branch B content" > conflict.txt
git add . && git commit -m "Branch B"
# 2. 尝试合并,会产生冲突
git checkout main
git merge branch-a
git merge branch-b # 冲突!
# 3. 手动解决冲突,完成合并
练习4: GitHub协作¶
# 1. 在GitHub上fork一个仓库
# 2. 克隆fork的仓库
git clone https://github.com/your-username/forked-repo.git
# 3. 添加上游仓库
git remote add upstream https://github.com/original-owner/original-repo.git
# 4. 创建分支,修改代码,提交PR
# 5. 同步上游更新
git fetch upstream
git merge upstream/main
🎯 自我检查¶
- 理解Git的三个工作区域
- 掌握基本的Git命令(add, commit, push, pull)
- 会使用分支进行并行开发
- 理解并能解决合并冲突
- 了解Git Flow和GitHub Flow工作流
- 会配置.gitignore文件
- 理解Pull Request流程
- 会使用stash储藏更改
📚 延伸阅读¶
- Pro Git(免费电子书)
- Git官方文档
- GitHub Flow
- Git Flow
- Oh Shit, Git!?! - 解决常见Git问题
🎉 恭喜完成阶段5!¶
你已经完成了工程最佳实践的学习!
你掌握了: - 虚拟环境管理 - 代码调试技巧 - 单元测试 - 代码规范 - 版本控制
下一步: 进入实战练习巩固所学知识。