###简介本文是对GitPro10.2Git内部原理-Git对象章节的解读和改造。主要介绍两件事:1)使用Git底层命令完成commit,2)尝试使用NodeJS(文中提供的Ruby)解析Git对象。###0x001初始化一个本地仓库:$mkdirgit-test$cdgit-test$gitinitInitializedemptyGitrepositoryin...查看文件结构:+git-test+.git+branches-config-description-HEAD+hooks+info+objects+info+pack+refs暂时不关注其他的,只关注objects,此时只有info和pack两个文件夹,我们不关注,我们只关注注意除info和pack之外的对象下的变化。0x002hash-object此命令用于计算文件的对象ID,并可能创建blob文件。这里有两层意思:1)计算对象ID,对象ID是什么?2)什么是blob文件?为什么可能?接下来会给出答案。执行命令:$echo'测试内容'|githash-object-w--stdind670460b4b4aece5915caf5c68d12f560a9fe3e4-w指示hash-object存储数据对象,如果不指定则返回计算出来的objectId。--stdin表示从标准输入中读取内容,即测试内容作为内容计算。当我们执行这个命令时,它会返回一个40个字符的SHA1哈希值。d670460b4b4aece5915caf5c68d12f560a9fe3e4,由于制定了-w,git会存储这次的计算,查看objects下的文件:+objects+d6-70460b4b4aece5915caf5c68d12f560a9fe3e4会发现,多了一个文件夹d6,而d6中有一个文件70460b4b4aece5915caf5c68d12f560a9fe3e4,这两者拼接ItlooksexactlyliketheobjectIDjustgenerated.Ifweexecutethiscommandmultipletimes,wewillfindthatthefilehasnotchangedbecauseitalreadyexists,whichisthereasonwhyitmaybegeneratedasmentionedearlier.Ifwechangethecontent,anewobjectIDandanewblobfilewillbegenerated.0x003cat-fileWehavealreadyfiguredouthowtostorefiles,sohowtoreadthem?可以使用cat-file$gitcat-file-pd670460b4b4aece5915caf5c68d12f560a9fe3e4testcontent0x004文件存储和版本恢复接下来我们使用文件,而不直接使用内容$echo'version1'>test.txt$githash-object-wtest.txt83baae61804e65cc73a7201a7252750c76066a30然后更新这个文件并存储$echo'version2'>test.txt$githash-object-wtest.txt1f7a7a472abf3dd9643fd615f6da379c4acb3e3a此时的objects+objects+1f-7a7a472abf3dd9643fd615f6da379c4acb3e3a+83-baae61804e65cc73a7201a7252750c76066a30+d6-70460b4b4aece5915caf5c68d12f560a9fe3e4然后吧文件内容恢复到第一个版本$gitcat-file-p83baae61804e65cc73a7201a7252750c76066a30>test.txt$cattest.txtversion1或者第二个版本$gitcat-file-p1f7a7a472abf3dd9643fd615f6da379c4acb3e3a>test.txt$cattest.txtversion20x005树对象和write-treeAddfilestothecache$gitupdate-index--add--cacheinfo100644\83baae61804e65cc73a7201a7252750c76066a30test.txtWritethecontentsofthecachetothetreeobject$gitwrite-treed8329fc1cc938780ffdd9f94e0d365e79ea74fcat-file-pd8329fc1cc938780ffdd9f94e0d364e0ea74f579100644blob83baae61804e65cc73a7201a7252750c76066a30test.txtCreateanewdataobjectcontainingthesecondversionoftest.txtandanewfile:$echo-xdate>$'newfilecacheinfo100644\1f7a7a472abf3dd9643fd615f6da379c4acb3e3atest.txt$gitupdate-index--addnew.txt$gitwrite-tree0155eb4229851634a0f03eb265b69f5a2d56f341$gitcat-file-p0155eb4229851634a0f03eb265b69f5a2d56f341100644blobfa49b077972391ad58037050f2a75f74e3671e92new.txt100644blob1f7a7a472abf3dd9643fd615f6da379c4acb3e3atest.txt0x006提交commit和commit-tree有了树对象之后,就可以提交该树对象,生成一个commit$echo'firstcommit'|gitcommit-treed8329fb51096bf62fa145c0b95ce18dc3020daa1f2556e查看这个commit$gitcat-file-pb51096bf62fa145c0b95ce18dc3020daa1f2556etreed8329fc1cc938780ffdd9f94e0d364e0ea74f579authorScottChacon
