Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • git 使用指南

    • 概念
      • 三区模型
      • 提交对象
      • HEAD 与引用
      • 分支
      • 合并提交
      • 第一父路径
      • 祖先路径
    • 命令
      • 基础操作
      • 初始化和克隆
      • 文件操作
      • 提交操作
      • 查看状态和差异
      • 分支操作
      • 合并与变基
      • 合并 (Merge)
      • 变基 (Rebase)
      • 远程操作
      • 其他常用命令
      • 标签
      • cherry-pick
      • stash
      • reset 与 revert
    • 底层命令
      • git rev-list
      • 其他底层命令
    • 配置
      • 配置级别
      • 基本配置
      • 别名配置
      • 推荐配置
      • 高级配置
    • 工作流
      • 基本工作流程
      • Git Flow 工作流
      • 提交信息规范
    • 故障排除
      • 常见问题
      • 解决冲突
      • 恢复和清理
      • 性能优化
    • 技巧
      • 别名和脚本
      • 搜索和查找
      • 高级查询
      • 钩子 (Hooks)
      • 分支管理技巧
    • 实战
      • 场景1:团队协作开发新功能
      • 场景2:紧急修复生产环境 Bug
      • 场景3:整理混乱的提交历史
      • 场景4:恢复误删的提交
      • 场景5:同时开发多个功能
      • 场景6:代码审查和反馈
    • 最佳实践
      • 提交规范
      • 分支管理
      • 协作开发
      • 安全考虑
    • 资源
      • 官方文档
      • 在线教程
      • 工具
      • 社区
  • other
  • tool
Jacky
2019-05-20
目录

git 使用指南

Git 是一个分布式版本控制系统,用于跟踪文件的变化。它最初由 Linus Torvalds 为 Linux 内核开发而创建。

  • Learn Git Online (opens new window)
  • Git 官方文档 (opens new window)

# 概念

# 三区模型

Git 有三个主要区域:

  1. 工作区 (Working Directory): 你实际编辑文件的地方
  2. 暂存区 (Staging Area/Index): 准备提交的文件临时存储区域
  3. 仓库 (Repository): 包含所有提交历史的数据库
# 查看当前状态
git status

# 添加文件到暂存区
git add <file>

# 提交到仓库
git commit -m "commit message"
1
2
3
4
5
6
7
8

文件状态流转:

未跟踪 (Untracked)
    ↓ git add
已暂存 (Staged)
    ↓ git commit
已提交 (Committed)
    ↓ 修改文件
已修改 (Modified)
    ↓ git add
已暂存 (Staged)
1
2
3
4
5
6
7
8
9

# 提交对象

提交是 Git 中最重要的概念,它代表项目在某个时间点的快照。

提交对象结构:

# 查看提交对象
git cat-file -p <commit-hash>

# 输出示例:
# tree abc123...           # 指向项目快照的树对象
# parent def456...         # 父提交(可能有多个)
# author Name <email>      # 作者信息
# committer Name <email>   # 提交者信息
# 
# 提交信息
1
2
3
4
5
6
7
8
9
10

提交对象包含:

  • 项目快照(tree 对象)
  • 父提交引用(普通提交 1 个,合并提交 2+ 个)
  • 作者信息
  • 提交时间
  • 提交信息

# HEAD 与引用

HEAD 指针是一个特殊的指针,指向当前所在的分支或提交。

# 查看 HEAD 指向
cat .git/HEAD

# HEAD 的不同引用方式
HEAD        # 当前提交
HEAD~1      # 父提交
HEAD~2      # 祖父提交
HEAD^       # 父提交(用于合并提交的第一个父提交)
HEAD^2      # 合并提交的第二个父提交
1
2
3
4
5
6
7
8
9

Detached HEAD 状态:

当 HEAD 直接指向某个提交而不是分支时,就处于 detached HEAD 状态。

# 切换到特定提交(进入 detached HEAD)
git checkout <commit-hash>

# 从 detached HEAD 创建新分支
git checkout -b new-branch

# 返回到分支
git checkout main
1
2
3
4
5
6
7
8

引用系统:

引用是指向提交的指针,主要包括:

  1. 分支引用: .git/refs/heads/ - 可变指针
  2. 远程引用: .git/refs/remotes/ - 远程分支的本地副本
  3. 标签引用: .git/refs/tags/ - 不可变指针
# 查看所有引用
git show-ref

# 查看特定引用指向的提交
git rev-parse main
git rev-parse HEAD

# 查看分支指向的提交
cat .git/refs/heads/main
# 输出:abc123def456...(一个 40 字符的 SHA-1 哈希)
1
2
3
4
5
6
7
8
9
10

# 分支

分支只是一个指向提交对象的可变指针,创建分支非常轻量(只有 41 字节)。

# 创建分支
git branch <branch-name>

# 切换分支
git checkout <branch-name>
git switch <branch-name>          # 新命令

# 创建并切换
git checkout -b <branch-name>
git switch -c <branch-name>       # 新命令

# 查看分支
git branch              # 本地分支
git branch -r           # 远程分支
git branch -a           # 所有分支
git branch -vv          # 详细信息

# 删除分支
git branch -d <branch-name>      # 安全删除
git branch -D <branch-name>      # 强制删除

# 重命名分支
git branch -m <old-name> <new-name>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 合并提交

合并提交与普通提交的区别在于它有多个父提交。

# 普通提交
A---B---C
    ↑
    只有一个父提交

# 合并提交
A---B---C---M
     \     /
      D---E
      ↑   ↑
      第二父提交和第一父提交
1
2
3
4
5
6
7
8
9
10
11
# 查看合并提交的父提交
git log --pretty=%P -1 <merge-commit>

# 查看第一父提交
git log --first-parent

# 查看第二父提交
git show <merge-commit>^2
1
2
3
4
5
6
7
8

合并类型:

  1. 快进合并 (Fast-forward):目标分支是当前分支的直接后继,指针直接移动
  2. 三方合并 (3-way merge):两个分支都有新提交,创建新的合并提交
  3. 压缩合并 (Squash merge):将多个提交压缩为一个

# 第一父路径

第一父路径是指沿着每个合并提交的第一个父节点追溯的路径,代表主线分支的演进历史。

# 合并前的历史
A---B---C (main)
     \
      D---E (feature)

# 执行 git merge feature 后
A---B---C---M (main)
     \     /
      D---E (feature)
1
2
3
4
5
6
7
8
9

在合并提交 M 中:

  • 第一父节点 (First Parent): C - 当前所在的分支(main)
  • 第二父节点 (Second Parent): E - 被合并进来的分支(feature)
# 查看第一父路径
git log --first-parent

# 查看完整历史
git log --oneline --graph --all
# *   M (HEAD -> main) Merge branch 'feature'
# |\
# | * Feature commit 2
# | * Feature commit 1
# * | Main commit 1
# |/
# * Initial commit

# 查看第一父路径(只看主分支演进)
git log --oneline --first-parent
# M (HEAD -> main) Merge branch 'feature'
# Main commit 1
# Initial commit
# 注意:Feature 的提交被忽略了

# 使用场景
git log --first-parent main                    # 查看主分支演进
git rev-list --first-parent --count main       # 统计主分支提交数
git log --first-parent --merges --oneline      # 查找合并点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 祖先路径

祖先路径是指从一个提交到另一个提交的直接祖先链,排除不在这条路径上的提交。

# 假设有这样的历史
A---B---C---D---E (main)
     \         /
      F---G---H (feature)
     /
    X---Y (other)

# git rev-list B..E
# 输出:E, D, C, H, G, F(所有可达的提交)

# git rev-list B..E --ancestry-path
# 输出:E, D, C, H, G(只包括从 B 到 E 的祖先路径)
# 排除了 X, Y(不在祖先路径上)
1
2
3
4
5
6
7
8
9
10
11
12
13
# 查找提交何时被合并
git rev-list <commit>..main --ancestry-path --merges

# 查看功能分支的合并历史
git log <commit>..main --ancestry-path --oneline

# 统计祖先路径上的提交数
git rev-list --count <commit>..main --ancestry-path
1
2
3
4
5
6
7
8

# 命令

# 基础操作

# 初始化和克隆

# 初始化新仓库
git init

# 克隆远程仓库
git clone <repository-url>
git clone -b <branch-name> <repository-url>    # 克隆特定分支
git clone --depth 1 <repository-url>           # 浅克隆
1
2
3
4
5
6
7

# 文件操作

# 添加文件到暂存区
git add <file>           # 添加特定文件
git add .                # 添加所有修改的文件
git add -A               # 添加所有文件(包括删除的)

# 从暂存区移除文件
git reset HEAD <file>
git restore --staged <file>    # 新命令

# 删除文件
git rm <file>            # 删除文件并添加到暂存区
git rm --cached <file>   # 从版本控制中移除,但保留本地文件
1
2
3
4
5
6
7
8
9
10
11
12

# 提交操作

# 创建提交
git commit -m "提交信息"
git commit -am "提交信息"        # 跳过暂存区,直接提交已跟踪文件

# 修改最后一次提交
git commit --amend
git commit --amend --no-edit     # 不修改提交信息

# 查看提交历史
git log
git log --oneline
git log --graph --oneline --all
git log --pretty=format:'%h - %an, %ar : %s'
git log --since="2024-01-01" --until="2024-12-31"
git log --author="username"
git log -- <file-path>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 查看状态和差异

# 查看当前状态
git status
git status -s            # 简短格式

# 查看差异
git diff                 # 工作区 vs 暂存区
git diff --staged        # 暂存区 vs 最后一次提交
git diff --cached        # 同上
git diff branch1..branch2    # 比较两个分支
git diff commit1 commit2     # 比较两个提交
git diff --name-only     # 只显示文件名
git diff --stat          # 显示统计信息

# 查看提交内容
git show                 # 查看最新提交
git show <commit-hash>   # 查看特定提交
git show <commit-hash>:<file-path>  # 查看特定文件的历史
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 分支操作

# 切换分支
git checkout <branch-name>
git switch <branch-name>

# 切换到上一个分支
git checkout -
git switch -

# 查看分支关系
git log --graph --oneline --all --decorate
1
2
3
4
5
6
7
8
9
10

# 合并与变基

# 合并 (Merge)

# 合并分支到当前分支
git merge <branch-name>

# 合并策略
git merge --no-ff <branch-name>  # 禁用快进合并
git merge --squash <branch-name> # 压缩合并

# 取消合并
git merge --abort
1
2
3
4
5
6
7
8
9

# 变基 (Rebase)

变基是重写提交历史的方法,将一个分支的提交"重新应用"到另一个分支上,创建更线性的历史。

# 变基操作
git rebase <base-branch>

# 交互式变基
git rebase -i <commit-hash>

# 继续/跳过/取消变基
git rebase --continue
git rebase --skip
git rebase --abort
1
2
3
4
5
6
7
8
9
10

变基 vs 合并:

特性 变基 (Rebase) 合并 (Merge)
历史记录 线性、清晰 保留分支结构
提交数量 较少 可能产生合并提交
安全性 重写历史,需谨慎 安全,不改变历史
适用场景 个人分支整理 公共分支合并

⚠️ 重要提醒:不要对公共分支进行变基,会影响其他协作者。

# 远程操作

# 查看远程仓库
git remote -v

# 添加/移除/重命名远程仓库
git remote add <name> <url>
git remote remove <name>
git remote rename <old-name> <new-name>
git remote set-url <name> <new-url>

# 推送到远程
git push <remote> <branch>
git push origin main
git push --force-with-lease  # 更安全的强制推送
git push origin --delete <branch-name>  # 删除远程分支

# 拉取更新
git pull <remote> <branch>
git pull origin main

# 获取远程更新(不合并)
git fetch <remote>
git fetch --all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 其他常用命令

# 标签

# 创建标签
git tag <tag-name>
git tag -a <tag-name> -m "标签信息"

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

# 删除标签
git tag -d <tag-name>

# 推送标签
git push origin <tag-name>
git push origin --tags
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# cherry-pick

# 应用特定提交
git cherry-pick <commit-hash>
git cherry-pick <commit1> <commit2>
git cherry-pick <start-commit>..<end-commit>

# 只应用修改,不创建提交
git cherry-pick -n <commit-hash>

# 继续/取消 cherry-pick
git cherry-pick --continue
git cherry-pick --abort
1
2
3
4
5
6
7
8
9
10
11

# stash

# 暂存当前修改
git stash
git stash push -m "暂存信息"
git stash -u             # 包括未跟踪的文件
git stash -a             # 包括所有文件

# 查看暂存
git stash list
git stash show
git stash show -p stash@{0}

# 应用暂存
git stash apply          # 应用但不删除
git stash pop            # 应用并删除
git stash apply stash@{n}

# 删除暂存
git stash drop stash@{n}
git stash clear

# 从暂存创建分支
git stash branch <branch-name>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# reset 与 revert

# reset - 重置到特定提交
git reset --soft <commit-hash>   # 保留工作区和暂存区
git reset --mixed <commit-hash>  # 保留工作区,清空暂存区
git reset --hard <commit-hash>   # 清空工作区和暂存区

# revert - 撤销提交(创建新提交)
git revert <commit-hash>
git revert <commit1> <commit2>
git revert -m 1 <merge-commit>   # 撤销合并提交
1
2
3
4
5
6
7
8
9

撤销操作对比:

操作 工作区 暂存区 提交历史 使用场景
git restore <file> 撤销 保留 保留 撤销工作区修改
git restore --staged <file> 保留 撤销 保留 取消暂存
git reset --soft HEAD~1 保留 保留 撤销 修改提交信息
git reset --mixed HEAD~1 保留 撤销 撤销 重新组织提交
git reset --hard HEAD~1 撤销 撤销 撤销 完全放弃修改
git revert <commit> 新提交 新提交 新提交 安全撤销公共提交

# 底层命令

# git rev-list

git rev-list 是底层命令,用于列出提交对象的 SHA-1 哈希值,是很多高级命令的基础。

# 基本用法
git rev-list <commit-range>

# 列出提交历史
git rev-list HEAD
git rev-list commit1..commit2
git rev-list main..feature      # 在 feature 但不在 main
git rev-list feature..main      # 在 main 但不在 feature

# 统计提交数量
git rev-list --count HEAD
git rev-list --count main..feature
git rev-list --count --first-parent main
git rev-list --count --merges HEAD

# 查找特定提交
git rev-list --merges HEAD      # 列出合并提交
git rev-list --no-merges HEAD   # 列出非合并提交
git rev-list -n 10 HEAD         # 列出最近 10 个提交
git rev-list --since="2024-01-01" --until="2024-12-31" HEAD

# 祖先路径
git rev-list commit1..commit2 --ancestry-path
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

rev-list vs log 对比:

特性 git rev-list git log
用途 底层命令,输出提交 SHA 高级命令,格式化输出
输出 只有提交哈希 包含作者、日期、信息
性能 更快 较慢
脚本使用 适合 不太适合
人类可读 否 是

实用示例:

# 查找两个分支的共同祖先
git merge-base main feature

# 查找提交何时被合并
commit_hash="abc1234"
git rev-list $commit_hash..main --ancestry-path --merges --reverse | head -1

# 比较两个分支
echo "Feature 领先 main: $(git rev-list --count main..feature) 个提交"
echo "Main 领先 feature: $(git rev-list --count feature..main) 个提交"

# 查找包含特定文件的提交
git rev-list --all -- path/to/file
git rev-list --count --all -- path/to/file
git rev-list --all --diff-filter=D -- path/to/file  # 查找删除文件的提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 其他底层命令

# git cat-file - 查看 Git 对象
git cat-file -t <object-hash>    # 查看对象类型
git cat-file -p <object-hash>    # 查看对象内容
git cat-file -s <object-hash>    # 查看对象大小

# git ls-tree - 列出树对象
git ls-tree HEAD
git ls-tree -r HEAD              # 递归列出
git ls-tree --name-only HEAD     # 只显示文件名

# git hash-object - 计算对象哈希值
git hash-object <file>
git hash-object -w <file>        # 写入对象数据库
1
2
3
4
5
6
7
8
9
10
11
12
13

# 配置

# 配置级别

Git 有三个配置级别,优先级从高到低:

  1. 本地配置 (--local): 仅对当前仓库有效,存储在 .git/config
  2. 全局配置 (--global): 对当前用户所有仓库有效,存储在 ~/.gitconfig
  3. 系统配置 (--system): 对所有用户有效,存储在 /etc/gitconfig
# 查看配置
git config --list
git config --local --list
git config --global --list
git config --system --list
git config --list --show-origin    # 查看配置来源
1
2
3
4
5
6

# 基本配置

# 设置用户信息
git config --global user.name "Your Name"
git config --global user.email "[email protected]"

# 设置默认编辑器
git config --global core.editor "vim"
git config --global core.editor "code --wait"  # VS Code

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

# 配置换行符处理
git config --global core.autocrlf true   # Windows
git config --global core.autocrlf input  # macOS/Linux

# 配置颜色显示
git config --global color.ui auto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 别名配置

# 基础别名
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

# 高级别名
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global alias.undo 'reset --soft HEAD~1'
git config --global alias.amend 'commit --amend --no-edit'
1
2
3
4
5
6
7
8
9
10
11
12

# 推荐配置

cat > ~/.gitconfig << 'EOF'
[user]
    name = Your Name
    email = [email protected]

[core]
    editor = vim
    autocrlf = input
    quotepath = false
    ignorecase = false

[init]
    defaultBranch = main

[color]
    ui = auto

[alias]
    st = status
    co = checkout
    br = branch
    ci = commit
    unstage = reset HEAD --
    last = log -1 HEAD
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

[pull]
    rebase = false

[push]
    default = simple
    followTags = true

[merge]
    conflictstyle = diff3

[diff]
    tool = vimdiff

[credential]
    helper = cache --timeout=3600
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 高级配置

# 子模块
git submodule add <repository-url> <path>
git submodule init
git submodule update
git clone --recurse-submodules <repository-url>

# 工作树
git worktree add <path> <branch>
git worktree list
git worktree remove <path>

# 二分查找
git bisect start
git bisect bad
git bisect good <commit-hash>
git bisect run <command>
git bisect reset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 工作流

# 基本工作流程

# 1. 克隆仓库
git clone <repository-url>
cd <project-name>

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

# 3. 开发和提交
git add .
git commit -m "Add new feature"

# 4. 推送到远程
git push origin feature/new-feature

# 5. 创建 Pull Request/Merge Request

# 6. 合并到主分支
git checkout main
git pull origin main
git merge feature/new-feature
git push origin main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# Git Flow 工作流

# 主分支
main        # 生产环境代码
develop     # 开发环境代码

# 功能分支
feature/*   # 新功能开发
release/*   # 发布准备
hotfix/*    # 紧急修复
1
2
3
4
5
6
7
8

# 提交信息规范

约定式提交 (Conventional Commits):

&lt;type>[optional scope]: &lt;description>

[optional body]

[optional footer(s)]
1
2
3
4
5

类型 (type):

  • feat: 新功能
  • fix: 修复bug
  • docs: 文档更新
  • style: 代码格式调整
  • refactor: 代码重构
  • test: 测试相关
  • chore: 构建过程或辅助工具变动

示例:

git commit -m "feat(auth): add user authentication system"
git commit -m "fix(api): resolve login endpoint timeout issue"
git commit -m "docs(readme): update installation instructions"
1
2
3

# 故障排除

# 常见问题

1. 推送被拒绝 (non-fast-forward)

# 解决方案1:先拉取再推送
git pull --rebase origin main
git push origin main

# 解决方案2:强制推送(谨慎使用)
git push --force-with-lease origin main
1
2
3
4
5
6

2. 提交到错误的分支

git reset --soft HEAD~1
git checkout correct-branch
git commit -m "Correct commit message"
1
2
3

3. 忘记添加文件到上次提交

git add forgotten-file
git commit --amend --no-edit
1
2

4. 提交了敏感信息

# 从最后一次提交中移除
git rm --cached sensitive-file
git commit --amend -m "Remove sensitive file"

# 从历史中完全移除
bfg --delete-files sensitive-file
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force --all
1
2
3
4
5
6
7
8
9

5. 合并后想要撤销

# 如果还没有推送
git reset --hard HEAD~1

# 如果已经推送
git revert -m 1 <merge-commit-hash>
1
2
3
4
5

6. 误删分支

git reflog
git checkout -b recovered-branch <commit-hash>
1
2

7. 解决 "detached HEAD" 状态

git checkout -b temp-branch    # 保存当前工作
git checkout main              # 或直接切换回分支
1
2

8. 大文件导致推送失败

git filter-branch --tree-filter 'rm -f large-file' HEAD
# 或使用 git-filter-repo(推荐)
git filter-repo --path large-file --invert-paths
1
2
3

# 解决冲突

# 查看冲突文件
git status

# 查看冲突详情
git diff

# 手动解决冲突后
git add <resolved-file>
git commit -m "Resolve merge conflicts"

# 使用合并工具
git mergetool

# 查看冲突的两个版本
git show :1:<file>  # 共同祖先版本
git show :2:<file>  # 当前分支版本
git show :3:<file>  # 合并分支版本

# 选择特定版本
git checkout --ours <file>    # 使用当前分支版本
git checkout --theirs <file>  # 使用合并分支版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

冲突标记:

&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
当前分支的内容
=======
合并分支的内容
>>>>>>> feature-branch
1
2
3
4
5

# 恢复和清理

# 恢复删除的文件
git log --diff-filter=D --summary
git checkout <commit-hash> -- <file-path>
git checkout HEAD~1 -- <file-path>

# 从 reflog 恢复
git reflog
git checkout <reflog-entry> -- <file-path>

# 清理未跟踪的文件
git clean -f              # 删除文件
git clean -fd             # 删除文件和目录
git clean -n              # 预览将要删除的文件
git clean -i              # 交互式清理

# 压缩仓库
git gc
git gc --aggressive
git reflog expire --expire=now --all
git gc --prune=now

# 查看仓库大小
git count-objects -vH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 性能优化

# 浅克隆
git clone --depth 1 <repository-url>

# 部分克隆
git clone --filter=blob:none <repository-url>

# 单分支克隆
git clone -b <branch> <repository-url>

# 使用 Git LFS
git lfs track "*.psd"
git lfs track "*.zip"
1
2
3
4
5
6
7
8
9
10
11
12

# 技巧

# 别名和脚本

# 实用别名(添加到 ~/.gitconfig)
[alias]
    st = status
    co = checkout
    br = branch
    ci = commit
    unstage = reset HEAD --
    last = log -1 HEAD
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
    undo = reset --soft HEAD~1
    amend = commit --amend --no-edit
    wip = commit -am "WIP"
    aliases = config --get-regexp alias
    contributors = shortlog --summary --numbered
    recent = branch --sort=-committerdate --format='%(committerdate:relative)%09%(refname:short)'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# git-sync.sh - 同步远程分支
git fetch --all
git pull --rebase
git push

# git-cleanup.sh - 清理已合并的分支
git branch --merged | grep -v "\*" | grep -v "main" | grep -v "master" | xargs -n 1 git branch -d
1
2
3
4
5
6
7
8

# 搜索和查找

# 在提交历史中搜索代码
git log -S "function_name" --source --all

# 在提交信息中搜索
git log --grep="bug fix" --oneline

# 查找谁修改了某行代码
git blame <file>
git blame -L 10,20 <file>

# 查找文件的修改历史
git log --follow -- <file>

# 查找包含特定文件的提交
git log --all -- <file>

# 查找删除/添加的文件
git log --diff-filter=D --summary
git log --diff-filter=A --summary
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 高级查询

查找分支创建点:

git reflog --date=local --all | grep <branch-name>
1

查看修改何时合并到主分支:

添加以下别名到 ~/.gitconfig:

[alias]
    find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
    show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"
1
2
3

find-merge 原理:

  1. --ancestry-path: 找到从起始提交到目标分支的所有祖先路径提交
  2. --first-parent: 只沿着主分支的第一父路径
  3. 两者的交集就是合并提交
A---B---C---D---E---F (main)
     \         /
      G---H---I (feature)

# 查找 G 何时合并到 main
git rev-list G..main --ancestry-path
# 输出:F, E, I, H

git rev-list G..main --first-parent  
# 输出:F, E, D, C

# 交集:F, E
# 最后一个(最新的):F(这就是合并提交)
1
2
3
4
5
6
7
8
9
10
11
12
13

使用示例:

# 查找特定提交何时合并到 master
git find-merge <commit-hash> master

# 显示合并提交的详细信息
git show-merge <commit-hash> master
1
2
3
4
5

# 钩子 (Hooks)

#!/bin/sh
# .git/hooks/pre-commit

# 运行测试
npm test

# 代码格式化检查
npm run lint

# 阻止提交特定文件
if git diff --cached --name-only | grep -q "debug.log"; then
    echo "Error: Cannot commit debug.log"
    exit 1
fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 分支管理技巧

# 删除已合并的分支
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

# 删除远程已删除的分支
git remote prune origin

# 查看分支关系
git log --graph --oneline --all --decorate

# 重命名分支
git branch -m old-name new-name
git push origin :old-name
git push origin new-name
1
2
3
4
5
6
7
8
9
10
11
12
13

# 实战

# 场景1:团队协作开发新功能

# 1. 从主分支创建功能分支
git checkout main
git pull origin main
git checkout -b feature/user-authentication

# 2. 开发过程中定期提交
git add src/auth/
git commit -m "feat(auth): add login functionality"

# 3. 同步主分支的最新更改
git fetch origin main
git rebase origin/main

# 4. 推送到远程
git push origin feature/user-authentication

# 5. 创建 Pull Request 后,根据反馈修改
git add .
git commit --amend

# 6. 强制推送更新
git push --force-with-lease origin feature/user-authentication

# 7. 合并后清理
git checkout main
git pull origin main
git branch -d feature/user-authentication
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 场景2:紧急修复生产环境 Bug

# 1. 从生产分支创建 hotfix 分支
git checkout main
git pull origin main
git checkout -b hotfix/critical-bug

# 2. 快速修复并测试
git add .
git commit -m "fix: resolve critical bug in payment module"

# 3. 合并到主分支
git checkout main
git merge --no-ff hotfix/critical-bug
git push origin main

# 4. 同时合并到开发分支
git checkout develop
git merge --no-ff hotfix/critical-bug
git push origin develop

# 5. 清理 hotfix 分支
git branch -d hotfix/critical-bug
git push origin --delete hotfix/critical-bug
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 场景3:整理混乱的提交历史

# 交互式变基整理最近 5 个提交
git rebase -i HEAD~5

# 在编辑器中调整提交
# pick -> 保留提交
# squash -> 合并到前一个提交
# reword -> 修改提交信息
# drop -> 删除提交

# 示例操作
pick abc1234 feat: add user model
squash def5678 fix typo
squash ghi9012 fix formatting
reword jkl3456 feat: add user validation
pick mno7890 docs: update README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 场景4:恢复误删的提交

# 1. 查看所有操作历史
git reflog

# 2. 找到误删前的提交
# abc1234 HEAD@{0}: reset: moving to HEAD~1
# def5678 HEAD@{1}: commit: important feature

# 3. 恢复提交
git cherry-pick def5678
# 或者重置到那个状态
git reset --hard def5678
1
2
3
4
5
6
7
8
9
10
11

# 场景5:同时开发多个功能

# 使用 worktree 同时处理多个分支
git worktree add ../project-feature1 feature/feature1
git worktree add ../project-feature2 feature/feature2

# 在不同目录中独立工作
cd ../project-feature1
# 开发 feature1

cd ../project-feature2
# 开发 feature2

# 完成后清理 worktree
git worktree remove ../project-feature1
git worktree remove ../project-feature2
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 场景6:代码审查和反馈

# 审查者检出 PR 分支
git fetch origin pull/123/head:pr-123
git checkout pr-123

# 查看修改
git log main..pr-123
git diff main...pr-123

# 开发者根据反馈修改
git add .
git commit -m "refactor: address code review comments"
git push origin feature-branch
1
2
3
4
5
6
7
8
9
10
11
12

# 最佳实践

# 提交规范

提交信息格式:

&lt;type>(&lt;scope>): &lt;subject>

&lt;body>

&lt;footer>
1
2
3
4
5

类型:

  • feat: 新功能
  • fix: Bug 修复
  • docs: 文档更新
  • style: 代码格式(不影响代码运行)
  • refactor: 重构
  • perf: 性能优化
  • test: 测试相关
  • chore: 构建过程或辅助工具的变动
  • ci: CI 配置文件和脚本的变动
  • build: 影响构建系统或外部依赖的更改

示例:

feat(auth): add JWT authentication

Implement JWT-based authentication system with:
- Token generation and validation
- Refresh token mechanism
- Middleware for protected routes

Closes #123
1
2
3
4
5
6
7
8

最佳实践:

  1. 原子性提交:每个提交只做一件事
  2. 频繁提交:小步快跑,便于回滚
  3. 描述性信息:清楚说明"做了什么"和"为什么"
  4. 使用现在时:使用 "add feature" 而不是 "added feature"
  5. 限制长度:标题不超过 50 字符,正文每行不超过 72 字符

# 分支管理

分支命名规范:

feature/user-authentication    # 功能分支
fix/login-error                # Bug 修复
hotfix/critical-security-issue # 热修复
release/v1.2.0                 # 发布分支
experiment/new-ui-design       # 实验性功能
1
2
3
4
5

分支管理策略:

  1. 保护主分支:禁止直接推送,要求 PR 审查,要求 CI 通过
  2. 及时清理分支:git branch --merged | grep -v "\*\|main\|develop" | xargs -n 1 git branch -d
  3. 使用分支策略:Git Flow(版本发布)/ GitHub Flow(持续部署)/ GitLab Flow(环境分支)

# 协作开发

代码审查清单:

  • [ ] 代码符合项目规范
  • [ ] 测试覆盖充分
  • [ ] 文档已更新
  • [ ] 没有调试代码
  • [ ] 性能影响可接受
  • [ ] 安全性考虑充分

冲突解决策略:

  1. 预防冲突:频繁同步主分支 git fetch origin main && git rebase origin/main
  2. 解决冲突:使用 git mergetool 或手动编辑后 git add <resolved-files> && git rebase --continue
  3. 团队沟通:修改同一文件前先沟通,大规模重构提前通知

# 安全考虑

# 1. 使用 .gitignore
cat >> .gitignore << EOF
.env
*.key
*.pem
secrets/
config/local.js
EOF

# 2. 使用环境变量
const apiKey = process.env.API_KEY;  # ✅ 正确
API_KEY=your_key_here  # ❌ 错误

# 3. 使用 git-secrets
git secrets --install
git secrets --register-aws

# 4. SSH 密钥配置
ssh-keygen -t ed25519 -C "[email protected]"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh -T [email protected]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 资源

# 官方文档

  • Git 官方文档 (opens new window)
  • Git 教程 (opens new window)
  • Git 参考手册 (opens new window)
  • 祖先引用、双点、三点... (opens new window)

# 在线教程

  • Learn Git Online (opens new window)
  • GitHub Learning Lab (opens new window)
  • Git 教程 - 廖雪峰 (opens new window)

# 工具

GUI 客户端:

  • GitHub Desktop - 简单易用
  • GitKraken - 功能强大
  • SourceTree - Atlassian 免费客户端
  • TortoiseGit - Windows 集成

命令行工具:

  • tig - 文本模式的 Git 浏览器
  • hub - GitHub 命令行工具
  • gh - GitHub CLI
  • git-flow - Git Flow 工作流工具

在线平台:

  • GitHub - 最流行的代码托管平台
  • GitLab - 功能丰富的 DevOps 平台
  • Bitbucket - Atlassian 的代码托管服务
  • Gitee - 国内的代码托管平台

# 社区

  • Stack Overflow Git 标签 (opens new window)
  • GitHub 讨论区 (opens new window)
  • Reddit r/git (opens new window)
#git#tool#toturial
上次更新: 2025/10/15, 21:57:35
最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式