Git 代码管理完整指南:从基础到实战

本文全面介绍 Git 版本控制系统,从基础概念到实际操作,再到常见问题解决,帮助你掌握 Git 的完整使用流程。


目录


一、Git 基础认知

1.1 什么是 Git

Git 定义

  • Git 是一个分布式版本控制系统(Distributed Version Control System)
  • 由 Linus Torvalds 在 2005 年开发,用于管理 Linux 内核开发
  • 目前最流行的版本控制工具

核心特点

  • 分布式:每个开发者都有完整的代码历史
  • 速度快:大部分操作在本地完成
  • 分支管理:强大的分支和合并功能
  • 数据完整性:使用 SHA-1 哈希保证数据完整性
  • 开源免费:完全开源,免费使用

与其他版本控制系统的区别

特性 Git SVN CVS
架构 分布式 集中式 集中式
速度 很慢
分支 强大 较弱 很弱
离线工作 ✅ 支持 ❌ 不支持 ❌ 不支持
学习曲线 中等 简单 简单

1.2 为什么需要 Git

版本控制的重要性

  1. 代码备份

    • 防止代码丢失
    • 可以恢复到任意历史版本
  2. 协作开发

    • 多人同时开发不冲突
    • 清晰的代码变更记录
  3. 问题追踪

    • 知道谁在什么时候修改了什么
    • 快速定位问题引入的提交
  4. 分支管理

    • 并行开发多个功能
    • 不影响主分支稳定性
  5. 代码审查

    • 通过 Pull Request 进行代码审查
    • 提高代码质量

实际应用场景

  • 个人项目:代码备份、版本管理
  • 团队协作:多人协作开发
  • 开源项目:GitHub、GitLab 上的项目
  • 企业开发:公司内部代码管理

1.3 Git 工作区域

四个核心区域

┌─────────────────────────────────────────┐
│  工作区 (Working Directory)             │
│  - 你正在编辑的文件                     │
│  - 未跟踪的文件                         │
└──────────────┬──────────────────────────┘
               │ git add
               ↓
┌──────────────┴──────────────────────────┐
│  暂存区 (Staging Area / Index)          │
│  - 准备提交的文件                       │
│  - git add 后的文件                     │
└──────────────┬──────────────────────────┘
               │ git commit
               ↓
┌──────────────┴──────────────────────────┐
│  本地仓库 (Local Repository)            │
│  - 已提交的代码历史                     │
│  - 所有分支和标签                       │
└──────────────┬──────────────────────────┘
               │ git push
               ↓
┌──────────────┴──────────────────────────┐
│  远程仓库 (Remote Repository)           │
│  - GitHub / GitLab / Gitee              │
│  - 团队共享的代码库                     │
└─────────────────────────────────────────┘

详细说明

  1. 工作区(Working Directory)

    • 你当前正在编辑的文件
    • 使用编辑器修改代码的地方
    • git status 显示未跟踪和已修改的文件
  2. 暂存区(Staging Area / Index)

    • 准备提交的文件临时存放区
    • git add 将文件添加到暂存区
    • git commit 将暂存区内容提交到本地仓库
  3. 本地仓库(Local Repository)

    • 完整的代码历史记录
    • 所有分支、标签、提交历史
    • 位于 .git 目录中
  4. 远程仓库(Remote Repository)

    • 团队共享的代码库
    • GitHub、GitLab、Gitee 等平台
    • git push 推送本地提交到远程

1.4 Git 核心概念

提交(Commit)

  • 代码变更的快照
  • 包含:作者、时间、提交信息、文件变更
  • 每个提交有唯一的 SHA-1 哈希值

分支(Branch)

  • 代码的独立开发线
  • 可以并行开发多个功能
  • 默认分支通常是 mainmaster

标签(Tag)

  • 标记重要的提交(如版本号)
  • 轻量标签:只是一个引用
  • 附注标签:包含更多信息

HEAD

  • 指向当前所在分支的最新提交
  • 移动 HEAD 可以切换分支或回退版本

1.5 分支策略

常见分支命名规范

master/main    - 生产环境分支(稳定版本,可随时部署)
develop        - 开发分支(集成分支,功能合并到这里)
feature/*      - 功能分支(新功能开发,如 feature/user-login)
hotfix/*       - 紧急修复分支(生产环境紧急修复)
release/*      - 发布分支(发布前的准备和测试)
bugfix/*       - Bug 修复分支(非紧急的 Bug 修复)

分支工作流示例

main (生产环境)
  │
  ├── develop (开发分支)
  │     │
  │     ├── feature/user-login
  │     ├── feature/payment
  │     └── bugfix/login-error
  │
  └── hotfix/security-patch (紧急修复)

1.6 Git 工作流程

基本工作流程

  1. 克隆或初始化仓库

    git clone <url>  # 或 git init
    
  2. 创建功能分支

    git checkout -b feature/new-feature
    
  3. 开发并提交

    git add .
    git commit -m "feat: 添加新功能"
    
  4. 推送到远程

    git push origin feature/new-feature
    
  5. 创建 Pull Request

    • 在 GitHub/GitLab 上创建 PR
    • 代码审查后合并
  6. 同步主分支

    git checkout main
    git pull
    

二、Git 安装与配置

1. 安装 Git

# Ubuntu/Debian
sudo apt-get install git

# CentOS/RHEL
sudo yum install git

# macOS
brew install git

# Windows
# 下载安装包:https://git-scm.com/download/win

2. 基础配置

# 设置用户名和邮箱(必须)
git config --global user.name "你的名字"
git config --global user.email "your.email@example.com"

# 设置默认编辑器
git config --global core.editor vim

# 设置默认分支名为 main
git config --global init.defaultBranch main

# 查看所有配置
git config --list

# 查看特定配置
git config user.name

# 配置文件位置
# 全局配置: ~/.gitconfig
# 项目配置: .git/config

3. 常用配置优化

# 显示中文文件名(不转义)
git config --global core.quotepath false

# 设置颜色
git config --global color.ui auto

# 设置别名
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 --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

# 忽略文件权限变化
git config --global core.filemode false

# 设置换行符转换(Windows)
git config --global core.autocrlf true

# 设置换行符转换(Linux/Mac)
git config --global core.autocrlf input

三、Git 常用命令

1. 仓库初始化

# 初始化本地仓库
git init

# 克隆远程仓库
git clone https://github.com/username/repo.git

# 克隆到指定目录
git clone https://github.com/username/repo.git my-project

# 克隆指定分支
git clone -b develop https://github.com/username/repo.git

2. 文件操作

# 查看状态
git status

# 查看状态(简洁模式)
git status -s

# 添加文件到暂存区
git add file.txt              # 添加单个文件
git add *.py                  # 添加所有 .py 文件
git add .                     # 添加所有变化的文件
git add -A                    # 添加所有变化(包括删除)
git add -u                    # 添加已跟踪文件的修改和删除

# 查看修改内容
git diff                      # 查看工作区与暂存区的差异
git diff --staged             # 查看暂存区与上次提交的差异
git diff HEAD                 # 查看工作区与上次提交的差异
git diff branch1 branch2      # 比较两个分支

# 撤销修改
git checkout -- file.txt      # 撤销工作区的修改
git restore file.txt          # 新版本撤销工作区修改
git reset HEAD file.txt       # 取消暂存
git restore --staged file.txt # 新版本取消暂存

# 删除文件
git rm file.txt               # 删除文件并暂存
git rm --cached file.txt      # 从 Git 中删除但保留本地文件

3. 提交操作

# 提交到本地仓库
git commit -m "提交说明"

# 添加并提交(已跟踪文件)
git commit -am "提交说明"

# 修改最后一次提交
git commit --amend

# 修改最后一次提交信息
git commit --amend -m "新的提交说明"

# 查看提交历史
git log                       # 详细日志
git log --oneline             # 单行简洁日志
git log --graph               # 图形化显示分支
git log -p                    # 显示每次提交的差异
git log -3                    # 显示最近 3 次提交
git log --author="张三"       # 查看指定作者的提交
git log --since="2 weeks ago" # 查看最近两周的提交
git log --grep="bug"          # 搜索提交信息

# 查看某个文件的修改历史
git log -- file.txt
git log -p file.txt

# 查看提交详情
git show commit_id

4. 分支操作

# 查看分支
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 checkout develop          # 切换分支
git switch develop            # 新版本切换分支

# 合并分支
git merge feature-login       # 将 feature-login 合并到当前分支
git merge --no-ff feature-login # 禁用快进合并(保留分支历史)

# 删除分支
git branch -d feature-login   # 删除已合并的分支
git branch -D feature-login   # 强制删除分支

# 重命名分支
git branch -m old-name new-name

# 设置分支跟踪
git branch --set-upstream-to=origin/develop develop

5. 远程仓库操作

# 查看远程仓库
git remote                    # 查看远程仓库名称
git remote -v                 # 查看远程仓库详细信息

# 添加远程仓库
git remote add origin https://github.com/username/repo.git

# 修改远程仓库地址
git remote set-url origin https://new-url.git

# 删除远程仓库
git remote remove origin

# 拉取远程更新
git fetch origin              # 获取远程更新但不合并
git fetch --all               # 获取所有远程分支更新

# 拉取并合并
git pull origin develop       # 拉取并合并指定分支
git pull                      # 拉取并合并当前分支

# 推送到远程
git push origin main          # 推送到指定分支
git push                      # 推送当前分支
git push -u origin main       # 推送并设置上游分支
git push --all                # 推送所有分支
git push --tags               # 推送所有标签

# 删除远程分支
git push origin --delete feature-login
git push origin :feature-login

6. 标签操作

# 查看标签
git tag                       # 列出所有标签
git tag -l "v1.*"             # 列出符合模式的标签

# 创建标签
git tag v1.0.0                # 轻量标签
git tag -a v1.0.0 -m "版本 1.0.0" # 附注标签

# 给历史提交打标签
git tag -a v0.9.0 commit_id

# 查看标签信息
git show v1.0.0

# 推送标签
git push origin v1.0.0        # 推送指定标签
git push origin --tags        # 推送所有标签

# 删除标签
git tag -d v1.0.0             # 删除本地标签
git push origin --delete v1.0.0 # 删除远程标签

7. 撤销与回退

# 撤销工作区修改
git checkout -- file.txt
git restore file.txt

# 撤销暂存
git reset HEAD file.txt
git restore --staged file.txt

# 回退版本
git reset --soft HEAD^        # 回退到上一版本(保留修改在暂存区)
git reset --mixed HEAD^       # 回退到上一版本(保留修改在工作区)默认
git reset --hard HEAD^        # 回退到上一版本(丢弃所有修改)

# 回退到指定版本
git reset --hard commit_id

# 恢复到某个版本但不删除历史
git revert commit_id

# 查看操作历史(可用于恢复误删的提交)
git reflog

8. 储藏操作

# 储藏当前修改
git stash                     # 储藏修改
git stash save "储藏说明"     # 储藏并添加说明

# 查看储藏列表
git stash list

# 应用储藏
git stash apply               # 应用最近的储藏
git stash apply stash@{0}     # 应用指定储藏
git stash pop                 # 应用并删除最近的储藏

# 删除储藏
git stash drop stash@{0}      # 删除指定储藏
git stash clear               # 删除所有储藏

# 查看储藏内容
git stash show
git stash show -p

四、.gitignore 文件

1. 基本语法

# .gitignore 文件示例

# 忽略所有 .log 文件
*.log

# 忽略所有 .pyc 文件
*.pyc

# 忽略整个目录
node_modules/
__pycache__/

# 忽略特定文件
config/database.yml

# 不忽略特定文件(!表示例外)
!important.log

# 忽略当前目录下的文件(不递归)
/TODO

# 忽略任意目录下的 build 文件夹
**/build/

2. Odoo 项目常用 .gitignore

# Odoo 开发常用 .gitignore

# Python
*.py[cod]
*$py.class
*.so
__pycache__/
*.egg-info/
dist/
build/

# Odoo
filestore/
sessions/
addons/

# 配置文件
*.conf
odoo.conf
openerp.conf

# 日志
*.log

# 数据库备份
*.sql
*.dump

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# 系统文件
.DS_Store
Thumbs.db

# 环境变量
.env
venv/
env/

五、实战场景

5.1 日常开发流程(详细步骤)

场景描述:作为团队成员,需要开发一个新功能并合并到主分支。

完整流程

# ========== 第一天:开始新功能 ==========

# 1. 同步最新代码
git checkout develop
git pull origin develop

# 2. 创建功能分支(命名规范:feature/功能名)
git checkout -b feature-user-login

# 3. 开始开发
# 编辑文件...
vim src/auth/login.py

# 4. 查看修改
git status
git diff

# 5. 提交代码(小步提交,每次一个逻辑单元)
git add src/auth/login.py
git commit -m "feat(auth): 添加登录页面UI"

# 继续开发...
git add src/auth/validator.py
git commit -m "feat(auth): 实现登录验证逻辑"

git add tests/test_login.py
git commit -m "test(auth): 添加登录功能测试"

# 6. 推送到远程
git push -u origin feature-user-login

# ========== 第二天:继续开发 ==========

# 1. 同步主分支(避免冲突)
git checkout develop
git pull origin develop

# 2. 切换回功能分支
git checkout feature-user-login

# 3. 合并主分支的更新(或使用 rebase)
git merge develop
# 如果有冲突,解决冲突后:
# git add .
# git commit -m "merge: 解决与 develop 的冲突"

# 4. 继续开发...
git add src/auth/session.py
git commit -m "feat(auth): 添加会话管理"

# 5. 推送更新
git push

# ========== 功能完成:准备合并 ==========

# 1. 最后一次同步主分支
git checkout develop
git pull origin develop

# 2. 切换回功能分支并合并最新代码
git checkout feature-user-login
git rebase develop  # 使用 rebase 保持历史整洁

# 3. 解决可能的冲突
# 如果有冲突,解决后:
# git add .
# git rebase --continue

# 4. 强制推送(因为 rebase 改变了历史)
git push --force-with-lease

# 5. 在 GitHub/GitLab 创建 Pull Request
# - 填写 PR 标题和描述
# - 请求代码审查
# - 等待审查和合并

# ========== PR 合并后:清理 ==========

# 1. 切换回主分支
git checkout develop

# 2. 拉取合并后的代码
git pull origin develop

# 3. 删除本地功能分支
git branch -d feature-user-login

# 4. 删除远程分支(如果还没自动删除)
git push origin --delete feature-user-login

关键要点

  • ✅ 功能分支命名清晰:feature/功能名
  • ✅ 小步提交,每次提交一个逻辑单元
  • ✅ 定期同步主分支,减少冲突
  • ✅ 使用 rebase 保持提交历史整洁
  • ✅ PR 合并后及时删除分支

5.2 解决合并冲突(详细步骤)

场景描述:你和同事同时修改了同一个文件,合并时出现冲突。

冲突类型

  1. 内容冲突:同一行代码被不同方式修改
  2. 修改/删除冲突:一方修改,另一方删除
  3. 添加/添加冲突:双方在不同位置添加了相同内容

解决步骤

# ========== 情况1:合并时冲突 ==========

# 1. 尝试合并
git checkout feature/user-login
git merge develop

# 输出:
# Auto-merging src/auth/login.py
# CONFLICT (content): Merge conflict in src/auth/login.py
# Automatic merge failed; fix conflicts and then commit the result.

# 2. 查看冲突状态
git status
# 输出:
# Unmerged paths:
#   both modified:   src/auth/login.py

# 3. 查看冲突文件内容
cat src/auth/login.py

# 冲突标记示例:
# <<<<<<< HEAD (当前分支:feature/user-login)
# def login(username, password):
#     # 你的实现
#     if validate_credentials(username, password):
#         create_session(username)
#         return True
#     return False
# =======
# def login(username, password):
#     # 同事的实现
#     user = get_user(username)
#     if user and check_password(user, password):
#         return True
#     return False
# >>>>>>> develop (要合并的分支)

# 4. 解决冲突(三种方式)

# 方式A:保留你的代码
# 删除冲突标记和同事的代码,保留你的代码

# 方式B:保留同事的代码
# 删除冲突标记和你的代码,保留同事的代码

# 方式C:合并双方代码(推荐)
# 手动合并,保留双方有用的部分:
def login(username, password):
    # 合并后的实现
    user = get_user(username)
    if user and check_password(user, password):
        create_session(username)
        return True
    return False

# 5. 删除所有冲突标记(<<<<<<<, =======, >>>>>>>)

# 6. 标记冲突已解决
git add src/auth/login.py

# 7. 完成合并
git commit -m "merge: 解决登录功能冲突,合并双方实现"

# ========== 情况2:Rebase 时冲突 ==========

# 1. 开始 rebase
git rebase develop

# 2. 遇到冲突
# CONFLICT (content): Merge conflict in src/auth/login.py

# 3. 解决冲突(同上)

# 4. 标记已解决
git add src/auth/login.py

# 5. 继续 rebase
git rebase --continue

# 如果想跳过当前提交
git rebase --skip

# 如果想放弃 rebase
git rebase --abort

# ========== 冲突解决工具 ==========

# 使用 VS Code 解决冲突
code src/auth/login.py
# VS Code 会高亮显示冲突,提供按钮选择保留哪一方

# 使用合并工具
git mergetool
# 会打开配置的合并工具(如 vimdiff, meld 等)

# ========== 预防冲突 ==========

# 1. 频繁同步主分支
git checkout develop
git pull origin develop
git checkout feature/user-login
git merge develop

# 2. 团队成员沟通,避免同时修改同一文件

# 3. 功能分支保持小而专注,快速合并

冲突解决策略

  • 保留双方代码:如果功能不冲突,可以都保留
  • 选择更优实现:如果功能冲突,选择更合适的实现
  • 重新实现:如果都不合适,可以重新实现
  • 团队讨论:复杂冲突可以团队讨论决定

3. 紧急修复 Bug

# 1. 从 master 创建 hotfix 分支
git checkout master
git checkout -b hotfix-critical-bug

# 2. 修复 Bug 并提交
git add .
git commit -m "fix: 修复关键安全漏洞"

# 3. 合并到 master
git checkout master
git merge --no-ff hotfix-critical-bug
git tag -a v1.0.1 -m "修复安全漏洞"

# 4. 同步到 develop
git checkout develop
git merge --no-ff hotfix-critical-bug

# 5. 推送
git push origin master
git push origin develop
git push origin --tags

# 6. 删除 hotfix 分支
git branch -d hotfix-critical-bug

5.4 代码回滚(多种场景)

场景1:还没推送,撤销最后一次提交

# 查看提交历史
git log --oneline
# abc1234 (HEAD -> feature/login) 最新提交
# def5678 上一次提交

# 方式1:保留修改在暂存区(可以重新提交)
git reset --soft HEAD^
git status  # 修改仍在暂存区

# 方式2:保留修改在工作区(需要重新 add)
git reset --mixed HEAD^  # 或 git reset HEAD^
git status  # 修改在工作区,未暂存

# 方式3:完全丢弃修改(危险!)
git reset --hard HEAD^
git status  # 所有修改都丢失

场景2:已推送,需要回滚但保留历史

# 查看提交历史
git log --oneline
# abc1234 (HEAD -> main, origin/main) 有问题的提交
# def5678 上一次提交

# 使用 revert 创建新提交来撤销更改(推荐)
git revert HEAD
# 会打开编辑器,编辑撤销说明
git push origin main

# 撤销多个提交
git revert HEAD~3..HEAD  # 撤销最近3次提交
git push origin main

# 撤销指定提交
git revert abc1234
git push origin main

场景3:本地分支完全混乱,重置为远程状态

# 1. 先备份当前分支(以防万一)
git branch backup-before-reset

# 2. 获取远程最新状态
git fetch origin

# 3. 查看远程和本地的差异
git log HEAD..origin/main  # 远程有但本地没有的提交
git log origin/main..HEAD  # 本地有但远程没有的提交

# 4. 完全重置为远程状态(丢弃所有本地修改)
git reset --hard origin/main

# 5. 清理未跟踪的文件(可选)
git clean -fd

场景4:回退到指定版本

# 1. 查看提交历史,找到目标版本
git log --oneline
# abc1234 最新提交
# def5678 目标版本
# ghi9012 更早的版本

# 2. 回退到目标版本
git reset --hard def5678

# 3. 如果已推送,需要强制推送(危险!)
git push --force origin main
# 或更安全的
git push --force-with-lease origin main

场景5:误删分支恢复

# 1. 查看操作历史
git reflog
# 输出:
# abc1234 HEAD@{0}: checkout: moving from develop to main
# def5678 HEAD@{1}: commit: 被删除分支的最后提交
# ghi9012 HEAD@{2}: checkout: moving from feature/login to develop

# 2. 找到被删除分支的提交 ID(def5678)

# 3. 恢复分支
git checkout -b recovered-feature-login def5678

# 或直接恢复提交
git cherry-pick def5678

场景6:恢复误删的文件

# 1. 查看文件删除历史
git log --diff-filter=D --summary | grep deleted_file.py

# 2. 找到删除该文件的提交
git log --all --full-history -- deleted_file.py

# 3. 从删除前的提交恢复文件
git checkout <commit_id>^ -- deleted_file.py

# 4. 提交恢复
git add deleted_file.py
git commit -m "restore: 恢复误删的文件"

回滚策略选择

场景 推荐方法 原因
未推送的提交 git reset 本地操作,不影响他人
已推送的提交 git revert 保留历史,安全
本地混乱 git reset --hard origin/main 快速恢复
误删分支 git reflog + checkout 可以恢复
误删文件 git checkout <commit>^ -- <file> 从历史恢复

5.5 多人协作最佳实践

核心原则

  1. 频繁同步:每天多次同步主分支
  2. 小步提交:每次提交一个逻辑单元
  3. 及时沟通:避免同时修改同一文件
  4. 代码审查:通过 PR 进行代码审查

完整工作流程

# ========== 每天开始工作 ==========

# 1. 同步最新代码(重要!)
git checkout develop
git pull origin develop

# 2. 查看是否有更新
git log HEAD..origin/develop  # 查看远程新提交

# ========== 创建功能分支 ==========

# 1. 从最新的 develop 创建分支
git checkout develop
git pull origin develop
git checkout -b feature/new-module

# 2. 推送到远程(建立跟踪)
git push -u origin feature/new-module

# ========== 开发过程中 ==========

# 1. 小步提交(每完成一个小功能就提交)
git add src/module/component1.py
git commit -m "feat(module): 实现组件1的基础功能"

git add src/module/component2.py
git commit -m "feat(module): 实现组件2的基础功能"

# 2. 定期同步主分支(每 2-3 小时一次)
git checkout develop
git pull origin develop
git checkout feature/new-module

# 方式A:使用 merge(保留分支历史)
git merge develop

# 方式B:使用 rebase(保持历史整洁,推荐)
git rebase develop
# 如果有冲突,解决后:
# git add .
# git rebase --continue

# 3. 推送更新
git push
# 如果使用了 rebase,需要强制推送
git push --force-with-lease

# ========== 功能完成,准备合并 ==========

# 1. 最后一次同步
git checkout develop
git pull origin develop
git checkout feature/new-module
git rebase develop

# 2. 运行测试确保一切正常
# pytest tests/
# npm test
# 等等...

# 3. 推送最终版本
git push --force-with-lease

# 4. 创建 Pull Request
# - 在 GitHub/GitLab 上创建 PR
# - 填写清晰的标题和描述
# - 请求相关同事审查
# - 等待审查和合并

# ========== PR 审查和修改 ==========

# 1. 审查者提出修改意见

# 2. 在功能分支上修改
git checkout feature/new-module
# 修改代码...
git add .
git commit -m "fix(module): 根据审查意见修改"
git push

# 3. PR 会自动更新,无需重新创建

# ========== PR 合并后 ==========

# 1. 切换回主分支
git checkout develop

# 2. 拉取合并后的代码
git pull origin develop

# 3. 删除本地功能分支
git branch -d feature/new-module

# 4. 删除远程分支(如果还没自动删除)
git push origin --delete feature/new-module

# 5. 清理远程跟踪分支
git remote prune origin

团队协作规范

  1. 分支命名规范

    feature/功能名      # 新功能
    bugfix/问题描述     # Bug 修复
    hotfix/紧急问题     # 紧急修复
    refactor/重构内容   # 代码重构
    docs/文档内容       # 文档更新
    
  2. 提交信息规范

    # 格式:<type>(<scope>): <subject>
    feat(auth): 添加用户登录功能
    fix(api): 修复接口返回值错误
    docs(readme): 更新安装说明
    refactor(utils): 重构工具函数
    
  3. 代码审查检查清单

    • ✅ 代码逻辑正确
    • ✅ 没有明显的 Bug
    • ✅ 遵循代码规范
    • ✅ 有适当的注释
    • ✅ 测试通过
    • ✅ 没有敏感信息
  4. 冲突预防

    • ✅ 频繁同步主分支
    • ✅ 功能分支保持小而专注
    • ✅ 团队成员沟通,避免同时修改同一文件
    • ✅ 使用 rebase 保持历史整洁
  5. 紧急情况处理

    # 如果主分支有紧急更新需要同步
    git checkout feature/my-feature
    git rebase develop
    # 解决冲突...
    git push --force-with-lease
    

六、高级技巧

1. Git Rebase

# 变基到 develop
git checkout feature-branch
git rebase develop

# 交互式变基(整理提交历史)
git rebase -i HEAD~3          # 整理最近 3 次提交

# 变基时解决冲突
git rebase --continue         # 解决冲突后继续
git rebase --skip             # 跳过当前提交
git rebase --abort            # 放弃变基

2. Cherry-pick

# 挑选特定提交到当前分支
git cherry-pick commit_id

# 挑选多个提交
git cherry-pick commit_id1 commit_id2

# 挑选提交但不自动提交
git cherry-pick -n commit_id

3. 子模块

# 添加子模块
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 init
git submodule update

# 更新所有子模块
git submodule update --remote

4. 查找问题

# 二分查找引入 Bug 的提交
git bisect start
git bisect bad                # 当前版本有问题
git bisect good v1.0.0        # v1.0.0 版本正常
# Git 会自动切换到中间版本,测试后标记
git bisect good               # 或 git bisect bad
# 重复直到找到问题提交
git bisect reset              # 结束查找

# 查找文件每一行的最后修改
git blame file.txt

# 查找文件某几行的修改历史
git blame -L 10,20 file.txt

七、常见问题解决

1. 推送被拒绝

# 错误: Updates were rejected because the remote contains work
# 解决方案1: 先拉取再推送
git pull --rebase origin main
git push

# 解决方案2: 强制推送(慎用!)
git push -f origin main

2. 文件大小写问题

# Git 默认不识别大小写变化
git config core.ignorecase false

# 重命名文件
git mv oldname.txt NewName.txt

3. 清理大文件

# 查找大文件
git rev-list --objects --all | \
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
  sed -n 's/^blob //p' | \
  sort --numeric-sort --key=2 | \
  tail -n 10

# 从历史中删除文件
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/large/file' \
  --prune-empty --tag-name-filter cat -- --all

# 或使用 BFG Repo-Cleaner(推荐)
java -jar bfg.jar --delete-files large-file.zip repo.git

4. 修改提交作者

# 修改最后一次提交的作者
git commit --amend --author="New Author <email@example.com>"

# 修改历史提交的作者
git filter-branch --env-filter '
if [ "$GIT_COMMITTER_EMAIL" = "old@example.com" ]; then
    export GIT_COMMITTER_NAME="New Name"
    export GIT_COMMITTER_EMAIL="new@example.com"
fi
' -- --all

八、Git 工作流

1. Git Flow

# 主分支
master/main   - 生产环境
develop       - 开发环境

# 辅助分支
feature/*     - 新功能 (从 develop 创建,合并回 develop)
release/*     - 发布准备 (从 develop 创建,合并到 master 和 develop)
hotfix/*      - 紧急修复 (从 master 创建,合并到 master 和 develop)

2. GitHub Flow

# 更简单的流程
main          - 主分支(随时可部署)
feature/*     - 功能分支(从 main 创建,通过 PR 合并回 main)

3. 提交信息规范

# 格式: <type>(<scope>): <subject>

# type 类型:
feat:     新功能
fix:      修复 Bug
docs:     文档更新
style:    代码格式(不影响功能)
refactor: 重构
test:     测试相关
chore:    构建/工具相关

# 示例:
git commit -m "feat(auth): 添加用户登录功能"
git commit -m "fix(api): 修复接口返回值错误"
git commit -m "docs(readme): 更新安装说明"

九、常见案例详解

9.1 案例一:新项目初始化到首次推送

场景:你创建了一个新项目,需要初始化 Git 并推送到远程仓库。

步骤详解

# 1. 在项目目录初始化 Git
cd my-project
git init

# 2. 创建 .gitignore 文件(重要!)
cat > .gitignore << EOF
# Python
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
venv/
env/

# IDE
.vscode/
.idea/
*.swp

# 系统文件
.DS_Store
Thumbs.db
EOF

# 3. 添加所有文件到暂存区
git add .

# 4. 首次提交
git commit -m "feat: 初始化项目"

# 5. 添加远程仓库(以 GitHub 为例)
git remote add origin https://github.com/username/my-project.git

# 6. 重命名分支为 main(如果默认是 master)
git branch -M main

# 7. 推送到远程并设置上游分支
git push -u origin main

注意事项

  • ✅ 首次提交前创建 .gitignore,避免提交不必要的文件
  • ✅ 使用 -u 参数设置上游分支,后续可以直接 git push
  • ✅ 提交信息要清晰,遵循提交规范

9.2 案例二:日常功能开发完整流程

场景:开发一个新功能(用户登录),从创建分支到合并的完整流程。

步骤详解

# 1. 每天开始工作前,同步最新代码
git checkout develop
git pull origin develop

# 2. 创建功能分支
git checkout -b feature/user-login

# 3. 开发功能(多次提交)
# 编辑文件...
git add src/auth/login.py
git commit -m "feat(auth): 添加登录页面"

# 继续开发...
git add src/auth/validator.py
git commit -m "feat(auth): 添加登录验证逻辑"

# 4. 开发过程中,定期同步主分支(避免冲突)
git checkout develop
git pull origin develop
git checkout feature/user-login
git merge develop  # 或使用 git rebase develop

# 5. 功能开发完成,推送到远程
git push -u origin feature/user-login

# 6. 在 GitHub/GitLab 创建 Pull Request
# - 填写 PR 描述
# - 请求代码审查
# - 等待合并

# 7. PR 合并后,清理本地分支
git checkout develop
git pull origin develop  # 拉取合并后的代码
git branch -d feature/user-login  # 删除本地分支

最佳实践

  • ✅ 功能分支命名清晰:feature/功能名
  • ✅ 提交粒度要小,每次提交一个逻辑单元
  • ✅ 定期同步主分支,减少冲突
  • ✅ PR 合并后及时删除分支

9.3 案例三:解决合并冲突

场景:你和同事同时修改了同一个文件,合并时出现冲突。

冲突示例

# 1. 尝试合并时发现冲突
git checkout feature/user-login
git merge develop

# 输出:
# Auto-merging src/auth/login.py
# CONFLICT (content): Merge conflict in src/auth/login.py
# Automatic merge failed; fix conflicts and then commit the result.

解决步骤

# 2. 查看冲突文件
git status
# 会显示:both modified: src/auth/login.py

# 3. 打开冲突文件,查看冲突标记
cat src/auth/login.py

# 冲突标记示例:
# <<<<<<< HEAD (当前分支)
# def login(username, password):
#     # 你的代码
#     return True
# =======
# def login(username, password):
#     # 同事的代码
#     return False
# >>>>>>> develop (要合并的分支)

# 4. 手动解决冲突(选择保留的代码,删除冲突标记)
# 编辑文件,保留需要的代码:
def login(username, password):
    # 合并后的代码
    if validate_user(username, password):
        return True
    return False

# 5. 标记冲突已解决
git add src/auth/login.py

# 6. 完成合并
git commit -m "merge: 解决登录功能冲突"

冲突解决策略

  • 保留双方代码:如果功能不冲突,可以都保留
  • 选择一方代码:如果功能冲突,选择更合适的实现
  • 重新实现:如果都不合适,可以重新实现

9.4 案例四:紧急修复生产环境 Bug

场景:生产环境发现严重 Bug,需要立即修复。

步骤详解

# 1. 从生产分支(main)创建 hotfix 分支
git checkout main
git pull origin main  # 确保是最新代码
git checkout -b hotfix/security-vulnerability

# 2. 修复 Bug
# 编辑文件修复问题...
git add src/security/fix.py
git commit -m "fix(security): 修复安全漏洞 CVE-2024-xxx"

# 3. 测试修复(重要!)
# 运行测试确保修复有效

# 4. 合并到 main(生产环境)
git checkout main
git merge --no-ff hotfix/security-vulnerability
git tag -a v1.0.1 -m "修复安全漏洞"
git push origin main
git push origin --tags

# 5. 同步到 develop(开发分支)
git checkout develop
git merge --no-ff hotfix/security-vulnerability
git push origin develop

# 6. 删除 hotfix 分支
git branch -d hotfix/security-vulnerability
git push origin --delete hotfix/security-vulnerability

注意事项

  • ✅ 从生产分支创建,确保修复基于生产代码
  • ✅ 修复后必须测试
  • ✅ 同时合并到 main 和 develop
  • ✅ 打标签标记版本

9.5 案例五:误提交了敏感信息

场景:不小心提交了密码、API Key 等敏感信息。

解决步骤

# 1. 如果还没推送,修改最后一次提交
git commit --amend
# 编辑文件,删除敏感信息
git add .
git commit --amend --no-edit

# 2. 如果已经推送,需要从历史中删除
# 方法1:使用 git filter-branch(不推荐,慢)
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch config/secrets.yml' \
  --prune-empty --tag-name-filter cat -- --all

# 方法2:使用 BFG Repo-Cleaner(推荐,快)
# 下载 BFG: https://rtyley.github.io/bfg-repo-cleaner/
java -jar bfg.jar --delete-files secrets.yml repo.git
cd repo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# 3. 强制推送(危险!需要团队协调)
git push --force --all
git push --force --tags

# 4. 通知团队成员重新克隆仓库

预防措施

  • ✅ 使用 .gitignore 忽略敏感文件
  • ✅ 使用环境变量存储敏感信息
  • ✅ 提交前检查 git diff 查看变更
  • ✅ 使用 Git hooks 检查敏感信息

9.6 案例六:回退到之前的版本

场景:最新版本有问题,需要回退到之前的稳定版本。

情况1:还没推送,只回退本地

# 查看提交历史
git log --oneline

# 回退到上一个提交(保留修改)
git reset --soft HEAD^

# 回退到上一个提交(保留修改在工作区)
git reset --mixed HEAD^  # 或 git reset HEAD^

# 回退到上一个提交(丢弃所有修改)
git reset --hard HEAD^

# 回退到指定提交
git reset --hard <commit_id>

情况2:已经推送,需要回退但保留历史

# 使用 revert 创建新的提交来撤销更改
git revert HEAD  # 撤销最后一次提交
git revert <commit_id>  # 撤销指定提交

# 推送到远程
git push origin main

情况3:完全重置到远程状态

# 放弃所有本地修改,完全同步远程
git fetch origin
git reset --hard origin/main

9.7 案例七:修改历史提交信息

场景:提交信息写错了,需要修改。

修改最后一次提交

# 只修改提交信息
git commit --amend -m "新的提交信息"

# 修改提交信息和作者
git commit --amend -m "新的提交信息" --author="新作者 <email>"

# 修改提交的文件(添加遗漏的文件)
git add forgotten_file.py
git commit --amend --no-edit  # 不修改提交信息

修改历史提交(交互式 rebase)

# 修改最近 3 次提交
git rebase -i HEAD~3

# 会打开编辑器,显示:
# pick abc1234 第一次提交
# pick def5678 第二次提交
# pick ghi9012 第三次提交

# 将 pick 改为 reword(或 r)来修改提交信息:
# pick abc1234 第一次提交
# reword def5678 第二次提交  # 修改这次提交的信息
# pick ghi9012 第三次提交

# 保存退出,Git 会再次打开编辑器让你修改提交信息

9.8 案例八:找回误删的文件或提交

场景:误删了文件或提交,需要恢复。

恢复误删的文件

# 1. 查看删除历史
git log --diff-filter=D --summary

# 2. 找到删除该文件的提交
git log --all --full-history -- path/to/file

# 3. 恢复文件(从删除前的提交)
git checkout <commit_id>^ -- path/to/file

# 4. 提交恢复
git add path/to/file
git commit -m "restore: 恢复误删的文件"

恢复误删的提交

# 1. 查看操作历史
git reflog

# 输出示例:
# abc1234 HEAD@{0}: commit: 最新提交
# def5678 HEAD@{1}: reset: moving to HEAD~1
# ghi9012 HEAD@{2}: commit: 被删除的提交

# 2. 找到被删除的提交 ID(ghi9012)

# 3. 恢复提交
git checkout -b recovered-branch ghi9012

# 或直接恢复
git cherry-pick ghi9012

9.9 案例九:处理大文件问题

场景:不小心提交了大文件(视频、数据库备份等),导致仓库过大。

查找大文件

# 查找仓库中的大文件
git rev-list --objects --all | \
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
  sed -n 's/^blob //p' | \
  sort --numeric-sort --key=2 | \
  tail -n 10

删除大文件

# 方法1:使用 git filter-branch
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/large-file.zip' \
  --prune-empty --tag-name-filter cat -- --all

# 方法2:使用 BFG Repo-Cleaner(推荐)
java -jar bfg.jar --delete-files large-file.zip repo.git

# 清理
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# 强制推送(需要团队协调)
git push --force --all

预防措施

  • ✅ 使用 .gitignore 忽略大文件
  • ✅ 使用 Git LFS(Large File Storage)管理大文件
  • ✅ 提交前检查文件大小

9.10 案例十:多人协作避免冲突

场景:多人同时开发,如何避免频繁冲突。

最佳实践流程

# 1. 每天开始工作前
git checkout develop
git pull origin develop  # 拉取最新代码

# 2. 创建功能分支
git checkout -b feature/my-feature

# 3. 开发过程中,定期同步主分支
# 每 2-3 小时同步一次
git checkout develop
git pull origin develop
git checkout feature/my-feature
git rebase develop  # 使用 rebase 保持历史整洁

# 4. 提交前再次同步
git checkout develop
git pull origin develop
git checkout feature/my-feature
git rebase develop

# 5. 推送功能分支
git push -u origin feature/my-feature

# 6. 如果推送被拒绝(远程有更新)
git pull --rebase origin feature/my-feature
git push

减少冲突的技巧

  • ✅ 频繁同步主分支(每天多次)
  • ✅ 功能分支保持小而专注
  • ✅ 团队成员沟通,避免同时修改同一文件
  • ✅ 使用 git rebase 保持历史整洁

十、常用命令速查表

10.1 配置命令

# 基础配置
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
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

10.2 仓库操作

# 初始化
git init
git clone <url>
git clone -b <branch> <url>

# 远程仓库
git remote -v
git remote add origin <url>
git remote set-url origin <url>
git remote remove origin

10.3 文件操作

# 状态查看
git status
git status -s
git diff
git diff --staged
git diff HEAD

# 添加文件
git add <file>
git add .
git add -A
git add -u

# 提交
git commit -m "message"
git commit -am "message"  # 已跟踪文件
git commit --amend

10.4 分支操作

# 查看分支
git branch
git branch -r
git branch -a
git branch -v

# 创建和切换
git branch <name>
git checkout <branch>
git checkout -b <branch>
git switch <branch>
git switch -c <branch>

# 合并和删除
git merge <branch>
git merge --no-ff <branch>
git branch -d <branch>
git branch -D <branch>

10.5 远程操作

# 拉取
git fetch origin
git fetch --all
git pull
git pull origin <branch>
git pull --rebase origin <branch>

# 推送
git push
git push origin <branch>
git push -u origin <branch>
git push --all
git push --tags
git push --force  # 慎用!

10.6 撤销操作

# 撤销工作区
git checkout -- <file>
git restore <file>

# 撤销暂存
git reset HEAD <file>
git restore --staged <file>

# 回退版本
git reset --soft HEAD^
git reset --mixed HEAD^
git reset --hard HEAD^
git reset --hard <commit_id>
git revert <commit_id>

10.7 查看历史

# 提交历史
git log
git log --oneline
git log --graph
git log -p
git log -3
git log --author="name"
git log --since="2 weeks ago"
git log --grep="keyword"

# 查看文件历史
git log -- <file>
git log -p <file>
git blame <file>

10.8 储藏操作

# 储藏
git stash
git stash save "message"
git stash list

# 应用储藏
git stash apply
git stash apply stash@{0}
git stash pop

# 删除储藏
git stash drop stash@{0}
git stash clear

10.9 标签操作

# 查看标签
git tag
git tag -l "v1.*"

# 创建标签
git tag v1.0.0
git tag -a v1.0.0 -m "message"
git tag -a v1.0.0 <commit_id>

# 推送标签
git push origin v1.0.0
git push origin --tags

# 删除标签
git tag -d v1.0.0
git push origin --delete v1.0.0

10.10 高级操作

# Rebase
git rebase <branch>
git rebase -i HEAD~3
git rebase --continue
git rebase --abort

# Cherry-pick
git cherry-pick <commit_id>
git cherry-pick -n <commit_id>

# 查找问题
git bisect start
git bisect good <commit>
git bisect bad <commit>
git bisect reset

# 子模块
git submodule add <url> <path>
git submodule init
git submodule update

总结

Git 是一个强大的版本控制工具,掌握它需要:

  1. 理解核心概念:工作区、暂存区、仓库、分支
  2. 熟练常用命令:add、commit、push、pull、merge
  3. 掌握工作流程:日常开发、冲突解决、紧急修复
  4. 遵循最佳实践:提交规范、分支策略、代码审查

学习建议

  • 从基础命令开始,逐步深入
  • 多实践,在实际项目中应用
  • 遇到问题先查文档,再搜索解决方案
  • 遵循团队规范,保持提交历史整洁

希望这份指南能帮助你掌握 Git,提高开发效率!