中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

如果非得了解下 git 系統(tǒng)… – 實(shí)踐篇

2018-09-17    來源:importnew

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

git的定義是一個(gè)內(nèi)容尋址文件系統(tǒng)。內(nèi)容、尋址、文件、系統(tǒng),該來的總會(huì)來的…

本文旨在通過實(shí)踐來介紹.git文件夾中的目錄及文件功能,屬git基礎(chǔ)知識(shí)。但在此基礎(chǔ)上可解決各git使用過程中可能遇到的問題,如“.git文件夾占用空間大”,“git如何找回丟失的對(duì)象(提交)”,”git diff 對(duì)比依據(jù)是什么”等,

話不多說,擼起袖子就是干,來看看 .git 是個(gè)啥樣,這些個(gè)貨色都是干嘛的。

# 初始化git,查看內(nèi)容
git init 產(chǎn)生一個(gè).git隱藏文件夾
cd .git
ls -F1
# 初始化時(shí)的.git長這樣
# HEAD
# config
# description
# hooks/
# info/
# objects/
# refs/
# 日常工作中的.git大概長這樣
# COMMIT_EDITMSG
# config
# description
# hooks/
# index
# info/
# logs/
# objects/
# refs/

隨著之后的多種 git操作 ,還會(huì)存在如 MERGE_HEAD 、 MERGE_MODE等和 COMMIT_EDITMSG 類似功能的文件,branches(分支信息)、lost-found(存儲(chǔ)被懸掛起/丟失的提交對(duì)象)、packed-refs(壓縮后的refs記錄)等和logs、objects類似功能的文件夾。

以上面的.git為例做個(gè)簡單的介紹:

COMMIT_EDITMSG?最近一次的 commit edit message ;

# 編寫提交信息的兩種姿勢(shì)
git commit
# 自動(dòng)打開文件編輯,在文件中輸入信息即可
git commit -m msg
# 信息都會(huì)被保存到 COMMIT_EDITMSG
# 如需修改提交信息,不可直接編輯COMMIT_EDITMSG,可執(zhí)行以下命令
git commit --amend 
# 自動(dòng)打開文件編輯,在文件中修改信息即可

description?描述文件,打開后里面提醒該為git倉庫創(chuàng)建個(gè)描述(Unnamed repository; edit this file ‘description’ to name the repository.)。

config?文件包含項(xiàng)目特有的配置選項(xiàng),如一些常用項(xiàng):

[core] ignorecase 是否忽略文件大小寫;

[remote "origin"] url 配置遠(yuǎn)程倉庫地址;

[remote "origin"] fetch 遠(yuǎn)程分支映射關(guān)系;

[user] name 用戶名

[user] email 郵箱

[alias] 命令別名配置 : cmt = commit

抑或更多其他config參數(shù)…

全局配置文件在 ~/.gitconfig ,Windows應(yīng)該是在Users/Administrator/.gitconfig。

info/?文件夾用以存儲(chǔ)一些有關(guān)git倉庫的信息,如exclude

# 包含一個(gè)全局性排除(global exclude)文件,用以放置那些不希望被記錄在 .gitignore 文件中的忽略模式(ignored patterns);
echo for git ignore > git-ignore
echo for git exclude > git-exclude
echo git-ignore > .gitignore
git status
    
# On branch test
# Untracked files:
# (use "git add <file>..." to include in what will be committed)

# .gitignore
# git-exclude

# git-ignore已被忽略,還有2個(gè)untracked的文件

cd .git
cd info/
vi exclude
    
# 最后一行新增 git-exclude
    
cd ../..
git status
# On branch test
# Untracked files:
# (use "git add <file>..." to include in what will be committed)

# .gitignore

# git-exclude 已被忽略,只有.gitignore還是untracked

除exclude文件外,還可能會(huì)有refs、grafts,attributes等文件

hooks/?文件夾包含客戶端或服務(wù)端的鉤子腳本(hook scripts),如pre-commit,post-receive等:

vi .git/hooks/pre-commit
# 保存以下信息  第一行指定用什么執(zhí)行
#!/bin/sh
echo "Message for pre commit";
exit 1;
# 開執(zhí)行權(quán)限
chmod +x .git/hooks/pre-commit   # user+group+other 執(zhí)行x(1)權(quán)限  ,備注 r(4,read),w(2,write),x(1,execute),-(0,no permission),s(special)
    
touch commit-hook-test
git add .
git commit -m “pre-commit test“
# 你會(huì)看到以下信息
# Message for pre commit

# 如果不exit,則繼續(xù)執(zhí)行,詳情可參考.git/hooks/下的*.sample文件
# Message for pre commit
# [test 038e6ec] pre-commit test
# 1 file changed, 1 insertion(+), 1 deletion(-)

logs/?放置git倉庫操作記錄的文件夾,包含HEAD文件 和 refs文件夾。

HAED 文件包含對(duì) git分支 的操作記錄,如

vi HEAD
# 99a10c283c33beed7f31c210a6c8b411d2a31085 5daf6094ea2cc60d17e947c0435096a4bdafe82d yeshou <yeshou@xxx.com> 1535082919 +0800       commit: rm files
# 5daf6094ea2cc60d17e947c0435096a4bdafe82d b8e02a5f9c2bf44342d15f5ea1e60ffd9434765a yeshou <yeshou@xxx.com> 1535087285 +0800        checkout: moving from test to master
# 先是刪除文件后提交了次,再是由test檢出到master

refs 文件夾包含 heads 文件夾,remote文件夾。heads 記錄本地相關(guān)的各 git分支 操作記錄,remote 記錄遠(yuǎn)程倉庫相關(guān)的各 git分支 操作記錄

cd heads
ls
# master   master分支操作記錄
# test     test分支操作記錄

cd remote/origin
ls
# master  遠(yuǎn)程master分支操作記錄
# test    遠(yuǎn)程test分支操作記錄

HEAD?文件指示當(dāng)前被檢出(所在)的分支,如當(dāng)前在test分支,文件內(nèi)容則為ref: refs/heads/test。

index?文件是當(dāng)前版本的文件索引,包含生成當(dāng)前樹(唯一確定的)對(duì)象的所虛信息,可用于快速比對(duì)工作樹和其他提交樹對(duì)象的差異(各commit和HEAD之間的diff),可用于存儲(chǔ)單文件的多個(gè)版本以有效的解決合并沖突。可使用git ls-files 查看index文件內(nèi)容。如:

git commit 的一次提交從index中的信息生成tree對(duì)象,將其存儲(chǔ)在對(duì)象數(shù)據(jù)庫中,并與本次新的commit做關(guān)聯(lián),產(chǎn)生本次commit的tree信息(下面的objects介紹中會(huì)提到commit和tree)。

refs/?(references) 文件夾存儲(chǔ)指向數(shù)據(jù)(分支)的提交對(duì)象指針;其中 heads 文件夾記錄內(nèi)部文件對(duì)應(yīng)名稱的分支的提交對(duì)象;tags記錄內(nèi)部文件對(duì)應(yīng)名稱的標(biāo)簽的提交對(duì)象;remotes記錄內(nèi)部文件對(duì)應(yīng)名稱的遠(yuǎn)程倉庫分支的提交對(duì)象;

舉個(gè)例子:

cat .git/refs/heads/master
 # ce1fed3fdbaf12e816e3028055f9feee57b33b45 當(dāng)前master的提交記錄
 git checkout -b test # 檢出一個(gè)新分支
 find .git
 # 多了個(gè) .git/refs/heads/test 文件
 git log

 # commit 63a85dcbc6978f2d43996f5bebc38993c2afadaa (HEAD -> test)
 # Author: yeshou <yeshou@xxx.com>
 # Date:   Sat Aug 25 13:57:26 2018 +0800
 #
 # branch test : edit test : add line : write d

 # commit ce1fed3fdbaf12e816e3028055f9feee57b33b45 (master)
 # Author: yeshou <yeshou@xxx.com>
 # Date:   Sat Aug 25 12:40:35 2018 +0800
 # 
 # edit test : add line : write c

 cat .git/refs/heads/test
 # 63a85dcbc6978f2d43996f5bebc38993c2afadaa   當(dāng)前test的最近提交記錄
 cat .git/refs/heads/master
 # ce1fed3fdbaf12e816e3028055f9feee57b33b45 依然是當(dāng)前master的最近提交記錄

另兩者亦然。

objects/?文件夾用以存儲(chǔ)git倉庫中的所有數(shù)據(jù)內(nèi)容。

一步步來…

先看看這個(gè)文件夾里是怎么存數(shù)據(jù)內(nèi)容的,再理解這些數(shù)據(jù)內(nèi)容又是什么。

# 為了清晰的看明白o(hù)bjects文件夾中文件的生成,初始化.git
rm -rf .git
git init  
cd .git 
find .git # 這時(shí)候objects文件夾下只有pack和info 兩個(gè)空文件夾
touch test
vi test
# 輸入 a ,保存,退出
git add test
find .git
# objects 下多了個(gè)文件夾,且里面有文件
# .git/objects/44
# .git/objects/44/2406aa9341668f9c43c2d5378a777ad69324a0

驗(yàn)證下這個(gè)文件內(nèi)容是什么,注意,這是個(gè)二進(jìn)制球,呸…是文件,文明觀球,呸…是觀看。這里我們用傳說中g(shù)it中的手術(shù)刀(?git cat-file?)來解剖git文件。

git cat-file -p 442406aa9341668f9c43c2d5378a777ad69324a0
# 輸出 a

9de29bb2d1d6434b8b29ae775ad8c2e48c5391 是個(gè)二進(jìn)制文件,是git對(duì)象中的blob對(duì)象,它記錄了當(dāng)前版本的該文件的數(shù)據(jù)內(nèi)容,并以SHA-1計(jì)算產(chǎn)生一個(gè)40個(gè)字符的校驗(yàn)和。 根據(jù)官方描述:這是一個(gè) SHA-1 哈希值——一個(gè)將待存儲(chǔ)的數(shù)據(jù)外加一個(gè)頭部信息(header)一起做 SHA-1 校驗(yàn)運(yùn)算而得的校驗(yàn)和。

繼續(xù)操作,修改test

vi test
# 第二行輸入 b ,保存,退出
git add test
find .git
# objects 下又多了個(gè)文件夾,且里面也有文件
# .git/objects/bf
# .git/objects/bf/daa0f1c3415c09d3080063911d155fd7259d18

這次的二進(jìn)制文件的數(shù)據(jù)內(nèi)容是 a (手動(dòng)換行) b 。

繼續(xù)走下去:

git commit -m “add test”
# wtf,怎么突然生出2個(gè)文件夾,來來來,看看內(nèi)容
# .git/objects/3e
# .git/objects/3e/5f95cd5c4f0ff429522b0fdfeda9369f92d89c
# .git/objects/fd
# .git/objects/fd/1332e4e95f8a64682c1516e175abb66b6f6325
git cat-file -t fd1332e4e95f8a64682c1516e175abb66b6f6325
# commit
git cat-file -p fd1332e4e95f8a64682c1516e175abb66b6f6325
# tree對(duì)象、作者、提交者、提交日期、提交信息、父對(duì)象(有的話帶一個(gè)或多個(gè)父對(duì)象)
# tree 3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c 
# author yeshou <yeshou@xxx.com> 1535168447 +0800
# committer yeshou <yeshou@xxx.com> 1535168447 +0800 
# add dir-test    
git cat-file -t 3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c
# tree
git cat-file -p 3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c
# 100644 blob bfdaa0f1c3415c09d3080063911d155fd7259d18    test
git cat-file -p bfdaa0f1c3415c09d3080063911d155fd7259d18
# a (換行) b

3e5f95cd5c4f0ff429522b0fdfeda9369f92d89c 也是個(gè)二進(jìn)制文件,是git對(duì)象中的tree對(duì)象,記錄著blob標(biāo)識(shí)符、路徑名和在一個(gè)tree下的所有文件的元數(shù)據(jù)。

fd1332e4e95f8a64682c1516e175abb66b6f6325 又是個(gè)二進(jìn)制文件,是git對(duì)象中的commit對(duì)象,它記錄了當(dāng)前版本的一次提交數(shù)據(jù)內(nèi)容,包含tree對(duì)象、作者、提交者、提交日期、提交信息、父對(duì)象(有的話帶一個(gè)或多個(gè)父對(duì)象)。

然后,pack文件夾是干嘛的?

隨著objects文件夾下的文件夾和文件不斷生成(也就是N多次的commit之后),objects文件夾明顯會(huì)”長大”,這時(shí)開發(fā)者可以用 git gc 來對(duì)之前的操作的對(duì)象做整理壓縮。
pack 文件夾內(nèi)有2個(gè)文件 pack-(SHA-1).pack 和 pack-(SHA-1).idx 前者是以壓縮形式存儲(chǔ)之前記錄對(duì)象的文件,后者用以存儲(chǔ)訪問索引的文件。

舉個(gè)例子:

git gc 
# Counting objects: 12, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (4/4), done.
# Writing objects: 100% (12/12), done.
# Total 12 (delta 0), reused 0 (delta 0)
find .git
# 發(fā)現(xiàn)少了很多objects里的文件夾和文件,多了以下2個(gè)文件
# .git/objects/pack/pack-2021ec3cb18c796fdfca8ef616fb6a20b1449ab1.pack
# .git/objects/pack/pack-2021ec3cb18c796fdfca8ef616fb6a20b1449ab1.idx
git verify-pack -v .git/objects/pack/pack-2021ec3cb18c796fdfca8ef616fb6a20b1449ab1.idx
# 列出之前存在objects里的所有操作數(shù)據(jù)內(nèi)容
# 655a12c9b83a029bb46fa852ea15e6affd1587d8 commit 167 117 510
# ...
# 616dfdb2643c725fa1027ecef76d49d482d9e26d tree   32 43 670
# ...
# bfdaa0f1c3415c09d3080063911d155fd7259d18 blob   5 14 853
# 也可以通過后面加 | grep keyword 來搜索所需的內(nèi)容,如下列出所有commit記錄
git verify-pack -v .git/objects/pack/pack-2021ec3cb18c796fdfca8ef616fb6a20b1449ab1.idx | grep commit

git gc ( garbage collect )命令將會(huì)收集所有松散對(duì)象并將它們存入 pack,合并這些 pack 進(jìn)一個(gè)大的 pack,然后將不被任何 commit 引用并且已存在一段時(shí)間 (數(shù)月) 的對(duì)象刪除,除此之外還會(huì)將所有引用 (references) 并入一個(gè)單獨(dú)文件(上面有提到隨著各種操作,.git下還會(huì)產(chǎn)生更多文件夾,.git中的packed-refs文件夾就是這時(shí)候產(chǎn)生的)。該命令可能通過修改配置中的 gc.auto 和 gc.autopacklimit 來調(diào)整操作閾值。注意:git gc 調(diào)用的也是 git prune ,如有需求也可關(guān)注這個(gè)命令。

至于”info文件夾是干嘛的?”這個(gè)問題還未知…? 官網(wǎng)的描述也沒看懂,也沒查到或者在項(xiàng)目中實(shí)際出現(xiàn)這個(gè)文件夾有存在什么文件,要么等遇到再說?

至此git對(duì)象中的三個(gè)對(duì)象已經(jīng)知道是咋回事了,還剩個(gè)tags對(duì)象,簡單介紹下。

tags對(duì)象通常也是一個(gè)commit對(duì)象,指的是一個(gè)指定了開發(fā)者可讀名稱的一個(gè)特殊對(duì)象,如有需要也可通過 git cat-file 來解析探索。

其間關(guān)系大致如下:

|- commit       aaaaa…
    |- tree       abbbb…
        |- blob       acccc… (可能是這次修改的)
        |- blob       adddd…(也可能是上次修改的)
        |- tree        aeeee…  
            |- blob        affff…

|- commit        bbbbb…

關(guān)系圖的話,這個(gè)是git官網(wǎng)的…? 和上面的結(jié)構(gòu)是一樣的。

基于objects的介紹再回過頭來看看”內(nèi)容、尋址、文件、系統(tǒng)”便比較清晰了:以git對(duì)象作為內(nèi)容,通過唯一的校驗(yàn)和尋址,文件形式存儲(chǔ)的一個(gè)版本控制系統(tǒng)。

了解完這些,主要還是希望能夠運(yùn)用到實(shí)際生產(chǎn)中來解決問題。如 “項(xiàng)目中.git文件為什么這么大?怎么處理?”

可能的處理方案:

1. 執(zhí)行 git gc ,如果壓縮后能達(dá)到預(yù)期效果,則不做過多處理

2.針對(duì)歷史記錄中對(duì)某些大文件的引用,則刪除對(duì)應(yīng)引用的對(duì)象,操作如下

git gc
git count-objects -v
git verify-pack -v .git/objects/pack/pack-(SHA-1).idx | sort -k 3 -n | tail -5
# 前面用過了git verify-pack,可知第三列信息表示的文件大小,這里用tail取前5個(gè)較大文件的記錄
git rev-list --objects --all | grep (SHA-1)
# 使用 git rev-list --objects -all 來查看指定 (SHA-1) 對(duì)象信息
# ce1fed3fdbaf12e816e3028055f9feee57b33b45 xxx.mp4  比如是個(gè)視頻文件
git log --pretty=oneline --branches -- xxx.mp4
# 找出哪些 commit 修改/操作了這個(gè)文件
# 94cbe08e... add xxx.mp4
git filter-branch --index-filter 'git rm --cached --ignore-unmatch xxx.mp4' -- 94cbe08e^..
# 刪除文件引用,rewrite 信息...
rm -rf .git/refs/original
rm -rf .git/logs/
git gc
# 刪除 .git/refs/original 和 .git/logs/ ,處理其中對(duì)xxx.mp4文件仍存在的引用,之后repack倉庫
git count-objects -v
# 檢查下操作后文件大小,或者直接在.git目錄下執(zhí)行 du -h -d 1 查看1級(jí)目錄/文件的大小

3.若還是難處理,或者不好處理,或者不想刪除大文件的引用,則備份一份.git,然后初始化git倉庫,操作如下

# 除去備份操作,備份操作使用者自定義
rm -rf .git
git init
git remote add origin xxx.git 
# 重新指向新的遠(yuǎn)程倉庫地址,也可根據(jù)上文所說修改config文件來指定
  • 關(guān)于git hooks,參考Customizing-Git-Git-Hooks
  • 關(guān)于更詳細(xì)的.git文件夾,參考?Gitrepository-layout-objectsinfo

標(biāo)簽: 腳本 開發(fā)者 權(quán)限 數(shù)據(jù)庫 搜索

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:SpringBoot | 第十九章:web 應(yīng)用開發(fā)之 WebSocket

下一篇:Java 內(nèi)存溢出排查