Yet another introduction to Git - from the bottom up

23,570 views
23,433 views

Published on

Published in: Technology, Business
6 Comments
62 Likes
Statistics
Notes
  • 這場真的很精彩!而且最後還有個亮點是 Linus 關於資料結構那段!
    真的是從 git 的設計一窺大師風範!感謝講師的引導!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 噢,試出來了,非常感謝!我發現我剛剛檢查 commit 內容時複製錯 sha1 了,所以看錯 commit, 以為 --date 同時會指定兩者的時間
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 你是用 --date 參數?? 那只會指定 author 時間喔,committer 時間還是會變。看文件似乎只能用環境變數指定: export GIT_COMMITTER_DATE=1375716607; git commit --amend --date 1375716607 這樣重複 commit 就會產生一樣的 SHA1 了
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 我觀察的結果其實是一致的,我也試著在 commit 時直接指定時間,看起來還是一致。或許是有什麼步驟做錯了吧,如果真的改變的只有時間
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • committer 的時間會變,所以 SHA1 會變。用 git cat-file -p 觀察就知道了。
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
23,570
On SlideShare
0
From Embeds
0
Number of Embeds
18,089
Actions
Shares
0
Downloads
333
Comments
6
Likes
62
Embeds 0
No embeds

No notes for slide

Yet another introduction to Git - from the bottom up

  1. 1. Yet another introduction to from the bottom up http://ihower.tw 2013/8/3@COSCUP
  2. 2. 我是誰 • 張⽂文鈿 a.k.a. ihower • http://ihower.tw • CTO, Faria Systems • http://faria.co • Organizer of RubyConf Taiwan • http://rubyconf.tw • Git user since 2008
  3. 3. 如何不⽤用 git add 和 git commit 指令進⾏行 commit 動作? ⼩小測驗
  4. 4. 如何不⽤用 git add 和 git commit 指令進⾏行 commit 動作? ⼩小測驗 (⽤用GUI操作不算,謝謝!)
  5. 5. 我的版本控制之路 • 2002 ⺫⽬目錄管理法 (定時 copy 備份⼀一次) • 2005 SubVersion • 2007 SVK • 2008 Git (像 SVN ⼀一樣只會 push/pull) • 2009 Git (開始習慣 feature branches) • 2011 Git (開始習慣使⽤用 rebase)
  6. 6. Agenda • 為什麼需要「版本控制系統」? • Git 是如何做「版本控制系統」的? • 結論
  7. 7. 1. 為什麼需要 版本控制系統
  8. 8. Version Control System 軟體開發的基本⼯工具 • 版本控制系統不祇可以幫助妳追蹤修訂 ⼿手上的⼯工作進度,讓妳在千鈞⼀一髮之際 還能拾回過往⾟辛苦的結晶,甚⾄至能夠讓 妳跟其他⼈人協同⼯工作、合作無間。 http://jedi.org/blog/archives/004784.html • 那些台灣軟體產業所缺少的 – 版本控制 系統 http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-vcs/
  9. 9. 2. Git 是如何做 版本控制系統的?
  10. 10. ⽤用 Graph 概念理解
  11. 11. 檔案A⺫⽬目錄 檔案B working area
  12. 12. 檔案內容A 檔案內容B git add . (將⺫⽬目錄節點和檔案內容節點關聯起來) ⺫⽬目錄
  13. 13. 檔案內容A V1 檔案內容B V1 git commit (產⽣生commit節點,指向⺫⽬目錄節點) ⺫⽬目 錄 V1 Commit V1
  14. 14. 檔案內容B V1 git commit (cont.) (產⽣生commitV2節點,指向parent commit節點) ⺫⽬目 錄 V1 Commit V1 檔案內容A V2 ⺫⽬目 錄 V2 Commit V2 檔案內容A V1 檔案內容B不變
  15. 15. Git is objects database Blob object Blob object Tree object Commit object
  16. 16. 儲存內容(demo) • echo hello > hello.txt • git add . • tree .git • 存在 .git/objects/ce/ 013625030ba8dba906f756967f9e9ca394464a • 這是 hello 內容的 SHA1 • printf "blob 6000hellon" | shasum • echo "hello" | git hash-object --stdin • git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
  17. 17. blob object 的實際檔案名稱 .git/objects/ce/013625030ba8dba906f756967f9e9ca394464a hello blob ce0136
  18. 18. Blob object • Git 是 Content-addressable filesystem • Blob 沒有 metadata,沒有檔名資訊 • Blob object 的儲存檔名,是根據內容產⽣生的 SHA1 • 內容⼀一樣的檔案,根據 SHA1 演算法只會存 成同⼀一份檔案,不會浪費空間
  19. 19. 儲存⺫⽬目錄(demo) • git write-tree (根據 staging area 產⽣生 Tree object) • git cat-file -p aaa96ced2d9a1c8e72c56b253a0e2fe78393feb7
  20. 20. Tree object 的實際檔案名稱 .git/objects/aa/a96ced2d9a1c8e72c56b253a0e2fe78393feb7 100644 blob ce0136 hello.txt Tree hello blob ce0136aaa96c
  21. 21. 儲存⺫⽬目錄 (cont.) • 再新增⼀一個檔案和⼦子⺫⽬目錄 • touch hola.txt & mkdir coscup & touch coscup/bonjour.txt • git add . • git write-tree • git cat-file -p 117a5b49c6de3adc2a1834dc5907189bf84f3d7a • git cat-file -p 122f77b55b5753c456b22d96a0b63103ced46334
  22. 22. 040000 tree 122f77 coscup 100644 blob ce0136 hello.txt 100644 blob e69de2 hola.txt Tree hello blob ce0136 117a5 blob e69de2 100644 blob e69de2 bonjour.txt Tree 122f77
  23. 23. 040000 tree 122f77 coscup 100644 blob ce0136 hello.txt 100644 blob e69de2 hola.txt Tree hello blob ce0136 117a5 blob e69de2 100644 blob e69de2 bonjour.txt Tree 122f77
  24. 24. Tree object • Git ⽤用 Tree object 把 Blob object 組織起來,包 括檔案命名和⺫⽬目錄結構 • Blob object 並沒有包含檔案名稱和⺫⽬目錄結構 • Tree object 裡⾯面還可以有 Tree object ⼦子⺫⽬目錄 • Tree object 的檔名,⼀一樣是根據內容產⽣生 SHA1
  25. 25. 遞交 Commit (demo) • git commit-tree 117a5b49c6de3adc2a1834dc5907189bf84f3d7a -m “First commit” • git cat-file -p 058d2d • cat .git/HEAD • git update-ref refs/heads/master 058d2d • git rev-parse HEAD
  26. 26. Commit object 指向 root tree SHA1 040000 tree 122f77 coscup 100644 blob ce0136 hello.txt 100644 blob e69de2 hola.txt Tree 117a5 tree 117a5b author ihower 1375381139 +0800 committer ihower1375381139 +0800 First commit 0e2757commit master HEAD
  27. 27. 再次遞交 Commit (demo) • 修改 hola.txt 檔案 • git commit -am “Second commit” • git cat-file -p 24eac58
  28. 28. Commit object 也指向 parent commit SHA1 040000 tree 122f77 coscup 100644 blob ce0136 hello.txt 100644 blob e69de2 hola.txt Tree 117a5 tree 117a5b author ihower 1375381139 +0800 committer ihower1375381139 +0800 First commit 058d2dcommit 040000 tree 122f77 coscup 100644 blob ce0136 hello.txt 100644 blob 38a5fc hola.txt Tree 5f398a tree 5f398a5 parent 058d2 author ihower 1375381779 +0800 committer ihower 1375381779 +0800 Second commit 24eac58commit
  29. 29. Commit object • 紀錄 root tree SHA1 • 紀錄 parent commit SHA1 • 紀錄作者、時間和 commit message 資訊 • Commit object 的檔名,⼀一樣是根據內容產⽣生 SHA1
  30. 30. Git commit 動作流程 • ⽤用內容產⽣生 blob object • 寫⼊入 file mode, blob SHA1, file name 到 staging area • 根據 staging area 產⽣生 Tree object • ⽤用 root tree SHA1 和 parent commit SHA1 產⽣生 commit object • ⽤用 commit SHA1 更新 master 參考
  31. 31. 如何不⽤用 git add 和 git commit 指令進⾏行 commit 動作? echo "hola" | git hash-object -w --stdin git update-index --add --cacheinfo 100644 5c1b14949828006ed75a3e8858957f86a2f7e2eb hola.txt git write-tree git commit-tree 27b9d5 -m "Second commit" -p 30b060 git update-ref refs/heads/master 97b806c9e5561a08e0df1f1a60857baad3a1f02e git add git commit https://gist.github.com/ihower/6132576 測驗解答
  32. 32. Tag object (Tag 分兩種:annotated tag 才會產⽣生 object) • git tag -a release • git rev-parse release • git cat-file -p 2450f3
  33. 33. caa307commitobject 24eac5 type commit tag release tagger ihower 1375383070 +0800 Release! 2450f3tag
  34. 34. ⼩小結論: Git 有四種 Objects • Blob • Tree • Commit • Tag
  35. 35. References 參照 • 單純⼀一個檔案紀錄⼀一個 SHA1參照 • Tag reference • Branch reference • HEAD reference (指向⺫⽬目前所在的 branch)
  36. 36. Tag reference • git tag tmp • cat .git/refs/tags/tmp • 不像 object 資訊豐富,reference 內容只 有 Commit object SHA1 24eac5commit24eac5 refs/tags/tmp
  37. 37. Branch 和 HEAD reference • 每次 commit 就會變動 reference • HEAD 指向⺫⽬目前在哪⼀一個 branch • cat .git/HEAD • cat .git/refs/heads/master
  38. 38. 24eac5commit24eac5 refs/heads/master ref: refs/heads/ master HEAD
  39. 39. 如果在 Branch 上產⽣生新 Commit... 24eac5commit24eac5 refs/heads/master ref: refs/heads/ develop HEAD 55cbccommit
  40. 40. Branch reference 就會⾃自動 改指到新的 commit 24eac5commit 55cbcb refs/heads/master ref: refs/heads/ master HEAD 55cbcbcommit
  41. 41. 開新 Branch develop git branch develop 55cbcbcommit55cbcb refs/heads/master 55cbcb refs/heads/develop ref: refs/heads/ master HEAD
  42. 42. 切換 Branch:改HEAD git checkout develop 55cbcbcommit55cbcb refs/heads/master 55cbcb refs/heads/develop ref: refs/heads/ develop HEAD
  43. 43. commit caa307 refs/heads/master caa307 refs/heads/develop commit commit commit 40b603da103e 合併 Branch git merge develop
  44. 44. commit caa307 refs/heads/master caa307 refs/heads/develop commit commit commit tree 5f398a5 parent 40b603 parent da103e author ihower 1375381779 +0800 committer ihower 1375381779 +0800 Merge branch ‘develop’ into master commit 40b603da103e 產⽣生的 merge commit 節點 有兩個 parents
  45. 45. commitcaa307 refs/heads/master caa307 refs/heads/develop commit commit 另⼀一種合併情況 fast-forward 將 develop 合併進 master
  46. 46. commit caa307 refs/heads/master caa307 refs/heads/develop commit commit 另⼀一種合併情況 fast-forward 沒有產⽣生 merge 節點,只是移動參考
  47. 47. Git 如何 Merge commits? • Git 進⾏行了⼀一個 Three-way merge 的動作 • three-way merge 除了要合併的兩個檔 案,還加上兩個檔案的共同祖先。如此 可以⼤大⼤大減少⼈人為處理 conflict 的情況。 • two-way merge 則只⽤用兩個檔案進⾏行合併 (svn預設即 two-way merge)
  48. 48. 1 2 1 2 3 4 A B Two-way merge
  49. 49. 1 2 1 2 3 4 A B Two-way merge
  50. 50. 1 2 1 2 3 4 A B Two-way merge
  51. 51. 1 2 1 2 3 4 A B 1 2 ? Two-way merge
  52. 52. 1 2 1 2 3 4 A B 1 2 ? Conflict! 需要⼈人⼯工判斷 Two-way merge
  53. 53. 1 2 1 2 3 4 A B
  54. 54. 1 2 1 2 3 4 A B Three-way merge: 先找出 AB 共同的祖先
  55. 55. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先
  56. 56. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先
  57. 57. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先
  58. 58. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3
  59. 59. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  60. 60. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  61. 61. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  62. 62. 1 2 1 2 3 4 A B 1 2 4 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  63. 63. 1 2 1 2 3 4 A B 1 2 4 ⾃自動合併出 正確結果 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  64. 64. Conclusion
  65. 65. additive • 跟 Unix filesystem 有類似的結構,除了 • Git filesystem 的設計是⼀一直累加的,不會 有東⻄西被刪除 • Blob object 沒有 metadata
  66. 66. Reference is cheap • 開新 branch 只是 refs ⽽而已,直到 commit 前都沒有負擔。 • 不像有些VCS 開分⽀支會複製⼀一份原始 碼,⾮非常耗費資源。
  67. 67. Integrity • SHA1 是內容的 checksum • 如果檔案內容有損毀,就會發現跟SHA1不 同。如果 tree 被偷改檔名,也會被發現。 • HEAD 指向的 SHA1,就是整個 repository 的 checksum • 這在分散式系統⾮非常重要:資料從⼀一個開 發者傳到另⼀一個開發者時,確保資料沒有 被修改。
  68. 68. Distributed • Local development • 集中式的VCS 系統,沒網路就不能開發,無法 commit,無法看 history log。 • 分散式 CSV 系統即使沒網路,照常可以 commit 和看 history log。 • 不⽤用擔⼼心備份,每個⼈人都有⼀一份完整的 • 開源專案:誰有權限 commit? 沒關係,你可以 fork • ⽀支援多種⼯工作流程 Workflow
  69. 69. "I will, in fact, claim that the difference between a bad programmer and a good one is whether he considers his code or his data structures more important. Bad programmers worry about the code. Good programmers worry about data structures and their relationships." - Linus Torvalds
  70. 70. 參考資料 • http://ihower.tw/blog/category/git • http://pragprog.com/screencasts/v-jwsceasy/source-control-made-easy • http://www.youtube.com/watch?v=4XpnKHJAok8 Linux 的演講 • http://www.softdevtube.com/2013/02/05/advanced-git/ • http://git-scm.com/book • Git from the bottom up http://ftp.newartisans.com/pub/git.from.bottom.up.pdf • Version Control with Git, O'Reilly • http://nfarina.com/post/9868516270/git-is-simpler • http://think-like-a-git.net/sections/graph-theory.html
  71. 71. 謝謝,請多指教 http://ihower.tw

×