版本控制系統之git

1874發表於2020-10-09

  一、簡介

  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 加上倉庫地址進行克隆

  提示:可以看到克隆成功後,本地就會和遠端倉庫一模一樣的檔案結構的目錄;

相關文章