簡體   English   中英

git pull 后顯示“強制更新”

[英]"Forced update" shown after git pull

在我的存儲庫中執行git pull后,它顯示

6cca7ee...32eb5b2 bug/12 -> origin/bug/12  (forced update)

以前,我從父分支parent/1.2.3創建了bug/12分支,對代碼進行了更改,並將bug/12分支合並到了parent/1.2.3分支並完成了bug/12 branch 但是由於某些問題,我需要再次重新打開 bug 12,因此我再次從parent/1.2.3創建了一個bug/12分支,並進行了代碼更改並將更改推送到bug/12分支。 但是現在當我拉動parent/1.2.3分支時,它顯示我強制更新。

因此,如果我將新創建的bug/12分支合並到parent/1.2.3分支中,它會產生任何問題還是會刪除強制更新?

這種“強制更新”的事情可能會非常令人困惑,但您已經提出了一個重要的問題。

是否有任何實際的問題就在這里,我懷疑有isn't,取決於是什么意思時,你說:

...並完成了bug/12 branch

Git 沒有一個叫做完成的概念。 因此,您導致在哪些存儲庫中發生的實際 Git 操作並不明顯。

Git 是分布式的,所以存儲庫不止一個

如果只有一個存儲庫,並且它有各種分支名稱,例如bug/12並且您執行了以下操作:

git checkout master
git merge bug/12
git branch -d bug/12

(這會將bug/12尖端的提交合並到master ,然后刪除分支名稱bug/12 )這種問題永遠不會出現:刪除了名稱,它不再存在。

但不只有一個存儲庫。 你:

  • 您的存儲庫中創建了名稱bug/12
  • 您的存儲庫中做了一些工作,創建提交
  • 將這些提交發送到另一個存儲庫,並讓他們他們的存儲庫中創建名稱bug/12
  • 讓你的 Git 從他們那里獲得新的提交和/或分支名稱:這發現他們現在在他們的存儲庫中有一個bug/12 ,所以你的 Git 在你的存儲庫中創建了一個origin/bug/12來記住他們的bug/12

現在,在這一切之后,我懷疑你所做的——所說的“完成的bug/12 branch ”——是你在使用 GitHub 或 Bitbucket 或 GitLab 或類似的東西,你進入了他們的網絡界面並使用了各種小按鈕將bug/12合並到他們存儲庫中的master ,然后刪除他們的bug/12 name 這與上面顯示的三個假設命令非常相似,除了 `git merge bug/12 可以執行快進操作而不是真正的合並,而 GitHub合並拉取請求按鈕永遠不會執行快進操作。

但我不知道這就是你所做的。 我只是懷疑而已。

陳舊的遠程跟蹤名稱

假設這就是您所做的,您可能會繼續從您自己的存儲庫中手動刪除分支名稱bug/12

git branch -D bug/12

從那時起,您可能已經運行了git fetch (或者以一種可以解決問題的方式運行git pull運行git fetch ),但您可能沒有fetch.prune設置為true 當您運行git fetch ,您的 Git 會在origin調用 Git 並讓它們列出它們的分支名稱。 他們此時沒有bug/12分支名稱,但是您的 Git 更早創建了您自己的origin/bug/12 ,當時他們確實有他們的bug/12分支名稱。 因此,您的 Git 不會對您自己的origin/bug/12名稱執行任何操作:此名稱沒有新值,但您沒有指示您的 Git刪除不再具有其他名稱的origin/*名稱。

這意味着就您的 Git 而言, origin/bug/12仍在記住另一個 Git 存儲庫中的有效bug/12名稱,即使不再有這樣的名稱 如果您將fetch.prune設置為true或運行git fetch --prune ,您的 Git 將刪除此origin/bug/12 所以在這一點上,你的origin/bug/12是一個陳舊的 name (Git 沒有定義這個術語——它沒有被稱為陳舊名稱的概念——但這對於這種名稱來說似乎是一個很好的術語。)

同樣,所有這些都是從事實中推斷出來的,實際上並不存在證據。 真的是這樣嗎? 我不知道:你告訴我的還不夠多。

陳舊的名稱可能會導致這種行為

現在,假設以上所有內容都是正確的,您自己的origin/bug/12還記得前段時間在origin記住的bug/12 那是您單擊合並變基和合並擠壓和合並Web 瀏覽器單擊按鈕之前。 在這一點上,我必須至少再做一個假設:您使用的按鈕不是純粹的合並,而是rebase 和 mergesquash 和 merge

讓我們畫出 rebase-and-merge 或 squash-and-merge 操作之前的情況。 在 GitHub 上的 Git 存儲庫中(此時我將假設為 GitHub),您有一系列提交,每個提交都以某個分支名稱指向的提交結束:

...--A--B--C--D   <-- parent/1.2.3
         \
          E--F   <-- bug/12

這里EF是修復錯誤的兩個提交。 您現在單擊變基並合並壓縮並合並並獲得兩個或一個新提交:

...--A--B--C--D--E'-F'  <-- parent/1.2.3
         \
          E--F   <-- bug/12

或者:

...--A--B--C--D--G   <-- parent/1.2.3
         \
          E--F   <-- bug/12

(我會用這張圖,因為它更簡單)。 你現在讓 GitHub 刪除它的bug/12名稱:

...--A--B--C--D--G   <-- parent/1.2.3
         \
          E--F   [abandoned]

在某個時候,在您的存儲庫中,您更新自己的 Git 對 GitHub Git 分支的內存:

...--A--B--C--D--G   <-- origin/parent/1.2.3
         \
          E--F   <-- origin/bug/12

請注意您的陳舊origin/bug/12名稱如何仍然記住提交F

此時,您可能會也可能不會向origin/parent/1.2.3添加更多提交和/或更新您自己的parent/1.2.3名稱。 讓我們再畫一個提交並同步顯示這兩個提交:

...--A--B--C--D--G--H   <-- parent/1.2.3, origin/parent/1.2.3
         \
          E--F   <-- origin/bug/12

請記住,這是存儲庫中內容的繪圖。 GitHub 存儲庫有這個:

...--A--B--C--D--G--H   <-- parent/1.2.3

它沒有origin/*名稱:它只有它的分支名稱。 您的Git 是具有origin/*名稱的 Git,包括陳舊的origin/bug/12 到目前為止,他們的Git 已經完全丟棄了提交EF 由於您的origin/bug/12名稱,您的Git 仍在保留其他不需要的EF提交。

現在你在他們的Git 中做一些創建名稱bug/12事情,指向提交H

...--A--B--C--D--G--H   <-- parent/1.2.3, bug/12

您現在在您的存儲庫中運行git fetch (通過git pull )。 你的 Git 看到他們的bug/12指向提交H 你的 Git目前有這個:

...--A--B--C--D--G--H   <-- parent/1.2.3, origin/parent/1.2.3
         \
          E--F   <-- origin/bug/12

但是您的 Git 現在將獲取您的origin/bug/12並將其從提交F拉出並將其移至指向提交H

...--A--B--C--D--G--H   <-- parent/1.2.3, origin/parent/1.2.3, origin/bug/12
         \
          E--F   [abandoned]

你的 Git 現在你的名字origin/bug/12執行這個不尋常的動作,將它從你仍然保留的提交中拉出來——提交F到提交H ,它不是提交F后代 (提交H的唯一父級是G G的父級是D ,其父級是C ,其父級是B 。因此,提交H不是F后代,盡管它們在提交B共享相同的祖先。)操作是非快進的,因此您的Git 打印:

+ 6cca7ee...32eb5b2   bug/12 -> origin/bug/12  (forced update)

前面的加號(您省略了)表示這是強制更新,因為它是非快進的

這里的兩個散列 ID 6cca7ee32eb5b2是我在上面調用FH的提交的完整散列 ID 的縮寫版本。 從輸出git fetch包括這兩個散列ID之間的三個點,表明6cca7ee不是的祖先32eb5b2

箭頭左側的名稱bug/12是在他們的存儲庫中看到的分支名稱(在 GitHub 上,或任何地方)。 名稱origin/bug/12您的 Git對其bug/12的記憶

最后的(forced update)與加號和三個點表示相同的事情:這是一個非快進,因此作為強制更新完成。

因此, git fetch命令已經三次告訴您有強制更新。

這里有問題嗎?

答案可能不是,但這取決於對origin/bug/12更改,而是取決於您自己的分支名稱。 在上面的圖中,我們已經繪制了一些分支名稱、一些遠程跟蹤origin/*名稱和一些其他 Git 的分支名稱,具體取決於我們正在討論的 Git 存儲庫。 但是我們還沒有繪制所有的分支名稱。

你的分支名稱是你的 他們可以指向你在你的存儲庫中的任何提交——包括其他Git,在 GitHub 上或任何地方,已經放棄的EF提交。 如果您允許您的分支名稱之一重新引入那些舊提交,那可能不太好。 如果您不允許這樣做,那很好。 如果你沒有任何分支名稱指向這老提交,你會不小心再推出他們。

這就是解開謎題的關鍵。 提交才是最重要的。 提交有提交哈希 ID,世界各地的每個 Git 都同意這些提交獲得這些哈希 ID。 沒有其他提交,無論何時何地,都可以擁有這些哈希 ID! 您的Git 仍然在您的遠程跟蹤名稱origin/bug/12下保留它們。 它不再使用該名稱:該名稱已更新以記住其他一些提交哈希 ID。 但是你仍然有你的分支名稱。 這些中的任何一個都記得與您的陳舊origin/bug/12相同的哈希 ID,直到您的git pull運行的git fetch更新它,就在最近?

只有可以回答這個問題,因為只有您擁有自己的Git 存儲庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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