2012年8月11日 星期六

git 之簡單介紹 part 2


這個章節中,我會設法介紹這些指令最基本的用法:
git init
git add
git commit
git checkout
git branch
並介紹 git 的快取 (cache)

git init:
透過這個指令,能把當前工作資料夾變成(形成)一個 git 的專案
是個大概不會用到太多次的指令 XD

git add:
透過 git add <檔案> 能將
  1. 已加入 git 專案的檔案加入快取,並紀錄其更動
  2. 未加入 git 專案的檔案加入快取,並紀錄為新檔案
  3. 已加入 git 專案的檔案刪除,並紀錄為刪除(用 git rm <檔案> 也可)
什麼是快取,以及加入快取的理由,在稍候會解釋,一個快取可以紀錄多個更動。
其實 git 不只提供了以「一個檔案」為單位的 git add,他提供了只把檔案的部份更動加入快取的功能,最小可以以「一行」為單位。

git commit:
這個命令能將被快取的檔案變成一個 commit
也就是說要形成一個 commit,要有兩個步驟
git add <你想 commit 的檔案>  →  git commit
commit 時會叫出一個文字編輯器,其中第一行要打入這次 commit 的簡要訊息,最多 50 自,第二行必須留白,第三行之後,如果你覺得第一行的 50 字實在不足以表達這次 commit 中想表達的文字的話,可以在這打入額外補充訊息。打完之後存檔變即完成了 commit。


git commit 這個步驟會新增一個 commit,姑且稱 commit B。還記得在 part 1 中有提到 HEAD 這個特殊的 branch,一般來說 HEAD 都會跟著一個 branch,使用 git commit 命令時會把 commit B 的祖先指向現在的 HEAD,並把 HEAD 移動到新增的這個 commit B,像下圖。而 git commit 時同時也會推進 HEAD 所跟著的這個 branch。
git commit @ Condition 1
git commit @ Condition 2

說明一下,在上圖及之後的圖片中
  1. 如果只有一個 branch 指向和 HEAD 同一個 commit,則 HEAD 跟著該 branch。
  2. 如果有多個 branch 指向和 HEAD 同一個 commit,則 HEAD 跟著圖片中離 HEAD 最近 branch。

順帶一提,如果想提交所有的檔案的話,使用
git commit -a
等同於執行了 add 所有檔案 →  commit 的連續兩步驟


快取 (cache):
這邊我解釋為何要有快取的概念,例如在某次的更動中有人增加了兩行:
我,我......才一點也不高興呢
(說真的其實我很高興)
但是因為這人是傲嬌有種種的理由他並不想 commit 第二行
因為 part 1 提到了所有 commit 都可以被別人檢視
即使在後來的 commit 中又刪掉了第二行,還是能檢視到這個 commit
因此我們將第一行加入 cache,再 commit 這些被 cache 的東西。
這樣我們就能在「只有我可以看到的工作目錄」中保留第二行的修改
但是其他與你協力的人看不到這樣的修改
直到哪一天你想把這個修改公開時再 commit 即可

git checkout <branch name>
這個指令做的事其實很簡單,當你運行 git checkout 時,git 會
  1. 把 HEAD 這個 branch 移動到 <branch name> 所參照之 commit,並把 HEAD 改跟為這個 branch。
  2. 同時把所有檔案換這個 commit 的狀態。
對於 commit tree 的更動會像這樣:
CMD = git checkout master

不過 git 有時後會不給你 checkout,這發生在你在 commit 之後做了任何更動(不管你有沒有 cache 這些更動),解決的方法之後會說明。

git branch <branch name>
這個指令會在現在 HEAD 所指的地方,新增一個 <branch name> 的參照,像下圖。
CMD = git branch hiiragi

git branch
這個指令會顯示出現在所有的 branch

git branch -d <branch name>
這個指令刪除 <branch name> 這個 branch,這個動作很單純,就是把 <branch name> 這個參照拿掉,這並不會影響 commit 的內容。這可以類比為在 C/C++ 中把 pointer 刪掉,不會影響 pointer 指向的資料。
CMD = git branch -d bar
有些時候刪除 branch 會失敗,常見的例如:

  1. HEAD 跟著你想刪掉的 branch,因為你如果刪掉這個 branch,HEAD 就不知道要跟著哪個 branch 了,這時一個常見又簡單的方法是 git checkout 到別的 branch,把 HEAD 改跟到別的 branch 上面。
  2. 從這個 branch 往其祖先走,有「只有這個 branch 走得到」的路徑,因為你刪掉了這個 branch 之後,你就無法容易的檢視這些 commit 了,可以想像 C/C++ 中的 memory leak。解法有二:其一是使用 git merge(稍候講)把 commit 結合;其二,如果執意要刪除這些 commit 的話,使用 git branch -D <branch name>,可以將「只有這個 branch 走得到」的路徑上的 commit 全部刪除,這時 branch 的表現就比較像一個真正的 branch,而不是只是一個參照(見 part 1 的說明)。

CMD = git branch -D foo


git checkout -b <branch name>
這個指令等效於連續運行下面兩個命令,應該是為了方便而產生的
git branch <branch name>
git checkout <branch name>

知道這些東西後,大約掌握了一半左右的單機使用所需的功能

沒有留言:

張貼留言