Git的締造者(father)javascript
第一代版本控制系統被稱爲本地版本控制系統。經過加鎖將併發執行轉換成順序執行。 一次只能有一我的處理文件。具體流程以下:首先,應該把文件放在一個服務器上,方便使用者上傳或下載文件;其次,任何人想對文件修改時,須要先把這個文件加鎖,經過checkout指令,使得其餘人沒法修改;最後,當修改完成以後,須要釋放鎖,經過checkin指令,造成一個新的版本,存放到服務器端。第一代版本控制系統主要有 RCS( Revision Control System )、SCCS。html
在硬盤上(本地,local computer)保存補丁集(文件修訂先後的變化),經過全部的補丁,能夠計算出各個版本的文件內容,大多都是採用某種簡單的數據庫來記錄文件的歷次更新差別。前端
第二代版本控制系統被稱爲集中式版本控制系統(Centralized Version Control Systems,CVCS),其對同步修改更加寬容,但有一個明顯的限制,用戶必須在容許提交以前將當前修訂合併到他們的工做中。不便之處就是要聯網,若中央服務器發生單機故障,宕機了,那麼在這宕機期間誰都沒法提交更新,也就沒法協同工做,還有中央服務器丟失數據的可能等。java
由下圖可看到,在集中式版本控制系統中,若是服務器嗝屁了,那麼全部的開發者就只能乾瞪眼了!由於,SVN 對於項目的管理是依賴於服務器中的中心倉庫的!咱們的更改必需要提交到服務器中的中心倉庫。第二代版本控制系統主要有 CVS、Subversion、SourceSafe、Team Foundation Server、SVK。git
第三代版本控制系統被稱爲分佈式式版本控制系統(Distributed Version Control Systems,DVCS),其容許合併和提交分開。在每一個使用者電腦上就有一個完整的數據倉庫,沒有網絡依然可使用。程序員
由下圖可看到,分佈式版本控制系統也能夠有個服務器端的倉庫,用來同步各開發者的私有倉庫。在分佈式版本控制系統中,每一個參與者的本地也會有一個完整的倉庫。及時服務器端崩潰,咱們仍然可使用 Git(僅在本地倉庫管理咱們的代碼),在網絡具有時,再和服務器進行同步便可!第三代版本控制系統主要有 Bazaar、Git、Mercurial、BitKeeper、Monotone。github
思考:web
- 怎麼理解分佈式與集中式?(廖雪峯老師給出的理解)
- 集中式:版本庫是集中存放在中央服務器的,而幹活的時候,用的都是本身的電腦,因此要先從中央服務器取得最新的版本,而後開始幹活,幹完活了,再把本身的活推送給中央服務器。中央服務器就比如是一個圖書館,你要改一本書,必須先從圖書館借出來,而後回到家本身改,改完了,再放回圖書館。
- 分佈式:分佈式版本控制系統根本沒有「中央服務器」,每一個人的電腦上都是一個完整的版本庫,這樣,你工做的時候,就不須要聯網了,由於版本庫就在你本身的電腦上。
特性 | SVN | GIT |
---|---|---|
架構模式 | 集中式 | 分佈式 |
安全性 | 較差,按期備份 | 高,開發者本地電腦就是一個完整的版本庫 |
適用性 | 文檔管理, | 代碼管理, |
易用性 | 簡單上手,對新手友好 | 上手困難,學習成本高但效率搞 |
靈活性 | 較低,易發生單點故障,拉取分支 | 高,單機本地操做,多個備份,本地新建分支 |
權限管理 | 擁有嚴格的權限管理 | 尚無嚴格權限管理,有帳號角色劃分 |
咱們使用Git來記錄每一次文件內容的變動,版本的更新,清晰地比較出不一樣版本的內容差別;可使用Git在項目的歷史版本自如地進行切換;還可使用Git從當前項目的更改中撤銷一些操做,能夠新建分支,合併分支甚相當聯遠程服務器倉庫等,這一切的背後都是怎麼實現的?瞭解Git的思想以及基本原理這些操做也就略知一二了。算法
.git下的文件夾數據庫
.git下的文件
HEAD 文件指向當前分支, 包含了一個分支的引用,經過這個文件Git能夠獲得下一次commit的parent,能夠理解爲指針
index 文件存儲着暫存區的內容信息
config 文件包含項目的配置信息
description 存儲着倉庫的描述信息,主要給gitweb等git託管系統使用
packed-refs 打包標頭和標籤以便高效的存儲庫訪問
FETCH_HEAD 是一個版本連接,指向着目前已經從遠程倉庫取下來的分支的末端版本
ORIG_HEAD 記錄的是在進行危險(drastic)操做(如合併merge,回退reset等)時,此操做以前HEAD所指向的位置,便於咱們在發生毀滅性失誤時進行回退
COMMIT_EDITMSG 保存最新的commit message,Git系統不會用到這個文件,只是給用戶一個參考
Git本質上是一個內容尋址文件系統(就是根據文件內容的hash碼來定位文件。 這就意味着一樣內容的文件,在這個文件系統中會指向同一個位置,不會重複存儲。)Git 的核心部分是一個簡單的鍵值對數據庫,能夠向該數據庫插入任意類型的內容,它會返回一個鍵值,經過該鍵值能夠在任意時刻再次檢索(retrieve)該內容
Git 保存的不是文件的變化或者差別,而是一系列不一樣時刻的文件快照。在進行提交操做時,Git 會保存一個提交對象(commit object)。該提交對象會包含一個指向暫存內容快照的指針。 但不只僅是這樣,該提交對象還包含了做者的姓名和郵箱、提交時輸入的信息以及指向它的父對象的指針。
git經過一種安全散列算法1(SHA-1)能夠獲得任意文件的SHA-1哈希值(40位的字符),也就是commit ID,而後經過文件哈希值存取數據,存取的數據都位於objects目錄,SHA-1哈希值的前兩個字符做爲子目錄名稱,後 38 個字符則做爲子目錄內文件的名稱。
Git經常使用命令共有30多個,可運行git help
查看;但Git總共有130多個命令,能夠經過git help -a
查看,這些命令能夠分爲高層命令和底層命令,底層命令被設計成unix風格,不經常使用
瀏覽完整的提交歷史,但爲了能遍歷那段歷史從而找到全部相關對象,須要記住最後提交的SHA-1值。咱們須要一個文件來保存 SHA-1 值,並給文件起一個簡單的名字,而後用這個名字指針來替代原始的 SHA-1 值。文件被稱爲「引用(references,或縮寫爲 refs)」,使用git branch (branchname)
這樣的命令時,Git 實際上會運行 update-ref
命令,取得當前所在分支最新提交對應的 SHA-1 值,並將其加入你想要建立的任何新引用中。
git/refs/heads
目錄下,每個分支對應一個文件refs/remotes
目錄下master分支爲項目的核心分支,也是最終對外發布的分支,惟一且穩定。僅提供可讀,不可在該分支上直接修改代
develop分支是項目的開發主幹分支,惟一。僅提供可讀,不可在該分支上直接修改代碼。新功能的開發需從該分支拉取新的分支展開。develop分支應該包含項目完整的所有歷史記錄。
featrue分支項是目的需求開發分支,可多個,從develop分支或其餘featrue分支拉取。程序員的多人分工協做即經過featrue來實現,是代碼具體實現的一線程序員接觸最多的分支。需求開發完成後,要合併回develop分支。
release分支爲預發佈分支,一般被叫作測試分支,主要用於開發階段的測試及bug修復。當feature分支開發完畢後會合併回develop分支,而後再從develop分支拉取release分支提測。測試並修復後的release分支要合併回develop分支以及master分支,並打上合適的tag標記(包含必要的releaseNote)。
hotfix分支爲緊急線上修復分支,即當對外發布的master分支出現重大bug,影響線上使用時,從master分支拉取hotfix分支進行緊急修復。修復後的hotfix分支要合併回master分支和develop分支。
而後,開發團隊中的其餘人克隆中央倉庫的develop分支到本地,造成全體成員統一的惟一的develop分支軌跡。以後,按照需求及成員各自的分工,各個成員能夠從develop分支拉取出各自的featrue分支(步驟②)進行獨立的開發;若涉及到多人合做開發同一分支,拉取的分支要及時推送至服務器,便於各成員共享。
當各成員完成各自的功能開發後,需將完成後的代碼提交到featrue分支,而後合併到develop分支(步驟③)。代碼合併後,featrue分支能夠再也不保留。
功能累積足夠且穩定或到達約定的提測週期時,項目負責人應當從develop分支拉取出release分支(步驟④),打包提交相應的版本給測試人員進行部署測試,測試中提交的bug所有在該release分支完成修改。
測試結束並完成bug修復後,release分支應該合併回develop分支和master分支(步驟⑤),代碼合併後,release分支能夠再也不保留。合併後的master分支,應由項目負責人及時推送到中央倉庫(步驟⑥)。同時全體成員要及時同步本身develop分支。
有上線需求時,直接從master分支打包提交應用版本進行部署。當線上版本出現重大bug,項目負責人需從master分支拉取hotfix分支(步驟⑦),進行線上的緊急修復。
最後,修復後的hotfix分支要合併回develop分支和master分支(步驟⑧)。並推送到中央倉庫(步驟⑨)。
git config --global user.name 'your name'
git config --global user.email 'your email'
$ ssh-keygen -t rsa -C "your email"
複製代碼
打開在windows(c盤)/用戶/xxx/.ssh文件夾下的id_rsa.pub文件,複製裏面的內容;粘貼在GitHub或Gitlab的setting的ssh key
HEAD
commit
branch
merge 合併指定分支
git merge branch 合併其餘分支到當前分支
rebase 衍合指定分支
reset 重置
revert 撤銷,回滾到指定的特定版本
cherry-pick 選擇合併某次提交的commit到當前分支
reflog 查看HEAD的全部移動軌跡
思考:
git merge 與 git rebase 的區別是?
- rebase會合並該分支與其餘分支的commit history,可能會獲得一個新的commit history
- rebase獲得更簡潔的項目歷史,去掉了merge commi,若是合併出現代碼問題不容易定位,由於re-write了commit history
- merge會建立新的commit,包括每一個分支的commit 詳情
- 每次merge會自動產生一個merge commit,特別是commit比較頻繁時,看到分支很雜亂。
- 想要獲得一個乾淨的,沒有merge commit的線性commit歷史記錄,選擇git rebase
- 想要獲得一個完整的commit歷史記錄,且想避重寫commit歷史記錄的風險,選擇git merge
git reset 與 git rebase的區別?
- git revert會生成一個新的提交來撤銷某次提交,這次提交以前的commit都會被保留,也就是說對於項目的版本歷史來講是往前走的。
- git reset 則是回到某次提交,相似於穿越時空。
附前端全站書籍PDF文檔下載連接:juejin.im/post/5d7216… (要書籍資源的請在下面留言,網盤收集了先後端時髦的書籍電子版)