帶着問題學git

  做爲git新手,常見的git clone,push,commit命令已經足夠完成一次代碼的發佈,可是若是不幸碰到問題每每會一籌莫展,利用網絡問答解決了以後也不知其因此然。因此,作一次好奇寶寶吧!git

git的安裝

  1. 下載安裝包,下載完成後,打開你的終端。
    http://git-scm.com/download/
  2. 配置用戶名,郵箱 。
    git config --global user.name "你的註冊用戶名"
    git config --global user.emall "你的註冊郵箱"
  3. 終端配置密鑰 。
    `ssh-keygen -t rsa
  4. 複製公鑰,粘貼到gitlab->my ssh keys。
    cd ~/.ssh
    cat id_rsa.pub
  5. 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也有本身的優化機制使得空間和時間有個平衡。併發

  1. 建立一個新分支
    screenshot
  2. 在新分支上有新的修改
    screenshot
  3. 新分支和master分支合併
    screenshot
      如圖所示,能夠清楚的看到從建立分支到和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爲例:

  1. 在IDE中修改代碼(index.js文件)後,運行git status檢驗git狀態:
    screenshot
    能夠看到提示的文件狀態爲modified,而且git提示咱們changes not staged,用add命令來staged或者用git checkout filename來放棄staged此次修改。
  2. 執行命令 git add build/js/page/banff/index.js,運行git status檢驗git狀態
    screenshot
    文件狀態仍然是modified(已修改),但能夠看到提示少了 not staged,代表文件已經staged,等待commit了。
    可使用git reset HEAD filename命令讓文件回到unstage狀態。
  3. 執行命令git commit build/js/page/banff/index.js -m 'test'
    (-m 提交註釋,必填),
    再運行git status檢驗git狀態:
    screenshot
    能夠發現,index.js文件已經不是modified狀態,git提示「有一次提交,請使用git push命令發佈這個本地commits」
  4. 執行命令git push origin daily/0.0.4
    screenshot
    因爲沒有遇到衝突,分支已經跟新到最新狀態(up-to-date)
    從以上實踐過程當中,能夠獲得以下圖的文件狀態變動過程:
    git_

Q6: 每次提交時生成的 key是什麼?

screenshot
  在保存到 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 刪除遠端分支
相關文章
相關標籤/搜索