版本控制系統之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 加上倉庫地址進行克隆
提示:可以看到克隆成功後,本地就會和遠端倉庫一模一樣的文件結構的目錄;