CS61b gitlet 项目完结撒花

main函数

在主函数里,只需要判断用户是使用哪个命令,进入Repository.java文件寻找对应的函数命令。
特别的地方只有在一开始需要判断gitlet是否已经初始化,即是否已经执行过init命令,这用于在当前文件夹下创建版本控制需要的文件夹GITLET_DIR 。其他命令都需要之前执行过init命令后才能执行。

GITLET_DIR文件夹结构

需要在当前的工作目录下创建GITLET_DIR文件夹,此文件夹内的文件结构如下:
其中OBJECT_DIR存储的是对象序列化之后的文件,BLOB_DIR存放的是Blob类的序列化对象,COMMIT_DIR存放的是Commit类的序列化对象。而STAGE_DIR存放的是不同版本的文件。其中ADDITION是下一次commit时提交的文件版本,REMOVAL存放的是下一次commit时要删除的文件版本。

        /* created the needed dirs and files, the file structure is shown as follows
        * GITLET_DIR
        *       OBJECT_DIR
        *               BLOB_DIR
        *               COMMIT_DIR
        *       STAGE_DIR
        *               ADDITION 
        *               REMOVAL 
        * */

Blob类

Blob类可用于保存不同版本的文件,类成员有文件名fileName和文件内容contents

Blob类的函数主要有2个:

  • saveBlob()函数将对象序列化后保存到文件夹BLOB_DIR中,每个对象序列化后可以通过哈希获得1个唯一的SHA编号,因此以此编号为文件名则可唯一地表示1个对象。
  • Blob fromFile(String SHA)则是获得从文件夹BLOB_DIR中文件名为SHA反序列化重新获得一个Blob对象。
public class Blob implements Serializable {
    /* The directory of all th blob obj file */
    public static File BLOB_DIR = join(OBJECT_DIR, "blob");
    /* The real filename */
    private String fileName;
    /* The contents of the file */
    private String contents;
    
    public void saveBlob();
    public static Blob fromFile(String SHA);
}

Commit类

用户可通过commit命令提交,因此用Commit类来表示1个提交命令:
其中的成员包括:

  • message: 提交时需要写入一个message,对当前的commit进行说明
  • timestamp: 在提交时,gitlet会自动生成一个时间戳timestamp表示提交时间
  • parent: 除了initcommit用于初始化.gitlet文件夹外,其他commit均会有1个commit父亲,表示当前commit是从哪个commit而来
  • secondParent: 在merge命令实现了将2个commit合并成1个commit,因此合并出来的commit会有2个父亲,此时第2个父亲则为secondParent。注意parent均用字符串表示。因为每个commit对象在确认无误后,会和Blob一样序列化为以SHA编号为文件名的文件保存在COMMIT文件夹中。因此其父亲则用其父亲对象序列化后生成的SHA编号字符串表示即可。
  • filePointer: 这个map类型用于存储当前提交的所有文件名,以及此文件名对应的版本,这是1个commit的实际有效内容。文件版本原本只是包含内容,但是为了版本更新方便,将文件内容连同文件名存储到Blob对象中,再用此对象序列化后保存以SHA编号为文件名的文件。mapkey则为实际文件名,value为生成Blob对象序列化后的SHA编号。

Commit类的成员函数:

  • 类似Blob类,有序列化后生成对象的对应文件的函数void saveCommit(),有从文件生成对应对象的函数public static Commit fromFile(String SHA)
  • public String toString() :在log命令打印日志时,需要将提交commit的信息打印出来,因此需要toString函数输出commitSHA编号,生成日期,提交信息。
  • public void tracking(TreeMap addedFiles, TreeMap removedFiles):在提交commit时,需要将STAGE文件夹中添加或删除的文件更新到当前commitfilePointer中,因此需要tracking函数添加或修改addedFiles的文件版本,而删除removedFiles中的文件版本。
public class Commit implements Serializable {
    /**
     * TODO: add instance variables here.
     *
     * List all instance variables of the Commit class here with a useful
     * comment above them describing what that variable represents and how that
     * variable is used. We've provided one example for `message`.
     */
    /* The directory where all the commit obj store. */
    public static File COMMIT_DIR = join(OBJECT_DIR, "commit");
    /* The message of this Commit. */
    private String message;

    /* The parent of this Commit. */
    private String parent;
    private String secondParent;

    /* The time at which this Commit is created. */
    private Date timestamp;

    /* Store the fileName and the blob references
    *  key: fileName
    *  value: ref of blob object
    * */
    private TreeMap<String, String> filePointer;
}

Stage类

  • 静态成员:Stage类中没有实际的非静态成员,因为主要是使用函数进行文件版本的更新。其中有3个静态成员,均是文件夹和文件路径。其中ADDITION文件存放的是要添加或更新的文件版本列表,为 TreeMap对象的序列化结果,第1个String为文件名,第2个String为文件名对应版本的Blob对象序列化后的SHA编号,因此此对象和Commit类中的filePointer成员类型是相同的。REMOVAL文件存放和ADDITION类似,是要删除的文件名和文件版本。

成员函数:

  • 成员函数有2种
    • 对于整个STAGE_DIR文件夹的
      • public static HashSet getUntrackedFiles()
    • 对于单个文件的,即单针对ADDITION文件或单针对REMOVAL文件的,在这样的函数传入File stageChoice参数来决定是针对哪个文件,增加代码复用,减少码量:
      • static void stageClear(File stageChoice):删除选定文件中的所有文件版本。
      • static void StageAdd(String addedFileName, File stageChoice):为选定文件添加或修改当前工作目录下的addedFileName版本,
public static File STAGE_DIR = join(GITLET_DIR, "stage");
/* store the SHA of the blob */
public static File ADDITION = join(STAGE_DIR, "addition");
public static File REMOVAL = join(STAGE_DIR, "removal");

CS61b gitlet 项目完结撒花_第1张图片

你可能感兴趣的:(java,开发语言,git)