Git版本控制入门教程
Git是目前世界上最先进的分布式版本控制系统。无论是个人项目还是团队协作,Git都是必不可少的工具。本教程将带你从零开始,系统学习Git的核心概念和常用操作。
一、Git简介与安装
Git由Linux之父Linus Torvalds在2005年创建。与集中式版本控制系统(如SVN)不同,Git是分布式的,每个开发者本地都有完整的代码仓库副本。
Git的核心概念
- 仓库(Repository):Git管理的一个目录,包含所有版本历史
- 工作区(Working Directory):你正在编辑的文件目录
- 暂存区(Staging Area / Index):准备提交的文件快照
- 提交(Commit):代码的一个版本快照
- 分支(Branch):独立的开发线
- 远程仓库(Remote):托管在服务器上的仓库(如GitHub)
安装Git
# Windows: 从官网下载安装包
# https://git-scm.com/download/win
# macOS: 使用Homebrew安装
brew install git
# Ubuntu/Debian
sudo apt update
sudo apt install git
# CentOS/RHEL
sudo yum install git
# 验证安装
git --version
初次配置
# 设置全局用户名和邮箱(每次提交都会用到)
git config --global user.name "你的名字"
git config --global user.email "your@email.com"
# 设置默认编辑器
git config --global core.editor "code --wait" # VS Code
git config --global core.editor vim # Vim
git config --global core.editor nano # Nano
# 设置默认分支名为main(Git 2.28+)
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 config --global alias.lg "log --oneline --graph --all"
# 之后可以用 git st 代替 git status
二、仓库初始化(init/clone)
使用Git管理代码,首先需要创建或获取一个仓库。
# ===== 方式1:初始化新仓库 =====
# 创建项目目录
mkdir my-project
cd my-project
# 初始化Git仓库
git init
# 会在当前目录创建 .git 隐藏目录,存放Git的所有数据
# ===== 方式2:克隆远程仓库 =====
# 克隆完整仓库
git clone https://github.com/user/repo.git
# 克隆到指定目录
git clone https://github.com/user/repo.git my-folder
# 只克隆最近一次提交(节省时间和空间)
git clone --depth 1 https://github.com/user/repo.git
# 克隆指定分支
git clone -b develop https://github.com/user/repo.git
# 使用SSH协议克隆(推荐,更安全)
git clone git@github.com:user/repo.git
三、基本操作(add/commit/status/log)
这是Git最核心的日常工作流程:修改文件、暂存、提交。
# ===== 查看状态 =====
git status # 查看工作区状态
git status -s # 简洁模式
# ===== 添加文件到暂存区 =====
git add file.txt # 添加单个文件
git add . # 添加当前目录所有变更
git add *.py # 添加所有Python文件
git add src/ # 添加整个目录
git add -p # 交互式添加(可选择性添加部分修改)
# ===== 提交到本地仓库 =====
git commit -m "提交信息"
git commit -m "标题" -m "详细描述"
# 跳过暂存直接提交(只对已跟踪的文件有效)
git commit -am "修改并提交"
# 修改最近一次提交(追加文件或修改信息)
git add forgotten_file.txt
git commit --amend -m "新的提交信息"
git commit --amend --no-edit # 保持原提交信息
# ===== 查看提交历史 =====
git log # 完整历史
git log --oneline # 每行一个提交
git log --oneline --graph # 图形化显示
git log --oneline --graph --all # 显示所有分支
git log -5 # 最近5次提交
git log --author="张三" # 按作者过滤
git log --since="2 weeks ago" # 按时间过滤
git log --stat # 显示文件变更统计
git log -p # 显示具体改动内容
# ===== 查看差异 =====
git diff # 工作区 vs 暂存区
git diff --staged # 暂存区 vs 最近提交
git diff HEAD # 工作区 vs 最近提交
git diff branch1 branch2 # 两个分支的差异
git diff --stat # 只显示统计信息
# ===== 撤销操作 =====
# 撤销工作区修改(未add的)
git checkout -- file.txt
git restore file.txt # Git 2.23+新语法
# 将文件从暂存区移回工作区(已add未commit的)
git reset HEAD file.txt
git restore --staged file.txt # Git 2.23+新语法
# 撤销最近的提交(保留修改在工作区)
git reset HEAD~1 # 撤销提交,保留修改
git reset --soft HEAD~1 # 撤销提交,保留在暂存区
git reset --hard HEAD~1 # 撤销提交,丢弃修改(危险!)
# 创建一个新提交来撤销之前的提交(安全,不改历史)
git revert HEAD
git revert <commit-hash>
提交信息规范
好的提交信息能让项目历史更清晰。推荐使用约定式提交规范:
# 提交信息格式
<type>(<scope>): <subject>
<body>
<footer>
# 类型(type)
feat: 新功能
fix: 修复Bug
docs: 文档变更
style: 代码格式(不影响功能)
refactor: 重构(既不是新功能也不是修Bug)
test: 增加测试
chore: 构建工具或辅助工具的变动
# 示例
feat(auth): 添加用户登录功能
fix(api): 修复用户列表分页错误
docs: 更新README安装说明
refactor(utils): 重构日期格式化函数
四、分支管理(branch/checkout/merge)
分支是Git最强大的特性。它让你可以在不影响主干的情况下进行独立开发。
# ===== 查看分支 =====
git branch # 查看本地分支(*标记当前分支)
git branch -r # 查看远程分支
git branch -a # 查看所有分支
git branch -v # 查看分支及最后一次提交
# ===== 创建分支 =====
git branch feature-login # 创建分支但不切换
git checkout -b feature-login # 创建并切换到新分支
git switch -c feature-login # Git 2.23+新语法
# 基于远程分支创建本地分支
git checkout -b feature origin/feature
# ===== 切换分支 =====
git checkout main # 切换到main分支
git switch main # Git 2.23+新语法
git checkout - # 切换回上一个分支
# ===== 删除分支 =====
git branch -d feature-login # 安全删除(已合并的才能删)
git branch -D feature-login # 强制删除
# ===== 重命名分支 =====
git branch -m old-name new-name # 重命名当前分支
git branch -m new-name # 重命名当前分支
# ===== 合并分支 =====
# 场景:将feature分支合并到main
git checkout main # 先切换到目标分支
git merge feature-login # 合并feature分支
# 合并选项
git merge --no-ff feature # 创建合并提交(保留分支历史)
git merge --ff-only feature # 只允许快进合并
git merge --squash feature # 压缩合并(将多个提交合成一个)
# ===== 查看分支图 =====
git log --oneline --graph --all
# 输出示例:
# * 7a3b2c1 (HEAD -> main) Merge branch 'feature'
# |\
# | * 4d5e6f7 (feature) 添加登录页面
# | * 2b3c4d5 添加用户模型
# |/
# * 1a2b3c4 初始化项目
五、远程仓库(remote/push/pull)
远程仓库用于团队协作和代码备份。GitHub、GitLab、Gitee都是流行的远程仓库托管平台。
# ===== 查看远程仓库 =====
git remote -v # 查看远程仓库地址
git remote show origin # 查看远程仓库详情
# ===== 添加远程仓库 =====
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git # fork场景
# ===== 修改远程仓库地址 =====
git remote set-url origin https://github.com/user/new-repo.git
# ===== 重命名/删除远程仓库 =====
git remote rename origin upstream
git remote remove origin
# ===== 推送代码 =====
# 首次推送:设置上游分支
git push -u origin main
# 之后只需
git push
# 推送指定分支
git push origin feature-login
# 推送所有分支
git push --all
# 推送标签
git push origin v1.0.0
git push --tags
# 强制推送(危险!会覆盖远程历史)
git push --force-with-lease # 安全的强制推送(推荐)
git push -f # 强制推送(不安全)
# ===== 拉取代码 =====
# git pull = git fetch + git merge
git pull origin main # 拉取并合并
git pull --rebase origin main # 拉取并变基(更干净的历史)
# git fetch 只下载不合并(更安全)
git fetch origin # 获取远程更新
git fetch --all # 获取所有远程更新
git log origin/main # 查看远程分支的提交
git merge origin/main # 手动合并
# ===== 创建标签(版本发布) =====
git tag v1.0.0 # 轻量标签
git tag -a v1.0.0 -m "发布版本1.0" # 附注标签(推荐)
git tag # 查看所有标签
git tag -d v1.0.0 # 删除本地标签
git push origin --delete v1.0.0 # 删除远程标签
六、合并冲突解决
当两个分支修改了同一文件的同一部分时,合并会产生冲突。解决冲突是Git使用中的常见操作。
# 模拟冲突场景
git checkout -b feature
# 修改README.md的第一行
git commit -am "feature分支修改README"
git checkout main
# 也修改README.md的第一行
git commit -am "main分支修改README"
# 合并feature分支(会产生冲突)
git merge feature
# 输出: CONFLICT (content): Merge conflict in README.md
# Automatic merge failed; fix conflicts and then commit the result.
冲突文件的内容会变成这样:
这是README.md文件的内容
<<<<<<< HEAD
这是main分支的修改内容
=======
这是feature分支的修改内容
>>>>>>> feature
后续内容...
# ===== 解决冲突的步骤 =====
# 1. 查看冲突文件
git status
# 会在 "Unmerged paths" 中列出冲突文件
# 2. 手动编辑文件,解决冲突
# 删除冲突标记(<<<<<<< ======= >>>>>>>)
# 保留需要的内容,或合并两边的内容
# 3. 标记冲突已解决
git add README.md
# 4. 完成合并
git commit -m "合并feature分支,解决README冲突"
# ===== 放弃合并 =====
git merge --abort # 取消合并,回到合并前的状态
# ===== 使用合并工具 =====
git mergetool # 启动配置的合并工具
# ===== 查看冲突的文件 =====
git diff --name-only --diff-filter=U # 只列出有冲突的文件
七、.gitignore
.gitignore文件用于指定哪些文件不应该被Git追踪,如编译产物、依赖、配置文件等。
# .gitignore 文件示例
# ===== Python项目 =====
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/
.venv/
*.egg-info/
dist/
build/
.eggs/
*.egg
# ===== Node.js项目 =====
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.npm
.yarn-integrity
# ===== Java项目 =====
*.class
*.jar
*.war
target/
.gradle/
build/
# ===== IDE和编辑器 =====
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
# ===== 环境配置和密钥 =====
.env
.env.local
config.ini
secrets.json
*.pem
*.key
# ===== 日志和临时文件 =====
*.log
logs/
tmp/
temp/
# ===== 操作系统文件 =====
.DS_Store # macOS
Thumbs.db # Windows
desktop.ini # Windows
# ===== 注意事项 =====
# .gitignore只能忽略未被追踪的文件
# 如果文件已经被git add,需要先移除追踪:
git rm --cached filename
git rm -r --cached directory/
# 全局gitignore(对所有项目生效)
git config --global core.excludesfile ~/.gitignore_global
八、实战案例:团队协作工作流
下面演示一个完整的团队协作Git工作流,包括功能开发、代码审查和发布。
# ============================================================
# 场景:开发一个新功能,提交PR,合并后发布
# ============================================================
# ===== 第1步:同步主仓库 =====
# 假设你fork了一个项目,先同步最新代码
cd my-project
git checkout main
git fetch upstream
git merge upstream/main
git push origin main
# ===== 第2步:创建功能分支 =====
# 从最新的main创建分支
git checkout -b feature/user-profile
# ===== 第3步:开发和提交 =====
# 编写代码...
echo "用户资料功能" > profile.py
git add profile.py
git commit -m "feat: 添加用户资料功能"
# 继续开发...
echo "资料编辑功能" >> profile.py
git add profile.py
git commit -m "feat: 添加资料编辑功能"
# 查看提交历史
git log --oneline
# 输出:
# 3d4e5f6 feat: 添加资料编辑功能
# 2b3c4d5 feat: 添加用户资料功能
# 1a2b3c4 (main) 初始化项目
# ===== 第4步:同步主仓库最新代码 =====
# 开发期间main可能有新提交,需要同步
git fetch upstream
git rebase upstream/main
# 如果有冲突,解决后:
# git add .
# git rebase --continue
# ===== 第5步:推送到自己的远程仓库 =====
git push origin feature/user-profile
# 如果之前push过,rebase后需要强制推送
git push --force-with-lease origin feature/user-profile
# ===== 第6步:创建Pull Request =====
# 在GitHub网页上创建PR: feature/user-profile -> main
# 填写PR标题和描述
# 等待代码审查(Code Review)
# ===== 第7步:根据审查意见修改 =====
# 审查者提出了修改建议
echo "根据审查意见优化" >> profile.py
git add profile.py
git commit -m "fix: 根据代码审查优化实现"
git push origin feature/user-profile
# ===== 第8步:PR合并后清理 =====
# PR被合并后,删除本地和远程分支
git checkout main
git pull upstream main
git push origin main
# 删除功能分支
git branch -d feature/user-profile
git push origin --delete feature/user-profile
Git工作流模式
# ============================================================
# 常见的Git工作流模式
# ============================================================
# ===== 1. GitHub Flow(简单,适合小团队) =====
# main分支始终可部署
# 1. 从main创建分支
# 2. 开发并提交
# 3. 创建PR
# 4. 审查通过后合并到main
# 5. 删除分支
# ===== 2. Git Flow(复杂,适合版本发布项目) =====
# main: 生产环境代码
# develop: 开发分支
# feature/*: 功能分支
# release/*: 发布分支
# hotfix/*: 紧急修复分支
# 创建develop分支
git checkout -b develop
git push -u origin develop
# 功能开发
git checkout -b feature/login develop
# ...开发...
git checkout develop
git merge --no-ff feature/login
git branch -d feature/login
# 准备发布
git checkout -b release/1.0 develop
# ...修复bug...
git checkout main
git merge --no-ff release/1.0
git tag v1.0.0
git checkout develop
git merge --no-ff release/1.0
git branch -d release/1.0
# 紧急修复
git checkout -b hotfix/1.0.1 main
# ...修复...
git checkout main
git merge --no-ff hotfix/1.0.1
git tag v1.0.1
git checkout develop
git merge --no-ff hotfix/1.0.1
git branch -d hotfix/1.0.1
# ===== 3. Trunk-Based Development(主干开发) =====
# 所有人直接向main提交,适合持续集成
# 1. 从main拉取最新代码
# 2. 小步开发,频繁提交
# 3. 通过PR或直接push到main
# 4. 使用feature flag控制功能可见性
常用Git技巧
# ===== 1. 暂存当前工作(stash) =====
# 临时保存当前修改,切换去做其他事
git stash # 暂存所有修改
git stash -u # 包括未追踪的文件
git stash save "功能开发中" # 带说明的暂存
git stash list # 查看暂存列表
git stash pop # 恢复最近的暂存并删除
git stash apply # 恢复但不删除暂存
git stash drop # 删除暂存
git stash clear # 清除所有暂存
# ===== 2. 查找引入Bug的提交 =====
git bisect start
git bisect bad # 标记当前版本有Bug
git bisect good v1.0.0 # 标记v1.0.0没有Bug
# Git会自动切换到中间版本,测试后:
git bisect good # 或 git bisect bad
# 重复直到找到引入Bug的提交
git bisect reset # 结束二分查找
# ===== 3. 修改历史提交 =====
# 交互式rebase(修改最近3次提交)
git rebase -i HEAD~3
# 可以: pick(保留) squash(合并) reword(改信息) edit(修改) drop(删除)
# ===== 4. Cherry-pick(摘樱桃) =====
# 将某个提交应用到当前分支
git cherry-pick <commit-hash>
git cherry-pick <hash1> <hash2> # 多个提交
# ===== 5. 查看某行代码是谁写的 =====
git blame file.py
git blame -L 10,20 file.py # 只看10-20行
# ===== 6. 清理未追踪的文件 =====
git clean -n # 预览将要删除的文件
git clean -f # 删除未追踪的文件
git clean -fd # 删除未追踪的文件和目录
git clean -fx # 包括.gitignore忽略的文件
总结
本教程系统介绍了Git版本控制的核心知识:
- 了解了Git的基本概念和安装配置方法
- 学会了仓库的初始化和克隆
- 掌握了add、commit、status、log等基本操作
- 学会了分支的创建、切换和合并
- 掌握了远程仓库的管理和代码推送拉取
- 学会了解决合并冲突
- 了解了.gitignore的配置方法
- 通过团队协作工作流实战掌握了Git的实战应用
Git学习建议:
- 多动手实践,在真实项目中使用Git
- 养成频繁提交的习惯,每次提交做一件事
- 写清晰的提交信息,未来会感谢自己
- 操作前先git status检查状态
- 重要操作前先备份(git branch backup)
- 学习使用图形化Git工具(如GitKraken、Sourcetree)