如何基于 Git 实现自己的版本控制系统 (基于 UCB CS 61B)

本博客内容基于 UCB CS 61B (数据结构,2021 春季学期)。欲了解更多信息,请查看 官方网站

Git 是一个功能强大、分布式的版本控制系统(VCS),广泛应用于软件开发。它由 Linus Torvalds 于 2005 年创建,使开发者能够跟踪更改、无缝协作和高效管理代码库。

1. Git 基础

Git 是一种分布式版本控制系统,允许多个开发者同时在一个项目上工作,而不会覆盖彼此的更改。它帮助跟踪更改、恢复到以前的状态,并高效协作。更详细的介绍可参见 MIT Missing Semester, 版本控制 (Git)

关键概念

  • 仓库:一个仓库(或 repo)是包含您所有项目文件及其更改历史的目录。
  • 提交:提交是您在特定时间点上的仓库快照。每个提交都有一个唯一的 ID。
o <-- o <-- o <-- o  (main)
  • 分支:分支是一个独立的开发线。Git 中的默认分支名称是 main。
o <-- o <-- o <-- o  (main)
           \
            \
             o <-- o  (new_feature)
  • 合并:合并是将一个分支的更改合并到另一个分支的过程。
o <-- o <-- o <-- o <---- o  (main)
           ^            /
            \          v
            --- o <-- o  (new_feature)
  • 暂存区 (索引):暂存区是您放置希望包含在下一个提交中的更改的地方。
  • HEAD:HEAD 是指向当前提交或当前分支顶端的指针。
  • 检出:检出用于切换分支。

Git 术语

# 一个文件是一串字节
type blob = array<byte>

# 一个提交包含父级、元数据和顶层树
type commit = struct {
    parents: array<commit>
    author: string
    message: string
    snapshot: tree
}

# 一个对象是 blob 或 commit
type object = blob | commit

# 所有对象通过它们的 SHA-1 哈希进行内容寻址
objects = map<string, object>

def store(object):
    id = sha1(object)
    objects[id] = object

def load(id):
    return objects[id]

2. Gitlet 概述

我们把这个版本称为 Gitlet,它模仿了一些 Git 的基本功能。版本控制系统有助于管理和跟踪项目中的更改,使您能够保存、恢复和查看文件的不同版本。Gitlet 的关键功能包括:
1. 提交:保存文件目录的状态。
2. 检出:恢复文件或提交的以前版本。
3. 日志:查看提交历史。
4. 分支:维护独立的提交序列。
5. 合并:将一个分支的更改集成到另一个分支中。

Gitlet 以链表的形式可视化提交,每个提交指向其父级。HEAD 指针跟踪提交历史中的当前状态。Gitlet 还支持分支,允许您维护和切换项目的不同版本,形成一个提交树。一旦创建,Gitlet 中的提交是不可变的,确保过去的状态被保存而不会被意外删除。

3. .gitlet 目录结构

我们的 .gitlet 目录类似于官方的 .git,当您使用 git init 初始化一个 Git 仓库时会创建。它包含您仓库的所有元数据和对象数据库。

.gitlet
├── HEAD
├── stageIndex
├── objects
├── refs
    └── heads
        └── main
  • HEAD:指向当前分支的引用。它包含在 refs/heads/ 中的当前分支的路径。
HEAD -> refs/heads/main
  • stageIndex:一个二进制文件,用于跟踪下一个提交的暂存文件。它也被称为暂存区。
  • objects/:包含构成仓库历史的所有对象(blobs、树和提交)。
objects/
    ├── 1234567890abcdef...
    ├── 34567890abcdef12...
    └── ...
  • refs/:存储指向提交对象的引用。它包含 heads/ 用于本地分支。
refs/
    └── heads/
        └── main

4. 项目结构 (Java)

Gitlet
├── Main.java
├── Commands.java
├── Branch.java
├── Commit.java
└── Utils.java

更多信息请查看 我的实现

现在,开始造轮子吧!