Git的17條基本用法

博文視點發表於2017-11-20

在開發過程中,經常會遇到一個專案由多人合力完成這種情況,每個人負責其中一個模組。專案開發過程中為了確保程式碼的可追溯,我們引入了版本控制概念,每個人修改了什麼程式碼或提交了什麼程式碼都能夠跟蹤記錄。現在流行的版本控制主要有:集中式版本控制(SVN)和分散式版本控制(GIT)。本文將介紹Git的17條基本用法。

1.初始化Git倉庫

  Git倉庫分為兩種型別:一種是存放在伺服器上面的裸倉庫,裡面沒有儲存檔案,只是存放.git的內容;一種是標準倉庫,會在專案根目錄下建立一個.git目錄。

   $ git init # 建立標準倉庫,在專案根目錄下建立一個隱藏的.git

資料夾

   $ git init –bare # 建立一個裸倉庫,裸倉庫只有.git目錄內容,

而沒有工作區域,一般用於在共享伺服器上面建立。

2.檢視當前Git配置

  Git配置資訊分成三個級別,分別存放在三個不同的地方。

  一個是系統級別的配置檔案,系統基本配置檔案存放在Git的安裝目錄中。

  一個是使用者級別配置檔案,使用者級別配置檔案存放在當前使用者目錄下的.gitconfig檔案內。

  一個是專案級別配置檔案,專案級別的配置檔案會存放在.git目錄的config檔案中。使用git config –list顯示的Git配置資訊,是從系統級配置•使用者級配置•專案級配置一層層疊加顯示出來的,當遇到同項不同內容時以低階的配置為準,如圖1至圖3所示。

  $ git config –list # 顯示當前Git配置資訊

  $ git config –system –list # 顯示系統級別Git配置資訊

  $ cat .git/config # 顯示專案配置檔案

  $ cat ~/.gitconfig # 顯示使用者級別配置資訊

圖1

圖2

圖3

3.配置當前使用者名稱和郵箱

  前面我們說過,用Git進行版本控制與集中式版本控制不同,集中版本控制需要驗證使用者資訊後才能提交程式碼,這樣可以識別出誰提交了程式碼;而分散式版本控制的所有檔案都儲存在本地磁碟中,當提交程式碼的時候,需要配置一個使用者資訊才能被Git執行,在團體合作開發的時候用於識別檔案是誰提交的,但這個識別並沒有驗證使用者的真偽,如圖4所示。

圖4

  $ git config –global user.name “使用者名稱” # 在使用者級配置上設定使用者名稱

  $ git config –global user.email “使用者郵箱” # 在使用者級配置上設定郵箱

  如圖5所示。

圖5

  注意:在使用者級別配置上設定使用者名稱和郵箱資訊,應避免如下情形,假設開發用的電腦為多人使用,並且有一個使用者忘記給專案設定使用者資訊,這時Git會把使用者資訊預設設定為系統級別的資訊,而不給出任何提示。

4.克隆倉庫

  克隆倉庫是從遠端伺服器上拉取一個完整的倉庫到本地磁碟,這樣做的好處在於每個人都有一個完整的程式碼庫,避免把雞蛋放在同一個籃子裡。但相對的,每個人都有一個完整倉庫,對程式碼的防洩露又是一個問題。

  $ git clone # 從一個遠端Git倉庫中克隆到本地磁碟

  注意:Git支援URL傳輸協議:本地協議(Local)、HTTP 協議、SSH(Secure Shell)協議、FTP協議、Git 協議。

(1)本地協議。

  本地協議(Local protocol),使用的是File Protocol(本地檔案傳輸協議),主要用於訪問本地計算機中的檔案,使用file://<檔案路徑>訪問。所以遠端版本庫就是硬碟內的另一個目錄。

  優點:

  基於檔案系統的版本庫的優點是簡單,並且直接使用了現有的檔案許可權和網路訪問許可權。 如果你的團隊已經有共享檔案系統,那麼建立版本庫會十分容易。只需像設定其他共享目錄一樣,把一個裸版本庫的副本放到大家都可以訪問的路徑,並設定好讀/寫許可權就可以了。這也是快速從別人的工作目錄中拉取更新的方法。如果你和別人一起合作一個專案,他想讓你從版本庫中拉取更新時,執行類似git pull /home/john/project的命令比推送到服務再取回要簡單得多。

  缺點:

  這種方法的缺點是,通常共享檔案系統比較難配置,並且不方便從多個位置訪問。如果你想從家裡推送內容,則必須先掛載一個遠端磁碟,與網路連線的訪問方式相比,配置不方便,速度也慢。值得一提的是,如果你使用的是類似於共享掛載的檔案系統,那麼這個方法也不一定是最快的。訪問本地版本庫的速度與訪問資料的速度是一樣的。在同一個伺服器上,如果允許Git訪問本地硬碟,則一般來說,通過NFS訪問版本庫的速度要慢於通過SSH訪問。

  這個協議並不能使倉庫避免意外的損壞。每一個使用者都有“遠端”目錄的完整shell許可權,我們無法阻止他們修改或刪除Git內部檔案或損壞倉庫。

(2)HTTP協議。

  Git通過HTTP通訊有兩種模式。在Git 1.6.6版本之前只有一個方式可用,十分簡單並且通常是隻讀模式的。Git 1.6.6版本引入了一種新的更智慧的協議,讓Git可以像通過SSH那樣智慧地協商和傳輸資料。之後幾年,這個新的HTTP協議因為其簡單、智慧變得十分流行。新版本的HTTP協議一般被稱為“智慧”HTTP協議,舊版本的一般被稱為“啞”HTTP協議。我們先了解一下“智慧”HTTP協議。

  智慧(Smart)HTTP協議。

  智慧HTTP協議的執行方式和SSH協議及Git協議類似,只是執行在標準的HTTP/S埠上,並且可以使用各種HTTP驗證機制,這意味著使用起來要比SSH協議簡單得多。比如可以使用HTTP協議的使用者名稱/密碼的基礎授權,免去設定SSH公鑰。

  智慧HTTP協議或許已經是最流行的使用Git的方式了,它既支援像git://協議一樣設定匿名服務,也可以像SSH協議一樣提供傳輸時的授權和加密。而且只用一個URL就可以做到,不必為不同的需求設定不同的URL。如果你要推送到一個需要授權的伺服器上(一般來講都需要),那麼伺服器會提示你輸入使用者名稱和密碼。從伺服器獲取資料時也是如此。

  啞(Dumb)HTTP協議。

  如果伺服器沒有提供智慧HTTP協議的服務,則Git客戶端會嘗試使用更簡單的啞HTTP協議。在啞HTTP協議裡,Web伺服器僅把裸版本庫當作普通檔案來對待,提供檔案服務。啞HTTP協議的優美之處在於設定起來簡單。基本只需把一個裸版本庫放在HTTP根目錄上,設定一個叫作post-update的掛鉤就可以了。此時,只要能訪問Web伺服器上你的版本庫,就可以克隆你的版本庫。下面是設定從HTTP訪問版本庫的方法。

  $ cd /var/www/htdocs/

  $ git clone –bare /path/to/git_project gitproject.git

  $ cd gitproject.git

  $ mv hooks/post-update.sample hooks/post-update # 將示例指令碼重新命名,需要去

掉.sample指令碼才能被識別執行

  $ chmod a+x hooks/post-update

  這樣就可以了。Git自帶的post-update掛鉤會預設執行合適的命令(git update-server-info),來確保通過HTTP的獲取和克隆操作正常工作。這條命令會在你通過SSH向版本庫推送之後被執行,然後別人就可以通過類似下面的命令來克隆了:

  $ git clone https://example.com/gitproject.git

  這裡我們使用了Apache裡設定時常用的路徑 /var/www/htdocs,不過你可以使用任何靜態Web伺服器——只需把裸版本庫放到正確的目錄下即可。Git的資料是以基本的靜態檔案形式提供的。通常會在可以提供讀/寫的智慧HTTP服務和簡單的只讀的啞HTTP服務之間選一個。極少會將二者混合起來提供服務。

  優點:

  我們將只關注智慧HTTP協議的優點。

  不同的訪問方式只需一個URL,且伺服器只需在授權時提示輸入授權資訊,這兩個簡便性讓終端使用者使用Git變得非常簡單。相比SSH協議,可以使用使用者名稱/密碼授權是一個很大的優勢,這樣使用者就不必在使用Git之前先在本地生成SSH金鑰對再把公鑰上傳到伺服器。對非資深的使用者,或者系統上缺少SSH相關程式的使用者而言,HTTP協議的可用性是主要的優勢。與SSH協議類似,HTTP協議也非常快速和高效。

  你也可以在HTTPS協議上提供只讀版本庫的服務,這樣你在傳輸資料的時候就可以加密資料;或者,你甚至可以讓客戶端使用指定的SSL證照。

  另一個好處是HTTPS協議被廣泛使用,一般的企業防火牆都允許這些埠的資料通過。

  缺點:

  在一些伺服器上,架設HTTPS協議的服務端會比架設SSH協議的服務端棘手一些。除了這一點,用其他協議提供Git服務與智慧HTTP協議相比就幾乎沒有優勢了。

  如果你在HTTP上使用需授權的推送,那麼管理憑證會比使用SSH金鑰認證麻煩一些。然而,你可以使用憑證儲存工具,比如OSX的Keychain或者Windows的憑證管理器。

(3)SSH協議。

  架設Git伺服器時常用SSH協議作為傳輸協議。因為大多數環境下已經支援通過SSH訪問——即使沒有也比較容易架設。SSH協議是一個驗證授權的網路協議,並且,因為其普遍性,架設和使用都很容易。

  通過SSH協議克隆版本庫,你可以指定一個ssh://的URL:

  $ git clone ssh://user@server/project.git

  或者使用一個簡短的scp式的寫法:

  $ git clone user@server:project.git

  也可以不指定使用者,Git會使用當前登入的使用者名稱。

  優點:

  用SSH協議的優勢很多。首先,SSH架設相對簡單——SSH守護程式很常見,多數管理員都有使用經驗,並且多數作業系統都包含了它及相關的管理工具。其次,通過SSH訪問是安全的——所有傳輸資料都要經過授權和加密。最後,與HTTP/S協議、Git協議及本地協議一樣,SSH協議很高效,在傳輸前也會盡量壓縮資料。

  缺點:

  SSH協議的缺點在於你不能通過它實現匿名訪問。即便只是讀取資料,使用者也要有通過SSH訪問你的主機的許可權,這使得SSH協議不利於開源的專案。如果只在公司網路使用,那麼SSH協議可能是你唯一要用到的協議。如果要同時提供匿名只讀訪問和SSH協議,那麼除了為自己推送架設SSH服務外,還要架設一個可以讓其他人訪問的服務。

(4)Git協議。

  接下來是Git協議。這是包含在Git裡的一個特殊的守護程式;它監聽在一個特定的埠(9418),類似於SSH服務,但是訪問無須任何授權。要想讓版本庫支援Git協議,則需要先建立一個git-daemon-export-ok檔案——它是Git協議守護程式為這個版本庫提供服務的必要條件——但是除此之外,沒有任何安全措施。要麼誰都可以克隆這個版本庫,要麼誰都不能。這意味著,通常不能通過Git協議推送。由於沒有授權機制,一旦你開放推送操作,就意味著網路上知道這個專案URL的人都可以向專案推送資料。不用說,極少會有人這麼做。

  優點:

  目前,Git協議是Git使用的網路傳輸協議裡速度最快的。如果你的專案有很大的訪問量,或者你的專案很龐大並且不需要為寫進行使用者授權,那麼架設Git守護程式來提供服務是不錯的選擇。它使用與SSH相同的資料傳輸機制,但是省去了加密和授權的開銷。

  缺點:

  Git協議的缺點是缺乏授權機制。把Git協議作為訪問專案版本庫的唯一手段是不可取的。一般的做法是,同時提供SSH或者HTTPS協議的訪問服務,只讓少數幾個開發者有推送(寫)許可權,其他人通過git://訪問只有讀許可權。Git協議許也是最難架設的。它要求有自己的守護程式,這就要配置xinetd或者其他程式,這些工作並不簡單。它還要求防火牆開放9418埠,但是企業防火牆一般不會開放這個非標準埠。而大型的企業防火牆通常會封鎖這個埠。

  說明:clone和checkout的區別如下。

  git clone命令是將版本庫完整克隆到本地新目錄中,在建立好本地庫後會自動檢出當前活動分支或初始化分支。

  git checkout命令是建立分支或切換分支,使用該命令後會自動更新HEAD檔案,將其改寫成當前分支。

5.檢視檔案狀態

  使用git status可以檢視當前工作區域內檔案的狀態,沒被跟蹤內容會在Untracked files中顯示,可以通過git add 新增被跟蹤,如圖6所示。

  $ git status

圖6

6.新增檔案追蹤

  使用git add 命令將檔案新增到index(索引)檔案中,這些檔案列表將在下一次提交時記錄到倉庫,如圖7所示。

  $ git add app/ # 將app目錄新增到index檔案中

圖7

7.提交程式碼

  使用git commit命令將index檔案中的更改記錄提交到本地版本庫。使用引數-m可以直接將要新增的備註資訊寫入,如圖8所示。

  $ git commit -m “add app folder” # 提交到版本庫,並寫入提交資訊

圖8

8.檢視遠端倉庫

  使用git remote命令可以顯示當前版本庫的遠端倉庫伺服器資訊。引數-v顯示遠端倉庫簡寫名稱和URL地址,如圖9所示。

  $ git remote -v # 顯示版本庫連線的遠端倉庫和URL

圖9

9.新增遠端倉庫

  使用git remote add <遠端倉庫別名> 為本地版本庫新增一個遠端倉庫,如圖10所示。

  $ git remote add origin https://github.com/lanmaokafei/python_fullstack.git # 新增一個遠端倉庫

圖10

10.推送程式碼

  使用git push <遠端倉庫別名> <本地分支>將本地版本庫推送到遠端倉庫,如圖11所示。

  $ git push origin master # 將本地master分支提交到別名為origin的遠端倉庫

圖11

11.從遠端倉庫更新程式碼到本地

  將程式碼推送到遠端倉庫後,其他非最新版本的使用者需要更新最新程式碼,可以使用git fetch或git pull命令來更新。區別在於fetch獲取最新的程式碼到本地倉庫,但不會自動合併分支,需要比較分支差異後合併,而pull則直接將遠端倉庫的版本合併到本地master上,所以git fetch相對安全些,如圖12和圖13所示。

  $ git fetch origin master # 下載origin最新的程式碼

圖12

  $ git merge origin/master # 將origin/master分支合併到本地master中

圖13

12.版本標記

  很多書或網上會把版本標記翻譯成里程碑,即給當前提交定義一個標籤,標記出當前提交內容有別於其他提交。例如,在開發完一個新功能後,可以將其標記一個v1.1,代表這個功能開發完成,方便以後歷史中定位這次提交。

  Git有兩種標籤型別:一種是lightweight輕量級標籤,只有版本號無其他資訊;另一種是annotated附註標籤,標籤附帶一條資訊,可以讓別人快速識別標籤作用,建議使用這種標籤。

  使用git tag -n[數字] 顯示當前分支下的標籤資訊,引數-n代表顯示備註資訊行數,如圖14所示。

圖14

  使用git tag -a <版本號> -m“備註”為最新提交打上標籤,如圖15所示。

圖15

  使用git show <版本號>顯示對應標籤的版本資訊和提交差異,如圖16所示。

圖16

13.新增忽略檔案

  在當前專案根目錄下建立一個.gitignore檔案,用於儲存忽略列表,如圖17所示。

圖17

  配置語法如下:

  “/”代表目錄;

  “*”代表通配任意字元;

  “?”代表通配單個字元;

  “[]”代表單個字元的匹配列表;

  “!”表示不忽略,一定要跟蹤。

14.檢視當前處在的分支

  使用命令 git branch可以檢視當前工作目錄所在的分支,如圖18所示。

圖18

15.建立分支

  在家裡開發使用的是PostgreSQL資料庫,到公司後沒有線上的資料就切換到SQLite,這樣我們就建立一個新的分支以便在公司開發。使用命令git checkout -b jsb建立並切換到jsb分支,命令git checkout -b等同於同時執行了命令git branch jsb 建立分支和命令git checkout jsb切換到jsb分支,如圖19所示。

圖19

16.合併分支

  當回到家時再把在公司開發的程式碼和家裡的版本庫合併分支,切換回master分支,使用命令git merge合併兩個分支,如圖20所示。

圖20

17.解決衝突

  之前使用了不同的忽略語句,兩個分支間沒有衝突,但是如果兩個分支同時修改了同一個檔案相同位置的不同引數時,在合併的時候就會產生衝突,如圖21所示。

圖21

  在master版本中,SQLALCHEMY_DATABASE_URI 是連線PostgreSQL的資料連線’postgresql://xyj:lanmaokafei@192.168.1.137/postgres’。

  在jsb版本中,SQLALCHEMY_DATABASE_URI是指向SQLite的資料檔案 ‘sqlite:///./db/ data.db’ 。
  當這兩個分支合併的時候就會產生衝突,需要人工修改才能合併,如圖22和圖23所示。

圖22

圖23

  說明:人工修改衝突部分,需要將自動生成的<<<<<<< HEAD、=======、>>>>>>> jsb全部刪除,自行判斷衝突部分需要保留什麼內容或者將兩者融合,修改完成後儲存檔案,重新使用命令git add新增檔案,後再提交一次,即可解決衝突問題。

  以上內容節選自《Python全棧開發實踐入門》
                 
  想及時獲得更多精彩文章,可在微信中搜尋“博文視點”或者掃描下方二維碼並關注。
                    圖片描述

相關文章