Git 是一个文件变更跟踪系统,它的核心功能是管理文件的修改,并通过索引(Index)和版本库(Repository)记录变更。本章将详细介绍 Git 的索引、文件分类、文件添加、提交、删除、重命名、追踪重命名、.gitignore 文件的使用,以及 Git 对象模型和文件的存储视图。

5.1 关于索引的一切

索引(Index),也称为暂存区(Staging Area),是 Git 在提交文件之前的一个缓存区域。它是 Git 处理文件变更的一个重要概念,起到了工作区(Working Directory)版本库(Repository)之间的桥梁作用。

Git 的三种文件状态:

  1. 已修改(Modified):文件发生了更改,但尚未被 Git 追踪。
  2. 已暂存(Staged):文件被 git add 添加到索引,但尚未提交。
  3. 已提交(Committed):文件已存入版本库,成为一个正式的版本快照。

可以使用 git status 命令查看索引和工作区的状态:

  1. git status

示例输出:

  1. On branch main
  2. Changes not staged for commit:
  3. (use "git add <file>..." to update what will be committed)
  4. modified: example.txt

这表示 example.txt 已修改但未暂存,需要使用 git add 添加到索引。


5.2 Git 中的文件分类

Git 根据文件的状态,将文件分为以下几类:

  1. 受 Git 追踪的文件(Tracked)

    • 已经被 Git 管理,包括未修改(Unmodified)已修改(Modified)已暂存(Staged)
    • 例如,已经 git addgit commit 的文件。
  2. 未受 Git 追踪的文件(Untracked)

    • 新创建的文件,但尚未 git add
    • 运行 git status 时,会显示类似 Untracked files 的提示。
  3. 忽略的文件(Ignored)

    • 通过 .gitignore 配置不需要 Git 追踪的文件(如日志、编译生成的二进制文件)。

5.3 使用 git add

git add 命令用于将修改的文件添加到索引区,准备提交到版本库。

  1. git add <filename>

添加所有更改的文件:

  1. git add .

添加某个特定文件夹:

  1. git add folder_name/

5.4 使用 git commit 的一些注意事项

git commit 用于将暂存区的修改提交到 Git 版本库,形成一个新的快照。

  1. git commit -m "提交说明"

如果想一次性添加所有文件并提交,可以使用 -a 选项:

  1. git commit -a -m "快速提交"

提交的最佳实践

  • 编写清晰的提交信息:提交信息应该简明扼要,描述本次修改的内容。
  • 分步骤提交:避免一次性提交大量无关的修改,确保每次提交都是一个独立的逻辑单元。
  • 使用 git commit --amend 纠正错误提交:如果提交信息有误或漏提交了文件,可以使用:

    1. git commit --amend

5.5 使用 git rm

git rm 用于从版本库中删除文件,同时也会从工作区中删除该文件。

删除文件并提交更改:

  1. git rm file.txt
  2. git commit -m "删除文件 file.txt"

如果只想从 Git 仓库中删除文件,但保留本地文件(即仅停止追踪该文件),可以使用 --cached 选项:

  1. git rm --cached file.txt
  2. git commit -m "停止追踪 file.txt"

5.6 使用 git mv

git mv 命令用于重命名文件,并让 Git 追踪这个重命名操作。

  1. git mv oldname.txt newname.txt
  2. git commit -m "重命名 oldname.txt 为 newname.txt"

手动重命名文件也可以,但需要手动 git addgit rm

  1. mv oldname.txt newname.txt
  2. git rm oldname.txt
  3. git add newname.txt
  4. git commit -m "手动重命名文件"

5.7 追踪重命名含义

在 Git 中,重命名文件并不会真正存储一个 “重命名” 操作,而是删除旧文件并创建一个新文件。Git 通过文件内容的哈希值来判断是否发生了重命名,因此,即使是 git mv,Git 也不会记录 “重命名” 操作,而是自动识别它。

查看 Git 是否检测到重命名:

  1. git log --follow filename

5.8 gitignore 文件

.gitignore 文件用于指定 Git 不需要追踪的文件类型,例如日志文件、编译生成的文件等。

创建 .gitignore 文件

在项目根目录创建 .gitignore 文件,添加如下内容:

  1. # 忽略所有 .log 文件
  2. *.log
  3. # 忽略特定目录
  4. /temp/
  5. # 忽略某个特定文件
  6. config.json

添加 .gitignore 后,需要将其提交到 Git:

  1. git add .gitignore
  2. git commit -m "添加 .gitignore 文件"

查看哪些文件被 .gitignore 忽略:

  1. git status --ignored

5.9 Git 中对象模型和文件的详细视图

Git 存储文件的方式不同于传统的文件系统,它使用 对象存储(Object Store)。Git 的对象存储包含三种基本对象:

  1. Blob(文件内容)

    • Git 存储文件的内容,而不是文件名或目录结构。
    • 每个文件被存储为一个 Blob 对象,并由 SHA-1 哈希标识。
  2. Tree(目录结构)

    • Tree 对象存储了文件名、目录结构,并指向 Blob 对象。
  3. Commit(提交对象)

    • Commit 对象记录了一次提交,包括提交者、时间戳、提交信息以及指向 Tree 对象的指针。

可以使用 git cat-file 查看 Git 对象:

  1. git cat-file -p <对象哈希>

例如,查看某个提交对象:

  1. git log --oneline
  2. git cat-file -p <提交哈希>

结论

本章介绍了 Git 文件管理和索引的核心概念,包括索引的作用、Git 文件的分类、文件的添加与提交、删除和重命名的方式,以及 .gitignore 文件的使用。最后,还讲解了 Git 的对象存储机制,以帮助读者深入理解 Git 的底层工作原理。

下一章将介绍 Git 的分支管理,包括创建、合并、删除分支等高级操作。