一个 .git 目录,领悟 Git 的强大!
Git 是一個(gè)強(qiáng)大的工具,但是使用起來(lái)卻不是很友好。如果程序員們能夠真正花時(shí)間去理解 Git 的構(gòu)成,將會(huì)避免很多不必要的麻煩。
以下為譯文:
初學(xué) Git 就像一個(gè)不懂當(dāng)?shù)卣Z(yǔ)言的人來(lái)到一個(gè)陌生的國(guó)家——如果你知道自己在哪,該去哪里,那還好。一旦你迷路了,那麻煩就大了。
網(wǎng)上有很多學(xué)習(xí) Git 基本命令的文章,但是本文并不屬于這一類文章。我在此處將嘗試提供一個(gè)不同的學(xué)習(xí)思路。
初學(xué)者一般都很害怕 Git,很難不怕。毫無(wú)疑問(wèn),Git 是一個(gè)強(qiáng)大的工具,但是使用起來(lái)卻不是很友好。使用 Git 要理解很多新的概念,將文件作為命令參數(shù)和不作為參數(shù)兩者的含義大相徑庭。
我認(rèn)為要想克服這些困難,不僅要學(xué)習(xí) Git 的 commit 和 push 的用法。如果我們能夠真正花時(shí)間去理解 Git 的構(gòu)成,將會(huì)避免很多不必要的麻煩。
一、研究 .git 目錄
好的,我們現(xiàn)在開始吧。
當(dāng)你通過(guò)?git init?創(chuàng)建 git 倉(cāng)庫(kù)時(shí), git ?就會(huì)創(chuàng)建 .git 目錄。該目錄包含讓 git 能夠正常工作所需的所有信息。直白點(diǎn)說(shuō),如果你不想在項(xiàng)目中繼續(xù)使用 git ,直接將 .git 目錄刪除只保留項(xiàng)目文件即可。但是為什么這樣做就可以呢?
下面是你第一次提交后 .git 文件夾的樣子:
?├──?HEAD??├──?branches??├──?config??├──?description??├──?hooks??│?├──?pre-commit.sample??│?├──?pre-push.sample??│?└──?...??├──?info??│?└──?exclude??├──?objects??│?├──?info??│?└──?pack??└──?refs??├──?heads??└──?tags??-
HEAD
后面再講。
-
config (配置)
該文件包含你的倉(cāng)庫(kù)配置,比如遠(yuǎn)程的 url ,你的郵箱和用戶名等。每次你在控制臺(tái)使用?git config...?都會(huì)對(duì)這里產(chǎn)生影響。
-
description(描述)
供 gitweb ( github ?的一種前身) 使用,顯示倉(cāng)庫(kù)的描述。
-
hooks (鉤子)
這是一個(gè)有趣的特性。Git 提供了一套腳本,可以在每個(gè)有意義的 Git 階段自動(dòng)運(yùn)行。這些被稱為鉤子的腳本可以在提交 (commit)、變基 (rebase)、拉取 ( pull ) 操作的前后運(yùn)行。腳本命預(yù)示著它的執(zhí)行時(shí)機(jī)。如我們可以編寫 pre-push 的作為鉤子,進(jìn)行推送代碼前的檢查。
-
info (信息)
你可以將不想被 git 管理的文件記錄到 .gitignore 文件中。排除文件的意思是不想共享這個(gè)文件。例如你不想共享你的 IDE 自定義配置,將其添加到 .gitignore 文件中即可。
二、一次提交包含哪些內(nèi)容?
每次你創(chuàng)建一個(gè)文件,并追蹤它,git 都將把文件進(jìn)行壓縮并存儲(chǔ)在自己的數(shù)據(jù)結(jié)構(gòu)中。被壓縮的對(duì)象將具有唯一的名稱和 hash 值,并將存儲(chǔ)到對(duì)象 (object) 目錄中。
在研究對(duì)象目錄之前,我們必須明白一次提交的含義是什么。你可能會(huì)說(shuō),一次提交就是當(dāng)前工作目錄的一個(gè)快照,但事實(shí)遠(yuǎn)不止如此。
實(shí)際上,當(dāng)你提交時(shí),git 通過(guò)下面兩個(gè)步驟對(duì)你的工作目錄創(chuàng)建快照:
-
如果文件沒(méi)啥變化,git 只是將壓縮的文件(哈希值)添加到快照中。
-
如果文件發(fā)生了變化, git 將對(duì)其進(jìn)行壓縮并將其存儲(chǔ)在 object 文件夾。最終,將這個(gè)壓縮文件的名稱(哈希值)添加到快照中。
這里給出一個(gè)簡(jiǎn)化的過(guò)程,實(shí)際上整個(gè)過(guò)程有點(diǎn)復(fù)雜,將在以后的文章中給出詳細(xì)的介紹。關(guān)注微信公眾號(hào):Java技術(shù)棧,在后臺(tái)回復(fù):git,可以獲取我整理的 N 篇最新 Git 教程,都是干貨。
一旦快照被創(chuàng)建出來(lái),它將會(huì)被壓縮,以哈希值命名。那么這些壓縮的對(duì)象存在哪里呢?他們被存在 object 文件夾中。
├──?4c?? │?└──?f44f1e3fe4fb7f8aa42138c324f63f5ac85828?//?hash?? ├──?86?? │?└──?550c31847e518e1927f95991c949fc14efc711?//?hash?? ├──?e6?? │?└──?9de29bb2d1d6434b8b29ae775ad8c2e48c5391?//?hash?? ├──?info?//?let's?ignore?that?? └──?pack?//?let's?ignore?that?too??這是我創(chuàng)建了一個(gè)空的文件 ?1.txt 并提交后 object 文件夾的樣子。請(qǐng)注意,如果你的文件哈希值為 "4cf44f1e…",git 會(huì)將其存儲(chǔ)到 "4c"子目錄中,并將其命名為"f44f1…"。這個(gè)小技巧,將?/objects?目錄的數(shù)量減少到 255 個(gè)以內(nèi)。
你要記住的是,一次提交包含 4 個(gè)部分:
工作目錄快照名稱(一個(gè)哈希值)。
一條評(píng)論/注釋。
提交者信息。
父提交的哈希值。
如果我們解壓提交的文件:
//?通過(guò)查看提交歷史,你可以輕松地查詢到提交的哈希值?? //?你都不需要復(fù)制完整的哈希值字符串,?? //?復(fù)制能夠保證哈希值的唯一性的前面一段即可。?? git?cat-file?-p?4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828??得到下面的內(nèi)容:
tree?86550c31847e518e1927f95991c949fc14efc711?? author?Pierre?De?Wulf?<test\[@gmail.com\](mailto:pierredewulf31@gmail.com)>?1455775173?-0500?? committer?Pierre?De?Wulf?<\[test@gmail.com\](mailto:pierredewulf31@gmail.com)>?1455775173?-0500??commit?A??正如預(yù)想的一樣,我們看到了快照的哈希值、作者信息和提交的注釋。
有兩個(gè)非常重要的事項(xiàng):
-
正如所預(yù)想的那樣,快照的哈希 "86550…" 也是一個(gè)對(duì)象,你可以在對(duì)象文件夾中找到它。
-
因?yàn)檫@是第一次提交,所以沒(méi)有父提交的哈希值。
那么,在快照中存的是啥呢?
git?cat-file?-p?86550c31847e518e1927f95991c949fc14efc711??100644?blob?e69de29bb2d1d6434b8b29ae775ad8c2e48c5391?file_1.txt??我們找到之前存儲(chǔ)的最后一個(gè)對(duì)象,也是我們快照中的唯一的一個(gè)對(duì)象。它是一個(gè) blob 對(duì)象,這是另外的知識(shí)點(diǎn),不在這里討論。
三、分支, 標(biāo)簽, HEAD 都一樣
你現(xiàn)在已經(jīng)了解到,git 中的所有內(nèi)容都可以通過(guò)正確的哈希值來(lái)獲取到。現(xiàn)在讓我們聚焦于 HEAD。那么什么是 HEAD?Git 高級(jí)用法,喜歡就拿去用。關(guān)注微信公眾號(hào):Java技術(shù)棧,在后臺(tái)回復(fù):git,可以獲取我整理的 N 篇最新 Git 教程,都是干貨。
cat?HEAD?? ref:?refs/heads/master??HEAD 不是一個(gè)哈希,HEAD 可以理解為指向你正在使用的分支的頂端的指針。我們接下來(lái)看下 refs/heads/master:
cat?refs/heads/master?? 4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828??看起來(lái)眼熟嗎?這和我們第一次提交的哈希值相同。這表明分支 ( branch) 和標(biāo)簽 (tag) 只不過(guò)是一個(gè)指向提交的指針。這就意味著,即使你刪掉了你要?jiǎng)h除的分支和標(biāo)簽,他們指向的提交依然還在那里,只不過(guò)刪除后難獲取這些提交更困難一些。如果你想了解更詳細(xì)的內(nèi)容,可以通過(guò) git book 來(lái)學(xué)習(xí)。
四、寫在最后
所以學(xué)到這里,你應(yīng)該明白 git 提交就是把你當(dāng)前工作目錄的文件“壓縮”,然后將其和其他信息一起存儲(chǔ)到對(duì)象文件夾中。如果你對(duì) git 足夠熟悉,你就會(huì)知道哪些文件會(huì)包含在提交中,哪些文件不會(huì)被提交。
我這里說(shuō)的提交,并不是指你的工作目錄快照,而是指你要提交的文件快照。在實(shí)際執(zhí)行之前,git 會(huì)在哪里存儲(chǔ)你要提交的文件?
它將他們存儲(chǔ)到索引文件中。不過(guò),我們暫時(shí)不打算深入研究它。如果你真的感興趣,可以通過(guò)這里(https://github.com/git/git/blob/master/Documentation/technical/index-format.txt)深入學(xué)習(xí)。
感謝閱讀!希望通過(guò)閱讀本文,你能夠?qū)W到有價(jià)值的內(nèi)容。希望本文能夠幫你更輕松地使用 git。
原文:https://www.daolf.com/posts/git-series-part-1/
作者:Pierre de Wulf ?
譯者:明明如月,責(zé)編:郭芮
總結(jié)
以上是生活随笔為你收集整理的一个 .git 目录,领悟 Git 的强大!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 不要再问了,数据库不建议上Docker
- 下一篇: 支撑日活百万用户的高并发系统,应该如何设