目录
5.3 Pull Request/Merge Request
1. Git简介与核心概念
1.1 什么是Git
Git是一个分布式版本控制系统,由Linus Torvalds在2005年为管理Linux内核开发而创建。它具有以下特点:
- 分布式架构:每个开发者都有完整的代码仓库副本
- 高效性能:大部分操作在本地完成,速度快
- 强大的分支系统:轻量级分支使分支操作几乎瞬间完成
- 数据完整性:使用SHA-1哈希确保代码历史不被篡改
- 灵活性:支持多种工作流程和开发模式
1.2 版本控制系统(VCS)的类型
- 本地版本控制系统:如RCS,只在单个计算机上跟踪文件变化
- 集中式版本控制系统(CVCS):如SVN,有中央服务器存储所有版本
- 分布式版本控制系统(DVCS):如Git,每个用户都有完整的仓库副本
1.3 Git核心概念
- 仓库(Repository):包含项目所有文件和版本历史的目录
- 工作目录(Working Directory):本地文件系统中的项目文件
- 暂存区(Staging Area/Index):准备下一次提交的文件集合
- 提交(Commit):保存到仓库中的项目快照
- 分支(Branch):指向特定提交的轻量级可移动指针
- HEAD:指向当前所在分支或提交的指针
- 远程(Remote):托管在服务器上的仓库副本
1.4 Git对象模型
Git的核心是一个简单的键值对存储系统,包含四种主要对象:
- Blob对象:存储文件数据
- Tree对象:表示目录结构,包含blob和其他tree
- Commit对象:包含作者信息、提交消息和指向tree的指针
- Tag对象:标记特定提交的永久引用
2. Git安装与配置
2.1 安装Git
Windows:
- 下载官方安装程序:Redirecting…
- 运行安装程序,按提示完成安装
- 安装后可在命令行使用
git --version
验证
macOS:
# 使用Homebrew安装
brew install git
# 或下载官方安装程序
https://git-scm.com/download/mac
Linux (Debian/Ubuntu):
sudo apt-get update
sudo apt-get install git
Linux (Fedora/RHEL):
sudo dnf install git
# 或
sudo yum install git
2.2 初始配置
首次使用Git前需要配置用户信息:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
常用配置选项:
# 设置默认编辑器(Vim/VS Code等)
git config --global core.editor "code --wait"
# 设置换行符处理(Windows)
git config --global core.autocrlf true
# 设置换行符处理(macOS/Linux)
git config --global core.autocrlf input
# 启用彩色输出
git config --global color.ui auto
# 设置默认分支名称
git config --global init.defaultBranch main
# 查看所有配置
git config --list
2.3 配置SSH密钥
- 生成SSH密钥:
ssh-keygen -t ed25519 -C "your_email@example.com"
# 或使用RSA
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
-
将公钥(~/.ssh/id_ed25519.pub)添加到GitHub/GitLab等平台
-
测试连接:
ssh -T git@github.com
3. Git基础操作
3.1 创建仓库
初始化新仓库:
git init [项目名称]
cd [项目名称]
克隆现有仓库:
git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git # SSH方式
git clone --depth 1 https://github.com/user/repo.git # 浅克隆(只获取最新版本)
3.2 基本工作流程
- 修改工作目录中的文件
- 将更改添加到暂存区:
git add <file> # 添加特定文件 git add . # 添加所有更改 git add -p # 交互式添加
- 提交更改到本地仓库:
git status # 查看工作目录和暂存区状态 git status -s # 简洁状态输出
3.3 查看状态与历史
查看状态:
git status # 查看工作目录和暂存区状态
git status -s # 简洁状态输出
查看提交历史:
git log
git log --oneline # 简洁显示
git log --graph # 显示分支图
git log --stat # 显示更改统计
git log -p # 显示具体更改内容
git log -n 5 # 显示最近5条提交
git log --since="2023-01-01"
git log --author="John"
git log --grep="bugfix"
git log file.txt # 查看特定文件的更改历史
查看更改:
git diff # 工作目录与暂存区的差异
git diff --staged # 暂存区与最后一次提交的差异
git diff HEAD # 工作目录与最后一次提交的差异
git diff commit1 commit2 # 比较两个提交
git diff branch1..branch2 # 比较两个分支
3.4 撤销更改
撤销工作目录的更改:
git checkout -- <file> # 丢弃工作目录中文件的更改
git restore <file> # Git 2.23+推荐方式
撤销暂存区的更改:
git reset HEAD <file> # 将文件移出暂存区
git restore --staged <file> # Git 2.23+推荐方式
修改最后一次提交:
git commit --amend # 修改提交信息或内容
回退到特定提交:
git reset --soft HEAD~1 # 撤销提交但保留更改在暂存区
git reset --mixed HEAD~1 # 撤销提交和暂存(默认)
git reset --hard HEAD~1 # 完全丢弃提交和更改(谨慎使用)
git revert HEAD # 创建新的提交来撤销更改(更安全)
3.5 忽略文件
# 忽略所有.class文件
*.class
# 忽略特定文件
config.ini
# 忽略目录
build/
node_modules/
# 例外规则(不忽略)
!important.class
4. 分支与合并
4.1 分支基础
查看分支:
git branch # 查看本地分支
git branch -v # 查看分支及最后提交
git branch -vv # 查看跟踪关系
git branch -a # 查看所有分支(包括远程)
创建分支:
git branch new-branch # 创建新分支
git checkout -b new-branch # 创建并切换到新分支
git switch -c new-branch # Git 2.23+推荐方式
切换分支:
git checkout branch-name
git switch branch-name # Git 2.23+推荐方式
删除分支:
git branch -d branch-name # 删除已合并的分支
git branch -D branch-name # 强制删除未合并的分支
4.2 合并与冲突解决
合并分支:
git merge branch-name # 将branch-name合并到当前分支
git merge --no-ff branch-name # 禁用快进合并
git merge --abort # 中止合并
解决冲突:
- Git会在冲突文件中标记冲突部分:
<<<<<<< HEAD 当前分支的内容 ======= 要合并的分支的内容 >>>>>>> branch-name
- 手动编辑文件解决冲突
- 标记冲突已解决:
git add <file> git commit
使用图形工具解决冲突:
git mergetool
4.3 变基(Rebase)
基本变基:
git rebase target-branch # 将当前分支变基到target-branch
git rebase --continue # 解决冲突后继续变基
git rebase --abort # 中止变基
git rebase --skip # 跳过当前提交
交互式变基:
git rebase -i HEAD~3 # 交互式修改最近3个提交
交互式变基可用命令:
- pick: 保留提交
- reword: 保留更改但修改提交信息
- edit: 保留更改但暂停修改
- squash: 将提交合并到前一个提交
- fixup: 类似squash但丢弃提交信息
- drop: 删除提交
4.4 储藏(Stash)
临时保存工作目录的更改:
git stash # 储藏所有更改
git stash push -m "message" # 储藏并添加消息
git stash list # 查看储藏列表
git stash apply stash@{n} # 应用特定储藏
git stash pop # 应用并删除最新储藏
git stash drop stash@{n} # 删除特定储藏
git stash clear # 删除所有储藏
git stash branch new-branch # 从储藏创建新分支
5. 远程仓库协作
5.1 远程仓库基础
查看远程仓库:
git remote -v # 查看远程仓库URL
git remote show origin # 查看远程仓库详细信息
添加/移除远程仓库:
git remote add origin https://github.com/user/repo.git
git remote rename origin upstream
git remote remove origin
从远程获取更改:
git fetch origin # 获取远程更改但不合并
git fetch --prune # 获取并删除本地不存在的远程分支
git pull origin main # 获取并合并远程更改(相当于fetch + merge)
git pull --rebase origin main # 获取并使用rebase合并
推送到远程仓库:
git push origin branch-name
git push -u origin branch-name # 设置上游分支
git push --force-with-lease # 安全强制推送
git push --all origin # 推送所有分支
git push --tags # 推送所有标签
5.2 协作工作流程
-
集中式工作流:
- 所有开发者向同一个中央仓库推送更改
- 适合小型团队或简单项目
-
功能分支工作流:
- 每个新功能在独立分支开发
- 完成后通过Pull Request合并到主分支
-
Git Flow:
- 严格的分支模型,有main, develop, feature, release, hotfix分支
- 适合有严格发布周期的项目
-
Forking工作流:
- 每个开发者fork主仓库,在自己的副本上工作
- 通过Pull Request贡献更改
- 适合开源项目
5.3 Pull Request/Merge Request
- 在GitHub/GitLab等平台创建PR/MR
- 讨论和代码审查
- 解决冲突(如有)
- 合并到目标分支
- 可选择删除源分支
5.4 处理上游更改
同步fork的仓库:
# 添加上游仓库
git remote add upstream https://github.com/original/repo.git
# 获取上游更改
git fetch upstream
# 合并到本地分支
git checkout main
git merge upstream/main
# 推送到自己的fork
git push origin main
6. 高级Git技巧
6.1 重写历史
修改多个提交信息:
git rebase -i HEAD~3
# 将pick改为reword
拆分提交:
git rebase -i HEAD~3
# 将pick改为edit
git reset HEAD^
git add -p
git commit -m "第一部分"
git commit -m "第二部分"
git rebase --continue
重新排序提交:
git rebase -i HEAD~3
# 在编辑器中重新排序提交
6.2 二分查找
查找引入bug的提交:
git bisect start
git bisect bad # 标记当前提交有问题
git bisect good v1.0 # 标记已知好的提交
# 测试后标记当前提交是好是坏
git bisect good
git bisect bad
git bisect reset # 结束二分查找
6.3 子模块(Submodule)
添加子模块:
git submodule add https://github.com/user/repo.git path/to/submodule
克隆包含子模块的项目:
git clone --recursive https://github.com/user/repo.git
# 或
git clone https://github.com/user/repo.git
cd repo
git submodule init
git submodule update
更新子模块:
git submodule update --remote
6.4 钩子(Hooks)
Git钩子是特定事件发生时自动运行的脚本,存储在.git/hooks/
目录。
常用钩子:
- pre-commit: 提交前运行
- prepare-commit-msg: 提交信息编辑器启动前
- post-commit: 提交完成后
- pre-push: 推送到远程前
- pre-rebase: 变基前
示例pre-commit钩子(检查代码风格):
#!/bin/sh
# 运行linter
npm run lint
if [ $? -ne 0 ]; then
echo "Lint检查失败,请修复错误后再提交"
exit 1
fi
6.5 引用日志(Reflog)
Git的"安全网",记录所有分支和HEAD的更改:
git reflog # 查看引用日志
git reflog show branch-name # 查看特定分支的日志
git reset --hard HEAD@{5} # 恢复到特定状态
6.6 大型文件存储(Git LFS)
处理大文件的扩展:
# 安装Git LFS
git lfs install
# 跟踪大文件类型
git lfs track "*.psd"
# 查看跟踪的文件模式
git lfs track
# 克隆包含LFS文件的项目
git lfs clone https://github.com/user/repo.git
7. Git内部原理
7.1 Git目录结构
项目中的.git
目录包含:
.git/
├── HEAD # 当前所在分支
├── config # 项目特定配置
├── description # 仓库描述
├── hooks/ # 钩子脚本
├── info/ # 全局排除模式
├── objects/ # 所有git对象
│ ├── pack/ # 打包对象
│ └── ... # 松散对象
├── refs/ # 分支和标签引用
│ ├── heads/ # 本地分支
│ ├── tags/ # 标签
│ └── remotes/ # 远程跟踪分支
├── index # 暂存区
└── ...
7.2 Git对象存储
Git使用SHA-1哈希作为对象标识符:
# 查看对象类型
git cat-file -t 1ff0c
# 查看对象内容
git cat-file -p 1ff0c
# 查找对象对应的文件
git ls-tree 1ff0c
# 查找包含特定字符串的提交
git grep "function_name" $(git rev-list --all)
7.3 包文件(Packfiles)
Git会定期将松散对象打包以节省空间:
git gc # 垃圾收集和打包
git count-objects -v # 查看对象统计
git verify-pack -v .git/objects/pack/pack-*.idx # 查看包文件内容
7.4 传输协议
Git支持多种传输协议:
- 本地协议:
/path/to/repo.git
或file:///path/to/repo.git
- HTTP协议:
http://
或https://
- SSH协议:
ssh://user@server/project.git
或user@server:project.git
- Git协议:
git://server/project.git
8. Git最佳实践
8.1 提交规范
原子性提交:
- 每个提交应该只包含一个逻辑更改
- 避免将不相关的更改放在同一个提交中
良好的提交信息:
类型(范围): 简短描述(50字符以内)
详细描述(72字符换行),解释:
- 为什么需要这个更改
- 如何解决问题
- 可能的影响
相关issue: #123
常用类型:
- feat: 新功能
- fix: bug修复
- docs: 文档更改
- style: 代码格式/样式
- refactor: 重构代码
- test: 测试相关
- chore: 构建/工具/配置更改
8.2 分支管理策略
- 主分支(main/master):稳定可发布的代码
- 开发分支(develop):集成分支,用于日常开发
- 功能分支(feature/):短期分支,开发新功能
- 发布分支(release/):准备发布的代码
- 热修复分支(hotfix/):紧急修复生产问题
8.3 代码审查
- 使用Pull Request/Merge Request进行代码审查
- 保持PR大小适中(300行以内最佳)
- 提供清晰的描述和上下文
- 使用代码评论工具进行讨论
- 要求至少一个核心成员的批准
8.4 持续集成
- 设置自动化测试和构建
- 在合并前要求所有测试通过
- 使用pre-commit钩子进行基本检查
- 集成代码质量工具(SonarQube等)
- 自动化部署流程
9. 常见问题与解决方案
9.1 常见错误与修复
撤销公共分支的更改:
# 错误方式(不要这样做)
git reset --hard HEAD~1
git push --force
# 正确方式
git revert HEAD
git push
找回丢失的提交:
git reflog
git checkout -b new-branch HEAD@{1}
解决"detached HEAD"状态:
git checkout -b temp-branch # 从当前状态创建新分支
# 或
git checkout main # 回到主分支
清理未跟踪文件:
git clean -n # 查看将被删除的文件
git clean -f # 删除未跟踪文件
git clean -fd # 删除未跟踪文件和目录
9.2 性能优化
加速大型仓库:
git config --global core.preloadindex true
git config --global core.fscache true
git config --global gc.auto 256
部分克隆:
git clone --filter=blob:none https://github.com/user/repo.git
稀疏检出:
git clone --sparse https://github.com/user/repo.git
cd repo
git sparse-checkout set dir1 dir2
9.3 跨平台问题
换行符问题:
# 在Windows上
git config --global core.autocrlf true
# 在macOS/Linux上
git config --global core.autocrlf input
# 禁止自动转换
git config --global core.autocrlf false
文件名大小写:
git config --global core.ignorecase false
10. Git工具与扩展
10.1 图形界面工具
- GitHub Desktop: GitHub Desktop | Simple collaboration from your desktop · GitHub
- GitKraken: GitKraken Legendary Git Tools | GitKraken
- SourceTree: Sourcetree | Free Git GUI for Mac and Windows
- TortoiseGit: TortoiseGit – Windows Shell Interface to Git
- VS Code Git集成: 内置Git支持
10.2 命令行增强工具
-
tig: 文本模式Git仓库浏览器
brew install tig
-
diff-so-fancy: 更好的Git diff显示
npm install -g diff-so-fancy git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"
-
lazygit: 终端Git UI
brew install lazygit
-
git-extras: 有用的Git扩展命令
brew install git-extras
10.3 其他扩展
-
git-flow: Git分支模型标准化工具
brew install git-flow
-
git-town: 高级Git工作流支持
brew install git-town
-
git-secrets: 防止提交敏感信息
brew install git-secrets
-
git-lfs: 大文件支持
brew install git-lfs
结语
Git是一个功能强大且灵活的工具,掌握它需要时间和实践。本指南涵盖了从基础到高级的Git知识,建议:
- 从基础命令开始,逐步学习高级功能
- 在实际项目中应用所学知识
- 遇到问题时查阅文档或本指南
- 定期练习以保持熟练度
- 关注Git的新功能和最佳实践
记住,Git的核心是记录和跟踪变化,理解这一点将帮助你更好地利用这个强大的工具。