日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

git查看分支记录_git原理

發布時間:2024/9/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 git查看分支记录_git原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

標準用法請參考git-scm。本文記錄筆者對git的一些理解,如有錯誤,歡迎指正。
引用內容已用markdown記號標出。版權所有,轉載請注明出處。
文章完成中

這是引用內容

First Edition:2021-01-27

文中的記號約定

<當前分支>:用尖括號包裹,需要被替換

軟件環境

筆者將介紹 命令行,TortiseGit,VS中git的使用

git學習指引

更適合把git當作某種數據結構來理解,從底層理解git

git中的一些概念

git分支并不是一個實體,而是一個指針,分支只存放了指向某個commit的指針,不保存其他信息。在master分支創建新提交后,分支指針指向為新的commit。

HEAD表示當前指向的位置,master/main一般用于主分支。不要混淆兩者概念

working-tree index lib
working-tree為工作目錄,即可以直接操作
index,也稱stage,git commit將當前index狀態保存,即git commit不處理工作目錄

git基本命令

  • add 添加文件到index
git add new.txt
  • commit 將當前index提交到Local Repository
git commit -m "<這里是commit的注釋>" git commit -m "<這里是commit的注釋>" --allow-empty //使用此命令學習git分支 git commit -m "<這里是commit的注釋>" --allow-empty-message -m "" //允許空注釋
  • checkout 修改HEAD指針 底層修改 ./git/HEAD
git checkout <指定位置> //修改HEAD 指針到<指定位置>
  • switch 修改HEAD指針,使其指向某個分支而不是某個結點
git switch <分支> //切換到某個分支 //switch與checkout的區別: //checkout功能更加底層,修改HEAD指針的內容,使其指向branch或者commit //switch只能指向分支
  • branch 創建分支
git branch new_branch //新建分支new_branch
  • reset 修改當前分支的指針 底層修改文件 ./git/refs/head/<分支名>
git reset ad13f1 //修改當前分支的指針 //git reset與checkout的區別 //git reset不修改HEAD指針,修改當前分支指向的commit //git checkout修改HEAD指針

git指令

git rebase
git revert
git reset
git checkout
git merge
git cherry-pick

git merge命令
當前工作再branch_master分支,此分支指向commitA,develop分支指向commitB,(AB字母僅供標識,沒有其他含義)。使用指令git merge develop,創建一個新的commitC,commitC以commitA和commitB為父結點。再次強調,git的分支是一個指針,存放在./git/refs文件夾下。分支所包含的結點是以類似鏈表的方式的進行查找的,并不是線性記錄在某個文件中。
git中刪除分支并不會直接刪除commit object,不過分支指針丟失了,難以進行查找,并且git有gc垃圾回收機制,會清理懸掛對象。(git誤操作后恢復數據原理,分支指針被清除,對象并未清除,而且在./git/logs文件夾內有日志。) git fsck 命令驗證數據庫中對象的連通性和有效性。
git revert命令
當前master分支有commitA commitB commitC
使用git revert commitA命令生成commitD,commitD的父節點為commitC,commitD的內容與A一致,但并不破壞歷史記錄.
注:git對象是以鏈表的形式組織。鏈表上的結點不能自由移動,但可以對讀取結點上的內容,創建新結點,這看起來像是回到了某次提交。
git reset命令
修改當前分支指向的結點(分支指針總是指向該分支的最后一個結點,或者說分支指針記錄了該分支最后一個結點,checkout命令是移動HEAD指針)
當前master分支有commitA commitB commitC
git reset commitA后,如果沒有分支線包含commitB,commitC,那么B、C不會顯示在git log中(因為git log是動態搜索),B、C可能會被清除。
注:git使用鏈接式的數據結構。
git cherry-pick命令

git區域

這幾個區域是使用概念上的區別。
git Working-Tree 即工作文件夾
git index index區內容,注意這里不是空的,使用git add 命令,將file1添加到object和index內。
git commit區域 git commit將index內容打包到tree obejct,建立commit object,修改當前分支的指針,在logs文件夾內寫入HEAD和當前分支的變更日志。
在git中,數據存放在以sha1為鍵名的數據庫中,以鏈表方式組織數據。這樣數據更加靈活。
git reflog是保存到本地的,不保存到遠程。git log是動態計算的

git對象 blob tree commit
git引用 分支引用 HEAD引用 標簽引用 遠程引用
git本地的遠程分支也僅保存指針,不保存數據。數據保存在object中。遠程分支標記了commit object。(由于sha1的特點,一般地,不同的文件不會具有相同的sha1)


Git分支與數據不直接關聯。
數據中文件內容和文件元信息不直接關聯。
commit不和文件直接關聯。
遠程分支建立在本地objects上,而不是簡單粗暴地下載遠程文件與本地文件比對。
git fetch操作是下載遠程分支所關聯地object(如果有某個結點有兩個父節點,那么這兩個方向的結點都會被下載),然后下載遠程分支指針。
git是以節點鏈表為核心,不是以孤立的分支為核心。
git保證了與分支所關聯的commit可以被安全保存。
patch分支修改了某項功能,隨后在master分支上merge patch分支,刪除patch分支。這三個節點都得到了保留。

附加:
TortiseGit


文件修改 文件增加 文件刪除 文件重命名

git演示1

  • 新建倉庫
    • 命令行中git init
    • TortiseGit ,右鍵菜單Create repo
    • vs中 (待補充)
  • 創建文件
    • 手動新建文件
    • 或者 echo “<字符>” >> new.txt
    • 或從 touch new.txt (windows下可能沒有此命令)
      打開文件,寫入new conent并保存
      注意:此時 ./.git/objects文件夾內并沒有生成對應的文件

  • 將文件添加到index git add new.txt
    注意./git/objects/文件夾內變化,增加了名為47的文件夾

  • 查看該文件夾的內容


    使用git底層命令查看該文件的內容git cat-file -p 47d2739ba2c34690248c8f91b84bb54e8936899a


    使用同樣的方法創建new.txt文件,并將其添加到index。在objects內生成了23/b6fc220420f74c5af7f34c106ef931a1fa15ea文件

    注:47d2739ba2c34690248c8f91b84bb54e8936899a為內容的sha1,實際上objects文件夾為數據庫,sha1與內容構成了鍵值對,按照<前2位sha1>/<后38位sha1>的方式存儲。

    注:將文件提交到index后,new.txt文件的內容已經被保存到了數據庫中。即git add的作用并不是僅對文件做標記,而是將其內容保存到數據庫中。可以將其分解為底層命令git hash-object,并未保存樹對象
    4.提交index到Local Repo

    git commit -m "First Commit"


    此時,查看objects文件夾的內容


    新增了5d/ d4/文件夾
    查看5d文件夾下新增文件的內容
    使用git cat-file -p <sha1>指令查看新增objects的內容
    使用git cat-file -t 指令查看新增objects的類型


    查看d4文件夾下新增文件的內容


    查看refs/heads文件夾


    查看master文件的內容


    發現其內容與新增的commit object的sha1一致。

    總結:使用git commit指令后 objects內新增兩個文件,分別為tree object,commit object。refs/heads文件夾內分支指針內容被改寫。

  • 查看當前HEAD指針的內容,HEAD指針指向了master分支
    注:HEAD 與heads不同

  • 6.繼續測試,使用git commit --allow-empty -m "empty commit"指令進行一次空提交
    注:使用windows下軟件everything 可以查看新增加的文件
    以下文件的修改時間與剛才的操作時間匹配


    分別為:

    • ./refs/heads/master
    • /logs/refs/heads/master
    • /logs/HEAD
    • 新增的object
    • COMMIT_EDITMSG (猜測,此文件可能供git comment --amend 選項使用)
      查看master文件內容,發現其指向了新的commit object
      logs文件夾內,有兩個文件發生了變化
      查看HEAD文件內容,記錄了HEAD指針的變化,新記錄增加到文件末尾。第一個sha1值表示父commit,第二個sha1表示當前的commit。第一次提交沒有父commit,所以用全0的sha1值表示。


    查看master文件內容,記錄了master指針的變化,新記錄增加到文件末尾


    使用git log命令


    其內容與logs內文件內容相似,不過最新的提交在頂部,從新到舊。
    使用命令git reflog


    記錄了HEAD指針的變化。
    注:HEAD@{N}表示HEAD之前的值

    提問:logs記錄的日志是否供git使用
    驗證:將logs文件夾移動其他位置,運行git log指令和git reflog指令
    運行git log指令,變更內容仍可輸出
    運行git reflog指令,無內容輸出。
    將logs文件夾移回,git reflog命令可正常使用
    總結:git log遍歷objects來建立日志,git reflog查詢.git/logs文件夾下內容

    注:git中箭頭含義,箭頭表示指向該節點,不能把箭頭當作時間方向

    TortiseGit介紹

    學習指導:要從底層理解Git工作原理,將高層指令細分了若干低層操作。Git指令過多,且指令效果復雜,如果把Git當作黑箱,則有些功能難以理解。從Git的基本工作原理入手


    Git Commit


    這里ReCommit表示完成此次提交后不關閉當前窗口,可進行下一次提交。(與amend last commit不同)


    Set author
    Set author date 在Message中添加作者和日期。
    Amend Last Commit (git commit --amend 修改上次提交)


    Show Unversioned Files 是否顯示未受版本控制的文件
    Message only 只提交Message,不提交文件


    show log同git log
    show reflog 同git reflog
    Browser References:瀏覽引用,即瀏覽分支
    Revision graph,顯示修訂版本圖(從圖中也可以看出,分支只是指針,不是分支實體)


    Repo Browser 倉庫瀏覽器,可快速查看不同修訂版本的內容,不需要修改Working-Tree內容。

    git底層命令

    git hash-object 寫入object
    git write-tree 將index內容寫入一個樹對象
    git update-index 更新index
    git cat-file [-p] [-t] [-s](pretty-print type size 查看文件

    git 內部原理分析(參考git-scm)

    https://git-scm.com/book/zh/v2/Git-內部原理-底層命令與上層命令

    1. git命令

    分為底層命令(plumbing),上層命令(porcelain)

    2. git文件目錄

    (注意,info/ 表示文件夾 HEAD 表示文件。根據末尾的/來區分文件和文件夾)config(config 文件包含項目特有的配置選項)description(僅供 GitWeb 程序使用)HEAD(HEAD指針,指向目前被檢出的分支hooks/(包含客戶端或服務端的鉤子腳本)info/(目錄包含一個全局性排除(global exclude)文件, 用以放置那些不希望被記錄在 .gitignore 文件中的忽略模式(ignored patterns)objects/(目錄存儲所有數據內容)refs/(存儲指向數據(分支、遠程倉庫和標簽等)的提交對象的指針)index(文件保存暫存區信息)

    3. git對象

    • git對象(object)存放在./git/object/ 文件夾。以<hash的前兩位>/<hash的后38位>的結構存儲
    • 對象分為 數據對象(blob object),樹對象(tree object),提交對象(commit object)
    • 數據對象僅保存了文件的內容,沒有保存文件名。
      • git cat-file -p <指定的sha1> 從Git中取回數據(-p 表示pretty-print 自動判斷類型 -t表示查看object的類型
      • git hash-object -w test.txt 將test.txt寫入Git
    • 樹對象(tree object)
      • 樹對象將文件組織到一起,一個樹對象包含了一條或多條樹對象記錄。每條記錄含有一個指向數據對象或者子樹對象的 SHA-1 指針,以及相應的模式、類型、文件名信息 * Git 根據某一時刻暫存區( index 區域,也稱為stage區域,使用git
        add命令后文件被添加到這里)所表示的狀態創建并記錄一個對應的樹對象。 * 底層命令 git
        update-index,必須為上述命令指定 --add
      • 文件模式為 100644,表明這是一個普通文件。 其他選擇包括:100755,表示一個可執行文件; 120000,表示一個符號鏈接
      • git write-tree 命令將暫存區內容寫入一個樹對象
    • 提交對象(commit object)
      • 調用 commit-tree 命令創建一個提交對象。為此需要指定一個樹對象的 SHA-1 值,以及該提交的父提交對象(如果有的話)。
      • 如果你做完了以上所有操作,那么現在就有了三個樹對象,分別代表我們想要跟蹤的不同項目快照。 然而問題依舊:若想重用這些快照,你必須記住所有三個 SHA-1 哈希值。
        并且,你也完全不知道是誰保存了這些快照,在什么時刻保存的,以及為什么保存這些快照。 而以上這些,正是提交對象(commit
        object)能為你保存的基本信息。
      • 提交對象 保存tree的sha1值,作者,保存時間,提交備注
      • 提交對象類似于數據結構中鏈表的結點,保存自身信息和父節點的位置

    總結

  • git blob object保存文件內容,tree object保存文件元信息以及目錄信息,commit tree保存提交信息。
  • 此時,通過object的sha1來查找object,未對object進行標注。
  • 4.git引用(references,簡寫為refs)

    筆者注:git引用可以理解為C語言的指針,指向某個地址。引用存放在.git/refs/heads/
    對分支進行操作時就是在操作【references】
    如果想更新某個引用,Git 提供了一個更加安全的命令 update-ref 來完成此事:
    Git 分支的本質:一個指向某一系列提交之首的指針或引用。

    HEAD 引用

    HEAD 文件通常是一個符號引用(symbolic reference),指向目前所在的分支。 所謂符號引用,表示它是一個指向其他引用的指針。

    標簽引用

    然而實際上還有第四種。 標簽對象(tag object) 非常類似于一個提交對象——它包含一個標簽創建者信息、一個日期、一段注釋信息,以及一個指針。 主要的區別在于,標簽對象通常指向一個提交對象,而不是一個樹對象。 它像是一個永不移動的分支引用——永遠指向同一個提交對象,只不過給這個提交對象加上一個更友好的名字罷了。

    遠程引用

    遠程引用是只讀的。 雖然可以 git checkout 到某個遠程引用,但是 Git 并不會將 HEAD 引用指向該遠程引用。因此,你永遠不能通過 commit 命令來更新遠程引用。 Git 將這些遠程引用作為記錄遠程服務器上各分支最后已知位置狀態的書簽來管理。

    參考資料

  • https://git-scm.com
  • 總結

    以上是生活随笔為你收集整理的git查看分支记录_git原理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。