3 1 Git - ianchen0119/AwesomeCS GitHub Wiki

最初,Linux Kernel 的社群採用壓縮檔或是補丁的方式進行維護工作。一直到 2002 年,開發 BitKeeper 的商業公司與社群合作,讓 Linux Kernel 社群改用 BitKeeper 這套分散式的版本控制系統進行維護工作。

這份合作關係一直持續到西元 2005 年,因為一起與逆向工程有關的爭議結束。這也迫使了社群以及 Linus Torvalds 需要一套可靠的解決方案。因此,Linux kernel 的主要貢獻者 - Linus Torvalds 吸收了使用 BitKeeper 時得到的經驗,打造了一套能使用於社群的版本控制系統,也就是當今廣為人知的 Git。

The name "git" was given by Linus Torvalds when he wrote the very first version. He described the tool as "the stupid content tracker" and the name as (depending on your way):

  • random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant.
  • "global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room.
  • stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang.

關於 Linus 的故事,可以參考他在 Ted 中的演講: Linus Torvalds: The mind behind Linux | TED Talk

Git 的資料流與儲存層

圖片取自維基百科。

  • 本地倉儲

    • 工作目錄 一般來說,工作目錄就是指你的專案資料夾,假設專案尚未使用 Git 進行版本控制,我們可以在安裝 Git 以後使用以下命令進行初始化:
      git init
      
    • 索引 在專案資料夾中進行初始化後,Git 會在工作目錄中擔任觀察者的角色 (觀察每個檔案的整體性是否有改變),不過,在預設情況下,Git 是不會留意這些檔案的。 因此,若要針對部分檔案進行版本控制,我們需要將目標檔案做索引,索引檔案的命令如下:
      git add index.py
      
      當然,我們也可以一次索引多個檔案:
      git add .
      
      索引後,我們可以利用 git status 查看專案的當前狀態,Git 便會告訴我們檔案已經從 Untracked files 變成 Changes to be committed (可以提交至倉儲的狀態了)。
    • 倉儲 將檔案進行索引後,如果我們覺得目前專案已經到達了某個段落,我們可以使用 git commit 將專案提交至倉儲,成為專案的第一個版本。 不只如此,好的工程師會留下一些資訊供其他開發者參考,我們可以在提交時使用 -m 參數補充提交訊息:
      git commit -m "我完成了 index.py 啦 QWQ"
      
  • 遠端倉儲 既然專案開發都會是多人協作的,我們就會需要有一個地方能夠存放整個專案的倉儲,現今較為熱門的遠端倉儲服務有兩個選項:

    • GitHub
    • GitLab

    如果要將本地倉儲推至遠端倉儲,需要使用 git push 命令,在 push 之前,還需要先讓 Git 知道這些資料要推到哪個遠端節點上:

    git remote add origin xxx.xxx.git
    

    新增遠端節點 origin 以後,我們就可以將本地資料推至遠端倉儲啦~

    git push origin master
    

    上面的命令代表: 將 master 分支送至遠端倉儲 origin 節點的 master 分支,如果遠端不存在 origin 分支,你就自動幫我建立一個吧!

    • master 是 Git 本地倉儲預設的分支名稱,至於分支是什麼,可以在本文的後半部看到。
    • 顧及族群和身份認同的平權,GitHub 已經將預設的分支名稱改為 main

多人協作的世界

分支的概念

在文章的上半部有提到,master 是 Git 的預設分支名稱,那為什麼 Git 會需要分支呢? 試想,我們開發了一個部落格系統,但我們希望為他增加文章分類功能,在我們完成新功能並通過測試之前,勢必會提交多個 Commit。 在這個情況中,如果我們都只在 master 分支做開發,就會沒辦法區隔目前穩定工作的版本是那一個 commit,一般來說,我們會針對新功能的開發設立一個新的分支。

根據上圖,我們可以知道目前 head 與 master 都指向 e137e9b 這一個 commit。 接著,筆者在 master 分支提交了一個新的 commit (7036d33):

為了增加部落格的分類功能,需要建立一個 feat/sort 分支:

git branch feat/sort

這樣一來,就成功建立新分支啦!

建立新分支以後,我們要把 head 指向 feat/sort,這樣子之後提交的程式碼才會送至 feat/sort 分支:

git checkout feat/sort

Git 練習場的功能好像不夠完整,當我把分支命名為 feat/sort 時會 head 會無法順利切換,所以我在這邊以 feat-sort 代替 feat/sort。

切換到 feat/sort 分支後,開發團隊用了 2 次 commit 將新功能完成了,這時,我們需要將 head 切換回 master 分支並將 feat/sort 分支合併:

git checkout master
git merge feat/sort

PR 是什麼?能吃嗎?

Pull request (PR) 是在軟體開發上常見的協作方式,當你在 GitHub 上看到有趣的專案並想為它增加新功能時,可以使用網站上的 fork 按鈕複製一份專案到自己的帳號底下。 開發完成後,我們可以在自己的 GitHub 的複製專案中看到 Create a pull request,提交拉取請求後,如果原作者喜歡你新增的功能他就會將你的分支合併回他的專案中。

更多資訊可以參考 與其它開發者的互動 - 使用 Pull Request

常見的開發流程

  • Git flow
  • GitHub flow

Reference