一、簡介
git是Linux核心專案發起者linus用C語言寫的,主要用來做專案的版本控制追蹤;git是無中心節點的分散式版本控制系統,也是目前很流行的版本控制系統;其安裝簡單,使用簡單;相比傳統的cvs和svn,git要比前兩者都要方便,前兩者是有中心節點的版本控制系統,有中心節點就意味著,每次提交程式碼都得連線到中心節點(倉庫),然後才能提交程式碼,提交程式碼(專案)依賴網路;而git在沒有網路的情況下也支援提交程式碼到本地的物件庫中;這樣一來使得git使用非常方便;
git整體架構
提示:以上是git的一個大概的工作邏輯圖,git版本控制系統主要由本地工作空間,本地倉庫和遠端倉庫三部分組成;本地工作空間中包含本地倉庫,本地倉庫中主要有索引和物件庫;使用者在本地空間初始化一個專案,就相當於在本地建立了一個本地git倉庫,其表現形式上在使用者的工作目錄下有一個.git的隱藏目錄;使用者要把本地的檔案提交到遠端倉庫,首先得將檔案新增到本地倉庫中的索引中去,然後再把索引中的內容提交到本地物件庫中儲存;然後再從本地push一份到遠端倉庫;使用者提交專案到遠端倉庫的過程就是這樣;當然使用者從遠端倉庫可以直接克隆遠端倉庫到本地;
git本地倉庫結構
提示:本地git倉庫主要由工作目錄、索引和物件庫組成;在使用者執行git init後,就把對應的工作目錄初始化為git本地倉庫;
git add 在本地倉庫中的表現
提示:以上表示使用者執行git後,在本地倉庫中的表現;使用者在工作目錄裡有綠藍兩個檔案,在執行git add後,它會在索引(暫存區)生成對應檔案的索引資訊,其索引主要記錄檔案的hash碼和對應在物件庫中的檔案一個關聯關係;這樣一來git就可以追蹤這兩個檔案的變化;如果此時我們在工作目錄中繼續編輯這兩個檔案,後續我們想知道我們編輯了那些內容,就可以把工作目錄中的檔案同物件庫中的檔案做對比;工作目錄中的檔案和物件庫中的檔案不同的是,在工作目錄中的檔案表現為兩個正常的檔名,而在物件庫中,這兩個檔案的檔名不再是工作目錄中的檔名,而是把對應檔案的內容做hash以後,把hash碼當作檔案的名稱;
git commit在本地倉庫的表現形式
提示:在使用者把工作目錄中的檔案add到暫存區以後,如果執行git commit,git會在物件庫中生成一個索引的快照檔案(物件庫中的黃三角)和一個提交物件(紫紅色圓形);提交物件中主要儲存了對應的索引快照是什麼時候床架的,對應提交指向的那個索引快照,專案的版本等等;上面我們說了索引中主要儲存檔案和物件庫中的檔案的關聯關係,如果此時我們把工作目錄中的檔案刪除以後,可以通過物件庫中的檔案進行恢復;其實在執行git add以後,把對應工作目錄中的檔案刪除以後,都可以從物件庫中找回;以上就是使用者把工作目錄中的檔案提交到git在本地倉庫中的一個工作流程;如果後續我們再次add 工作空間的檔案到本地倉庫也是一樣的邏輯;
提示:當使用者第二次提交時,在物件庫中會生成第二個索引快照和提交物件;並且HEAD指標會指向當前才生成的提交物件;這樣一來在物件庫中就存在多個提交物件,如果此時我們需要恢復到某個版本,可以直接把head指標指向對應的提交物件即可;
二、git安裝
[root@node01 ~]# yum install git Loaded plugins: fastestmirror base | 3.6 kB 00:00:00 epel | 4.7 kB 00:00:00 extras | 2.9 kB 00:00:00 updates | 2.9 kB 00:00:00 (1/2): epel/x86_64/updateinfo | 1.0 MB 00:00:00 (2/2): epel/x86_64/primary_db | 6.9 MB 00:00:01 Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com Resolving Dependencies --> Running transaction check ---> Package git.x86_64 0:1.8.3.1-23.el7_8 will be installed --> Processing Dependency: perl-Git = 1.8.3.1-23.el7_8 for package: git-1.8.3.1-23.el7_8.x86_64 --> Processing Dependency: rsync for package: git-1.8.3.1-23.el7_8.x86_64 --> Processing Dependency: perl(Term::ReadKey) for package: git-1.8.3.1-23.el7_8.x86_64 --> Processing Dependency: perl(Git) for package: git-1.8.3.1-23.el7_8.x86_64 --> Processing Dependency: perl(Error) for package: git-1.8.3.1-23.el7_8.x86_64 --> Running transaction check ---> Package perl-Error.noarch 1:0.17020-2.el7 will be installed ---> Package perl-Git.noarch 0:1.8.3.1-23.el7_8 will be installed ---> Package perl-TermReadKey.x86_64 0:2.30-20.el7 will be installed ---> Package rsync.x86_64 0:3.1.2-10.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ========================================================================================================================== Package Arch Version Repository Size ========================================================================================================================== Installing: git x86_64 1.8.3.1-23.el7_8 updates 4.4 M Installing for dependencies: perl-Error noarch 1:0.17020-2.el7 base 32 k perl-Git noarch 1.8.3.1-23.el7_8 updates 56 k perl-TermReadKey x86_64 2.30-20.el7 base 31 k rsync x86_64 3.1.2-10.el7 base 404 k Transaction Summary ========================================================================================================================== Install 1 Package (+4 Dependent packages) Total download size: 4.9 M Installed size: 23 M Is this ok [y/d/N]: y Downloading packages: (1/5): perl-TermReadKey-2.30-20.el7.x86_64.rpm | 31 kB 00:00:00 (2/5): rsync-3.1.2-10.el7.x86_64.rpm | 404 kB 00:00:00 (3/5): perl-Error-0.17020-2.el7.noarch.rpm | 32 kB 00:00:00 (4/5): git-1.8.3.1-23.el7_8.x86_64.rpm | 4.4 MB 00:00:00 (5/5): perl-Git-1.8.3.1-23.el7_8.noarch.rpm | 56 kB 00:00:00 -------------------------------------------------------------------------------------------------------------------------- Total 5.0 MB/s | 4.9 MB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : 1:perl-Error-0.17020-2.el7.noarch 1/5 Installing : rsync-3.1.2-10.el7.x86_64 2/5 Installing : perl-TermReadKey-2.30-20.el7.x86_64 3/5 Installing : perl-Git-1.8.3.1-23.el7_8.noarch 4/5 Installing : git-1.8.3.1-23.el7_8.x86_64 5/5 Verifying : git-1.8.3.1-23.el7_8.x86_64 1/5 Verifying : 1:perl-Error-0.17020-2.el7.noarch 2/5 Verifying : perl-TermReadKey-2.30-20.el7.x86_64 3/5 Verifying : perl-Git-1.8.3.1-23.el7_8.noarch 4/5 Verifying : rsync-3.1.2-10.el7.x86_64 5/5 Installed: git.x86_64 0:1.8.3.1-23.el7_8 Dependency Installed: perl-Error.noarch 1:0.17020-2.el7 perl-Git.noarch 0:1.8.3.1-23.el7_8 perl-TermReadKey.x86_64 0:2.30-20.el7 rsync.x86_64 0:3.1.2-10.el7 Complete! [root@node01 ~]#
三、git基本命令使用
git init 初始化一個空倉庫
git add 把當前工作目錄中的檔案新增到暫存區
提示:以上命令表示把當前目錄下的檔案新增到暫存區;點表示當前目錄,當然也可以使用*,也可以使用對應的檔名;
git ls-files -s:檢視暫存區中的檔案列表
[root@node01 test]# git ls-files -s 100644 a63efecf511676df4bf5b4a50e19c958f156f3c6 0 fstab [root@node01 test]#
git ls-files -o:把當前目錄的檔案同暫存區中的檔案列表比較,列出未被追蹤的檔案;
[root@node01 test]# git ls-files -o [root@node01 test]# cp /etc/passwd . [root@node01 test]# git ls-files -s 100644 a63efecf511676df4bf5b4a50e19c958f156f3c6 0 fstab [root@node01 test]# git ls-files -o passwd [root@node01 test]#
git cat-file:檢視檔案內容
提示:-p是以美觀方式顯示檔案內容;檢視物件庫中的檔案,需要指定物件庫中的檔名稱,通過ls-files -s可以列出暫存區檔案的列表,其中包含檔案的許可權資訊,檔案的hash名稱,以及對應本地目錄的檔名稱;
git config:配置git環境
git的配置分三級,倉庫特有,其配置檔案放在REPONAME/.git/config;使用者持有,也稱為全域性配置,這裡的全域性指某個使用者的全域性,其配置檔案在使用者的家目錄下的.gitconfig,用--global來指定;系統持有,指本機所有使用者的git通用配置,其配置文是/etc/gitconfig,用--system來指定;
示例:配置倉庫持有配置的使用者名稱和使用者郵箱
提示:git標記一個使用者是靠使用者名稱和郵箱標記;當然在生產中使用git通常上面的使用者名稱和郵箱都是真實有效的,以便後續專案上的問題可以通過郵箱進行交流和反饋;
驗證:看看我們配置的user.name和user.email是否儲存在當前倉庫的.git/config檔案中呢?
配置全域性git環境
配置系統git環境
git hash-object:計算指定檔案的hash碼
提示:可以看到本地倉庫中的fstab檔案的hash碼同物件庫中的檔名一樣;說明在物件庫中的檔名就是把對應檔案內容hash以後的hash碼當作檔名;
git rm:刪除工作目錄中的檔案,及索引中的對映;--cache表示只刪除索引中的對映,當前工作目錄的檔案並不刪除;
刪除當前目錄檔案的同時,也刪除索引中的對應關係
提示:直接使用git rm刪除檔案是刪除不掉的,必須使用-f,-f表示強制刪除檔案和索引中的檔案,--cache表示只刪除索引中的檔案,並不對應本地檔案做刪除操作;
git mv:改變工作目錄中的檔名,及索引中的對映;
提示:更改檔名稱,如果使用shell命令mv更改檔名稱,git會認為更改後的檔名的檔案是一個新檔案;所以要想更改索引中的檔名稱,需要使用git mv來更改;
git commit:提交暫存區的檔案到本地倉庫
[root@node01 test]# git commit -m "v1" [master (root-commit) 6f8bf56] v1 1 file changed, 22 insertions(+) create mode 100644 password [root@node01 test]#
git log:檢視提交日誌
[root@node01 test]# git log commit 6f8bf56578144cee9cf16539587fca5aaf61e3bc Author: tom <admin@admin.com> Date: Fri Oct 9 21:03:03 2020 +0800 v1 [root@node01 test]#
git diff:比較提交、索引及工作目錄;工作流程如下
示例:工作目錄同索引(暫存區)中的檔案比較
提示:git diff命令用來比較當前工作目錄下的檔案同索引中的檔案差異,上面顯示結果表示,本地password檔案相比索引中的password檔案多了一個test;如果我們在把當前檔案刪除一點資料,它會告訴我們在當前目錄的檔案中少了某某資料;如下
刪除本地檔案中的一些資料,再做比較
提示:以上提示說本地檔案相比索引中的檔案,少了root:x:0:0:root:/root:/bin/bash這行資料,多了一個test;
git diff HEAD:當前工作目錄的檔案同最近提交的檔案做比較
提示:以上反饋告訴我們,當前工作目錄中的password檔案同最近提交(物件庫)中的password比較,少了root:x:0:0:root:/root:/bin/bash這行資料,多了一個test;
git diff --cached:對比當前索引和最近一次提交做比較
提示:之所以索引和最近一次提交比較和當前目錄的password同最近一次提交比較,結果相同;原因是我們只是新增到索引,並未提交,如果此時提交,那麼當前工作目錄的password檔案就和索引和最近一次提交,三者都會相同;也就是執行git diff/git diff HEAD/git diff --cached的結果都是沒有任何輸出;
驗證:提交暫存區的檔案到物件庫,然後再次比較
提示:可以看到提交以後,不管怎麼比較都是相同的;
比較v3和v2的不同
提示:以上顯示錶示v3相比較v2少了root:x:0:0:root:/root:/bin/bash這行資料,多了一個test;
git reset:撤消此前的操作;--soft:將HEAD引用指向給定的提交,但不影響索引和工作目錄;--mixed:將HEAD引用指向給定的提交,並將索引內容改變為指定提交的快照;但不改變工作目錄;--hard:將HEAD引用指向給定的提交、將索引內容改變為指定提交的快照,並改變工作目錄中的內容反映指定提交的內容;
提示:以上主要做了兩個不同的版本提交,第一次提交有test1檔案,其內容是version1以及issue檔案;第二次提交首先刪除了test1檔案,然後建立了teset2檔案,其內容為version2,並且把fstab檔案一併提交了;
驗證:將HEAD引用指向第一次提交,並不改變工作目錄的檔案情況和索引;
提示:--soft就相當於回到第一提交以後,第二次把檔案新增到暫存區,並未做提交到狀態;
驗證:將HEAD指向v1,並將索引更改為v1,並不更改當前目錄檔案
提示:--mixed就相當於第一次提交以後,第二次還未新增到暫存區的情況;重新新增並提交就會把head指向當前提交的版本,並且把索引快照,指向最近的提交;
驗證:將HEAD引用指向給定的提交、將索引內容改變為指定提交的快照,並改變工作目錄中的內容反映指定提交的內容;
提示:--hard就相當於直接回到提交第一次時的狀態;當然第一次到第二次提交的中間資料會全部丟失;
git clone:從遠端倉庫克隆目錄到本地
示例:從github上克隆ansible-for-kubernetes到本地
複製遠端倉庫地址後,在本地使用git clone 加上倉庫地址進行克隆
提示:可以看到克隆成功後,本地就會和遠端倉庫一模一樣的檔案結構的目錄;