Yet another introduction to Git - from the bottom up

  • 21,797 views
Uploaded on

 

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

Views

Total Views
21,797
On Slideshare
0
From Embeds
0
Number of Embeds
34

Actions

Shares
Downloads
287
Comments
6
Likes
59

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Yet another introduction to from the bottom up http://ihower.tw 2013/8/3@COSCUP
  • 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. 如何不⽤用 git add 和 git commit 指令進⾏行 commit 動作? ⼩小測驗
  • 4. 如何不⽤用 git add 和 git commit 指令進⾏行 commit 動作? ⼩小測驗 (⽤用GUI操作不算,謝謝!)
  • 5. 我的版本控制之路 • 2002 ⺫⽬目錄管理法 (定時 copy 備份⼀一次) • 2005 SubVersion • 2007 SVK • 2008 Git (像 SVN ⼀一樣只會 push/pull) • 2009 Git (開始習慣 feature branches) • 2011 Git (開始習慣使⽤用 rebase)
  • 6. Agenda • 為什麼需要「版本控制系統」? • Git 是如何做「版本控制系統」的? • 結論
  • 7. 1. 為什麼需要 版本控制系統
  • 8. Version Control System 軟體開發的基本⼯工具 • 版本控制系統不祇可以幫助妳追蹤修訂 ⼿手上的⼯工作進度,讓妳在千鈞⼀一髮之際 還能拾回過往⾟辛苦的結晶,甚⾄至能夠讓 妳跟其他⼈人協同⼯工作、合作無間。 http://jedi.org/blog/archives/004784.html • 那些台灣軟體產業所缺少的 – 版本控制 系統 http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-vcs/
  • 9. 2. Git 是如何做 版本控制系統的?
  • 10. ⽤用 Graph 概念理解
  • 11. 檔案A⺫⽬目錄 檔案B working area
  • 12. 檔案內容A 檔案內容B git add . (將⺫⽬目錄節點和檔案內容節點關聯起來) ⺫⽬目錄
  • 13. 檔案內容A V1 檔案內容B V1 git commit (產⽣生commit節點,指向⺫⽬目錄節點) ⺫⽬目 錄 V1 Commit V1
  • 14. 檔案內容B V1 git commit (cont.) (產⽣生commitV2節點,指向parent commit節點) ⺫⽬目 錄 V1 Commit V1 檔案內容A V2 ⺫⽬目 錄 V2 Commit V2 檔案內容A V1 檔案內容B不變
  • 15. Git is objects database Blob object Blob object Tree object Commit object
  • 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. blob object 的實際檔案名稱 .git/objects/ce/013625030ba8dba906f756967f9e9ca394464a hello blob ce0136
  • 18. Blob object • Git 是 Content-addressable filesystem • Blob 沒有 metadata,沒有檔名資訊 • Blob object 的儲存檔名,是根據內容產⽣生的 SHA1 • 內容⼀一樣的檔案,根據 SHA1 演算法只會存 成同⼀一份檔案,不會浪費空間
  • 19. 儲存⺫⽬目錄(demo) • git write-tree (根據 staging area 產⽣生 Tree object) • git cat-file -p aaa96ced2d9a1c8e72c56b253a0e2fe78393feb7
  • 20. Tree object 的實際檔案名稱 .git/objects/aa/a96ced2d9a1c8e72c56b253a0e2fe78393feb7 100644 blob ce0136 hello.txt Tree hello blob ce0136aaa96c
  • 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. 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. 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. Tree object • Git ⽤用 Tree object 把 Blob object 組織起來,包 括檔案命名和⺫⽬目錄結構 • Blob object 並沒有包含檔案名稱和⺫⽬目錄結構 • Tree object 裡⾯面還可以有 Tree object ⼦子⺫⽬目錄 • Tree object 的檔名,⼀一樣是根據內容產⽣生 SHA1
  • 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. 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. 再次遞交 Commit (demo) • 修改 hola.txt 檔案 • git commit -am “Second commit” • git cat-file -p 24eac58
  • 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. Commit object • 紀錄 root tree SHA1 • 紀錄 parent commit SHA1 • 紀錄作者、時間和 commit message 資訊 • Commit object 的檔名,⼀一樣是根據內容產⽣生 SHA1
  • 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. 如何不⽤用 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. Tag object (Tag 分兩種:annotated tag 才會產⽣生 object) • git tag -a release • git rev-parse release • git cat-file -p 2450f3
  • 33. caa307commitobject 24eac5 type commit tag release tagger ihower 1375383070 +0800 Release! 2450f3tag
  • 34. ⼩小結論: Git 有四種 Objects • Blob • Tree • Commit • Tag
  • 35. References 參照 • 單純⼀一個檔案紀錄⼀一個 SHA1參照 • Tag reference • Branch reference • HEAD reference (指向⺫⽬目前所在的 branch)
  • 36. Tag reference • git tag tmp • cat .git/refs/tags/tmp • 不像 object 資訊豐富,reference 內容只 有 Commit object SHA1 24eac5commit24eac5 refs/tags/tmp
  • 37. Branch 和 HEAD reference • 每次 commit 就會變動 reference • HEAD 指向⺫⽬目前在哪⼀一個 branch • cat .git/HEAD • cat .git/refs/heads/master
  • 38. 24eac5commit24eac5 refs/heads/master ref: refs/heads/ master HEAD
  • 39. 如果在 Branch 上產⽣生新 Commit... 24eac5commit24eac5 refs/heads/master ref: refs/heads/ develop HEAD 55cbccommit
  • 40. Branch reference 就會⾃自動 改指到新的 commit 24eac5commit 55cbcb refs/heads/master ref: refs/heads/ master HEAD 55cbcbcommit
  • 41. 開新 Branch develop git branch develop 55cbcbcommit55cbcb refs/heads/master 55cbcb refs/heads/develop ref: refs/heads/ master HEAD
  • 42. 切換 Branch:改HEAD git checkout develop 55cbcbcommit55cbcb refs/heads/master 55cbcb refs/heads/develop ref: refs/heads/ develop HEAD
  • 43. commit caa307 refs/heads/master caa307 refs/heads/develop commit commit commit 40b603da103e 合併 Branch git merge develop
  • 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. commitcaa307 refs/heads/master caa307 refs/heads/develop commit commit 另⼀一種合併情況 fast-forward 將 develop 合併進 master
  • 46. commit caa307 refs/heads/master caa307 refs/heads/develop commit commit 另⼀一種合併情況 fast-forward 沒有產⽣生 merge 節點,只是移動參考
  • 47. Git 如何 Merge commits? • Git 進⾏行了⼀一個 Three-way merge 的動作 • three-way merge 除了要合併的兩個檔 案,還加上兩個檔案的共同祖先。如此 可以⼤大⼤大減少⼈人為處理 conflict 的情況。 • two-way merge 則只⽤用兩個檔案進⾏行合併 (svn預設即 two-way merge)
  • 48. 1 2 1 2 3 4 A B Two-way merge
  • 49. 1 2 1 2 3 4 A B Two-way merge
  • 50. 1 2 1 2 3 4 A B Two-way merge
  • 51. 1 2 1 2 3 4 A B 1 2 ? Two-way merge
  • 52. 1 2 1 2 3 4 A B 1 2 ? Conflict! 需要⼈人⼯工判斷 Two-way merge
  • 53. 1 2 1 2 3 4 A B
  • 54. 1 2 1 2 3 4 A B Three-way merge: 先找出 AB 共同的祖先
  • 55. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先
  • 56. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先
  • 57. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先
  • 58. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3
  • 59. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  • 60. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  • 61. 1 2 1 2 3 4 A B 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  • 62. 1 2 1 2 3 4 A B 1 2 4 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  • 63. 1 2 1 2 3 4 A B 1 2 4 ⾃自動合併出 正確結果 1 2 3 Three-way merge: 先找出 AB 共同的祖先 -3 +4
  • 64. Conclusion
  • 65. additive • 跟 Unix filesystem 有類似的結構,除了 • Git filesystem 的設計是⼀一直累加的,不會 有東⻄西被刪除 • Blob object 沒有 metadata
  • 66. Reference is cheap • 開新 branch 只是 refs ⽽而已,直到 commit 前都沒有負擔。 • 不像有些VCS 開分⽀支會複製⼀一份原始 碼,⾮非常耗費資源。
  • 67. Integrity • SHA1 是內容的 checksum • 如果檔案內容有損毀,就會發現跟SHA1不 同。如果 tree 被偷改檔名,也會被發現。 • HEAD 指向的 SHA1,就是整個 repository 的 checksum • 這在分散式系統⾮非常重要:資料從⼀一個開 發者傳到另⼀一個開發者時,確保資料沒有 被修改。
  • 68. Distributed • Local development • 集中式的VCS 系統,沒網路就不能開發,無法 commit,無法看 history log。 • 分散式 CSV 系統即使沒網路,照常可以 commit 和看 history log。 • 不⽤用擔⼼心備份,每個⼈人都有⼀一份完整的 • 開源專案:誰有權限 commit? 沒關係,你可以 fork • ⽀支援多種⼯工作流程 Workflow
  • 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. 參考資料 • 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. 謝謝,請多指教 http://ihower.tw