序
做爲git新手,常見的git clone,push,commit命令已經足夠完成一次代碼的發佈,可是若是不幸碰到問題每每會一籌莫展,利用網絡問答解決了以後也不知其因此然。因此,作一次好奇寶寶吧!git
git的安裝
- 下載安裝包,下載完成後,打開你的終端。
http://git-scm.com/download/
- 配置用戶名,郵箱 。
git config --global user.name "你的註冊用戶名"
git config --global user.emall "你的註冊郵箱"
- 終端配置密鑰 。
`ssh-keygen -t rsa
- 複製公鑰,粘貼到gitlab->my ssh keys。
cd ~/.ssh
cat id_rsa.pub
- git服務端和本機便打通了,能夠經過git clone ssh地址下載代碼了 。
安裝流程如上所述,但是爲何這麼作呢?github
Q1:什麼是ssh?gitlab上得地址爲何分爲ssh和http?
SSH 爲 Secure Shell 的縮寫。經過使用SSH,你能夠把全部傳輸的數據進行加密,這樣"中間人"這種攻擊方式就不可能實現了。算法
能夠看到,倉庫的地址分爲ssh和http兩種路徑,客戶端也能夠選擇經過http或者ssh兩種方式來從服務器上獲取數據,公司都是用的ssh方式,由於更安全。安全
Q2:密鑰是作什麼的,爲何要粘貼公鑰到gitlab?
這要從SSH安全驗證的原理提及:
SSH分爲兩種級別的安全驗證,一種是用戶名密碼方式,一種是公鑰私鑰方式。這裏用到得是公鑰私鑰方式。
密鑰方式的驗證流程是這樣的:
1. 客戶端生成一對密鑰:公鑰+私鑰。(對應git的安裝步驟三)
2. 將客戶端生成的公鑰複製到服務器上。(對應git的安裝步驟四)
3. 客戶端發起鏈接請求,併發送公鑰給服務器。(能夠看作在本機執行git命令請求服務器響應)
4. 服務器尋找這個公鑰,找到後驗證若合法,就生成一個隨機數,用公鑰加密。
5. 服務器把加密後的隨機數發送給客戶端。
6. 客戶端收到後用私鑰解密,將解密的結果發送給服務器。
7. 服務器將客戶端發送的解密結果和加密前數據對比,若能匹配上,則安全驗證成功。
由此可知,有了公鑰和私鑰才能和遠程的gitlab服務器進行鏈接和交互。每換一臺電腦(若電腦上沒有私鑰)都須要從新生成一次密鑰。服務器
git 的文件操做
若是使用git作版本控制,咱們最經常使用到得命令就是git clone,git add, git commit,git push。正常狀況下,有這些命令也夠咱們完成一次代碼的發佈了。可是SVN只須要小烏龜一次提交,爲何到git就要兩次提交呢?網絡
Q3: git爲何下載比其餘版本控制器(如SVN)更快?
其餘版本控制器如SVN,每次更新存儲的是文件具體差別。git不保存具體差別,而是把有變化的文件做一個快照存儲下來。每次提交更新,都會保存一個指向新快照的索引;若文件沒有改動,則索引指向上一個快照。
因此若是要查看或者使用歷史版本,git只須要直接load出來,而svn還須要merge,因此很快。固然git須要的存儲空間也更大了,不過git也有本身的優化機制使得空間和時間有個平衡。併發
- 建立一個新分支
- 在新分支上有新的修改
- 新分支和master分支合併
如圖所示,能夠清楚的看到從建立分支到和master合併的整個過程。
Q4: git爲何要分屢次提交?
須要從git的工做區域提及。git的工做區域有三個:ssh
- 工做目錄(Working Directory)
日常咱們用IDE開發的那個工程目錄,工程根目錄下有隱藏的.git文件標識是git目錄。
- 暫存目錄(Stage or Index)
存儲文件的快照(快照的解釋見上一個問題)
- 倉庫(Git directory)
有本地倉庫和遠程倉庫。
git基本的工做流程:
1. 在工做目錄中修改文件。
2. 第一次提交,git add ..。暫存文件,將文件的快照放入暫存區域。
3. 第二次提交,git commit..。提交更新,找到暫存區域的文件,將快照存儲到本地 Git 倉庫。
4. 第三次提交,git push..。提交更新到遠程git倉庫。
由於git是分佈式的管理文件系統,使得無需聯網也能夠方便的管理文件的版本。就是得益於本地和遠程屢次提交的流程。分佈式
Q5: git的文件狀態有哪些?
文件狀態在日常代碼修改、執行一次代碼提交的過程當中,其實就能夠看到。svn
以文件index.js爲例:
- 在IDE中修改代碼(index.js文件)後,運行git status檢驗git狀態:

能夠看到提示的文件狀態爲modified,而且git提示咱們changes not staged,用add命令來staged或者用git checkout filename來放棄staged此次修改。
- 執行命令 git add build/js/page/banff/index.js,運行git status檢驗git狀態

文件狀態仍然是modified(已修改),但能夠看到提示少了 not staged,代表文件已經staged,等待commit了。
可使用git reset HEAD filename命令讓文件回到unstage狀態。
- 執行命令git commit build/js/page/banff/index.js -m 'test'
(-m 提交註釋,必填),
再運行git status檢驗git狀態:

能夠發現,index.js文件已經不是modified狀態,git提示「有一次提交,請使用git push命令發佈這個本地commits」
- 執行命令git push origin daily/0.0.4

因爲沒有遇到衝突,分支已經跟新到最新狀態(up-to-date)
從以上實踐過程當中,能夠獲得以下圖的文件狀態變動過程:
Q6: 每次提交時生成的 key是什麼?
在保存到 Git 以前,全部數據都要進行內容的校驗和(checksum)計算。Git 使用 SHA-1 算法計算數據的校驗和,經過對文件的內容或目錄的結構計算出一個 SHA-1 哈希值,做爲指紋字符串。因此git能夠快速的算出你的文件是否有變動。git的每一次提交都對應惟一的commit id。在git中也是經過這個KEY來對應到提交內容。
Q7: git,gitlab,github三者是什麼關係?
- git是一個版本控制工具,經過命令行來操做
- github,gitlab 都是使用git來作版本控制工具,在此基礎上搭建起來的WEB服務,提供給用戶存儲空間來做爲git倉儲。
- gitlab能夠把代碼部署在本身的服務器上,好比公司就用的公司的服務器,適合作私密的項目。
- github私有repo比較貴,適合作開源項目
常見git命令
- git status 查看修改了什麼文件,以及文件狀態
- git diff filename 查看具體修改了什麼內容
- git branch 查看當前分支名字
- git log 查看歷史記錄
- git reset --hard HEAD^ 或 git reset --hard commitID
在git中,用HEAD表示最新版本,那麼HEAD^表示上一個版本
- 回滾
場景1:當你改亂了工做區某個文件的內容,想直接丟棄工做區的修改時,用命令git checkout -- file。
場景2:當你不但改亂了工做區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操做。
- git push origin master:分支名 clone的是master的代碼,可是將改動提交到另外一個分支上
- git clone -b 分支名 ssh地址 . clone指定分支的代碼
- 刪除遠端分支 git branch -a 能夠查看遠端分支的名稱,會打印出remotes/origin/分支名 git push origin --delete branchname 刪除遠端分支