>> >> >> Reference << << << <<<<<<Ref>>>>>>
Three Local Area
Modified: 2025-12-31 | Author:ljf12825

工作区

工作区就是实际操作的目录,包含项目的所有文件和子目录

作用

常用命令

git add

git add是Git中最基础且重要的命令之一,用于将工作目录中的变更添加到暂存区,为后续提交做准备

基本语法

git add [选项] <文件/目录/模式>

主要用法

  1. 添加单个文件
git add filename.txt

将指定的文件变更添加到暂存区

  1. 添加多个文件
git add file1.txt file2.js file3.css

可以一次性添加多个文件

  1. 添加整个目录
git add dirname/

添加指定目录下的所有变更(不包括子目录,除非使用递归选项)

  1. 添加当前目录所有变更
git add .

添加当前目录及其所有子目录中的所有已追踪文件的变更(不包括未追踪的新文件)

  1. 添加所有变更(包括为未跟踪的文件)
git add -A
# 或
git add --all

添加工作区中所有已跟踪文件的修改和删除,以及所有未跟踪的新文件(不包括.gitignore中指定的文件)

  1. 交互式添加
git add -i
# 或
git add -interactive

进入交互模式,可以更精细地控制要暂存的变更,在交互模式中,可以选择

  1. 按补丁添加(部分添加)
git add -p
# 或
git add --patch

交互式选择文件中的部分变更进行添加,而不是整个文件,操作提示:

  1. 添加已跟踪文件的修改(不包括新文件)
git add -u
# 或
git add --update

特殊用法

  1. 使用通配符添加文件
git add *.js

添加所有.js文件

  1. 添加修改和删除的文件,但不包括新文件
git add -u .
  1. 强制添加被忽略的文件
git add -f ignored_file.log

常用参数

选项全称说明
-n--dry-run只显示要添加的文件,不实际执行
-v--verbose显示详细信息
-f--force允许添加通常被忽略的文件
-e--edit手动编辑差异
--ignore-errors跳过因错误无法添加的文件
--ignore-missing检查文件是否存在

注意事项

  1. git add不会自动添加.gitignore忽略的文件
  2. 添加后的变更可以通过git reset从暂存区移除
  3. 使用git add -Agit add .时要小心,避免添加不必要的文件
  4. 建议经常使用git status查看添加后的状态变化

git restore

git restore是Git2.23版本引入的一个新命令,旨在提供更职官和安全的文件恢复操作,它替代了部分git checkoutgit reset功能

核心功能

git restore主要用于三种场景

  1. 丢弃工作区的修改(恢复到最后一次提交或暂存区状态)
  2. 取消暂存(将文件从暂存区移出)
  3. 从指定提交恢复文件

基础用法

  1. 丢弃工作区修改(危险操作)
git resotre <file>
  1. 取消暂存(安全操作)
git resotre --staged <file>
  1. 从特定提交恢复
git restore --source=<commit> <file>
  1. 组合操作
git restore --source=HEAD --staged --worktree <file>
  1. 交互式恢复
git restore --patch <file>
  1. 恢复整个目录
git restore

注意事项

  1. git restore是一个破坏性操作,特别是没有--staged选项时会丢弃工作区修改
  2. 恢复操作不可逆,建议先提交或备份重要更改
  3. 可以使用--dry-run选项先模拟操作结果

暂存区

暂存区也称为”索引“(Index)。它是Git工作流程中的一个中间步骤,位于工作目录和版本库之间

作用

  1. 选择性提交:允许只提交部分修改过的文件,甚至是一个文件中的部分修改
  2. 准备提交内容:将工作目录中的变更收集起来,形成一个逻辑上完整的变更集
  3. 分离修改与提交:可以在提交前审查和整理变更

特点

常用命令

原理

  1. 存储位置:.git/index二进制文件
  2. 内容结构
  1. 查看原始内容
git ls-files --stage # 查看暂存区完整内容

Git仓库

Git仓库是Git存储项目历史记录的地方,包含所有提交的对象

特点

仓库结构

Git仓库核心目录结构(.git目录)

.git/
├── HEAD                  # 当前所在分支的引用
├── config                # 仓库特定的配置
├── description           # 仓库描述(主要用于GitWeb)
├── hooks/                # 客户端和服务端钩子脚本
│   ├── pre-commit.sample    # 提交前钩子示例
│   ├── post-update.sample   # 更新后钩子示例
│   └── ...                 # 其他钩子示例
├── info/                 # 全局排除模式
│   └── exclude           # 本地忽略规则(不共享)
├── objects/              # 所有Git对象数据库
│   ├── info/             # 对象信息
│   └── pack/             # 打包的对象(优化存储)
├── refs/                 # 引用(分支和标签)指针
│   ├── heads/            # 本地分支引用
│   └── tags/             # 标签引用
└── index                 # 暂存区(索引)文件

objects in .git

Git的核心是一个简单的键值对数据库(key-value data store),这个数据库主要包含四种基本对象:blob对象、tree对象、commit对象和tag对象。这些对象共同构成了Git版本控制的基础

git对象的存储机制 所有Git对象都存储在.git/objects目录下,采用分目录 + 压缩的方式每个对象都有一个40个字符的SHA-1哈希值作为唯一标识

<type> <size>\0<content>

这是Git计算SHA-1哈希的原始数据格式

四种对象类型

  1. Bolb对象(二进制大对象)
  1. Tree对象(树对象)
  1. Commit
git cat-file -p <commit_sha>
  1. Tag
git cat-file -p <tag_sha>
commit ----> tree ----> blob (文件内容)
----> tree ----> blob
tag ------> commit

commit只认它的顶级Tree tag是commit的别名,方便引用

总结

Git对象的层级关系

  1. Blob和Tree
  1. Commit
  1. Tag

常用命令

git commit

git commit的作用是将staging area中的内容作为一个新的提交保存到Git仓库中

git commit -m "提交信息"

这会

  1. 将暂存区的内容创建一个新的提交
  2. 使用指定的提交信息记录这次变更
  3. 更新当前分支指向这个新提交

常用参数

  1. 修改提交信息
git commit --amend

这会

git commit --amend -m "新的提交信息"
  1. 添加变更到上次提交
git commit --amend --no-edit

这会

  1. 跳过暂存区直接提交
git commit -a -m "提交信息"

git commit -am "提交信息"

这会:

  1. 部分文件提交
git add file1.txt file2.txt
git commit -m "部分提交"
  1. 空提交
git commit --allow-empty -m "空提交"

用于触发CI

  1. 指定作者信息
git commit -m "提交信息" --author="名字 <emali>"
  1. 指定日期
git commit -m "提交信息" --date="2023-01-01T12:00:00"

最佳实践

  1. 原子性提交:每个提交只做一件事
  2. 频繁提交:小步提交比大变更更好
  3. 描述性信息:清楚地说明为什么变更,而不仅是做了什么
  4. 验证提交:提交前使用git dirr --cached检查

git show

git show是Git中用于显示各种Git对象(如提交、标签、树和blob)详细信息的强大命令

基本用法

  1. 显示最新提交的详细信息
git show

这会显示最近一次提交的:

  1. 显示特定提交的详情
git show <commit-hash>
  1. 显示标签对应的提交
git show <tag-name>
  1. 仅显示提交信息(不显示diff)
git show --stat <commit>

这会显示

  1. 显示特定文件的变更
git show <commit>:<file-path>
  1. 简洁格式显示
git show --oneline <commit>
  1. 显示原始差异(raw diff)
git show --raw <commit>
  1. 显示特定作者提交
git show <commit> --author="John"
  1. 比较两次提交间的差异
git show <commit1>..<commit2>
  1. 显示合并提交的父提交差异
git show -m <merge-commit>
  1. 显示文件在特定提交时的内容
git show <commit>:<path/to/file>
  1. 显示提交引入的补丁
git show -p <commit>
  1. 输出格式控制 自定义格式
git show --pretty=format:"%h - %an, %ar : %s" <commit>

常用格式占为符

JSON格式输出

git show --pretty=format:'{%n  "commit": "%H",%n  "author": "%an",%n  "date": "%ad",%n  "message": "%s"%n}' -s <commit>

git init

git init是初始化命令,用于创建一个新的Git仓库

git init

这会在当前目录创建一个新的Git仓库,生成一个隐藏的.git目录,包含所有必要的Git元数据

常用选项

  1. 指定目录名称
git init <目录名>

这会:

  1. 创建裸仓库
git init --bare

裸仓库特点:

  1. 指定初始分支名称
git init -b <分支名>

注意事项

  1. 在已有Git仓库中再次运行git init是安全的,不会覆盖已有内容
  2. Git2.28+版本开始,默认初始分支可以通过配置修改
git config --global init.defaultBranch main
  1. 初始化后需要至少一个提交才会真正创建分支

git clone

git clone用于将远程仓库完整地复制到本地

git clone <仓库URL> [目录名]

核心功能

  1. 完整复制远程仓库:包括所有历史记录、分支和配置
  2. 自动设置远程追踪:默认创建名为origin的远程连接
  3. 检出工作副本:自动检出默认分支(通常是mainmaster

常用用法

  1. 基本克隆
git clone <repoURL>
  1. 克隆到指定目录
git clone <repoURL> [目录名]
  1. 克隆时指定分支
git clone -b branch_name <repoURL>
  1. 克隆深度克隆(只获取最近历史)
git clone --depth 1 <repoURL>
  1. 克隆裸仓库
git clone --bare <repoURL>
  1. 克隆时排除某些历史
git clone --filter=blob:none <repoURL>
  1. 克隆子模块(递归克隆)
git clone --recursive <repoURL>
  1. 克隆时指定配置
git clone -c core.autocrlf=input <repoURL>

支持的协议

git clone支持多种协议

注意事项

  1. 克隆大型仓库可能需要较长时间和足够的磁盘空间
  2. 私有仓库需要配置正确的认证方式
  3. 默认只克隆默认分支,其他分支需要通过git checkout获取
  4. 克隆后会自动设置远程跟踪分支,可以直接使用git pull更新

git gc

git gc(Garbage Collection)是Git的垃圾回收命令,用于优化本地仓库性能并清理不必要的文件

git gc

核心功能

  1. 清理松散对象:删除不再被引用的对象(commit,tree,blob等)
  2. 压缩对象:将多个松散对象打包成更高效的.pack文件
  3. 优化仓库结构:重组Git内部数据结构提高性能
  4. 修剪过时引用:清理陈旧的reflog条目

常用选项

选项描述
--aggressive更彻底的优化(耗时更长)
--auto只在必要时执行(Git自动调用时使用)
--prune=<date>删除指定日期前的松散对象(如--prune=now
--no-prune不删除任何松散对象
--quiet静默模式,减少输出

执行时机

Git会在以下情况自动执行gc

手动执行场景

  1. 仓库体积异常增大时
  2. Git操作变慢时
  3. 大量提交后准备归档时
  4. 长时间使用的仓库定期维护

配置参数

可通过git config调整GC行为

# 自动设置GC的松散对象阈值
git config gc.auto 1000

# 设置自动打包的对象阈值
git config gc.autoPackLimit 50

# 设置prune过期时间(默认两周)
git config gc.pruneExpire "1 month ago"

git prune

git prune是Git中用于清理不可达对象的底层命令,通常被git gc自动调用,但在某些特殊情况下需要手动调用

git prune [-n] [-v] [--expire <time>] [--] [<head>...]

核心功能

  1. 删除孤立对象:清理没有被任何引用(分支、标签、reflog等)指向的Git对象
  2. 回收存储空间:减少.git/objects目录的大小
  3. 维护仓库健康:移除无用数据,优化仓库性能

常用选项

选项描述
-n/--dry-run只显示将要删除的对象,不实际执行
-v-/–verbose`显示详细处理信息
--expire <time>只删除早于指定时间的对象(如--expire=now
--progress显示进度条

工作原理

  1. 扫描.git/objects目录中的所有对象
  2. 检查每个对象是否被以下引用
  1. 删除所有未被引用的对象

注意事项

  1. 危险操作:删除的对象无法恢复,确保没有重要数据未被引用
  2. 通常不需要手动执行:git gc会自动调用prune
  3. 可能影响悬空提交:会清理违背引用但可能有价值的提交
  4. 大型仓库耗时:对象多的仓库可能需要较长时间

git repack

git gc的子操作,git repack是Git中用于优化仓库存储结构的底层命令,它会将多个松散对象(loose objects)重新打包成更高效的pack文件

git repack [选项]

核心功能

  1. 将松散对象打包:将.git/objects中的单个文件对象合并为pack文件
  2. 删除冗余对象:移除重复的或未被引用的对象
  3. 优化存储:通过delta压缩减少仓库体积
  4. 提高性能:减少Git操作时需要访问的文件数量

常用选项

选项描述
-a打包所有松散对象(包括未被引用的)
-d打包后删除冗余的松散对象
-f强制重新打包已有pack文件
-l保留旧的pack文件(安全选项)
-n只显示将要执行的操作,不实际运行
--window=<n>设置delta压缩窗口大小(默认10)
--depth=<n>设置delta压缩的深度(默认50)
--threads=<n>设置打包使用的线程数

配置参数

可通过git config调整repack行为

# 设置 delta压缩窗口大小
git config repack.window 50

# 设置 delta的深度
git config repack.depth 100

# 设置自动打包
git config gc.autoPackLimit 50

注意事项

  1. 大型仓库可能耗时:深度优化可能需要较长时间
  2. 网络仓库慎用:可能导致后续推送需要重新上传对象
  3. 内存使用:大窗口/深度设置会增加内存消耗
  4. 通常不需要手动执行:git gc会自动处理

git fsck

git fsck(File System ChecK)是Git提供的仓库完整性检查工具,用于验证Git对象数据库的连通性和有效性

git fsck [选项]

核心功能

  1. 验证对象完整性:检查所有Git对象(blob、tree、commit、tag)是否有效
  2. 检测损坏对象:找出存储损坏或内容不完整的对象
  3. 发现孤立对象:识别没有被任何引用指向的对象
  4. 检查仓库健康状态:确保仓库数据结构一致

常用选项

选项描述
--full执行完整检查(默认行为)
--unreachable只显示不可达对象
dangling显示悬空对象(无引用但未损坏)
--no-reflogs忽略refolg引用进行检查
--strict执行更严格的检查
--verbose显示详细输出
--lost-found将悬空对象写入.git/lost-found

输出分析

  1. 悬空对象
dangling blob <sha1>
dangling commit <sha1>

这些是未被引用但内容完整的对象,通常安全

  1. 损坏对象
corrut blob <sha1>
missing blob <sha1>

表示对象已损坏或丢失,需要修复

  1. 不可达对象
unreachable commit <sha1>

这些提交无法从任何引用达到

git reflog

git reflog是Git的安全网,它记录了本地仓库中所有的引用变更历史,可以帮助恢复意外丢失的提交或分支

git reflog [show] [<引用>] # 显示引用日志
git reflog expire # 删除过期的reflog条目
git reflog delete # 删除特定reflog条目

核心概念

  1. 引用日志:记录HEAD和分支引用的所有变更
  2. 时间限制:默认保留90天(可通过gc.reflogExpire配置)
  3. 本地特有:reflog不会推送到远程仓库

使用

  1. 查看HEAD的变更历史
git reflog
  1. 查看特定分支的历史
git reflog show feature-branch

关键组成部分

  1. 提交哈希:每次操作对应的提交ID(可能缩写)
  2. 引用位置:如HEAD@{n}表示HEAD的第n次前位置
  3. 操作类型:commit、reset、checkout、merge等
  4. 操作描述:简要说明发生了什么

实用场景

  1. 恢复误删的提交
git reflog
# 找到删除前的提交哈希
git checkout <提交哈希>
git checkout -b  recovered-branch
  1. 撤销错误的reset
git reflog
git reset --hard HEAD@{1} # 恢复到上一步状态
  1. 找回误删的分支
git reflog | grep "deleted branch"
git branch <分支名> <提交哈希>
  1. 查看分支创建时间
git reflog show --date=iso <分支名>
  1. 显示详细时间信息
git reflog --date=iso
  1. 搜索特定操作
git reflog | grep "merge"
  1. 清理旧纪录
git reflog expire --expire=now --all
git gc

注意事项

  1. reflog是本地独有的,不会推送到远程
  2. 默认保留90天(可通过git config gc.reflogExpire修改)
  3. 执行git gc --prune=now会清理reflog
  4. 重要变更建议立即创建分支或标签,而非依赖reflog

git filter-branch

git filter-branch是Git中一个强大的历史重写工具,它可以批量修改提交历史。由于它的破坏性和复杂性,Git官方现在推荐使用git filter-repo作为替代

git filter-branch [选项] <过滤器> [修订范围]

主要用途为

常用过滤器类型

过滤器选项作用
--tree-filter对每个提交的工作树执行命令(慢但彻底)
--index-filter只修改暂存区(快,适用于文件删除)
--parent-fileter修改提交的父引用
--msg-filter修改提交信息
--env-filter修改作者/提交者环境变量
--subdirectory-filter提取子目录作为新根目录

使用场景

  1. 从历史中删除大文件
git filter-branch --force --index-filter \
  'git rm --cached --inigore-unmatch 文件名' \
  --prune-empty --tag-name-filter cat -- --call
  1. 批量修改作者名字
git filter-branch --env-filter '
  if [ "$GIT_AUTHOR_NAME" = "旧名字" ];
  then
    GIT_AUTHOR_NAME="新名字";
    GIT_AUTHOR_EMAIL="新邮箱";
  fi
' -- --all
  1. 提取子目录为新仓库
git filter-branch --sundirectory-filter 子目录名 -- --all
  1. 全局替换文件内容
git filter-branch --tree-filter \
  'sed -i "s/旧文件/新文本/g" 文件名' -- --all

注意事项

  1. 破坏性操作:会重写整个历史,必须提前备份
  2. 协作影响:重写后所有协作者需要重新克隆
  3. 性能问题:大型仓库可能耗时极长
  4. 替代方案:考虑使用git filter-repo(更现代的工具)

git archive

git archive是Git提供的归档命令,用于将仓库内容打包成非Git格式的压缩文件,非常适合代码发布、备份或与不需要Git历史的用户共享项目

git archive [选项] <tree-ish> [<路径>...]

核心功能

  1. 将代码快照打包:不包含.git目录和版本控制信息
  2. 支持多种格式:zip, tar, tar.gz, tar.xz等
  3. 精确控制内容:可指定特定提交/分支/标签和子目录
  4. 保留文件权限:保持原始执行权限和属性

常用选项

选项描述
--format=<fmt>指定格式(zip, tar, tar.gz)
--output=<file>指定输出文件名
--prefix=<prefix>/为文件添加路径前缀
-v/--verbose显示详细处理信息
-l/--list列出支持的格式

用法

  1. 打包当前分支最新代码
git archive --format=zip --output=release-v1.0.zip HEAD
  1. 打包特定标签版本
git archive --format=tar.gz v2.1.0 | gzip > project-v2.1.0.tar.gz
  1. 只打包指定子目录
git archive --format=zip HEAD:src/ > src-only.zip
  1. 添加前缀路径
git archive --format=tar --prefix=project-1.0/ v1.0 | gzip > project-1,0.tar.gz
  1. 基于工作树创建归档(包含未提交修改)
git archive -o pathc.zip HEAD $(git diff --name-only HEAD)
  1. 导出特定日期版本的代码
git archive -o snapshot.zip $(git rev-list -n 1 --before="2023-01-01" main)
  1. 创建分卷压缩包
git archive --format=tar HEAD | split -b 50m - project.tar.part
  1. 排除某些文件
git archive HEAD --format=tar --output=project.tar $(git ls-files | grep -v 'test/')

与普通压缩的区别

特性git archive普通压缩
内容来源版本库快照工作目录文件系统
包含.git从不包含可能包含
文件权限精确保留可能丢失
元数据不含.git信息保留所有文件属性
构建方式基于提交对象基于文件系统

注意事项

  1. 归档不包含Git历史记录,仅包含文件快照
  2. 默认基于提交对象,如需包含工作目录修改需特殊处理
  3. 大仓库归档可能需要较长时间
  4. 建议在归当前执行git gc优化仓库

git replace

基本作用

  1. 替换任意Git对象:commit、tree、blob、tag都可以
  2. Git读取对象时,如果存在替换关系,会自动用替换对象替换原对象
  3. 原对象文件不变,提花内心戏记录在.git/refs/replace/

语法

# 创建替换
git replace <old> <new>

# 列出替换记录
git replace -l

# 删除替换
git replace -d <old>

# 清空所有替换
git replace --delete <old> # 单个
git replace --delete $(git replace -l) # 全部

应用场景

  1. 修复历史提交信息
git cat-file commit <commit_sha> tmp.txt
# 编辑tmp.txt修改作者信息
git hash-object -t commit -w tmp.txt
git replace <old_commit_sha> <new_commit_sha>

这样Git会认为旧commit已经被替换了

  1. 测试新的父提交
  1. 调试或数据恢复
  1. 部分历史替换

底层实现

当执行git replace A B时,Git会创建.git/refs/replace/A,里面的内容是B;当Git读取A时,会先看.git/refs/replace/A是否存在,如果有,就用B代替

注意事项