第五章 git

git 是一個在軟體開發上的版本控管系統 (Version Control System), 早期流行的 CVS、svn (subversion) 也都是屬於同類型的系統。它主要是用來控管程式碼 (檔案) 的版本。當你的程式碼在持續開發時, 每一次修改都會被記錄。要對照不同的版本、時間點、作者, 都非常好用。而通常它也是很好的備份方案, 因此如果誤刪檔案, 還可以很快速的救回來。

這邊只會講到非常基礎與簡單的用法。現在網路上有非常多資源在說明 git, 這邊就只針對最基礎的部分說明。

建立一個 repository

現在雲端的 git service 很方便, 如 GithubBitbucket 或是 GitLab 都是很常見的服務。我們會以 GitLab 為例, 但是其實你使用其他的服務也都大同小異。

首先, 在我們開程式專案時, 先建立一個 repository (倉庫)。在 GitLab 裡面找到「New Project」就可以開啟一個新的專案。

New Project

在 Project name 填上專案的名稱, 再按下 Create Project 即可

New Project Form

至於到底要如何命名你的專案名稱呢? 目前看到的都是以「全部小寫」以及「-」連接為主。可以參考下面兩篇文章:

(或是直接搜尋「git repo naming conventions」)

新增認證金鑰

建立好專案之後, 我們需要做一個類一次性的動作 (取決於你會使用多少不同的電腦來存取這個 git repository), 那就是建立與新增金鑰到 GitLab 上。

首先要先建立金鑰, 但在建立之前, 有可能之前已經建立過了, 所以先看看檔案在不在

$ ls ~/.ssh/id_rsa.pub

如果出現的訊息是

ls: /Users/yychen/.ssh/id_rsa.pub: No such file or directory

那就是還沒有建立過, 等等需要建立。如果出現的訊息是

/Users/yychen/.ssh/id_rsa.pub

那代表已經有這個檔案, 可以不用建立金鑰 (也就是可以跳過下面「建立金鑰」的步驟)。

建立金鑰

建立金鑰的指令很簡單, 只要輸入 ssh-keygen 這個指令即可

$ ssh-keygen

它會先問要金鑰要存放在哪裡, 你只要按下 Enter, 選擇它預設的值即可

Enter file in which to save the key (/Users/yychen/.ssh/id_rsa):

接著, 它會要求你建立一個密碼 (以及再打一次確認)

Enter passphrase (empty for no passphrase): 
Enter same passphrase again:

如果你此時打了密碼, 則你每一次使用到這個金鑰時都需要輸入密碼才能成功。你也可以按下 Enter 留白, 就不會建立密碼。之後使用它的時候也不用每次都輸入。

此時, 你的金鑰就已經建立完成。金鑰包含兩個部分, 分別是公鑰與私鑰, 他們分別會被存在 ~/.ssh/id_rsa.pub 以及 ~/.ssh/id_rsa 這兩個檔案裡面。

新增金鑰到 GitLab

我們先把我們剛建立好的 (或是之前建立好的) 公鑰內容複製

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDg44DR4HXmHS... [email protected]

把 ssh-rsa (包含) 開頭的整個好幾行的內容, 全部圈選起來複製。接著到 GitLab 的 Profile Settings 裡面的 SSH Keys。將內容貼在 Key 的框框裡面, 然後再按下 Add Key 即可。

Add SSH Key

在自己的電腦上作業

我們在 GitLab 上面已經新增好專案了, 那現在就要讓自己的電腦上跟這個專案做連結。不過我們還有一個一次性的設定要在我們自己的電腦上面做, 那就是設定 git 的使用者姓名與 E-mail。在你的 git 安裝好之後, 只要設定一次即可。在 command line 鍵入下面指令

$ git config --global user.name "Tom Chen"
$ git config --global user.email "[email protected]"

當然, 上面的 Tom Chen[email protected] 記得要換成你自己的。

接著, 就要跟 GitLab 上面的專案與自己的電腦上的東西做連動了。連動的方式有兩種, 第一種是你什麼東西都還沒有, 也就是還沒有任何程式碼任何檔案, 那我們會直接將 GitLab 上剛建立的 repository 給 clone (複製) 下來。第二種則是你已經有一些程式碼了, 我們會初始化你放程式碼的目錄, 並且設定與 GitLab 上的專案連結。關於第二種的設定方式, 請參考本章下方「已經有程式碼了, 但 git 是新開的」。

在開始之前, 先找到 repository 的位址並且複製下來。它就位於專案首頁的框框裡面。如果框框的前面寫著 HTTP, 請改成選擇 SSH。HTTP 也是可以使用, 但缺點是你會需要一直輸入帳號密碼, 很不方便。

Git URL

然後再 command line 輸入下列指令

$ git clone [email protected]:ctchen1/test-project.git

clone 後面就是剛剛複製下來的位址。下了這個指令它就會把 test-project 抓下來放在 test-project 這個目錄裡面了。

新增檔案到 Repository

在 git 裡頭, 每一次的變更我們會稱作為 commit。你可以想像它是一個批次 - 這個批次包含一個或數個檔案的變動。舉例來說, 你有可能修正某一個 bug, 而修正的當中會有好幾個不同的檔案的變更, 那我們會將這一整個變更稱作為 commit。當然, 也有可能你只是新增一個檔案, 而這個 commit 就只有包含這一個檔案。

到底多少的變動要 commit 一次進去, 大家都有很多的討論, 這不會是這邊要講的內容, 但他確實是一個被探討的議題。關於這個議題, 可以參考:

我們現在先來建立一個新的檔案叫做 README.md, 內容如下

# README
我的第一個檔案

編輯好之後, 我們要用 git add [file] 的指令將這個檔案加到這一次的 commit 裡頭

$ git add README.md

接著, 我們可以用 git status 來看目前的狀態

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   README.md

你可以看到它寫說準備要被 commit 的變更有「新檔案: README.md」。

我們這一次變更就只要這一個, 因此我們再用 git commit 這個指令來把確認我們這一個 commit

$ git commit -m 'First commit. Add README.md'

上面指令的 -m ... 代表的是這一次變更的註解。註解其實很重要, 它有助於在事後翻閱變更紀錄時, 了解我們這一次做了什麼事情。想要瞭解更多關於如何寫好 commit message, 可以參考

最後, 我們要將我們現在的狀態推上 GitLab, 我們會用到 git push 這個指令

$ git push origin master

其中 origin 代表 repository 的來源, 也就是 GitLab, 而 master 則是預設的分支 (branch)。所以這個指令就是把 code 推到 origin (GitLab) 的 master 分支。

當你這個步驟做完的時候, 你就會發現 GitLab 上面這個專案的首頁有所改變, 你所打的 README.md 的內容會依照 Markdown 的格式顯示在專案的首頁下方。

README

你也可以按「Repository」的欄位, 或「Files」去看這個 repository 底下有哪些檔案

Files

.gitignore

在 git 裡頭, 我們可以編輯 .gitginore 這個檔案來告訴 git 哪些檔案應該被 git 忽略掉。忽略的原因不外乎我們不希望某些類別的檔案進到 git 裡面。

怎麼樣的檔案我們不希望進到 git 呢? 譬如說編譯好的執行檔、物件檔, 或是第三方套件, 或是編輯器用的暫存檔。簡單來說, 如果原始碼最後可以編譯出執行檔, 那我們就只留原始碼, 當要使用這個專案的開發人員把程式碼拉下來後, 再自己編譯即可。而第三方套件的部分, 如 node.js 的慣例是會有 node_modules 目錄會直接存放這個專案需要的第三方套件, 而通常可以直接透過 package.json 這個檔案來安裝所有第三方套件, 那麼我們就是留 package.json 進 git, 而不留 node_modules

因為不同程式語言、框架, 你的 .gitignore 可能會有所不同, 以 Python 的專案為例, .gitignore 可能內容如下

*.pyc
*.swp

其中 .pyc 是被編譯過的 bytecode, 而 .swp 則是 vim 的暫存檔。

Node.js 的 .gitignore 可能就會長得像這樣

*.swp
node_modules

也有一些很酷的服務可以自動產生相對應的 .gitignore, 譬如 gitignore.io。或者是你可以自己搜尋 gitignore 以及你所使用的語言、框架。

當我們編輯好 .gitignore 之後, 他也是可以被進到 git 裡面的。如果你現在只是練習, 那麼你可以新增一個 .gitignore 的檔案, 內容如下

*.swp

接著, 我們可以再簡易的複習上面的流程

$ git add .gitignore
$ git commit -m 'Add *.swp to .gitignore'
$ git push origin master

.gitignore 加入這次的 commit 之後, 就 commit, 然後把它推到遠端去。

變更檔案

如果現在我們更改了 README.md, 將內容變成

# Test-Project
這是一個測試專案, 好棒棒!

更改後, 我們下的指令一樣是 git add, 將這個檔案加到這次的 commit 裡面

$ git add README.md

最後一樣, 將它 commit 之後推回去

$ git commit -m 'Change content of README.md'
$ git push origin master

目前看起來好像就是 git add, git commit 然後 git push。當然, 你可以 git add 好幾個檔案, 也就是這個 commit 會包含多個檔案變更, 然後才 commit。然後你也可以好幾個 commit 之後, 才 push 回去。不過當然, 儘早 push 回 GitLab, 因為難保有什麼萬一, 例如你的硬碟壞掉, 誤刪檔案, 或是有人在此時也進 code 到時候會產生衝突 (conflict)。

刪除檔案

如果你有一個檔案要從 git 裡面刪掉, 則你需要用 git rm 這個指令。例如, 我們想要把 README.md 刪掉, 則需要打下列指令

$ git rm README.md

後續動作則跟上面一樣, 將刪除的這個動作進到這次的變更, 然後 push 回去

$ git commit -m 'Delete README.md'
$ git push origin master

更新

當然既然你會做變更, 然後推回去, 那麼同樣的事情也有可能會有別人做。因此每次我們開始要更改程式碼之前, 最好先將目前的 repository 從 GitLab 拉下來。而這個動作很簡單, 就是透過 git pull 這個指令

$ git pull origin master

是否跟推回去的指令很類似呢? :D

已經有程式碼了, 但 git 是新開的

如果你已經有一個專案, 它是已經有程式碼在裡面了, 但是卻沒有使用 git, 流程上會是如何呢? 首先, 最前面也是一樣, 先開一個 GitLab 的專案。

接著, 去到你本地端專案的資料夾, 假設是 ~/test-project, 執行 git init

$ cd ~/test-project
$ git init

然後將這個資料夾跟我們 GitLab 上的專案做連結

$ git remote add origin [email protected]:ctchen1/test-project.git

其中 origin 後面的連結就是我們剛剛新開專案 GitLab 上面的連結。

接下來我們就準備把所有的檔案加進去, 但是在這之前, 我們最好先設定好 .gitignore, 所以等等那些我們不想進去的資料夾與檔案不會進去。

等到設定好之後, 將所有的檔案加入, 並且 commit

$ git add .

. 的意思是當下的目錄, 也就是把目前這個目錄底下的所有東西都加進這一次的 commit。最後, 再把它推回去

$ git push origin master

基本工作流程

這邊提一個最基本的工作流程

  1. git pull origin master
  2. 編輯檔案
  3. git add xxxgit rm xxx
  4. git commit -m 'xxx'
  5. git push origin master

也就是每次改之前先拉, 然後進行修改、變更, 然後 commit 之後推回去。

results matching ""

    No results matching ""