理解 Git

主要內(nèi)容介紹

1.設(shè)計(jì)思想

2.數(shù)據(jù)流向

3.git flow

4.其他介紹

5.思考討論

6.參考資料

1.設(shè)計(jì)思想

1.快照記錄,每一次commit ,記錄工作目錄的完整快照。
2.不變模式婿失,任何改變都將生成一個(gè)新的對(duì)象(類(lèi)似java string 設(shè)計(jì))枕赵。
3.分布式 ,幾乎所有操作都在本地倉(cāng)庫(kù)完成(非常高效且無(wú)依賴(lài))箱玷,不同節(jié)點(diǎn)可以通過(guò)同步來(lái)更新內(nèi)容。
4.復(fù)用陌宿,使用對(duì)象池復(fù)用對(duì)象锡足,相同內(nèi)容的文件,在對(duì)象池中只會(huì)存儲(chǔ)一份壳坪。

2.數(shù)據(jù)流向

git數(shù)據(jù)交互.png

2.1術(shù)語(yǔ)

  • work-dir :
    表示工作目錄舶得,與.git 綁定的目錄,其他名稱(chēng)(working-tree爽蝴,工作空間)
    不一定與.git 目錄在相同的位置(默認(rèn)是相同的)

  • repo:
    表示.git 目錄里面的內(nèi)容

  • commit-tree:
    每一次提交對(duì)應(yīng)的tree,其他名稱(chēng)(tree沐批,tree-ish纫骑,commit),commit 結(jié)構(gòu)見(jiàn) 4其他介紹

  • index/cache:
    對(duì)應(yīng).git/index 文件珠插,其他名稱(chēng)(cache惧磺,index,stage(區(qū)別于 stash))

  • object-pool:
    對(duì)應(yīng).git/objects/ 目錄下面的內(nèi)容捻撑,里面存有的對(duì)象有 blob(文件)磨隘,tree(dir and subdir) ,commit 顾患,tag

2.2數(shù)據(jù)流向

1.repo(object-pool) —> work-dir
2.work-dir —>repo(object-pool)
3.git-inter(object-pool) —>merge object (object-pool)-->new object(object-pool)

2.3 主要操作:

  1. 無(wú)work-dir番捂, 向repo 寫(xiě)入內(nèi)容,
  2. 使用work-dir 向repo 寫(xiě)入內(nèi)容
  3. repo內(nèi)容檢出到work-dir
  4. work-dir江解,index(cache)设预,repo(commit-tree),比較
  5. commit-tree 構(gòu)建,新增犁河,合并鳖枕,重建,撤銷(xiāo)
  6. commit-log 查看

2.4 測(cè)試結(jié)果查看關(guān)鍵命令

查看work-dir 查看repo 內(nèi)容
ls git ls-files :查看index 文件內(nèi)容桨螺。git ls-files -s:查看index 文件內(nèi)容宾符,并且顯示blob id
tree git ls-tree [commit-id] :查看commit 對(duì)應(yīng)的tree 結(jié)構(gòu),以及在tree 上面所有的文件
cat git cat-file -t <blob-id>:查看blob 文件類(lèi)型灭翔,blob-id 為對(duì)象池里面對(duì)應(yīng)對(duì)象的id
find find .git/objects -type f : 查找文件 find ./ -mmin -1 -type f :查找最近一分鐘修改的文件 git log:查看commit log魏烫, (其他命令git show ) git log --all --graph —oneline:查看所有提交日志 git log --graph --oneline :查看當(dāng)前分支提交日志
git diff: 比較[repo ,work-dir], [repo,repo],[repo,index],[index,worlk-dir] 其他比較命令:diff-tree/diff-files/diff-index
git status : work-dir ,index,tree 對(duì)比后的狀態(tài)查看
git for-each-ref :查看所有引用(指針)

2.5 測(cè)試以及命令解釋

2.5.1 無(wú)work-dir肝箱, 向repo 寫(xiě)入內(nèi)容

詳細(xì)描述: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
主要命令:

  • git hash-object : 向object-pool 寫(xiě)入文件對(duì)象
  • git update-index : 向 index 文件添加 blob 記錄(關(guān)聯(lián)到blob)
  • git ls-files -s : 查看index 文件內(nèi)容
  • git write-tree: 用index 文件內(nèi)容向 object-pool 寫(xiě)入tree 對(duì)象
  • git read-tree : 用commit-tree 生成內(nèi)容哄褒,寫(xiě)入index 文件
  • git ls-tree: 查看tree 內(nèi)容
  • git commit-tree : 寫(xiě)入commit 對(duì)象
  • git log : 查看commit 日志

2.5.2 使用work-dir 向repo 寫(xiě)入內(nèi)容

  • git stash : 暫時(shí)保存work-dir /index 內(nèi)容,產(chǎn)生一次特殊的commit(stash commit)


    stash-commit.png
  • git add : 工作空間內(nèi)容添加到object-pool,index (cache)文件記錄添加的文件以及blob-id

  • git commit:生成 commit 對(duì)象煌张,用index中的文件內(nèi)容構(gòu)建commit-tree(tree)

注:流程:工作空間—>緩存(index)—>存儲(chǔ)

2.5.3 repo內(nèi)容檢出到work-dir

  • git checkout :檢出repo 到work-dir呐赡,index,修改相關(guān)指針(HEAD ,分支)骏融,repo 對(duì)象(blob罚舱,tree)
  • git checkout-index: 用index 文件記錄的內(nèi)容,覆蓋work-dir绎谦,repo 對(duì)象 為 blob,tree
  • git reset:git add 的逆操作 粥脚,修改index窃肠,修改work-dir,修改指針(HEAD)刷允,repo 對(duì)象為 blob冤留,tree
  • git revert :git commit 的逆操作碧囊,repo 對(duì)象為 tree

注:
1.blob 可以用文件路徑引用,tree 用commit-id引用纤怒,tree 對(duì)象比較時(shí)糯而,如果是文件增加減少一般可以自動(dòng)完成操作,如果涉及同一個(gè)文件的多次修改泊窘,操作可能失敗熄驼,需要合并tree。
2.流程:工作空間<—緩存(index)<—存儲(chǔ)

2.5.4 比較working-tree ,index, tree

  • git diff : 默認(rèn) working-tree diff index ,—cached [commit-id] : index diff tree,
  • git diff [commit-id] :tree diff commit-id-tree
  • git diff-index :git diff-index [commit-id],當(dāng)前index 比較 commit-id-index
  • git diff-files :working-tree-file diff index-file
  • git diff-tree [commit-id]:比較tree烘豹,commit-id-tree diff commit-id-parent-tree


work-dir瓜贾,working-tree 表示相同含義
index ,cache携悯,cache-tree表示相同含義
commit-tree祭芦,tree,commit 表示相同含義

2.5.5 tree (commit / commit-tree) 構(gòu)建憔鬼,新增龟劲,合并,重建轴或,撤銷(xiāo)

  • git commit:生成 commit 對(duì)象昌跌,用index中的文件內(nèi)容構(gòu)建commit-tree(tree)
  • git merge : 當(dāng)前分支的HEAD(tree) 合并 其他分支的HEAD(tree),生成一個(gè)新的tree 侮叮,且當(dāng)前分支的指針移動(dòng)到新的tree
  • git rebase :以 onto 為新的基點(diǎn),重新構(gòu)建 [to'parent ,to] 這一范圍的tree
  • git cherry-pick:以cherry-pick 的commit 避矢,重新構(gòu)建當(dāng)前分支的tree
  • git revert:將 revert [commit] 的內(nèi)容,從當(dāng)前分支tree移除囊榜,并產(chǎn)生一次新的提交來(lái)構(gòu)建新的tree

2.5.6 commit-log 查看

  • git log 审胸,- - online :一行日志 ,- - graph 圖形展示,—pretty=raw 原始格式 - -all 所有分支,默認(rèn)為當(dāng)前分支
  • git show :見(jiàn) git help show
  • git whatchanged:見(jiàn)git help show

3. git flow

  • 指針介紹:指向某一個(gè)提交的commit (也就能找到對(duì)應(yīng)的tree)
  • 分支(如下圖)
    master :指向F ,通過(guò)尋找parent commit 就可以構(gòu)建一條完整的鏈路卸勺。
    experiment: 指向D砂沛,通過(guò)尋找parent commit 就可以構(gòu)建一條完整的鏈路


    branch.png
  • 當(dāng)前分支:當(dāng)前分支指針位置(最后一次commit-id),值保留在HEAD 里面
  • stash 指針:git stash 產(chǎn)生的提交曙求,最后的commit-id
    標(biāo)簽:也是指向一次commit-id 的位置碍庵,是不可變的(普通的分支還能進(jìn)行提交)
    注:分支存儲(chǔ)位置 .git/HEAD ,refs/*,里面都是保留最新的commit-id
  • 分支其他引用表示:
    commit-id :commit-id的前幾位可以定位,只要依據(jù)前幾位能夠定位到內(nèi)容
   $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
   $ git show 1c002dd4b536e7479f
   $ git show 1c002d

HEAD@{5}/stash@{1}:reflog 與stash 引用
HEAD^[number] :head 的父節(jié)點(diǎn)悟狱,可以引用多個(gè)父節(jié)點(diǎn)(一個(gè)節(jié)點(diǎn)可能有多個(gè)直接父節(jié)點(diǎn))
HEAD~[number] :head的父節(jié)點(diǎn)静浴,只能指明第一個(gè)父節(jié)點(diǎn)
詳見(jiàn): https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection

3.1 分支協(xié)作

  • 單遠(yuǎn)程倉(cāng)庫(kù):
    master:穩(wěn)定分支,默認(rèn)分支
    feature:功能分支挤渐,一般完成合并后苹享,刪除
    hotfix: 緊急bug 修復(fù)分支
    develop:開(kāi)發(fā)分支

  • 多遠(yuǎn)程倉(cāng)庫(kù):一個(gè)本地倉(cāng)庫(kù)可以對(duì)應(yīng)多個(gè)遠(yuǎn)程倉(cāng)庫(kù),可以同時(shí)在多個(gè)倉(cāng)庫(kù)協(xié)作開(kāi)發(fā)浴麻。比如github fork得问, pull request 等操作

    注:多倉(cāng)庫(kù)配置見(jiàn) git help config ,git help remote

4 其他介紹

  • .git目錄
    HEAD :保存當(dāng)前分支指針,指向refs
    index :緩存當(dāng)前work-tree 目錄結(jié)構(gòu)以及文件囤攀,以及文件狀態(tài)
    objects: git 的數(shù)據(jù)庫(kù),保存所有對(duì)象(tree宫纬,blob焚挠, tag ,commit) 漓骚。
    refs: 保存所有分支/tag(每個(gè)分支/tag記錄自己當(dāng)前指針位置)

  • 配置 見(jiàn) git help config

  • git數(shù)據(jù)結(jié)構(gòu)

    • blob對(duì)象:
      header={[blob-type][空格][content.length][\0]}
      body={[content]}
      sha1 = Digest::SHA1.hexdigest(header+body)
      store=Zlib::Deflate.deflate(header+body)

    • commit 對(duì)象:
      tree: 指向tree 對(duì)象的id
      parent:父commit (可能有多個(gè)parent蝌衔,比如合并)
      author: 作者
      committer:提交者
      msg/log: 備注信息,日記顯示內(nèi)容
      commit-結(jié)構(gòu)示例(如下圖):


      commit-結(jié)構(gòu)示例
    • tree 對(duì)象:
      記錄文件认境,目錄關(guān)系胚委,以及文件對(duì)應(yīng)的屬性(修改時(shí)間,創(chuàng)建時(shí)間叉信,文件類(lèi)型等)

    • index 文件:
      記錄working-tree 目錄下面所偶遇文件以及文件對(duì)應(yīng)的屬性(修改時(shí)間亩冬,創(chuàng)建時(shí)間,文件類(lèi)型等)
      文件不同區(qū)域?qū)?yīng)的id, tree-hash-id,cache-hash-id,wdir-hash-id,通過(guò)對(duì)比不同區(qū)別的id 值來(lái)判斷文件狀態(tài)

5 思考/討論

1硼身、怎么合并tree 硅急,以及找到tree 不同,git怎么決定沖突的佳遂?

1营袜、 commit1-tree1,commit2-tree2
2丑罪、如果commit1是commit2 的祖先荚板,直接使用commit2-tree2 (直接前驅(qū),使用最新版本吩屹,無(wú)沖突)
3跪另、commit1 與commit2 不是直接沒(méi)有直接的祖父關(guān)系,則比較 tree1 煤搜,tree2 ,
4免绿、tree1,tree2 上面含有相同的文件路徑擦盾,但是文件內(nèi)容不同嘲驾,則產(chǎn)生沖突。需要手動(dòng)處理迹卢。(無(wú)法判斷那一次的內(nèi)容是最新版本辽故,)
5、沖突處理方式腐碱, 使用 tree1(ours) ,使用tree2 (others),使用手動(dòng)處理的版本
6榕暇、tree1,tree2 合并后產(chǎn)生一個(gè)新的tree-new。

2、git status 顯示文件狀態(tài)依據(jù)彤枢?

依據(jù)working-tree ,index(cache),tree 里面的對(duì)應(yīng)的hash 值來(lái)判斷。

3筒饰、怎么顯示增量更新內(nèi)容缴啡?

比較兩次提交的tree。

4瓷们、 commit 操作具體是如何構(gòu)建tree 的业栅?

從當(dāng)前 index 文件 構(gòu)建tree

5、如何實(shí)現(xiàn) git 與遠(yuǎn)程分支數(shù)量對(duì)比谬晕,本地落后遠(yuǎn)程幾次提交碘裕,本地多于遠(yuǎn)程幾次提交?

1攒钳、找到遠(yuǎn)程head 與本地head 共同的祖先A
2帮孔、 [A,remote-head] commit 數(shù)量為本地落后遠(yuǎn)程分支數(shù)量
3、 [A,local-head] commit 數(shù)量為本地多于遠(yuǎn)程分支數(shù)量
4不撑、 git log 可以實(shí)現(xiàn)

6文兢、delta storage VS snapshot storage,snapshot 有何優(yōu)勢(shì) ?

1焕檬、snapshot 實(shí)現(xiàn)簡(jiǎn)單姆坚,高效(復(fù)用已有對(duì)象),保留了全部?jī)?nèi)容实愚〖婧牵可實(shí)現(xiàn)的功能更多
2、delta 模式腊敲,記錄復(fù)雜击喂,實(shí)現(xiàn)復(fù)雜。
3兔仰、delta storage VS snapshot storage:

delta vs snapshot.png

7茫负、javer 如何開(kāi)發(fā)git 適用工具 ?

dea4git 實(shí)現(xiàn):
ProcessBuilder pb = new ProcessBuilder(cmdLine)
執(zhí)行g(shù)it 命令
解析git 命令輸出結(jié)果

8、比較算法為何高效乎赴?

tree 比較算法介紹: http://thume.ca/2017/06/17/tree-diffing/
文件比較算法介紹: patience|minimal|histogram|myers https://blog.jcoglan.com/2017/09/19/the-patience-diff-algorithm/

9忍法、如何更改commit 日志信息?

git rebase -i (reword):edit the commits which are rebased
git commit --amend : 修改提交commit-msg
注 amend:修改,修正榕吼,git rebase 交互模式詳情:https://git-scm.com/docs/git-rebase

10饿序、如何讓work-tree clean ,不丟內(nèi)容羹蚣?

git stash原探,將work-dir 內(nèi)容commit 。并checkout HEAD 內(nèi)容到working-tree

11、如何debug git 咽弦?

1徒蟆、查看.git/logs/ 目錄下面日志 ,git 命令執(zhí)行日志型型,不是commit(git log 命令) 日志段审。
2、使用git core (Plumbing Commands)命令
3闹蒜、使用debug 選項(xiàng) git ls-files —debug

12寺枉、git gc 與jvm gc 有何異同 ?

jvm gc 基于內(nèi)存绷落,會(huì)涉及內(nèi)存碎片整理姥闪,有多種垃圾處理策略(標(biāo)記整理,標(biāo)記復(fù)制等)
git gc基于磁盤(pán)存儲(chǔ)砌烁,不用整理磁盤(pán)碎片
都是基于tree 來(lái)查找垃圾對(duì)象

6筐喳、參考資料

1、Pro Git :https://git-scm.com/book/en/v2
2往弓、 Manual Page https://git.github.io/htmldocs/
3疏唾、Pro Git 作者talk : https://www.youtube.com/watch?v=xbLVvrb2-fY
4、幫助 man git 函似、 git help [command]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末槐脏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子撇寞,更是在濱河造成了極大的恐慌顿天,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔑担,死亡現(xiàn)場(chǎng)離奇詭異牌废,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)啤握,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)鸟缕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人排抬,你說(shuō)我怎么就攤上這事懂从。” “怎么了蹲蒲?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵番甩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我届搁,道長(zhǎng)缘薛,這世上最難降的妖魔是什么窍育? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮宴胧,結(jié)果婚禮上漱抓,老公的妹妹穿的比我還像新娘。我一直安慰自己恕齐,他們只是感情好辽旋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著檐迟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪码耐。 梳的紋絲不亂的頭發(fā)上追迟,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音骚腥,去河邊找鬼敦间。 笑死,一個(gè)胖子當(dāng)著我的面吹牛束铭,可吹牛的內(nèi)容都是我干的廓块。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼契沫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼带猴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起懈万,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拴清,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后会通,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體口予,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年涕侈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沪停。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裳涛,死狀恐怖木张,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情调违,我是刑警寧澤窟哺,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站技肩,受9級(jí)特大地震影響且轨,放射性物質(zhì)發(fā)生泄漏浮声。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一旋奢、第九天 我趴在偏房一處隱蔽的房頂上張望泳挥。 院中可真熱鬧,春花似錦至朗、人聲如沸屉符。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)矗钟。三九已至,卻和暖如春嫌变,著一層夾襖步出監(jiān)牢的瞬間吨艇,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工腾啥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留东涡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓倘待,卻偏偏與公主長(zhǎng)得像疮跑,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凸舵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • git 使用筆記 git原理: 文件(blob)對(duì)象祖娘,樹(shù)(tree)對(duì)象,提交(commit)對(duì)象 tree對(duì)象 ...
    神刀閱讀 3,771評(píng)論 0 10
  • 因?yàn)樵奶L(zhǎng)超出字?jǐn)?shù)贞间,Lesson 3 就放在另一篇文章里 How to Use Git and GitHub 標(biāo)...
    赤樂(lè)君閱讀 5,216評(píng)論 1 5
  • 什么是Git 基于文件快照的分布式版本控制工具 Git基礎(chǔ)概念 三個(gè)重要的工作區(qū): 數(shù)據(jù)倉(cāng)庫(kù):保存了所有Git提交...
    無(wú)為無(wú)味無(wú)心閱讀 562評(píng)論 0 1
  • 1.Git簡(jiǎn)介 Git是一個(gè)開(kāi)源的分布式版本控制系統(tǒng)贿条,可以有效、高速的處理從很小到非常大的項(xiàng)目版本管理增热。Git 是...
    qfstudy閱讀 252評(píng)論 0 0
  • 看完了《擺渡人》這本書(shū)整以,內(nèi)心久久不能平靜。 如果人生是一條孤獨(dú)的長(zhǎng)河峻仇,誰(shuí)會(huì)是你靈魂的擺渡人公黑?我想在我們的一...
    MissS啦閱讀 217評(píng)論 0 0