簡體   English   中英

git 結帳刪除 git 日志歷史記錄

[英]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 對人類非常不利(快點, 801608941f024901799208e328bb0d3908c2ba7a801608941f024901797208e328bb0d3908c2ba7a一樣嗎?)。 所以我們通常不使用 hash ID。 Git確實使用了 hash ID,但 Git 為我們提供了分支名稱標簽名稱以及許多其他類型的名稱。 那些是我們通常使用的。

每個提交存儲兩件事:

  • 直接地,每個提交存儲一些元數據,提供諸如提交人的姓名和 email 地址等信息。
  • 間接地,每個提交存儲每個文件的完整快照

所有這些東西,一旦進入提交,就完全是只讀的:它永遠無法更改,即使是 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找到了當前提交。

HEAD 通常包含一個分支名稱

因為 hash ID 對人類有害,所以我們傾向於不使用它們。 Git 為我們提供了創建任意數量的分支名稱的選項。 每個分支名稱都存儲一個 hash ID,無論 hash ID 是“內部”分支名稱,還是該分支“上”的最后一次提交:

... <-F <-G <-H   <--main

這里的名字main指向H ,就像H指向GG指向F等等。 所以git log main將從H開始,向后工作。

我們可以有任意多的分支名稱,都直接指向提交H

...--G--H   <-- main, develop, feature1, feature2

為了記住哪個名稱當前名稱,Git 會將特殊名稱HEAD附加到這些分支名稱之一:

...--G--H   <-- main, develop, feature1 (HEAD), feature2

在這里,我們“在”分支feature1上——運行git statuson branch feature1 ——和git log ,沒有任何起點,將使用名稱feature1來查找提交H ,並顯示該提交,然后是GF等等。

分離頭模式

但是,如果我們運行:

git checkout <hash-id>

對於一些丑陋的 hash ID,Git 將 hash ID直接存儲在特殊名稱HEAD中,現在我們有:

...--F   <-- HEAD
      \
       G--H   <-- main, develop, ...

運行git log現在從提交F開始並向后運行。 提交GH發生了什么? 什么也沒有:他們還在里面。 您只需要提交H時啟動git log ,就可以看到它們。 為此,您可以運行:

git log main

因為main指向H 或者您可以git switch maingit checkout mainHEAD重新附加到分支名稱,以便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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM