腦圖
介紹
Git是一個分布式版本控制系統,能夠使得身處不同物理位置的開發者緊密的協同開發一個軟件.也能夠控制開發者能夠查閱與修改的代碼權限.簡而言之,git是多人協同開發必不可少的工具,下面我來逐一介紹git的一些概念:
版本庫(repository)
版本庫是一個簡單的數據庫.提供版本庫自身與所有文件的副本.
它主要維護2種數據結構:對象庫與索引.
對象庫(object store)
對象庫包含三個部分:原子對象, 存儲系統與一個簡單的數據庫.
原子對象
原子對象是版本庫的基礎對象,分為四種類型:
塊(blob)
每一個文件的版本表示為塊,它只被目錄樹引用.
目錄樹(tree)
保存blob的標識符,路徑名和一個目錄中所有文件的元數據.
引用blob對象,每一次變化(比如新增了文件)都會產生一個新的樹,新樹包含著所有文件,舊樹則包含著除了新增文件文件外的其他文件.
目錄樹只會包含該目錄下的文件與子目錄的信息,不會包含子目錄下的文件及孫子目錄的信息.
提交(commit)
保存版本庫中每一次變化的元數據,諸如作者,提交者等.每一個提交對象都指向一個目錄樹對象.
標簽(tag)
標簽分為輕量級標簽與標注
輕量級標簽是一個提交對象的引用,通常被版本庫視為私有.
標注則可以根據RFC4880來使用GnuPG密匙進行數字簽名.
索引(index)
索引是臨時,動態的二進制文件,描述整個版本庫的目錄結構.
不包含任何文件內容,只追蹤你想要提交的那些內容.
添加文件到索引的操作被稱為暫存.
工作目錄
文件所在目錄
內容追蹤與存儲機制
只追蹤內容
git只追蹤內容,如果兩個文件的內容完全一樣,就算名字不一樣,目錄結構不一樣,git也只會保存其中一份,用以,并以這一份文件代指其他內容一樣的文件.
對文件變化的處理
文件發生改變時,會計算新的SHA1值,然后將新的blob添加到對象庫中.
文件差異的存儲
第一次存儲時,會儲存全部文件.之后則只會存儲不同文件中有差異的那一部分,而不是又把文件再完整存儲一份.
文件分類
已追蹤(Tracked)
已在版本庫或已被暫存到索引中的文件.
被忽略(Ignored)
被索引忽視的文件
未追蹤(Untracked)
未被忽略且未被索引的文件
提交(commit)
絕對提交名
散列id
相對提交名
引用和符號引用:
.git/heads代表本地分支
.git/remotes代表遠程分支
提交歷史記錄
提交圖: 使用gitk即可查看版本庫的DAG.
查找提交
查找錯誤提交
git bisect:該指令會讓用戶判斷哪些提交沒問題,哪些提交有問題,最后找出有問題的提交.
git blame: 獲取每一行是誰修改的和那一次提交做出了變更.
可達提交
把提交看成一棵樹,可達提交就是指從某一個節點開始,他的所有父節點及其父節點的兄弟節點,都是可達提交的節點.
合并
概要
要合并的分支必須位于同一個版本庫.
分支沖突時,git不解決沖突,并且會在索引中標價為未合并(unmerged).
git merge的當前分支是目標分支.
沖突的合并
這里列舉幾條解決沖突的建議:
- 使用diff指令查看工作目錄與索引的差異,它會通過額外的+與-符號來表示相對于最終版本的來之余多個源的變化,方便找出沖突
- git status則是一個更好的選擇,相比diff會展示所有細節,status只展示未合并與有沖突的文件.
- git log --merge --left-right -p 這個指令將會顯示2個提交之間的沖突
- 建議提交大型修改之后,修復沖突的復雜性.高頻率小型提交是更合適的實踐.
回滾
git reset --hard [<commit>]
這條指令會把工作目錄和索引還原到某一次提交.常用的git reset --hard HEAD^則會回退至當前分支的上一個版本.