1/15
<

Git 版本控制系统

GIT从入门到精通的指南

准备好掌握现代软件开发的必备技能了吗?

讲师
王越洋
日期
2025年5月

什么是Git及其优势

Git核心特性

分布式系统

每个开发者都拥有完整的代码仓库副本

高效性能

速度快,占用空间小,本地操作不依赖网络

强大的分支管理

轻量高效的分支创建与合并

数据完整性

SHA-1哈希校验机制确保数据安全

Git的历史

  • 2005年由Linus Torvalds创建
  • 为Linux内核开发而设计
  • 取代BitKeeper作为Linux内核的版本控制系统
  • 在短短几年内成为最流行的版本控制系统

Git已成为现代软件开发的基础设施

Git vs 其他版本控制系统

特性 Git (分布式) SVN/CVS (集中式)
仓库结构 每个开发者拥有完整副本 单一中央服务器
离线工作 完全支持 不支持
分支管理 轻量高效 较重,复制整个目录
性能 快速(本地操作) 较慢(网络依赖)
数据安全性 多副本,高安全性 单点故障风险

安装配置与基础概念

安装Git

Windows

https://git-scm.com/download/win

或使用: winget install --id Git.Git

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

Git的四个区域

工作区 (Working Directory)

项目文件夹中实际看到和编辑的文件

暂存区 (Staging Area / Index)

临时保存即将提交的修改,位于.git目录

本地仓库 (Local Repository)

.git目录,保存项目的完整历史

远程仓库 (Remote Repository)

托管在服务器上的版本,如GitHub上的仓库

Git的文件状态与对象

未跟踪 (Untracked)

Git不知道的新文件

已跟踪 (Tracked)

  • 未修改(Unmodified)
  • 已修改(Modified)
  • 已暂存(Staged)

Git对象模型

blob

文件内容对象

tree

目录结构对象

commit

提交信息对象

tag

标记对象

基本Git命令 (1)

创建仓库

// 初始化新仓库
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命令 (2)

提交更改

// 提交更改
git commit -m "提交信息"
git commit -a -m "提交信息"  # 跳过暂存区,直接提交所有已跟踪文件的修改
git commit --amend  # 修改最后一次提交

查看差异

// 查看差异
git diff  # 工作区与暂存区的差异
git diff --staged  # 暂存区与最新提交的差异
git diff HEAD  # 工作区与最新提交的差异
git diff commit1 commit2  # 两次提交之间的差异

.gitignore 文件

# 忽略所有 .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命令 (3)

撤销操作

// 撤销工作区修改,恢复到上次提交或暂存的状态
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

安全地撤销公共分支上的提交

分支管理 (1)

分支的概念与原理

分支是Git最强大的功能之一,它允许开发者在不影响主代码的情况下进行并行开发。

  • 分支本质上是指向某个提交对象的可移动指针
  • 创建新分支只是创建了一个新指针,不涉及代码复制
  • HEAD指针指向当前工作的分支
  • 当提交时,当前分支指针会自动向前移动

分支操作几乎是瞬时的,鼓励频繁使用分支

查看分支

// 列出所有分支
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  # 删除远程仓库上的分支

分支管理 (2)

合并分支

// 合并到当前分支
git merge source-branch  # 将source-branch合并到当前分支

// 禁用快进合并(创建合并提交)
git merge --no-ff source-branch

// 压缩合并(将所有更改合并为一个提交)
git merge --squash source-branch

快进合并 (Fast-forward)

当目标分支是源分支的直接后代时,只是简单地移动指针

三方合并 (3-way merge)

当分支历史出现分叉时,创建一个新的合并提交

变基(Rebase)

// 基本变基操作
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  # 取消变基

Git工作流

集中式工作流

类似SVN的使用方式,所有开发者基于主分支(mainmaster)开发

  • 简单直接,易于理解
  • 适合小团队和简单项目
  • 冲突处理较频繁
  • 主分支可能不稳定

功能分支工作流

基于功能创建分支,完成后合并回主分支

  • 隔离开发工作,避免干扰
  • 主分支始终保持稳定
  • 便于代码审查和问题追踪
  • 适合大多数项目

Gitflow工作流

定义严格的分支模型,支持大型项目和持续部署

main/master

生产环境代码

develop

开发主分支

feature/*

特性分支

release/*

发布准备分支

hotfix/*

紧急修复分支

bugfix/*

Bug修复分支

Forking工作流

基于fork的协作模式,典型开源项目方式

  • 每个开发者有自己的远程仓库
  • 通过Pull Request贡献代码
  • 原始仓库权限控制严格
  • 适合开源项目和大型团队
  • 促进代码审查和质量控制

Git高级功能

贮藏 (Stash)

// 保存工作进度
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  # 删除所有贮藏

贮藏功能用于临时保存工作目录的修改,以便切换到其他任务。

Cherry-pick

// 选择性应用提交
git cherry-pick commit-hash  # 应用单个提交
git cherry-pick commit1..commit2  # 应用多个提交
git cherry-pick -x commit-hash  # 保留原始提交信息
git cherry-pick --no-commit commit-hash  # 不自动提交

从一个分支选择性地应用特定提交到另一个分支。

子模块 (Submodules)

// 添加子模块
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仓库的子目录。

Git Hooks

// 常见钩子
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内部原理探索

底层命令

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数据库

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

分支命名建议:

  • 使用小写字母、数字和连字符
  • 保持分支名称简短但有描述性
  • 包含问题跟踪系统的ID
  • 遵循团队约定的前缀

代码审查要点

  • 代码质量和编码标准

    检查是否符合项目的编码规范,命名约定等

  • 功能完整性

    验证是否实现了所有需求,边界条件处理

  • 测试覆盖

    确保有适当的单元测试、集成测试等

  • 安全隐患

    检查潜在的安全问题如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
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

Git工具生态

GUI客户端

跨平台

  • GitKraken
  • SourceTree
  • GitHub Desktop
  • VS Code Git

平台特定

  • Windows: TortoiseGit
  • macOS: Tower, Fork
  • Linux: GitEye, git-cola

代码托管平台

GitHub

最流行的Git托管平台

特色: Actions, Pages, Discussions

GitLab

可自托管,企业功能丰富

特色: CI/CD集成, 容器注册表

Gitee(码云)

国内领先托管平台

特色: 快速访问, 中文支持

Bitbucket

Atlassian产品,与Jira集成

特色: Pipelines, Trello集成

CI/CD与Git集成

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定义管道

Git扩展工具

代码质量工具

  • Husky: Git钩子管理
  • lint-staged: 对暂存文件运行linter
  • Commitlint: 检查提交信息格式
  • Conventional Commits: 提交消息标准

工作流辅助

  • git-flow: GitFlow工作流工具
  • git-town: 高级Git命令包装
  • git-extras: 实用命令集合
  • diff-so-fancy: 美化diff输出

实战演练示例

场景一: 功能开发流程

// 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

要点:

  • 从最新的主分支创建功能分支
  • 提交前确保代码符合质量标准
  • 使用变基保持提交历史整洁
  • 通过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

要点:

  • 使用stash保存当前工作状态
  • 从生产分支创建hotfix分支
  • 确保修复经过充分测试
  • 合并到主分支后可能需要同步到开发分支
  • 可能需要创建版本标签记录修复版本

场景三: 解决合并冲突

// 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

解决冲突工具:

  • VS Code内置冲突解决器
  • Beyond Compare
  • KDiff3
  • Meld

防止冲突策略:

  • 频繁同步主分支的更新
  • 减小提交的粒度
  • 避免多人同时修改同一文件
  • 合理规划代码模块化设计

资源与进阶学习

官方文档与书籍

  • Git官方文档

    最权威的Git资源

  • Pro Git中文版

    免费电子书,全面介绍Git

  • 《GitHub入门与实践》

    大塚弘记著

  • 《Git权威指南》

    蒋鑫著

在线学习资源

实用备忘单

练习项目

实践建议:

  • 创建个人项目用于练习Git命令
  • 参与开源项目,了解实际工作流
  • 尝试不同的分支策略
  • 模拟冲突并练习解决
  • 使用Git钩子实现自动化
  • 尝试建立CI/CD流程

记住:

Git学习是个循序渐进的过程,从基础命令开始,逐步掌握高级功能。实践是最好的学习方式!