Git 小檔案

Git 是一個罵人的字, 意思大概是蠢蛋, 由 Linux 的作者 Linus Torvalds 所命名. 說到 Git,  總有些人不熟悉, 但是講到它的競爭對手 CVS, Subversion 大家應該就有點感覺了吧!

Git 算是個分散式的版本管理系統, 和笨重的 SVN 相比, 它只記錄 content 的變化, 而不以檔案為管理的對象. 基本上 Git 由 blob object (file's content)、tree object (directory)、commit object (tree's history)、和 tag object (metadata 的 container) 所構成.

因為 Git commit 的動作可以在 local repository 就完成, 所以可以同時 maintain 一個量產的版本, 一個或多個的 branch 開發新 feature, 卻不用為每一個 branch check out 到一個 local 的目錄. 等到連上了網路之後, 做一個 push 的動作, 才把 local 的東西 commit 到 server.

Git 可以對所有的 object 做 SHA-1 的 hash, 把 hash value 當作 object 的名稱. 因此一段 code 從 A.h 搬到 B.h, 就等效於一個 object 搬家, 加上對應的 object 跟著改變 (object 支援 zip 的壓縮). 反觀 SVN 中, 這意味著 A.h 和 B.h 獨立地改變了. 若下次只 check out A.h, compiler 就會報錯.

只靠這樣粗淺的了解, 我覺得 git 至少比 SVN 節能減碳,少用很多硬碟空間 – 不必為每顆 IC 建一棵樹. 但不知道全靠 metadata 來維繫的 "假的 branch" 是不是比較容易毀損呢? 目前看到 Git 不如 SVN 的地方就是它沒有 Windows 的版本. 如果這個東西做出來, SVN 咳咳, 可就要 bye bye 了. 請看迴響 1, Git 也有 Windows 版囉!

[ref]

1. http://en.wikipedia.org/wiki/Git_(software)

2. http://ihower.tw/blog/archives/2591

3. http://ihower.tw/blog/archives/2620

4. https://peepcode.com/products/git-internals-pdf (賣 9 USD)

SVN 小筆記

SVN (Subversion) 是一個免費的版本管理系統, 雖然很浪費空間, 但是功能強大. 它的基本功能 check out、update、commit 大家應該都會吧! 我來講一下比較會讓人暈頭的 merge 和 switch.

Switch 相對簡單, 只要下 switch, PC 硬碟上的目錄就可以從 server 的 A 目錄改成對應 B 目錄. 這有甚麼用呢? 當我們改 code 改了半天,  可能既要 commit A 目錄, 又可以 commit 到 B 目錄. 如果一開始的 code 是從 server 的 A 目錄 check out 出來的, 那麼 commit 回 A 目錄當然不成問題. 可以要 commit B 目錄的話, 就沒那麼直覺了.

因為這個 PC 上的 A 目錄與子目錄裡面有很多 .svn 的隱藏檔 (每個目錄一個), 所以它硬是要效忠於 server 上的 A 目錄 (儘管名稱可以不同). 若是把 .svn 都砍掉, 倒是可以把它 copy 起來, 再蓋到 PC 上的目錄 B, 接著再 commit. 不過這樣做就太痤了. Switch 可以直接讓 .svn 的效忠對象改變, 這樣就省了很多了麻煩.

再說到 merge. 一般手工 merge code 當然是看看有甚麼 diff (difference). 但是 SVN 有現成的 merge 指令讓我們 merge A version 到 B version. 在此處有幾個東西要注意: (1) Merge from older version to newer version. 如果把順序弄反的話, 就會變得亂七八糟. (2) 可以在 PC 上的 A 目錄 merge 或是 B 目錄 merge. 選擇 PC 上的目錄決定了merge 的結果對應到 server 上的哪一個目錄, 它與 start URL 與 end URL 為何沒有關係.

此處的 merge 結果可能還需要手工修正, 但假如目錄 B 是從 frozen 的目錄 A branch 出來的, 那麼 A-B merge 的結果就等於目錄 B 蓋掉目錄 A. 此時拿 merge 的結果再 commit 成新版就好了, 也是相當方便!