1. 程式人生 > >Git & Gitlab 使用學習過程

Git & Gitlab 使用學習過程

原文:http://www.restran.net/2016/02/23/git-and-gitlab-guide/?utm_source=tuicool&utm_medium=referral

1. 關於 Git 你應該知道的東西

Git 是一個分散式版本控制系統。分散式的意思是,每個人電腦上都是一份完整的程式碼庫,包含了所有的程式碼提交歷史。由於 Git 分散式的特點,在沒有網路的情況下,依然可以自由地將程式碼提交的本地的程式碼庫中,等網路恢復後再推送到伺服器,開發更加靈活和自由。

重要概念:本地一個程式碼庫,對本地檔案的所有操作,最後都是提交到這個程式碼庫中。同時可以設定多個遠端(remote,預設的remote通常用origin表示),當你要將程式碼更新到伺服器上時(稱作push),就通過設定的remote,更新到指定的伺服器。

關於多個remote:例如其他公司的開發人員,在自己的公司中開發程式碼,將預設remote設定為公司自己的原始碼管理伺服器,同時設定另外一個remote為移動的原始碼伺服器。這樣即可以將程式碼提交到自己公司的伺服器,同時也可以提交到移動的伺服器。

1.1 一些術語

  • Fetch(獲取),從遠端程式碼庫更新資料到原生代碼庫。 注意 :Fetch 只是將程式碼更新到原生代碼庫,你需要檢出(check out)或與當前工作分支合併(merge)才能在你的工作目錄中看到程式碼的改變。
  • Pull(拉取),從遠端程式碼庫更新資料到原生代碼庫,並與當前工作分支合併,等同於 Fetch + Merge。
  • Push(推送),將原生代碼庫中已提交(commit)的資料推送到指定的 remote,沒有 commit 的資料,不會push
  • HEAD,指向你正在工作中的本地分支的指標
  • Master 分支:主分支,所有提供給使用者使用的正式版本,都在這個主分支上釋出。 關於分支管理的擴充套件閱讀
  • Tags(標籤):用來記錄重要的版本歷史,例如里程碑版本
  • Origin:預設的 remote的名稱
  • Git clone(克隆版本庫):從服務端將專案的版本庫克隆下來
  • Git init(在本地初始化版本庫):在本地建立版本庫的時候使用

1.2 工作流程

  1. 對程式碼進行修改
  2. 完成了某項功能,提交(commit,只是提交到原生代碼庫),1-2可以反覆進行,直到覺得可以推送到伺服器上時,執行3
  3. 拉取(pull,或者用獲取 fetch 然後再手動合併 merge)
  4. 如果存在衝突,解決衝突
  5. 推送(push),將資料提交到伺服器上的程式碼庫

1.3 Gitlab 可以做什麼

Gitlab 是 Git 服務端的整合管理平臺,提供了:

  1. 程式碼託管服務
  2. 訪問許可權控制
  3. 問題跟蹤,bug的記錄、跟蹤和討論
  4. Wiki,專案中一些相關的說明和文件
  5. 程式碼審查,可以檢視、評論程式碼

目前官方沒有中文版,有個人漢化版本,一些地方對中文的支援較不好(詳見後續章節),如果有需要中文翻譯的地方,可以自己修改對應的程式碼。

怎麼安裝和維護 Gitlab,請看我另外一篇部落格 CentOS 6.5 Minimal 安裝 Gitlab 7.5

2. 安裝與配置

需要安裝以下工具:

Git 圖形介面操作工具

TortoiseGit只有 Windows 版本,有32位和64位版本,請根據自己的電腦選擇相應的版本,同時下載對應版本的中文語言包。

2.1 設定 TortoiseGit 中文語言

右鍵 -> TortoiseGit -> 設定



2.2 設定使用者名稱和郵箱

點選 Git 選項,然後點選右側的 全域性 ,最後輸入使用者名稱和郵箱即可。這裡的使用者名稱和郵箱,將作為以後提交資料到Git服務端的作者資訊,請一定要設定。


2.3 設定儲存密碼

預設情況下,Git 客戶端每次與伺服器互動,都需要輸入密碼。但是我們可以配置儲存密碼,只需要輸入一次,就不再需要輸入密碼。


選擇 編輯全域性.git/config ,在末尾新增


    
  1. [credential]
  2. helper = store


2.4 配置 SSH Key

Git 可以通過 HTTP 和 SSH 的方式連線,如果要使用SSH的方式連線,需要確保自己的 IP 有訪問 Gitlab 伺服器 22 埠的許可權。

通過 SSH 的方式,可以不用每次與伺服器進行互動時都需要輸入使用者名稱和密碼。如果是 IDE 中的 Git 外掛,則有儲存密碼的功能。

2.5 生成 SSH Key

2.5.1 在 Git Bash 命令列下生成

滑鼠右鍵 -> Git Bash


  
  1. ssh-keygen -t rsa -C "uasername@139.com"

生成後的公鑰會存放在

C:/Users/You_User_Name/.ssh/id_rsa.pub

  

2.5.2 在視覺化工具下生成

注意:使用這種方法生成時,預設會用計算機名,作為生成的 SSH Key 的名稱,如果計算機名包含中文,則會因編碼問題而出錯。這時候可以使用在 Git Bash 命令列下生成的方法。

滑鼠右鍵 -> Git Gui


幫助 -> Show SSH Key


點選 Generate Key,彈出一個對話方塊,提示輸入 passphrase(密碼短語),需要輸入兩次。意思就是以後提交資料到服務端,只要輸入這個密碼短語就可以了。這裡可以為空,直接點OK,這樣,以後就不需要輸入任何密碼。但建議還是要輸入密碼短語。


複製 SSH Key 的公鑰


2.6 在 Gitlab 上配置 SSH Key

配置好 SSH Key 以後提交程式碼,可以不用輸入密碼。點選右上角的資料設定 -> SSH 金鑰 -> 增加 SSH 金鑰


貼上剛剛複製的 SSH Key 公鑰,標題為可選,不寫會自動生成


2.7 配置 Gitlab

2.7.1 上傳個人頭像

請上傳個人頭像,主要是為了易於識別使用者。


2.7.2 設定郵件通知

如果不想收到郵件通知,可以設定關閉。但是建議開啟郵件通知。


3. Git 基本功能簡介

3.1 我是專案的建立者,我要建立專案

3.1.1 在 Gitlab 上執行建立新專案

  1. 取一個恰當的名字。
  2. 選擇正確的名稱空間。所有人都可以在自身使用者名稱下建立新專案,但是群組名稱空間下的專案只能由具有相應許可權的人建立。
  3. 填寫詳細的專案描述
  4. 選擇可見等級


專案建立完成後,需要初始化,請保留該頁面,在必要時複製專案的 SSH 地址

Git 同時支援 SSH 和 HTTP 的方式訪問,SSH 可以不用輸入密碼。


3.1.2 初始化專案

以下這些操作,需要在專案的目錄下進行。請注意如果你的專案資料夾路徑包含中文,請使用 TortoiseGit 工具來操作,不要使用 Git Gui,否則會出現錯誤。

3.1.3 建立一份排除版本控制的檔案型別清單

在專案中,實際上有很多檔案是不需要版本控制的,例如編譯過程中生成的中間檔案 .obj ,IDE 的配置檔案(Intellj IDEA 的.idea 資料夾),編譯生成的檔案(/out/ 和 /bin/ 資料夾),Python的.pyc檔案,像這些型別的檔案我們可以設定過濾,避免導致版本庫很大。

我們只要在專案的目錄下,放一個 .gitignore 檔案就可以了。


這份 .gitignore 檔案,排除了.idea/,out/,bin/ 資料夾,以及所有型別為 .pyc 的檔案


Github 上面有一個 .gitignore 模板的專案

如果後續開發中有新型別的檔案要排除,可以在檔案上

右鍵 -> TortoisGit -> 刪除並新增到忽略列表

  

3.1.4 建立一份 README.md 檔案

README.md 檔案用來填寫專案的描述和說明,會直接顯示在 Gitlab 的專案檔案頁面,方便直接檢視專案的描述資訊。

.md 是 Markdown 格式的檔案,關於 Markdown,可以檢視 作業部落


3.1.5 在自己的電腦上建立版本庫

在專案目錄下

右鍵 -> Git init here

  

這樣就可以在當前資料夾建立一個 Git 版本控制的庫,同時建立一個分支 master。

該操作會在這個資料夾下自動建立一個 .git 的隱藏資料夾,所有關於版本控制的資訊都放在這個資料夾下面的檔案中。


3.1.6 提交程式碼到本地版本庫

右鍵 -> Git 提交

  


選擇要提交的檔案,並填寫描述資訊


3.1.7 設定 remote


將專案的 SSH 地址複製過來,並將預設的 remote 名稱設定為 origin



如果提示是否關閉獲取標籤,也選擇 No

3.1.8 推送到伺服器上的版本庫(push to remote)



如果提示該伺服器主機是未知的,請選擇是,新增到已知主機列表


到這一步專案的程式碼庫已建立完成,可以去 Gitlab 上檢視專案


3.1.9 建立開發分支

預設情況下,master 分支在 Gitlab 中是保護分支。保護分支只允許 Master 級別以上的使用者才能 push 和 delete。而普通的開發人員(Developer 級別)是無法提交程式碼到 master分支的。

這麼設計的原因是:我們通常將 master 分支作為穩定版本釋出的分支,在這個分支上的程式碼都是最新可用版本。而日常的開發,通常在開發分支 develop 上進行。等到功能穩定後,再由專案的管理員合併到 master 分支上。

請在 Gitlab 中操作



3.2 我是開發人員,我要獲取和提交程式碼

3.2.1 克隆專案

在一個空白的專案資料夾下,右鍵 -> Git克隆。

如果你已配好了SSH Key,請輸入專案的SSH地址,這樣就可以不用再輸入密碼。Git 支援 SSH 和 HTTP 的方式訪問,這裡也可以使用 HTTP 地址。


如果提示該伺服器主機是未知的,請選擇 ,新增到已知主機列表


3.2.2 檢出開發分支

Git 克隆預設會檢出 master 分支,但是我們需要在開發分支中工作。



檢查當前所在的分支


注意:切換分支的時候,如果有未提交的內容,需要先提交,否則無法切換分支。如果不想提交可以用貯藏(stash)

到這一步完成,你就可以在本地自由地做開發了

3.2.3 從伺服器的程式碼庫更新資料

請注意,選擇拉取功能,就不需要再執行合併。如果是獲取,就需要再執行一次合併。兩者的區別在於,拉取省略了合併的細節。


3.2.4 衝突與解決

出現無法推送


試試拉取,但拉取的時候出現衝突,Merge conflict in test.html


這時候需要先解決衝突


解決方法有兩種,一種是開啟衝突的檔案,手動刪除衝突標記

上面那部分的內容是原生代碼庫,HEAD 所指向分支的程式碼,下面那部分的內容是伺服器端程式碼庫的內容

<<<<<<< HEAD
<pre>This is for test.</pre>
=======
<p><a>This is for test.</a></p>
>>>>>>> 5f065407ecf91415f109c882119291f0be37b07a

只需要決定最後的內容,然後刪除衝突標記,例如,只剩下

<pre>This is for test.</pre>


刪除完衝突標記後,需要右鍵空白的地方,點選 Git Add all files now


另一種方法是使用 TorgoiseGit 的工具


雙擊衝突的檔案


點選儲存


不管使用哪種方法,最後都要執行的兩步操作是 提交推送

提交


推送


當成功推送到伺服器的程式碼庫後,衝突才算真正解決

3.2.5 提交和推送程式碼到伺服器的版本庫

請檢視 3.2.3 和 3.2.5,注意選擇正確的分支。

請注意:只有專案的 master 許可權或者 owner 許可權的人才能將程式碼推送到保護分支中,master 分支預設是保護分支。假如自己沒有推送到保護分支的許可權時,你可以將程式碼提交到,如 develop 分支中(或者自己建立的分支中),等 develop 分支的程式碼穩定後,然後在 Gitlab 的專案地址中,發起一個 merge request 請求,系統會發送郵件通知對應的人執行合併操作。這樣就可以將程式碼合併到保護分支中(如 master 分支)

發起合併請求


選擇需要合併的分支,點選“比較分支”(需要先比較分支,可以檢視到這兩個分支的差異)


描述分支合併請求,然後指派給專案的管理員,專案管理員會收到合併請求的郵件

3.3 分支與標籤

3.3.1 建立分支與標籤

分支可以基於任意提交(commit)、已有分支、已有標籤中建立。

當你要做實驗,或者開發新功能,修正bug時,都可以通過建立分支來安全的處理。這樣就不會影響正常的開發,當完成的時候,再合併回去。

建立完分支後,記得切換到正確的分支中去工作。

標籤是隻讀的,通常只用來記錄特定的歷史時刻,如里程碑版本等,這是為了方便以後檢出特定版本的程式碼。


3.3.2 推送分支或標籤到伺服器的版本庫

使用推送命令,可以將本地版本庫中的分支推送到伺服器的版本庫中。如果要推送標籤,請勾選 包含標籤

3.3.3 分支合併


選擇要合併到當前工作分支中的分支,例如當前所在的分支是 master,選擇 develop,則會將 develop 中的程式碼合併到 master 中。


合併分支有可能會出現衝突,解決衝突的方法請參見 3.3.4

4 Gitlab 基本功能

4.1 為專案寫 WiKi

WiKi 可以放專案的相關說明文件,包括部署手冊,使用手冊等等。



Gitlab 的 Wiki 使用了 Markdown 格式(是一種輕量級標記語言,可以使用易讀易寫的純文字格式編寫出排版漂亮的文件)

簡易入門請看 作業部落

4.2 檢視專案的標籤資訊

在儀表盤中,點選專案

5 高階功能

5.1 從SVN遷移到Git

Git 最為重要的特性之一是名為 git svn 的 Subversion 雙向橋接工具。該工具把 Git 變成了 Subversion服務的客戶端,從而可以將 SVN 的程式碼庫遷移到 Git,同時保留提交日誌。

使用 TortoiseGit 的 Git 克隆,選擇從 SVN 版本庫

將程式碼克隆下來後,再設定下 Git 程式碼庫的 remote,然後推送過去就可以了。

5.2 從 TFS 遷移到 Git

需要使用工具 git-tfs,下載地址在這裡

https://github.com/git-tfs/git-tfs/releases

請注意 v0.20.0 版本不支援 TFS 伺服器是 2008 版本,如果是 TFS 2008,請選擇 v0.19.2。

需要將 git-tfs 檔案目錄新增到環境變數。

還需要再安裝 TFS Team Explorer。如果伺服器是TFS 2008版本,必須確保自己的電腦上只能安裝 TFS Team Explorer 2008,如果安裝了 TFS Team Explorer 2013,則仍然會提示不支援 TFS 2008,無法正確使用 git-tfs。可以切換到虛擬機器中,只安裝 TFS 2008 中。

在 Git Bash 中輸入如下命令


  
  1. git-tfs clone http://192.168.8.25:8080 $/qzmcc_uuv

qzmcc_uuv 為專案在 TFS 上的名稱, http://192.168.8.25:8080 為 TFS 的伺服器地址。

5.3 比較版本差異

右鍵,Tortoise Git -> 顯示日誌

按 Ctrl 滑鼠左鍵選擇兩個版本,右鍵選擇比較差異

右鍵選擇要比較差異的檔案,選擇比較差異

TortoiseGit 可以比較 Word 檔案的差異

文字檔案的差異比較是這樣的

5.4 刪除分支

當我們將分支合併到主分支,或者放棄該分支的時候,可以對分支進行刪除操作。

在 TortoiseGit 上進行分支刪除操作非常簡單,首先開啟 “CheckOut/Switch” 對話方塊,通過 “Switch to Branch” 更多按鈕開啟分支列表,或者通過選單 “Browser References” 開啟分支列表(預設該選單是隱藏的)。選擇相應的分支,單擊右鍵,選擇刪除。

注意:

  1. 刪除分支,既可以刪除本地分支,也可以刪除遠端分支。
  2. 如果刪除遠端分支,推送後,伺服器上對應的分支會被刪除。當其他開發者更新資料後,其對應的本地分支並不會刪除。
  3. 在刪除遠端分支的時候,本地分支並不會刪除,這也說明了本地分支與遠端分支並無從屬關係。

5.5 重置程式碼到以前的版本

當我們發現當前的程式碼有問題,想回退到之前的版本時,可以使用重置版本。在專案目錄下,

右鍵 -> TorgoiseGit -> 顯示日誌

  

進入日誌資訊視窗,選擇指定的版本

右鍵 -> 重置到這個版本

  

5.5.1 重置型別,soft, mixed, hard 的區別

soft 不改動工作區和索引

假設有一些 commits

A - B - C (master)

  

HEAD 指向 C, 並且暫存區(stage,或稱為 index)matches C.

當使用 git reset --soft B 時,master 和 HEAD 指向 B,但是依然保留了 C 新增跟蹤的檔案,此時會將這些檔案放入暫存區中,顯示為已快取。同時工作區中修改的檔案,顯示為未快取。

mixed 保持工作區不變,重置索引

當使用 git reset --mixed B 時,master 和 HEAD 指向 B,這時候 C 新增跟蹤的檔案仍然會在,但是會顯示為未快取(不是版本控制),而當前工作目錄中的修改內容,仍然會在,顯示未快取的狀態

(如果不知道怎麼選,預設使用 mixed)

hard 重置索引和工作區(丟棄所有本地變更)

當使用 git reset --hard B 時,C 新增跟蹤的檔案,以及當前工作目錄中的修改內容,都會丟失。

6 Eclipse 中使用 EGit

6.1 檢出專案

File/Import


6.2 更新和推送資料

6.2.1 獲取資料(fetch)

專案右鍵 -> Team -> Remote -> Fetch From

  

Gerrit 是基於 Git 的程式碼稽核軟體

選擇遠端程式碼庫

自定義選擇要獲取的遠端分支,該圖是遠端倉庫中的所有

fetch 只是把服務端的程式碼更新,放到本地的程式碼庫中,還需要與本地分支合併,才能真正將程式碼更新到工作目錄中。

分支的合併也是在這裡操作,注意上圖中,當前是 master,然後要把 origin/master 合併到 master 中


    
  1. squash:不建立新的 commit
  2. pull = fetch + merge

6.2.2 推送(push)

如果要刪除分支,也可以在這裡操作,Add delete ref specification

6.2.3 Fetch from Upstream, Push to Upstream

Git 可以同時設定多個遠端分支,這裡的 Upstream 可以簡單的理解成是預設的遠端分支,因為程式碼的版本歷史,就像溪流不斷向前,因此把程式碼源稱為 Upstream(因為本地的程式碼 clone 自這裡)。

6.3 解決衝突

選擇 Team -> Merge Tool

  

  • 第一項是將GIT自動合併過的檔案和伺服器端檔案進行對比
  • 第二項是用本地最新版本的檔案和伺服器端檔案進行對比,建議用此項

修改左邊的本地資料,修改好後 Ctrl+S 儲存檔案就可以了。這時候再次檢視檔案,衝突標記已經自動去掉。


    
  1. <<<<<<< HEAD
  2. =======
  3. > >>>>>> remote

然後右鍵點選此衝突檔案


  
  1. 選擇 Team -> Add to index

再次將檔案加入索引控制,此時檔案已經不是衝突狀態,並且可以進行提交併 push 到伺服器端。一定要重新 commit,並 push 到服務端,才算真正解決衝突。

6.4 分支和標籤

建立分支

建立標籤

6.5 reset 到某個版本