diff --git "a/\347\254\254\344\272\214\351\230\266\346\256\265\344\273\273\345\212\241\350\247\243\350\257\273.md" "b/\347\254\254\344\272\214\351\230\266\346\256\265\344\273\273\345\212\241\350\247\243\350\257\273.md" new file mode 100644 index 0000000..fa132e7 --- /dev/null +++ "b/\347\254\254\344\272\214\351\230\266\346\256\265\344\273\273\345\212\241\350\247\243\350\257\273.md" @@ -0,0 +1,121 @@ +## 第二阶段任务大纲: + +**首先改进第一阶段的代码和文档,再进行第二阶段的任务。** + +**具体如下:** + +#### 一. 更新第一阶段的代码 + + 1. 只留两个类,一个是Key-Value类,一个是UnitTest类 + + 2. 不再分blob类、tree类、commit类。全部统一封装到key-value类中,针对这三种类型提供三种重载构造方法来实例化相应的key-value对象。在key-value类中统一提供getkey和setkey方法以及getvalue方法(同样是重载函数实现多态)。 + + 3. 单元测试类,根据学长的建议:使用代码来生成一些文件,并用这些文件进行测试。这样就实现了测试用例的生成以及验证的自动化。 + + 4. sha值计算方法按照张学长以及陈鹏同学提供的方法进行补足长度的优化(小组成员搞清楚原理) + + 5. 整理第一阶段的设计文档:文档内容包括①某个类具体提供了什么方法和数据域;②为什么要进行这种设计的理由 + +#### 二. 实现Commit + +##### 2.1 内容要求: +- 需要存储指向当前最新commit的HEAD指针 + +- 每次新生成一个commit前,需要把根目录的tree key与已有的最新commit的tree key进行比较,发现不相同时(即文件发生了变动)才添加这个commit + + +##### 2.2 我的想法: + +如果我对一个工作区目录里的一些内容提交commit,会有两处变化:①commit文件、②HEAD文件 +具体如下: + +---------------------------------------------------------------------------------------------- + +##### 2.2.1 commit文件: + key-value类中新增commit的构造方法来生成commit的key-value文件。 + + 1) commit文件中显示的内容形如:学长《第一周总结》ppt里第6页展示的信息,即: + + 1. precommitkey(构造commit对象时会调用setprecommitkey方法来修改这个属性) + + 2. 当前提交内容的key(这里的key一定是根目录的tree key) + + 3. author信息、 + + 4. commiter信息、 + + 5. commit时的说明信息 + + 2)实现构思 + + 重载key-value类里面的构造方法,方法体中要进行如下条件判断: + + 需要把根目录的tree key与已有的最新commit的tree key进行比较,发现不相同时(即文件发生了变动)才添加这个commit + + 3)应该提供的方法: + + 1. setnote方法(commit说明) + + 2. setbranch方法(建立分支) + + 3. setprecommitkey方法(每次commit读当前HEAD文件里那一条commitkey并附给私有属性precommitkey) + + 4. gitreset方法(回退到某次commit) + + 5. getcommiter方法(得到当前commiter信息) + + 6. getauthor方法(得到当前author信息) + + 7. getprecommitkey方法(得到上次commit的key,猜想通过链表实现) + + 8. viewlog方法(查看commit历史) + + 9. getbranch方法(得到当前的分支信息) + + 10. getnote方法(得到某次commit的注释信息) + + 11. getvalue方法(得到某次commit里的所有信息blob key,tree key,author等等) + + 12. getdiff方法(得到当前commit和某次commit之间哪些文件发生了差异) +---------------------------------------------------------------------------------------------- + +##### 2.2.2 HEAD文件: + 仓库里始终只有一个HEAD文件,在第一次commit时会被创建,HEAD文件里面保存的是当前一个具体分支指向的一个具体commit(考虑到后期可能会有多个分支,每个分支都有自己的HEAD) + + 1)HEAD文件中显示的内容形如: + + 分支名字1----当前分支1的HEAD指针指向的commit的key值 + + 分支名字2----当前分支2的HEAD指针指向的commit的key值 + +​ + +#### 三. 解读、疑惑、知识分享 +##### 3.1 关于gitreset()方法的解读 + + 我理解gitreset()就是将HEAD指针移动到某次commit,可以有这样两种重载方法: + + 1. gitreset(int i)i为回退的次数来回到某次commit(通过回退次数调整HEAD指针) + + 2. gitreset(string key)来回到某次key对应的commit(通过commit id调整HEAD指针) + +##### 3.2 存在的疑惑 +##### 3.2.1 gitreset方法联系git log方法的疑惑: + + 1)疑惑1:假设有x+n次commit,此时我调用gitreset方法回到第x次commit后再调用git log是不是不会显示第x次commit后的提交的n次commit信息呢? + + 2)疑惑2:如果我借助一个log文件缓存我的commit信息,这样就可以直接读这个文件来实现gitlog即查看日志方法 + + log文件实现构思: + 每次有新的commit提交时,就会在文件尾加入这个commit的信息。 + 具体更新的内容包括: + 1.这个commit的key值 + 2.这个commit和precommit的比较信息(key值有无变化) + 3.这个commit所属的分支信息(显示对应分支的名字): + 学长的解答时如果用这种利用文件缓存的方法实现gitlog,那么git reset后还需要更新git log里的信息。这里的逻辑是因为git reset会擦去某次commit(reset后的HEAD指向commit)后的一些commit信息,所以才要更新git log吗? + +##### 3.3 知识分享 + + 1.为什么要对byte[]进行&0xff的原理介绍:https://my.oschina.net/andyfeng/blog/1592690 + +