iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 5
0

【應試目標能力】

701.3 源碼管理 Source Code Management (5)

  • 瞭解 Git 的概念及儲存庫 (repository) 的結構
  • 在 Git 儲存庫中管理檔案
  • 管理分支 (branch) 和標籤 (tag)
  • 使用遠端儲存庫、分支、子模組 (submodule) 工作
  • 合併檔案及分支
  • 知道 SVN、CVS,包括集中式 (centralized) 及分散式 (distributed) 源碼管理解決方案的概念

第二個要介紹的是源碼管理工具 Git。這個由 Linux 之父 Linus Torvalds 所發明的工具,我想大家都很熟悉了。在源碼管理工具中,Git 普遍被認為是一個進入門檻較高的工具,但隨著 GitHub、GitLab 這類以 Git 作為基礎的代碼託管平台的盛行,網路上有愈來愈多人發表各樣的教學文件或影片供大眾學習。Git 的功能十分強大,一般情況下我覺得很難掌握它的全部特性,而且有的功能可能要很久才會用到一次,因此還是先以瞭解 Git 的基本用法作為這幾天的學習目標。

在開始學習 Git 之前,應該要先對源碼管理或版本控制有一些概念。我在念書的時候不知道有版本控制工具這種東西能用,於是就把目錄或檔案名稱加上日期作為不同版本的區別,然後程式碼中也四處充斥著註解掉的程式碼。其實也不是說這樣作就一定不好,如果只有自己一個人寫程式碼,也很習慣這樣的工作模式,那不需要特別改變。以個人經驗來說,在一個人的專案中使用 Git 的好處,是知道只要有提交 (commit) 就幾乎一定可以找得回來,所以可以比較放心的去刪除修改程式。當然如果是多人一起協同開發,那麼有一套源碼管理工具就是十分必要的了。我覺得在學習 Git 時,除了知道指令怎麼用之外,還要去體會 Git 的設計,它的使用方式如何與各種協同開發工作模式相互作用。我想這也是 Git 為什麼這麼受歡迎的原因之一,因為它為團隊合作開發帶來了新的模式及可能性。

我將 Git 的學習分為三個維度,第一個維度為上下,考慮線性時間,在這個維度包括瞭解提交 (commit)、如何提交、如何回覆檔案狀態至某一個版本等基礎操作。第二個維度是左右,在原本單一線性的基礎上考慮分支,在這個維度要瞭解 branch 的用途及如何管理。第三個維度為前後,考慮與他人合作,在這個維度要瞭解遠端儲存庫 (remote repository) 的相關操作。如果只是一個人開發管理不太大的專案,其實瞭解到第一個維度也就夠用了,但如果是團隊的協同開發,那麼綜合第二個維度與第三個維度,才能發揮 Git 的真正作用。抱持這樣的想法,依照自己的需求去學習實際上會用到的功能,這樣應該會輕鬆一些。

今天打算介紹第一個維度的內容,主要的程式碼及圖片取自 Pro Git,第二版由 Scott Chacon 和 Ben Straub 合寫,在 https://git-scm.com/book/en/v2 提供線上閱讀,部分章節亦有繁體中文翻譯。

Git 的版本控制原則上是以一個目錄為範圍,在這個目錄裡面的檔案及子目錄,我們可以隨時紀錄在某個時刻下的特定狀態,包括有那些資料、那些資料的內容等等,每一次的記錄稱為一個 commit。在這裡把 commit 翻成「提交」,也可以作動詞使用,指的是我們「告訴 Git 記錄目前狀態」的動作 。提交可以想成是 Git 會在它的資料庫中,用它的方式將目錄中的資料保留一份,這個資料庫在 Git 的術語稱作儲存庫 (repository)。

提交有先後次序之分,因此可以將其排列成一個線性的記錄。版本控制系統最主要的一個功能,就是讓我們可以查看這個線性的記錄,並允許我們讓目前的工作目錄內容,回復到任何一個先前曾被記錄的狀態。

目前 Git 已有圖形化介面的客戶端軟體,不過我們學習時還是以命令列模式的指令為主。Git 安裝方法請參考 https://git-scm.com/downloads 的說明。安裝好之後,我們要進行一些簡單的設定,最主要的是告訴 Git 你是誰。Git 的設定有範圍大小區分,從整個系統、單一使用者到專案,而告訴 Git 身份是屬於使用者範圍的設定,例如:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

另一個常用的設定文字編輯器類型,例如:

$ git config --global core.editor vim

上述設定在提交時會用到,包含使用那種文字編輯器來編輯提交訊息,以及提交時會保留的提交者資訊。

要看目前的設定內容,可以用

$ git config --list

接下來要正式進入工具的使用。前面有提過版本控制以一個目錄為範圍,所以我們先選擇一個目錄,稱之為工作目錄 (working directory),進入該目錄後,使用

$ git init

這個指令會在此目錄中產生一個 .git 的目錄,用以存放 Git 進行版本管理時所產生的內容。如果這個目錄之後不需版控,直接將 .git 目錄刪除即可。

在這個目錄中新增一些檔案並隨意編輯其內容,現在我們要進行初次提交,Git 會幫忙記住此刻在這個目錄中有那些內容。接下來是很重要的概念 -- Git 的兩階段提交。在真正的提交之前,要先告訴 Git 有那些東西想要提交,使用的指令是

$ git add <file>

針對在工作目錄中第一次新增的檔案,這個指令告訴 Git 我們想要 Git 「納管」這個檔案,Git 就會開始追蹤這個檔案。接下來若我們更改了這個檔案的狀態(可能是修改或刪除),在提交之前,必須再使用一次 git add 指令告訴 Git 它的狀態更動了。在 Git 中這個階段叫 staging ,有點像是把檔案放入暫存區 (staging area) 的概念,在文件中有另外一種說法叫作 index,git add 就是把檔案加到 index 的意思。如果想要更新工作目錄中所有檔案的狀態,可以加上 -A 參數。

$ git add -A

在提交之前,可能會想看一下目前工作目錄的狀態,指令如下:

$ git status

以下我們借用 Pro Git 一書中的範例儲存庫,可由下述指令取得:

$ git clone https://github.com/schacon/simplegit-progit

執行完這個指令,會在當前目錄下新增 simplegit-progit 這個目錄,裡面有三個檔案。為了說明方便,我在工作目錄中作一些修改,以下為修改後執行 git status 這個指令的輸出。前兩行它會告訴我們目前所在的分支,以及和遠端儲存庫的同步狀態,之後會再介紹。我們看到下方關於檔案狀態的描述有三個段落,說明如下:

  1. Changes to be committed,表示這是 Git 有納管的檔案,而且在這次提交中已先使用 git add 指令告知狀態更改。deleted 表示此檔案被刪除,modified 表示檔案內容有更動,new file 表示為此次提交要新增納管的檔案。
  2. Changes not staged for commit 表示這個檔案先前已被納管,但是更動內容後並沒有再以 git add 告知我們要在這次的提交中更新其狀態。
  3. Untracked files 表示這個檔案沒有被 Git 納管。

在括號內的文字說明針對這三個狀態的檔案後續可能進行的操作,包括回復先前狀態或放棄變更,之後會有更詳細的說明。

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    README
    modified:   Rakefile
    new file:   new-file.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   lib/simplegit.rb

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    no-commit.txt

要是沒問題的話就可以用下面的指令進行提交了。

$ git commit

今天先到這裡,明天針對提交再作進一步的說明。


上一篇
[Day 04] Vagrant (2)
下一篇
[Day 06] Git (2)
系列文
30 天準備 LPI DevOps Tools Engineer 證照30

尚未有邦友留言

立即登入留言