准备好掌握现代软件开发的必备技能了吗?
分布式系统
每个开发者都拥有完整的代码仓库副本
高效性能
速度快,占用空间小,本地操作不依赖网络
强大的分支管理
轻量高效的分支创建与合并
数据完整性
SHA-1哈希校验机制确保数据安全
Git已成为现代软件开发的基础设施
特性 | Git (分布式) | SVN/CVS (集中式) |
---|---|---|
仓库结构 | 每个开发者拥有完整副本 | 单一中央服务器 |
离线工作 | 完全支持 | 不支持 |
分支管理 | 轻量高效 | 较重,复制整个目录 |
性能 | 快速(本地操作) | 较慢(网络依赖) |
数据安全性 | 多副本,高安全性 | 单点故障风险 |
macOS
brew install git
或通过Xcode命令行工具
Linux
Ubuntu: sudo apt-get install git
Fedora: sudo dnf install git
验证安装
git --version
应显示当前Git版本
// 设置用户信息(必要配置)
git config --global user.name "你的名字"
git config --global user.email "your.email@example.com"
// 设置默认编辑器
git config --global core.editor vim
// 设置默认分支名
git config --global init.defaultBranch main
// 查看所有配置
git config --list
系统级配置
/etc/gitconfig
全局级配置
~/.gitconfig
仓库级配置
.git/config
工作区 (Working Directory)
项目文件夹中实际看到和编辑的文件
暂存区 (Staging Area / Index)
临时保存即将提交的修改,位于.git
目录
本地仓库 (Local Repository)
.git
目录,保存项目的完整历史
远程仓库 (Remote Repository)
托管在服务器上的版本,如GitHub上的仓库
未跟踪 (Untracked)
Git不知道的新文件
已跟踪 (Tracked)
blob
文件内容对象
tree
目录结构对象
commit
提交信息对象
tag
标记对象
// 初始化新仓库
git init
// 克隆现有仓库
git clone https://github.com/username/repo.git
git clone git@github.com:username/repo.git # SSH方式
git clone https://github.com/username/repo.git my-folder # 指定目录名
// 查看仓库状态
git status
git status -s # 简洁模式
// 查看提交历史
git log
git log --oneline # 简洁模式
git log --graph # 图形化显示
git log -p # 显示变更内容
// 添加文件到暂存区
git add filename # 添加单个文件
git add . # 添加所有修改和新文件
git add -u # 仅添加已跟踪的文件变化
git add -p # 交互式添加,可以选择部分更改
// 提交更改
git commit -m "提交信息"
git commit -a -m "提交信息" # 跳过暂存区,直接提交所有已跟踪文件的修改
git commit --amend # 修改最后一次提交
// 查看差异
git diff # 工作区与暂存区的差异
git diff --staged # 暂存区与最新提交的差异
git diff HEAD # 工作区与最新提交的差异
git diff commit1 commit2 # 两次提交之间的差异
# 忽略所有 .log 文件
*.log
# 忽略 build 目录
build/
# 忽略根目录下的 config.json
/config.json
# 不忽略 important.log
!important.log
使用.gitignore文件来告诉Git哪些文件或目录不需要被跟踪
// 创建标签
git tag v1.0.0 # 轻量标签
git tag -a v1.0.0 -m "发布1.0.0版本" # 附注标签
// 查看标签
git tag # 列出所有标签
git show v1.0.0 # 查看标签详情
// 推送标签到远程
git push origin v1.0.0 # 推送特定标签
git push origin --tags # 推送所有标签
// 撤销工作区修改,恢复到上次提交或暂存的状态
git checkout -- filename # Git 2.23之前的命令
git restore filename # Git 2.23之后的新命令
// 撤销暂存区修改,但保留工作区的修改
git reset HEAD filename # Git 2.23之前的命令
git restore --staged filename # Git 2.23之后的新命令
// 撤销提交的不同方式
git reset --soft HEAD^ # 保留暂存区和工作区的修改
git reset --mixed HEAD^ # 保留工作区的修改(默认)
git reset --hard HEAD^ # 完全撤销(危险操作!)
git revert HEAD # 创建新提交来撤销上一次提交
// 远程仓库管理
git remote add origin https://github.com/user/repo.git
git remote -v # 查看所有远程仓库
git remote show origin # 显示远程仓库详情
// 推送到远程仓库
git push origin branch-name # 推送指定分支
git push -u origin branch-name # 推送并设置上游分支
git push --force origin branch-name # 强制推送(谨慎使用)
// 获取远程更新
git fetch origin # 获取远程更新(不合并)
git pull origin branch-name # 获取并合并远程更新
git pull --rebase origin branch-name # 获取并以变基方式合并
查找丢失的提交
git reflog
显示所有操作记录,包括已撤销的提交
恢复删除的分支
git checkout -b new-branch 提交哈希
使用reflog找到的提交哈希恢复分支
撤销已推送的提交
git revert 提交哈希
git push origin branch-name
安全地撤销公共分支上的提交
分支是Git最强大的功能之一,它允许开发者在不影响主代码的情况下进行并行开发。
分支操作几乎是瞬时的,鼓励频繁使用分支
// 列出所有分支
git branch # 本地分支
git branch -r # 远程分支
git branch -a # 所有分支(本地+远程)
git branch -v # 查看每个分支的最后一次提交
// 创建新分支
git branch new-branch # 基于当前HEAD创建新分支(但不切换)
git branch new-branch commit-hash # 基于指定提交创建分支
// 切换到已有分支
git checkout branch-name # 传统方式
git switch branch-name # 新方式(Git 2.23+)
// 创建并切换
git checkout -b new-branch # 传统方式
git switch -c new-branch # 新方式
// 删除已合并的分支
git branch -d branch-name # 安全删除(检查是否已合并)
// 强制删除未合并的分支
git branch -D branch-name # 不检查合并状态,强制删除
// 删除远程分支
git push origin --delete branch-name # 删除远程仓库上的分支
// 合并到当前分支
git merge source-branch # 将source-branch合并到当前分支
// 禁用快进合并(创建合并提交)
git merge --no-ff source-branch
// 压缩合并(将所有更改合并为一个提交)
git merge --squash source-branch
快进合并 (Fast-forward)
当目标分支是源分支的直接后代时,只是简单地移动指针
三方合并 (3-way merge)
当分支历史出现分叉时,创建一个新的合并提交
// 基本变基操作
git rebase target-branch # 将当前分支变基到target-branch上
// 交互式变基(可以修改、重排、删除或合并提交)
git rebase -i HEAD~3 # 交互式变基,修改最近3个提交
黄金法则: 不要对已推送到公共仓库的提交进行变基。变基会重写历史,这可能导致协作问题。
变基可以创建更线性、更干净的提交历史,但会改变提交的SHA-1值。
// 冲突文件中的标记
<<<<<<< HEAD
当前分支的内容
=======
要合并的分支的内容
>>>>>>> branch-name
// 解决冲突后
git add 解决后的文件
git merge --continue # 继续合并
git rebase --continue # 继续变基
// 放弃操作
git merge --abort # 取消合并
git rebase --abort # 取消变基
类似SVN的使用方式,所有开发者基于主分支(main
或master
)开发
基于功能创建分支,完成后合并回主分支
定义严格的分支模型,支持大型项目和持续部署
main/master
生产环境代码
develop
开发主分支
feature/*
特性分支
release/*
发布准备分支
hotfix/*
紧急修复分支
bugfix/*
Bug修复分支
基于fork的协作模式,典型开源项目方式
// 保存工作进度
git stash # 基本用法
git stash save "描述信息" # 添加描述
git stash -u # 包含未跟踪文件
// 管理贮藏
git stash list # 查看贮藏列表
git stash apply # 应用但不删除
git stash pop # 应用并删除
git stash drop stash@{0} # 删除特定贮藏
git stash clear # 删除所有贮藏
贮藏功能用于临时保存工作目录的修改,以便切换到其他任务。
// 选择性应用提交
git cherry-pick commit-hash # 应用单个提交
git cherry-pick commit1..commit2 # 应用多个提交
git cherry-pick -x commit-hash # 保留原始提交信息
git cherry-pick --no-commit commit-hash # 不自动提交
从一个分支选择性地应用特定提交到另一个分支。
// 添加子模块
git submodule add https://github.com/user/repo.git path/to/submodule
// 初始化和更新子模块
git submodule init
git submodule update
git submodule update --init --recursive # 一步到位
// 克隆包含子模块的项目
git clone --recurse-submodules repo-url
子模块允许将一个Git仓库作为另一个Git仓库的子目录。
// 常见钩子
pre-commit: 提交前执行
commit-msg: 验证提交信息
pre-push: 推送前执行
post-receive: 接收推送后执行
// 启用钩子
chmod +x .git/hooks/pre-commit
// 示例: 提交前运行测试
#!/bin/bash
npm test
if [ $? -ne 0 ]; then
echo "测试失败,提交被取消"
exit 1
fi
Git钩子是在Git执行特定操作时自动运行的脚本,可用于自动化流程。
底层命令
git cat-file -p 对象哈希
git hash-object 文件
git ls-tree 树对象哈希
探索Git对象存储
引用管理
git update-ref refs/heads/branch 提交哈希
git symbolic-ref HEAD refs/heads/main
操作Git引用系统
数据恢复
git fsck --full
git gc --prune=now
git count-objects -v
维护和恢复Git数据库
// 结构化提交消息
<类型>(<范围>): <简短描述>
<详细描述>
<关联问题>
// 类型示例
feat: 新功能
fix: Bug修复
docs: 文档变更
style: 代码风格变更(不影响功能)
refactor: 代码重构
perf: 性能优化
test: 测试相关
chore: 构建过程或辅助工具变更
良好提交示例:
feat(auth): 添加OAuth2登录功能
实现了使用Google和GitHub账号登录的功能。
添加了相关的配置选项和中间件。
Closes #42
功能分支
feature/user-auth
feature/JRA-123
Bug修复分支
bugfix/login-error
bugfix/issue-42
紧急修复分支
hotfix/security-patch
hotfix/v1.2.1
发布分支
release/v1.2.0
release/2023-q2
分支命名建议:
代码质量和编码标准
检查是否符合项目的编码规范,命名约定等
功能完整性
验证是否实现了所有需求,边界条件处理
测试覆盖
确保有适当的单元测试、集成测试等
安全隐患
检查潜在的安全问题如SQL注入、XSS等
避免提交敏感信息
密码、API密钥、证书等不应提交到仓库
使用.gitignore排除敏感文件
排除配置文件、环境变量文件等
使用git-secrets检查敏感信息
自动扫描密钥、密码等敏感信息
签名提交
git config --global user.signingkey 你的GPG密钥ID
git commit -S -m "提交信息"
合并冲突
error: 自动合并失败;修复冲突然后提交结果。
解决方案: 手动编辑冲突文件,标记为已解决,然后继续合并
分离头指针 (detached HEAD)
You are in 'detached HEAD' state...
解决方案: git switch -c new-branch 创建新分支保存修改
推送被拒绝
error: failed to push some refs to...
解决方案: 先拉取(git pull --rebase),解决冲突后再推送
// 仓库优化
git gc # 垃圾收集
git prune # 删除无引用对象
git repack -a -d # 重新打包
// 配置调优
git config --global core.preloadindex true
git config --global core.fscache true
git config --global gc.auto 256
这些命令可以帮助优化大型仓库的性能,减少存储空间。
// 安装Git LFS
git lfs install
// 跟踪大文件
git lfs track "*.psd"
git add .gitattributes # 提交跟踪配置
// 正常使用Git
git add file.psd
git commit -m "Add design file"
git push
Git LFS (Large File Storage) 用于高效管理大型二进制文件。
提示:
当项目变大时,考虑使用浅克隆来提高性能:
git clone --depth=1 repo-url
跨平台
平台特定
GitHub
最流行的Git托管平台
特色: Actions, Pages, Discussions
GitLab
可自托管,企业功能丰富
特色: CI/CD集成, 容器注册表
Gitee(码云)
国内领先托管平台
特色: 快速访问, 中文支持
Bitbucket
Atlassian产品,与Jira集成
特色: Pipelines, Trello集成
GitHub Actions
工作流定义在.github/workflows/目录
基于事件触发(push、PR等)
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm test
GitLab CI/CD
配置在.gitlab-ci.yml文件
基于Runner执行任务
Jenkins
自托管CI/CD系统
使用Jenkinsfile定义管道
代码质量工具
工作流辅助
// 1. 从主分支创建功能分支
git checkout main
git pull
git checkout -b feature/user-auth
// 2. 开发并提交
// ...编写代码...
git add .
git commit -m "feat: implement user authentication"
// 3. 同步主分支最新更改
git checkout main
git pull
git checkout feature/user-auth
git rebase main
// 4. 推送并发起合并请求
git push -u origin feature/user-auth
// 在GitHub/GitLab上创建PR/MR
要点:
// 1. 保存当前工作
git stash
// 2. 从生产分支创建修复分支
git checkout main
git checkout -b hotfix/login-error
// 3. 修复并提交
// ...修复代码...
git add .
git commit -m "fix: login error on mobile devices"
// 4. 测试并合并到主分支
git push -u origin hotfix/login-error
// 创建PR/MR并合并
// 5. 返回原来的工作
git checkout feature/user-auth
git stash pop
要点:
// 1. 拉取最新更改时发生冲突
git pull origin main
CONFLICT (content): Merge conflict in src/component.js
// 2. 解决冲突
// 编辑冲突文件,修复冲突标记
<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 3000;
>>>>>>> branch-name
// 修改为
const timeout = 3000;
// 3. 标记为已解决并完成合并
git add src/component.js
git commit -m "merge: resolve timeout conflict"
// 或者,如果是在变基过程中
git add src/component.js
git rebase --continue
解决冲突工具:
防止冲突策略:
最权威的Git资源
免费电子书,全面介绍Git
《GitHub入门与实践》
大塚弘记著
《Git权威指南》
蒋鑫著
交互式学习Git分支操作
图文并茂的Git教程
全面的Git指南
常用Git命令
适合从SVN迁移
交互式查找Git命令
实践建议:
记住:
Git学习是个循序渐进的过程,从基础命令开始,逐步掌握高级功能。实践是最好的学习方式!