我有兩個提交git log
commit a38056f9da4dcf48c188e79fe632b3624e6ffef4 (HEAD, main)
Author: user
commit 2
commit 801608941f024901799208e328bb0d3908c2ba7a
Author: user
commit 1
,我想回去提交 1,我可以用git checkout 801608941f024901799208e328bb0d3908c2ba7a. 問題是,當我這樣做時,我git log轉向
commit 801608941f024901799208e328bb0d3908c2ba7a
Author: user
commit 1
而且我再也找不到提交 2 的 SHA。如果我通過向上滾動到我的第一個git log然后git checkout提交 2 的 SHA 找到提交 2 的 SHA,我會按預期回傳提交 2 的快照,但是git log不顯示提交 2 的 SHA 很煩人這是正常的嗎?如果是這樣,我現在應該如何找到提交歷史commit 2?
uj5u.com熱心網友回復:
TL;博士
跑:
git switch main
或者:
git checkout main
長的
Git 沒有洗掉任何東西。你只是看不到它。原因如下:該git log命令通過倒退來作業。
在 Git 存盤庫中,歷史無非就是該存盤庫中的提交。Git通過它們又大又丑的哈希 ID 來查找提交:
a38056f9da4dcf48c188e79fe632b3624e6ffef4801608941f024901799208e328bb0d3908c2ba7a
Git迫切需要這些哈希 ID 才能找到提交。但是這些哈希 ID 對人類來說是非常不利的(快,是801608941f024901799208e328bb0d3908c2ba7a一樣的801608941f024901797208e328bb0d3908c2ba7a嗎?)。所以我們通常不使用哈希 ID。Git確實使用哈希 ID,但 Git 為我們提供了分支名稱和標簽名稱以及許多其他型別的名稱。這些是我們通常使用的。
每個提交存盤兩件事:
- 直接地,每個提交都存盤一些元資料,提供諸如提交人的姓名和電子郵件地址等資訊。
- 間接地,每個提交存盤每個檔案的完整快照。
所有這些東西,一旦在一個提交中,就完全是只讀的:它永遠不會被改變,即使是 Git 本身也不能,只要你通過它的大而丑陋的哈希 ID檢索那個提交。該哈希 ID 是該提交的“真實名稱”。
在每個提交的元資料中,Git 存盤了一個先前提交的串列,這就是git log實際的作業方式:它從某個特定的提交開始,該提交具有一些特別大的丑陋哈希 ID,并向git log您顯示該提交。然后git log使用該提交的元資料來查找先前的提交。該git log命令現在顯示該提交,然后使用其元資料再次后退。
這樣做的最終結果是,您會看到所有提交,一次一個,從您開始的任何地方(或者它是“結束”?),遵循 Git 在您作業時偽造的內部鏈:
... <-F <-G <-H
這里大寫字母代表那些又大又丑的哈希ID,所以H是一些哈希的縮寫。如果你給 Git 的哈希 ID H,它會顯示給你H,然后它會H用來查找G. 我們說 commitH 指向較早的 commit G。Git 然后顯示G,然后使用G的元資料來查找 的哈希 ID F,依此類推。
但是:如果你運行時git log 沒有給它一個哈希 ID,它怎么知道從哪里開始呢?答案是 Git 具有當前提交的概念,Git 使用特殊的、神奇的名稱來找到它HEAD。
HEAD 通常包含一個分支名稱
因為哈希 ID 對人類不利,所以我們傾向于不使用它們。Git 為我們提供了創建任意數量的分支名稱的選項。每個分支名稱都存盤一個哈希 ID,無論哈希 ID 在分支名稱“內部”是什么,這都是該分支“上”的最后一個提交:
... <-F <-G <-H <--main
這里名稱main 指向 H,就像H指向G和G指向F等等。所以git log main將開始H并向后作業。
我們可以有任意多的分支名稱,所有分支名稱都直接指向 commit H:
...--G--H <-- main, develop, feature1, feature2
為了記住哪個名稱是當前名稱,Git 會將特殊名稱附加HEAD到以下分支名稱之一:
...--G--H <-- main, develop, feature1 (HEAD), feature2
在這里,我們在“on”分支feature1——runninggit status會說on branch feature1——and git log,沒有任何起點,將使用名稱feature1來查找 commit H,并顯示該提交,然后G和F等等。
分離式 HEAD 模式
但是,如果我們運行:
git checkout <hash-id>
對于一些大而丑陋的哈希 ID,Git 將哈希 ID直接存盤在特殊名稱HEAD中,現在我們有了:
...--F <-- HEAD
\
G--H <-- main, develop, ...
現在運行git log從提交開始F并向后運行。提交G和發生了什么H?什么都沒有:他們還在里面。你只需要從 commit開始git log ,H就可以看到它們。為此,您可以運行:
git log main
因為main指向H; 或者您可以git switch main或git checkout main重新附加 HEAD到分支名稱,以便git log從那里開始。
請注意,提交通常在許多分支上
鑒于:
...--G--H <-- main, develop, feature1 (HEAD), feature2
提交在哪個分支上?
答案是:全部!
但是,如果我們現在進行新的提交,會發生以下情況:
...--G--H <-- main, develop, feature2
\
I <-- feature1 (HEAD)
Git 不僅會寫出新的提交,給它一個新的唯一哈希 ID(大而丑陋的哈希 ID 是唯一的),它會設定新的提交,以便它指向提交H——我們用作當前的提交剛才提交——然后將新提交的哈希 ID 寫入當前分支名稱。
這就是分支正常增長的方式,一次提交一個。
還有更多,但這些對于使用 Git 來說是必不可少的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528621.html
標籤:混帐
