一個 .git 目錄,領悟 Git 的強大!

原文: https://www.daolf.com/posts/g...
做者:Pierre de Wulf
譯者:明明如月,責編:郭芮
來源:CSDN(ID:CSDNnews)

Git 是一個強大的工具,可是使用起來卻不是很友好。若是程序員們可以真正花時間去理解 Git 的構成,將會避免不少沒必要要的麻煩。java

如下爲譯文:git

初學 Git 就像一個不懂當地語言的人來到一個陌生的國家——若是你知道本身在哪,該去哪裏,那還好。一旦你迷路了,那麻煩就大了。程序員

網上有不少學習 Git 基本命令的文章,可是本文並不屬於這一類文章。我在此處將嘗試提供一個不一樣的學習思路。github

初學者通常都很懼怕 Git,很難不怕。毫無疑問,Git 是一個強大的工具,可是使用起來卻不是很友好。使用 Git 要理解不少新的概念,將文件做爲命令參數和不做爲參數二者的含義截然不同。web

我認爲要想克服這些困難,不只要學習 Git 的 commit 和 push 的用法。若是咱們可以真正花時間去理解 Git 的構成,將會避免不少沒必要要的麻煩。面試

1、研究 .git 目錄後端

好的,咱們如今開始吧。微信

當你經過 git init 建立 git 倉庫時, git  就會建立 .git 目錄。該目錄包含讓 git 可以正常工做所需的全部信息。直白點說,若是你不想在項目中繼續使用 git ,直接將 .git 目錄刪除只保留項目文件便可。可是爲何這樣作就能夠呢?數據結構

下面是你第一次提交後 .git 文件夾的樣子:多線程

 ├── HEAD  
    ├── branches  
    ├── config  
    ├── description  
    ├── hooks  
    │ ├── pre-commit.sample  
    │ ├── pre-push.sample  
    │ └── ...  
    ├── info  
    │ └── exclude  
    ├── objects  
    │ ├── info  
    │ └── pack  
    └── refs  
     ├── heads  
     └── tags
  • HEAD

    後面再講。

  • config (配置)

    該文件包含你的倉庫配置,好比遠程的 url ,你的郵箱和用戶名等。每次你在控制檯使用 git config... 都會對這裏產生影響。

  • description(描述)

    供 gitweb ( github  的一種前身) 使用,顯示倉庫的描述。

  • hooks (鉤子)

    這是一個有趣的特性。Git 提供了一套腳本,能夠在每一個有意義的 Git 階段自動運行。這些被稱爲鉤子的腳本能夠在提交 (commit)、變基 (rebase)、拉取 ( pull ) 操做的先後運行。腳本命預示着它的執行時機。如咱們能夠編寫 pre-push 的做爲鉤子,進行推送代碼前的檢查。

  • info (信息)

    你能夠將不想被 git 管理的文件記錄到 .gitignore 文件中。排除文件的意思是不想共享這個文件。例如你不想共享你的 IDE 自定義配置,將其添加到 .gitignore 文件中便可。

2、一次提交包含哪些內容?

每次你建立一個文件,並追蹤它,git 都將把文件進行壓縮並存儲在本身的數據結構中。被壓縮的對象將具備惟一的名稱和 hash 值,並將存儲到對象 (object) 目錄中。

在研究對象目錄以前,咱們必須明白一次提交的含義是什麼。你可能會說,一次提交就是當前工做目錄的一個快照,但事實遠不止如此。

實際上,當你提交時,git 經過下面兩個步驟對你的工做目錄建立快照:

  • 若是文件沒啥變化,git 只是將壓縮的文件(哈希值)添加到快照中。
  • 若是文件發生了變化, git 將對其進行壓縮並將其存儲在 object 文件夾。最終,將這個壓縮文件的名稱(哈希值)添加到快照中。

這裏給出一個簡化的過程,實際上整個過程有點複雜,將在之後的文章中給出詳細的介紹。關注微信公衆號:Java技術棧,在後臺回覆:git,能夠獲取我整理的 N 篇最新 Git 教程,都是乾貨。

一旦快照被建立出來,它將會被壓縮,以哈希值命名。那麼這些壓縮的對象存在哪裏呢?他們被存在 object 文件夾中。

├── 4c  
│ └── f44f1e3fe4fb7f8aa42138c324f63f5ac85828 // hash  
├── 86  
│ └── 550c31847e518e1927f95991c949fc14efc711 // hash  
├── e6  
│ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 // hash  
├── info // let's ignore that  
└── pack // let's ignore that too

這是我建立了一個空的文件  1.txt 並提交後 object 文件夾的樣子。請注意,若是你的文件哈希值爲 "4cf44f1e…",git 會將其存儲到 "4c"子目錄中,並將其命名爲"f44f1…"。這個小技巧,將 /objects 目錄的數量減小到 255 個之內。

你要記住的是,一次提交包含 4 個部分:

  1. 工做目錄快照名稱(一個哈希值)。
  2. 一條評論/註釋。
  3. 提交者信息。
  4. 父提交的哈希值。

若是咱們解壓提交的文件:

// 經過查看提交歷史,你能夠輕鬆地查詢到提交的哈希值  
// 你都不須要複製完整的哈希值字符串,  
// 複製可以保證哈希值的惟一性的前面一段便可。  
git cat-file -p 4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828

獲得下面的內容:

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

正如預想的同樣,咱們看到了快照的哈希值、做者信息和提交的註釋。

有兩個很是重要的事項:

  • 正如所預想的那樣,快照的哈希 "86550…" 也是一個對象,你能夠在對象文件夾中找到它。
  • 由於這是第一次提交,因此沒有父提交的哈希值。

那麼,在快照中存的是啥呢?

git cat-file -p 86550c31847e518e1927f95991c949fc14efc711  
  
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file_1.txt

咱們找到以前存儲的最後一個對象,也是咱們快照中的惟一的一個對象。它是一個 blob 對象,這是另外的知識點,不在這裏討論。

關注微信公衆號:Java技術棧,在後臺回覆:git,能夠獲取我整理的 N 篇最新 Git 教程,都是乾貨。

3、分支, 標籤, HEAD 都同樣

你如今已經瞭解到,git 中的全部內容均可以經過正確的哈希值來獲取到。如今讓咱們聚焦於 HEAD。那麼什麼是 HEAD?

cat HEAD  
ref: refs/heads/master

HEAD 不是一個哈希,HEAD 能夠理解爲指向你正在使用的分支的頂端的指針。咱們接下來看下 refs/heads/master:

cat refs/heads/master  
4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828

看起來眼熟嗎?這和咱們第一次提交的哈希值相同。這代表分支 ( branch) 和標籤 (tag) 只不過是一個指向提交的指針。這就意味着,即便你刪掉了你要刪除的分支和標籤,他們指向的提交依然還在那裏,只不過刪除後難獲取這些提交更困難一些。若是你想了解更詳細的內容,能夠經過 git book 來學習。

4、寫在最後

因此學到這裏,你應該明白 git 提交就是把你當前工做目錄的文件「壓縮」,而後將其和其餘信息一塊兒存儲到對象文件夾中。若是你對 git 足夠熟悉,你就會知道哪些文件會包含在提交中,哪些文件不會被提交。

我這裏說的提交,並非指你的工做目錄快照,而是指你要提交的文件快照。在實際執行以前,git 會在哪裏存儲你要提交的文件?它將他們存儲到索引文件中。不過,咱們暫時不打算深刻研究它。若是你真的感興趣,能夠經過這裏(https://github.com/git/git/bl...)深刻學習。

感謝閱讀!但願經過閱讀本文,你可以學到有價值的內容。但願本文可以幫你更輕鬆地使用 git。

推薦去個人博客閱讀更多:

1.Java JVM、集合、多線程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、後端、架構、阿里巴巴等大廠最新面試題

生活很美好,明天見~

相關文章
相關標籤/搜索