[英]git checkout removes git log history
我的git log
中有兩個提交
commit a38056f9da4dcf48c188e79fe632b3624e6ffef4 (HEAD, main)
Author: user
commit 2
commit 801608941f024901799208e328bb0d3908c2ba7a
Author: user
commit 1
,我想 go 回到提交 1,我可以使用git checkout 801608941f024901799208e328bb0d3908c2ba7a
。 問題是,當我這樣做時,我的git log
變成
commit 801608941f024901799208e328bb0d3908c2ba7a
Author: user
commit 1
而且我再也找不到提交 2 的 SHA。 如果我通過向上滾動到我的第一個git log
然后git checkout
提交 2 的 SHA 找到提交 2 的 SHA,我 go 按預期回到提交 2 的快照,但令人討厭的是git log
不顯示提交 2 的 SHA 這正常嗎? 如果是這樣,我現在應該如何找到commit 2
的提交歷史記錄?
跑步:
git switch main
或者:
git checkout main
Git 沒有刪除任何東西。 你只是看不到它。 原因如下: git log
命令通過倒退來工作。
在 Git 存儲庫中,歷史不過是該存儲庫中的提交。 Git 通過他們丑陋的大 ID hash找到提交:
a38056f9da4dcf48c188e79fe632b3624e6ffef4
801608941f024901799208e328bb0d3908c2ba7a
Git迫切需要這些 hash ID 才能找到提交。 但是這些 hash ID 對人類非常不利(快點, 801608941f024901799208e328bb0d3908c2ba7a
和801608941f024901797208e328bb0d3908c2ba7a
一樣嗎?)。 所以我們通常不使用 hash ID。 Git確實使用了 hash ID,但 Git 為我們提供了分支名稱和標簽名稱以及許多其他類型的名稱。 那些是我們通常使用的。
每個提交存儲兩件事:
所有這些東西,一旦進入提交,就完全是只讀的:它永遠無法更改,即使是 Git 本身也不能更改,只要您通過其丑陋的大 ID hash檢索該提交。 該 hash ID 是該提交的“真名”。
在每個提交的元數據中,Git 存儲了以前提交的列表,這就是git log
的實際工作方式:它從某個特定的提交開始,它有一些特別丑陋的 hash ID, git log
向您顯示該提交。 然后git log
使用該提交的元數據來查找之前的提交。 git log
命令現在顯示該提交,然后使用其元數據再次后退。
這樣做的最終結果是,您會看到所有提交,一次一個,向后,從您開始的任何地方(或者它是“結束”?),遵循 Git 在您工作時偽造的內部鏈:
... <-F <-G <-H
這里大寫字母代表那些又大又丑的 hash ID,所以H
是一些 Hash 的縮寫。如果你給 Git H
的 hash ID,它會顯示你H
,然后它使用H
找到G
的 hash ID。 我們說提交H
指向更早的提交G
。 Git 然后顯示G
,然后使用G
的元數據找到F
的 hash ID,依此類推。
但是:如果你運行git log
而不給它一個 hash ID,它怎么知道從哪里開始呢? 答案是 Git 具有當前提交的概念,Git 使用特殊的魔法名稱HEAD
找到了當前提交。
因為 hash ID 對人類有害,所以我們傾向於不使用它們。 Git 為我們提供了創建任意數量的分支名稱的選項。 每個分支名稱都存儲一個 hash ID,無論 hash ID 是“內部”分支名稱,還是該分支“上”的最后一次提交:
... <-F <-G <-H <--main
這里的名字main
指向H
,就像H
指向G
和G
指向F
等等。 所以git log main
將從H
開始,向后工作。
我們可以有任意多的分支名稱,都直接指向提交H
:
...--G--H <-- main, develop, feature1, feature2
為了記住哪個名稱是當前名稱,Git 會將特殊名稱HEAD
附加到這些分支名稱之一:
...--G--H <-- main, develop, feature1 (HEAD), feature2
在這里,我們“在”分支feature1
上——運行git status
會on branch feature1
——和git log
,沒有任何起點,將使用名稱feature1
來查找提交H
,並顯示該提交,然后是G
和F
等等。
但是,如果我們運行:
git checkout <hash-id>
對於一些丑陋的 hash ID,Git 將 hash ID直接存儲在特殊名稱HEAD
中,現在我們有:
...--F <-- HEAD
\
G--H <-- main, develop, ...
運行git log
現在從提交F
開始並向后運行。 提交G
和H
發生了什么? 什么也沒有:他們還在里面。 您只需要在提交H
時啟動git log
,就可以看到它們。 為此,您可以運行:
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 不僅會寫出新的提交,給它一個新的唯一的 hash ID(大而丑陋的 hash ID 是唯一的),它還會設置新的提交,以便它指向回提交H
我們用作current commit just a moment ago—然后將新提交的 hash ID 寫入當前分支名稱。
這就是分支正常增長的方式,一次一個提交。
還有很多,但這些是使用 Git 時需要了解的基本內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.