當咱們執行git init命令,或者clone網上某個代碼倉庫後,會看到有一個.git目錄,git全部版本控制信息就是放在目錄裏面,下面對這個.git目錄進行分析。git
hooks:鉤子目錄,存放執行指定git命令前或者後觸發的腳本,能夠看到默認會有幾個sample文件,若是要開啓某個鉤子腳本,就把腳本文件名的後綴simple去掉就能夠,這些鉤子會在特定的時機被觸發執行,好比post-commit在整個提交過程完成後執行,能夠用於發送提交通知等,另外也有服務端鉤子,在推送前或者後執行,好比post-receive在推送結束後會被執行,能夠用於通知打包平臺啓動打包任務。關於git鉤子更詳細的信息能夠參考:自定義 Git - Git 鉤子。算法
info:保存git的相關信息網絡
logsssh
refs:暫存記錄,本地分支記錄,遠程分支記錄post
HEAD:記錄每次的變動操做版本控制
objects:存放真實數據,以Git對象形式存放指針
refs對象
heads:存放全部本地分支最新的commit哈希值進程
stash:存放stash對應的哈希值開發
tags:存放tags相關的
config:配置文件
HEAD:當前分支,並不存放SHA1值,相似/refs/heads/master,這個指向的文件裏會有最新commit的SHA1值
index:二進制文件,暫存區
數據對象
數據對象就是用於存儲真實的文件數據,其建立過程以下:
計算內容大小,構造header
將header添加到內容前面,構造數據對象
使用sha1算法計算Git對象的160位hash碼,表示成16進制就是40位
使用zlib的deflate算法壓縮數據對象
存儲到.git/objectes/目錄下,文件夾名爲hash碼的前兩位,文件名爲hash碼的後38位
tree對象
保存目錄信息,也就是目錄樹的非葉子節點的版本控制信息,須要從暫存區中建立。
commit對象
保存某次提交的詳細信息,包括時間、提交人等。
tag對象
跟commit對象相似,包含了一個指針,該指針指向一個commit對象,並且永遠不會改變。
添加到暫存區:git add xxx
建立數據對象
更新index文件
提交:git commit -m "xxxx"
若是存在目錄,就建立tree對象
建立commit對象
將上面建立的對象保存爲目錄和文件
能夠看到,git提交的整個過程,其實就是建立數據對象、tree對象和commit對象的過程,最終這些對象都會保存到objects目錄下。
Git默認採用的是鬆散對象格式,也就是每次保存一份完整數據,好比有個大文件10MB,第一次提交被保存起來了,後面修改了一點東西又提交,這時Git會保存兩個10Mb的對象數據,這樣看起來就會比較浪費,最好是可以只保存文件的差別部分。
實際上Git就是這樣作的,若是存在太多的鬆散對象,或者執行了push命令,或者git gc命令,Git就會將鬆散對象進行打包到一個pack文件中,該文件保存文件不一樣版本之間的差別內容,減小了存儲佔用,並且是該pack文件是二進制文件,須要採用命令git verify-pack查看。
注意這裏pack會將最新版本保存爲完整對象,而以前的版本保存差別信息,由於大部分狀況下訪問的都會是最新版本。
Git有四種傳輸協議,包括本地協議、HTTP協議,SSH協議,GIT協議。
本地協議
遠程倉庫就存放在硬盤中,這裏的硬盤,能夠是遠程掛載的網絡硬盤,遠程倉庫的地址直接指定爲目錄路徑,也能夠加上file前綴。不過共享文件系統配置起來比較麻煩,速度也比較慢。
HTTP協議
採用http/https協議進行傳輸,這裏細分有兩種協議:啞協議和智能協議,啞協議是Git 1.6.6版本以前使用的協議,Git 1.6.6引入了智能協議。
啞協議
獲取info/refs文件,肯定全部分支的最新commit的SHA1值
獲取HEAD文件,肯定當前分支,檢出到工做目錄
獲取第一個commit對象的數據
往上追溯,獲取全部對象數據
智能協議(大部分使用)
無論是上傳(好比push等)仍是下載(好比pull等),都是客戶端開一個進程,服務端開一個進程,而後協商須要傳輸的數據,確認好哪些數據須要傳輸,進程端口是http或者https端口。
HTTP協議的優勢:1.就是使用方便,只須要一個遠程地址便可,2.認證方便,直接輸用戶名密碼,不須要像SSH首次配置那麼麻煩。
SSH協議
使用ssh協議作爲傳輸協議,使用時須要配置ssh信息,配置後就不用每次都輸入用戶名和密碼了。
Git協議
與http智能協議原理相似,但它監聽的端口是9418,Git協議沒有受權機制,也就是不能實現控制一部分人能push,另外一部分不能push,所以大部分狀況的作法是讓Git協議只開放讀取,禁止推送。
develop:開發分支
master:發佈分支
feature:特性分支,用於臨時開發新功能,從develop拉,最終合入到develop。
release:預發佈分支,當develop分支開發完本版本需求後,就拉release分支,用於修bug,配置發佈信息等,這時develop分支繼續開發下一版本的需求。當release分支修改結束後,就合入develop和master。注意合入到master時要打tag作標記,好比master_8.1之類的命名。
hotfix:修復分支,用於修復線上緊急bug,從master拉,最終合入到develop和master。注意合入到master時要打tag作標記,好比master-8.1.1之類的命名。