那些年前端接觸的Git知識大全

一、Git誕生的歷史

  • Git的定義

    • Git是當下最早進的開源分佈式版本控制系統,能夠高效便捷地管理大大小小的項目版本
    • 所謂的分佈式,按個人理解就是主要專一於字,分開,分離,把某些事物分開佈置在各個角落上,分佈式版本控制系統不把相應的版本項目集中在一個電腦/服務器/中央服務器上,而是每一個人的電腦都保存着一個完整的版本項目。
    • 所謂的版本控制系統,通俗地說就是對一個或若干個文件的內容改動狀況按照特定的版本號進行保存,以便未來瀏覽者快速清晰瞭解文件的改動信息(內容變化信息,內容改動時間,做者等)
  • Git的締造者(father)javascript

    • 名稱:Linus Torvalds 林納斯 託瓦茲 芬蘭人 現受聘于開放源代碼開發實驗(OSDL:Open Source Development Labs, Inc)
    • 他的自傳《樂者爲王》just for fun 都說通常吊炸天的大牛之牛,脾氣都有些古怪,哈哈

    圖片加載失敗

  • Git的誕生史

    • 1991年,Linus建立可謂統治服務器的操做系統-Linux系統,因爲它的快速發展Linux的代碼管理成爲一個大難題
    • 2002年之前,Linus其實都是經過手工方式合併世界各地開發者提交的源代碼
    • 2002年,名爲BitMover的這家公司出於人道主義精神免費提供BitKeeper商業版的版本控制系統的使用權
    • 2005年,但因爲Linux秀兒衆多,開發Samba的Andrew試圖Crack BitKeeper的協議,被BitMover公司發現了,因而BitMover公司怒了,要收回Linux社區的無償使用權
    • 不讓用便本身搞一個,Linus便花費10天的時間用C語言開發了Git,日後時間,Linux的源碼都是用Git管理。
    • 2008年GitHub網站上線,爲開源的項目免費提供Git存儲。

二、Git的版本控制系統

  • 本地版本控制系統

    • 第一代版本控制系統被稱爲本地版本控制系統。經過加鎖將併發執行轉換成順序執行。 一次只能有一我的處理文件。具體流程以下:首先,應該把文件放在一個服務器上,方便使用者上傳或下載文件;其次,任何人想對文件修改時,須要先把這個文件加鎖,經過checkout指令,使得其餘人沒法修改;最後,當修改完成以後,須要釋放鎖,經過checkin指令,造成一個新的版本,存放到服務器端。第一代版本控制系統主要有 RCSRevision Control System )、SCCS。html

    • 硬盤上(本地,local computer)保存補丁集(文件修訂先後的變化),經過全部的補丁,能夠計算出各個版本的文件內容,大多都是採用某種簡單的數據庫來記錄文件的歷次更新差別。前端

      圖片沒法加載
  • 集中式版本控制系統

    • 第二代版本控制系統被稱爲集中式版本控制系統(Centralized Version Control Systems,CVCS),其對同步修改更加寬容,但有一個明顯的限制,用戶必須在容許提交以前將當前修訂合併到他們的工做中。不便之處就是要聯網,若中央服務器發生單機故障,宕機了,那麼在這宕機期間誰都沒法提交更新,也就沒法協同工做,還有中央服務器丟失數據的可能等。java

    • 由下圖可看到,在集中式版本控制系統中,若是服務器嗝屁了,那麼全部的開發者就只能乾瞪眼了!由於,SVN 對於項目的管理是依賴於服務器中的中心倉庫的!咱們的更改必需要提交到服務器中的中心倉庫。第二代版本控制系統主要有 CVSSubversion、SourceSafe、Team Foundation Server、SVK。git

      圖片加載失敗
  • 分佈式版本控制系統

    • 第三代版本控制系統被稱爲分佈式式版本控制系統(Distributed Version Control Systems,DVCS),其容許合併和提交分開。在每一個使用者電腦上就有一個完整的數據倉庫,沒有網絡依然可使用。程序員

    • 由下圖可看到,分佈式版本控制系統也能夠有個服務器端的倉庫,用來同步各開發者的私有倉庫。在分佈式版本控制系統中,每一個參與者的本地也會有一個完整的倉庫。及時服務器端崩潰,咱們仍然可使用 Git(僅在本地倉庫管理咱們的代碼),在網絡具有時,再和服務器進行同步便可!第三代版本控制系統主要有 Bazaar、Git、Mercurial、BitKeeper、Monotone。github

    圖片沒法加載

思考:web

  1. 怎麼理解分佈式與集中式?(廖雪峯老師給出的理解)
    • 集中式:版本庫是集中存放在中央服務器的,而幹活的時候,用的都是本身的電腦,因此要先從中央服務器取得最新的版本,而後開始幹活,幹完活了,再把本身的活推送給中央服務器。中央服務器就比如是一個圖書館,你要改一本書,必須先從圖書館借出來,而後回到家本身改,改完了,再放回圖書館。
    • 分佈式:分佈式版本控制系統根本沒有「中央服務器」,每一個人的電腦上都是一個完整的版本庫,這樣,你工做的時候,就不須要聯網了,由於版本庫就在你本身的電腦上。
  • SVN與GIT的特性對比:

    特性 SVN GIT
    架構模式 集中式 分佈式
    安全性 較差,按期備份 高,開發者本地電腦就是一個完整的版本庫
    適用性 文檔管理, 代碼管理,
    易用性 簡單上手,對新手友好 上手困難,學習成本高但效率搞
    靈活性 較低,易發生單點故障,拉取分支 高,單機本地操做,多個備份,本地新建分支
    權限管理 擁有嚴格的權限管理 尚無嚴格權限管理,有帳號角色劃分

三、Git與Github、Gitlab

  • GitHub

    • GitHub是什麼?
      • 百度百科上的定義是:面向開源以及私有軟件項目的代碼託管平臺,只支持git 做爲惟一的版本庫格式進行託管,故名GitHub。
      • GitHub是一個代碼託管雲服務網站,幫助開發者存儲和管理其項目源代碼,且可以追蹤、記錄並控制用戶對其代碼的修改。甚至能夠把它看成存儲代碼等的網盤,用來存儲任何東西。
    • Github與Git的關係?
      • GitHub不等同於Git,兩者徹底是不一樣物,不能搞混,相似地,捋一捋java與javascript、周杰與周杰倫的關係,或許你能從中領悟到一些真諦。
      • Git只是一個命令行工具,一個分佈式版本控制系統。正是它在背後管理和跟蹤你的代碼歷史版本,比如一個時光機,讓你在代碼出錯時不至於手忙腳亂,能快速回退以前的歷史版本。
      • GitHub是一個代碼託管網站,背後使用Git做爲版本管理工具(而非svn)。主要服務是將你的項目代碼託管到雲服務器上,而非存儲在本身本地硬盤上。
    • GitHub能作什麼?
      • 託管代碼,管理項目的歷史版本
      • 查找查看開源項目的介紹及源碼等
      • 使用GitHub Pages更能,可以搭建屬於本身的我的博客
      • 分享技術心得、項目等,在線交流,提高本身的影響力
  • Gitlab

    • Gitlab是什麼?
      • GitLab 是一個用於倉庫管理系統的開源項目,使用Git做爲代碼管理工具,並在此基礎上搭建起來的web服務(在線代碼倉庫管理軟件)。
    • Gitlab與GitHub的區別?查看對比
      • GitHub上存放的項目是面向世界開源的,若想存放私人倉庫,得交錢,交錢使你的項目變得更隱私
      • GitHub是在線代碼倉庫,全世界只有GitHub一家,你們把代碼存儲在人家的服務器上
      • GitLab比較私密,用於企業、學校或者我的的代碼託管庫
      • Gitlab至關於小型的GitHub,你能夠在本地搭建一個屬於你本身的相似GitHub倉庫,讓小夥伴把代碼存儲在上面,這樣代碼只有大家幾我的能看見,可是你要存在GitHub上,全世界都能看見
    • Gitlab能爲咱們作什麼?
      • Git倉庫管理、代碼審查、問題跟蹤、動態訂閱、wiki等功能,GitHUb能作的Gitlab也能作(99%)。
  • 國內代碼託管平臺

四、Git的工做原理

咱們使用Git來記錄每一次文件內容的變動,版本的更新,清晰地比較出不一樣版本的內容差別;可使用Git在項目的歷史版本自如地進行切換;還可使用Git從當前項目的更改中撤銷一些操做,能夠新建分支,合併分支甚相當聯遠程服務器倉庫等,這一切的背後都是怎麼實現的?瞭解Git的思想以及基本原理這些操做也就略知一二了。算法

  • Git的分區

    • workspace: 工做區 直接編輯的地方,開發者可見具體的項目,能夠直接操做項目文件
    • index(stage): 暫存區 數據暫存的地方
    • repository: 本地倉庫 存放已提交的數據
    • remote: 遠程倉庫 在遠程服務器上存放本地倉庫的數據

圖片沒法加載

  • .git文件夾

    • .git下的文件夾數據庫

      • hooks 文件夾則存放項目的客戶端或服務端鉤子腳本
      • info 文件夾下的exclude文件包含項目全局忽略匹配模式,與.gitignore文件互補
        • exculd 文件
      • logs 保存全部更新的引用記錄
        • refs
        • HEAD # 最後一次的提交信息
      • objects 文件夾存儲着Git數據庫的全部內容,存儲全部Git的對象
        • info 記錄對象存儲的附加信息
        • pack 以壓縮形式(.pack)存儲許多對象的文件,附帶索引文件(.idx)以容許它們被隨機訪問
      • refs 文件夾存儲着全部分支指向各自提交對象的指針;本地分支,遠端分支,標籤等
        • heads 記錄commit分支的樹根
          • master 標識了本地項目中的master分支指向的當前commit的哈希值
        • remotes 記錄從遠程倉庫copy來的commit分支的樹根(只讀)
          • origin
            • HEAD
            • master 標識了遠端項目中的master分支指向的當前commit的哈希值。
        • tags 記錄任何對象名稱(不必定是提交對象或指向提交對象的標籤對象)
    • .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系統不會用到這個文件,只是給用戶一個參考

        images loading rror

  • Git數據庫

    • Git本質上是一個內容尋址文件系統(就是根據文件內容的hash碼來定位文件。 這就意味着一樣內容的文件,在這個文件系統中會指向同一個位置,不會重複存儲。)Git 的核心部分是一個簡單的鍵值對數據庫,能夠向該數據庫插入任意類型的內容,它會返回一個鍵值,經過該鍵值能夠在任意時刻再次檢索(retrieve)該內容

    • Git 保存的不是文件的變化或者差別,而是一系列不一樣時刻的文件快照。在進行提交操做時,Git 會保存一個提交對象(commit object)。該提交對象會包含一個指向暫存內容快照的指針。 但不只僅是這樣,該提交對象還包含了做者的姓名和郵箱、提交時輸入的信息以及指向它的父對象的指針。

    • git經過一種安全散列算法1(SHA-1)能夠獲得任意文件的SHA-1哈希值(40位的字符),也就是commit ID,而後經過文件哈希值存取數據,存取的數據都位於objects目錄,SHA-1哈希值的前兩個字符做爲子目錄名稱,後 38 個字符則做爲子目錄內文件的名稱

    • Git的數據存儲原理

      • Git對象
        • 數據對象(blob object) 存儲的是一個文件的具體內容
        • 樹對象(tree object) 存儲的文件的目錄,一大坨指針,指向子級tree,或者blob
        • 提交對象(commit object) 存儲做者信息,提交者信息,註釋,指向一個 big tree 的指針
        • 標籤對象(tag object)它包含一個標籤建立者信息、一個日期、一段註釋信息,以及一個指針。
      • Git的底層命令、高層命令
        • Git經常使用命令共有30多個,可運行git help查看;但Git總共有130多個命令,能夠經過git help -a查看,這些命令能夠分爲高層命令和底層命令,底層命令被設計成unix風格,不經常使用

          圖片沒法加載

          • 往Git數據庫存入數據
          • 往Git數據庫取出數據
          • 首次提交 testA.txt文件
          • 第二次提交,修改了test.txt文件內容
          • 第三次提交,增長一個新文件 testB.txt ,一個新目錄 lib ,lib 裏增長一個文件 testC.txt
          • 第四次提交,新建一個分支 branchB,而且在新分支中作了一次 commit
          • 第五次提交, 合併一分支
      • Git的引用(reference或refs)

        瀏覽完整的提交歷史,但爲了能遍歷那段歷史從而找到全部相關對象,須要記住最後提交的SHA-1值。咱們須要一個文件來保存 SHA-1 值,並給文件起一個簡單的名字,而後用這個名字指針來替代原始的 SHA-1 值。文件被稱爲「引用(references,或縮寫爲 refs)」,使用git branch (branchname) 這樣的命令時,Git 實際上會運行 update-ref 命令,取得當前所在分支最新提交對應的 SHA-1 值,並將其加入你想要建立的任何新引用中。

        • HEAD引用
          • 分支和標籤都是指向提交對象的指針,全部的本地分支都存儲在 git/refs/heads 目錄下,每個分支對應一個文件
          • Git 分支的本質:一個指向某一系列提交之首的指針或引用
        • 遠程引用
          • 若是你添加了一個遠程版本庫並對其執行過推送操做,Git 會記錄下最近一次推送操做時每個分支所對應的值,並保存在 refs/remotes 目錄下
        • 標籤引用

    Git的對象模型

5. Gitflow工做流

  • Gitflow工做流約定使用的分支簡介

    • 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分支。

      圖片沒法加載

  • GitFlow工做流程

圖片沒法加載
首先,完成中央倉庫的初始化,將新項目搭建起框架後的工程代碼或要轉gitflow的項目代碼上傳至git中央倉庫。項目負責人克隆中央倉庫到本地造成master分支,並拉取develop分支(步驟①)推送至服務器。通常的實際場景,開發團隊中只有項目負責人有權限操做master分支,拉取develop分支,並將develop分支的代碼合併到master分支中。

而後,開發團隊中的其餘人克隆中央倉庫的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經常使用命令

  • 配置Git-SSH

    • 配置Git的user name以及Git要關聯的郵箱email

      git config --global user.name 'your name'
      git config --global user.email 'your email'

    • 生成密鑰
      $ ssh-keygen -t rsa -C "your email"
      複製代碼
    • 按三個回車,跳過設置密碼,通常咱們使用Git不須要設置密碼,最終生成id_rsaid_rsa.pub這兩個文件,(若以前就已經生成過這個兩個文件,就直接overwrite進行覆蓋)
    • 登陸Github或者Gitlab,添加ssh

      打開在windows(c盤)/用戶/xxx/.ssh文件夾下的id_rsa.pub文件,複製裏面的內容;粘貼在GitHub或Gitlab的setting的ssh key

    images loading error

  • 簡單命令

    圖片沒法加載

  • 高級命令

    • HEAD

      • 老是指向當前分支最新的一次提交commit
      • git diff HEAD 顯示工做區與當前最新commit之間的差別
    • commit

      • git commit --amend -m [message] 修改上一次提交
    • branch

      • git branch --track remote-branch 新建一個分支,與指定的遠程分支創建追蹤關係
      • git branch --set-upstream-to=origin/[remote branch] 將remote設置爲當前分支的上游分支
    • 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… (要書籍資源的請在下面留言,網盤收集了先後端時髦的書籍電子版)

images loading error
相關文章
相關標籤/搜索