版本控制系統之git

  一、簡介

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

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