当前位置: 首页 > 科技观察

如果你非要了解GIT系统...-练习

时间:2023-03-21 19:36:06 科技观察

git被定义为内容寻址的文件系统。内容、寻址、文件、系统,该来的总会来的……本文旨在通过实践介绍.git文件夹中的目录和文件功能,属于git基础知识。不过在这个基础上,可以解决git使用过程中可能遇到的问题,比如“那个.等等,废话少说,撸起袖子看看.git是个什么样子,这些东西是做什么用的”.#初始化git,查看内容gitinit生成一个.git隐藏文件夹cd.gitls-F1#Initialization.git在日常工作中是这样的#HEAD#config#description#hooks/#info/#objects/#refs/#。git大概是这样的#COMMIT_EDITMSG#config#description#hooks/#index#info/#logs/#objects/#refs/后面各种git操作,都会有类似COMMIT_EDITMSG的功能比如MERGE_HEAD,MERGE_MODE等文件、branches(分支信息)、lost-found(存储挂起/丢失的提交对象)、packed-refs(压缩后的refs记录)等,都是类似logs和objects功能的文件夹,以上面的.git为例简单介绍一下:COMMIT_EDITMSG最新的提交编辑信息;#写两个提交信息的姿势gitcommit#自动打开文件进行编辑,在文件中输入信息即可gitcommit-mmsg#信息会被删除保存到COMMIT_EDITMSG#如果需要修改提交信息,不能直接编辑COMMIT_EDITMSG,可以执行如下命令gitcommit--amend#Automaticallyopenthefileforediting,修改文件中的信息描述描述文件,打开后会提示创建git仓库Description(Unnamedrepository;编辑此文件“描述”以命名存储库。)。config文件包含项目特定的配置选项,比如一些常用的项目:[core]ignorecase是否忽略文件大小写;[remote"origin"]url配置远程仓库地址;[remote"origin"]fetch远程分支映射关系;[user]name用户名[user]email邮箱[alias]commandaliasconfiguration:cmt=commitormoreotherconfigparameters...全局配置文件在~/.gitconfig,Windows应该在Users/Administrator/.gitconfig.info/文件夹用来存放git仓库的一些信息,比如exclude#contains一个全局排除(globalexclude)文件用来放置那些不想被记录在.gitignore文件中的忽略模式(ignoredpatterns);echoforgitignore>git-ignoreechoforgitexclude>git-excludeechogit-ignore>.gitignoregitstatus#Onbranchtest#Untrackedfiles:#(use"gitadd..."toincludeinwhatwillbecommitted)#.gitignore#git-exclude#git-ignore被忽略了,还有2未跟踪文件cd.gitcdinfo/viexclude#***添加一行git-excludedec../..gitstatus#Onbranchtest#Untrackedfiles:#(use"gitadd..."toincludeinwhatwillbecommitted)#.gitignore#git-excludealreadyIgnored,only.gitignoreoruntracked除了exclude文件外,还可能有refs,grafts,attributes等文件。hooks/文件夹包含客户端或服务端的钩子脚本(hookscripts),比如pre-commit,post-receive等:vi.git/hooks/pre-commit#保存以下信息***行指定执行什么#!/bin/shecho"Messageforprecommit";exit1;#开启执行权限chmod+x.git/hooks/pre-commit#user+group+otherexecutex(1)权限,注意r(4,read),w(2,write),x(1,execute),-(0,nopermission),s(特殊)touchcommit-hook-testgitadd.gitcommit-m"pre-committest"#Youwillseethefollowinginformation#Messageforprecommit#Ifyoudonotexit,continuetoexecute,fordetails,pleaserefertothe*.samplefileunder.git/hooks/#Messageforprecommit#[test038e6ec]pre-committest#1filechanged,1insertion(+),1deletion(-)logs/放置git仓库操作记录的文件夹,包含HEAD文件和refs文件夹HAED文件包含对git分支的操作记录,如viHEAD#99a10c283c33beed7f31c210a6c8b411d2a310855daf6094ea2cc60d17e947c0435096a4bdafe82dyeshou1535082919+0800commit:rmfiles#5daf6094ea2cc60d17e947c0435096a4bdafe82db8e02a5f9c2bf44342d15f5ea1e60ffd9434765ayeshou1535087285+0800checkout:movingfromtesttomaster#Firstdeletethefileandsubmititonce,andthencheckouttothemasterrefsfolderbytest,includingtheheadsfolderandtheremotefolder.headsrecordtheoperationrecordsofeachgitbranchrelatedtothelocal,andremoterecordstheoperationrecordsofeachgitbranchrelatedtotheremotewarehouseTheHEADfileindicatesthebranchthatiscurrentlycheckedout(whereitislocated).Ifitiscurrentlyinthetestbranch,thefilecontentisref:refs/heads/test.Theindexfileisthefileindexofthecurrentversion,whichcontainsallthevirtualinformationtogeneratethecurrenttree(uniquelydetermined)object,andcanbeusedtoquicklycomparethedifferencebetweentheworkingtreeandothercommittreeobjects(thediffbetweeneachcommitandHEAD),availableUsefulforstoringmultipleversionsofasinglefiletoefficientlyresolvemergeconflicts.Youcanusegitls-filestoviewthecontentsoftheindexfile.例如:gitcommit的一个commit根据index中的信息生成一个tree对象,存储到对象数据库中,并与本次新的commit关联,生成本次commit的tree信息(在介绍中会提到)提交和树下的对象)。refs/(引用)文件夹存放提交对象指针指向数据(分支);heads文件夹记录了内部文件名对应的分支的??提交对象;tags记录了内部文件名对应的标签的提交对象;remotes记录了内部文件对应名称的远程仓库分支的提交对象;例如:cat.git/refs/heads/master#ce1fed3fdbaf12e816e3028055f9feee57b33b45当前master的提交记录gitcheckout-btest#checkout一个新分支find.git#不止一个。heads/test文件gitlog#commit63a85dcbc6978f2d43996f5bebc38993c2afadaa(HEAD->test)#Author:yeshou#Date:SatAug2513:57:262018+0800##branchtest:edittest:addline:writed#commitce1fed3fdbaf12e816e3028055f9feee57b33b45(master)#Author:yeshou#Date:SatAug2512:40:352018+0800##edittest:addline:writeccat.git/refs/heads/test#63a85dcbc6978f2d43996f5bebc38993c2afadaa当前测试的最新commit记录cat.git/refs/heads/master#ce1fed3fdbaf12e816e3028055f9feee57b33b45仍然是当前master最近的commit记录,另外两个也是。objects/文件夹用于存放git仓库中的所有数据内容。循序渐进...先看看数据内容是如何存放在这个文件夹中的,然后再了解数据内容是什么。#为了清楚了解objects文件夹中文件的生成,进行初始化。.git#objects下多了一个文件夹,里面有个文件#.git/objects/44#.git/objects/44/2406aa9341668f9c43c2d5378a777ad69324a0,验证这个文件的内容是什么。注意这是一个二进制球,呸……是一个文件,文明看球,呸……是在看。这里我们使用git中传说中的手术刀(gitcat-file)来剖析git文件。gitcat-file-p442406aa9341668f9c43c2d5378a777ad69324a0#outputa9de29bb2d1d6434b8b29ae775ad8c2e48c5391是一个二进制文件,是git对象中的一个blob对象,记录了当前版本文件的数据内容,并使用SHA生成一个40位字符的校验和按照官方的描述:这是一个SHA-1哈希值——对要存储的数据进行SHA-1校验运算得到的校验和加上一个header。继续操作,修改testvitest#第二行,输入b,保存,退出gitaddtestfind.git#objects又多了一个文件夹,里面还有一个文件#.git/objects/bf#.git/objects/bf/daa0f1c3415c09d3080063911d155fd7259d18这个时候二进制文件的数据内容是a(手动包装的)b。Keepgoing:gitcommit-m"addtest"#wtf,whydid2folderssuddenlyappear,comeandseethecontent#.git/objects/3e#.git/objects/3e/5f95cd5c4f0ff429522b0fdfeda9369f92d89c#.git/objects/fd#.git/objects/fd/1332e4e95f8a64682c1516e175abb66b6f6325gitcat-file-tfd1332e4e95f8a64682c1516e175abb66b6f6325#commitgitcat-file-pfd1332e4e95f8a64682c1516e175abb66b6f6325#tree对象、作者、提交者、提交日期、提交信息、父对象(有的话带一个或多个父对象)#tree3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c#authoryeshou1535168447+0800#committeryeshou1535168447+0800#adddir-testgitcat-file-t3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c#treegitcat-file-p3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c#100644blobbfdaa0f1c3415c09d3080063911d155fd7259d18testgitcat-file-pbfdaa0f1c3415c09d3080063911d155fd7259d18#a(换行)b3e5f95cd5c4f0ff429522b0fdfeda9369f92d89cisalsoabinaryfile,whichisatreeobjectinthegitobject,whichrecordstheblobidentifier,pathnameandmetadataofallfilesunderatree.fd1332e4e95f8a64682c1516e175abb66b6f6325是另外一个二进制文件,是git对象中的commit对象,记录了当前版本的一个commit数据的内容,包括树对象、作者、提交者、提交日期、提交信息、父对象(如果有的话,带来一个或多个父对象)。那么,pack文件夹是做什么用的呢?由于objects文件夹下的文件夹和文件是不断生成的(即N次commit后),objects文件夹明显会“长大”,开发者可以使用gitgc对之前操作的对象进行整理压缩。pack文件夹中有两个文件pack-(SHA-1).pack和pack-(SHA-1).idx。前者是以压缩形式存储以前记录的对象的文件,后者用于存储访问索引文件。例如:gitgc#Countingobjects:12,done.#Deltacompressionusingupto4threads.#Compressingobjects:100%(4/4),done.#Writingobjects:100%(12/12),done.#Total12(delta0),reused0(delta0)find.git#发现objects里面很多文件夹和文件都丢失了,添加了下面2个文件git/objects/pack/pack-2021ec3cb18c796fdfca8ef616fb6a20b1449ab1.idx#列出之前存在ob??jects里的所有操作数据内容#655a12c9b83a029bb46fa852ea15e6affd1587d8commit167117510#...#616dfdb2643c725fa1027ecef76d49d482d9e26dtree3243670#...#bfdaa0f1c3415c09d3080063911d155fd7259d18blob514853#也可以通过后面加|grepkeyword来Searchfortherequired内容,如下列出所有commit记录gitverify-pack-v.git/objects/pack/pack-2021ec3cb18c796fdfca8ef616fb6a20b1449ab1.idx|grepcommitgitgc(垃圾收集)命令会收集所有松散的对象,并将它们存储在pack中,将这些pack合并到一大pack,然后删除没有被任何commit引用且已经存在了一段时间(几个月)的对象,另外将所有引用合并到一个文件中(上面提到的各种操作,.git下会生成更多的文件夹,并且此时会生成.git中的packed-refs文件夹)。该命令可以通过修改配置中的gc.auto和gc.autopacklimit来调整运行阈值。注意:gitgc也会调用gitprune,有需要的也可以关注这个命令。至于“信息文件夹是做什么用的?”这个问题还是未知数。。。没看懂官网上的描述,也没有在这个文件夹里找到项目中实际出现的文件,还是等遇到了再说?至此git对象中的三个对象已经知道是怎么回事了,还有一个tags对象,简单介绍一下。tags对象通常也是一个commit对象,它指的是一个特殊的对象,它指定了一个开发者可读的名称,如果需要可以通过gitcat-file来解析和探索。它们之间的关系大致如下:|-commitaaaaa...|-treeabbbb...|-blobacccc...(可能是本次修改)|-blobadddd...(可能是上次修改)|-treeaeeee...|-blobaffff...|-commitbbbbb...至于关系图,这个来自git官网...和上面的结构是一样的。基于对象的介绍,回过头来看“内容、寻址、文件、系统”会更加清晰:以git对象为内容,通过唯一校验寻址,以文件形式存储的版本控制系统。了解了这些之后,主要是希望能够应用到实际生产中去解决问题。如《为什么项目中的.git文件这么大?怎么处理?》可能的解决方法:1、执行gitgc,如果压缩后能达到预期的效果,就不要做太多的处理2、对于历史文件引用中的一些大文件,删除对应的引用对象,操作如下gitgcgitcount-objects-vgitverify-pack-v.git/objects/pack/pack-(SHA-1).idx|sort-k3-n|tail-5使用gitverify-pack后,我们可以知道其中的信息所代表的文件大小第三栏。在这里,使用tail来获取前5个较大文件的记录。gitrev-list--objects--all|grep(SHA-1)#使用gitrev-list--objects-all查看指定的(SHA-1)对象信息#ce1fed3fdbaf12e816e3028055f9feee57b33b45xxx.mp4比如是视频文件gitlog--pretty=oneline--branches--xxx.mp4#找出哪些提交修改/操作了这个文件#94cbe08e...addxxx.mp4gitfilter-branch--index-filter'gitrm--cached--ignore-unmatchxxx。mp4'--94cbe08e^..#删除文件引用,改写信息...rm-rf.git/refs/originalrm-rf.git/logs/gitgc#删除.git/refs/original和.git/logs/,处理仍然存在的xxx.mp4文件的引用,然后重新打包仓库gitcount-objects-v#运行size后查看文件,或者直接在.git目录下执行du-h-d1查看一级大小目录/文件。然后初始化git仓库,操作如下以上指定githooks的参考,参考Customizing-Git-Git-Hookshttps://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks更详细的.git文件夹,参考Gitrepository-layout-objectsinfohttps://git-scm.com/docs/gitrepository-layout#gitrepository-layout-objectsinfo