原文: 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
後面再講。
該文件包含你的倉庫配置,好比遠程的 url ,你的郵箱和用戶名等。每次你在控制檯使用 git config...
都會對這裏產生影響。
供 gitweb ( github 的一種前身) 使用,顯示倉庫的描述。
這是一個有趣的特性。Git 提供了一套腳本,能夠在每一個有意義的 Git 階段自動運行。這些被稱爲鉤子的腳本能夠在提交 (commit)、變基 (rebase)、拉取 ( pull ) 操做的先後運行。腳本命預示着它的執行時機。如咱們能夠編寫 pre-push 的做爲鉤子,進行推送代碼前的檢查。
你能夠將不想被 git 管理的文件記錄到 .gitignore 文件中。排除文件的意思是不想共享這個文件。例如你不想共享你的 IDE 自定義配置,將其添加到 .gitignore 文件中便可。
2、一次提交包含哪些內容?
每次你建立一個文件,並追蹤它,git 都將把文件進行壓縮並存儲在本身的數據結構中。被壓縮的對象將具備惟一的名稱和 hash 值,並將存儲到對象 (object) 目錄中。
在研究對象目錄以前,咱們必須明白一次提交的含義是什麼。你可能會說,一次提交就是當前工做目錄的一個快照,但事實遠不止如此。
實際上,當你提交時,git 經過下面兩個步驟對你的工做目錄建立快照:
這裏給出一個簡化的過程,實際上整個過程有點複雜,將在之後的文章中給出詳細的介紹。關注微信公衆號: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 個部分:
若是咱們解壓提交的文件:
// 經過查看提交歷史,你能夠輕鬆地查詢到提交的哈希值 // 你都不須要複製完整的哈希值字符串, // 複製可以保證哈希值的惟一性的前面一段便可。 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
正如預想的同樣,咱們看到了快照的哈希值、做者信息和提交的註釋。
有兩個很是重要的事項:
那麼,在快照中存的是啥呢?
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。
推薦去個人博客閱讀更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
生活很美好,明天見~