我正在學習 GitHub 并找到了用于分叉存盤庫的下游/上游概念。我還瀏覽了各種檔案/博客,但無法弄清楚當我們按下“上游獲取”時實際發生了什么?
uj5u.com熱心網友回復:
git fetch upstream從遠程存盤庫中獲取(“下載”)所有更改upstream并將它們存盤在本地upstream。然后,您可以使用此前綴參考這些本地副本(例如,檢查它們、設定跟蹤分支、挑選提交等)。例如,git checkout upstream/some-branch會檢查some-branch您剛剛從upstream.
uj5u.com熱心網友回復:
要正確理解這一點,您需要了解以下有關 Git 的知識:
- Git 是關于提交的。這與檔案無關(盡管提交包含檔案)。這與分支無關(盡管分支名稱可以幫助我們,而 Git 可以找到提交)。這真的是關于commits。
- 提交被編號。數字是巨大的、丑陋的、隨機的,以十六進制表示;每個提交都有一個唯一的編號,與每個 Git 存盤庫中的每個其他提交都不同。如果兩個不同的 Git 存盤庫中具有相同的提交編號,則它們中具有相同的提交:從某種意義上說,編號就是提交(盡管您必須擁有提交本身:編號只是關鍵,在關鍵-value 資料庫,Git 用來查找,即查找,提交)。
- 除了像or 、、等分支名稱之外,Git 還有其他名稱:標記名稱,例如,以及稱為遠程跟蹤名稱的東西(Git 實際上將這些遠程跟蹤分支名稱稱為,但我發現如果省略它會更有意義這里不必要的詞分支)。每個名稱都可以存盤一 (1) 個哈希 ID。這就是我們所需要的,因為提交也存盤哈希 ID。
mainmasterdevfeature/tallv3.14
當我們克隆一個 Git 存盤庫時,我們會獲得其他存盤庫的所有提交,而沒有任何分支。1 我們的 Git 沒有分支名稱,而是采用另一個克隆的分支名稱并將它們轉換為我們的遠程跟蹤名稱。如果我們呼叫另一個 Git——我們現在正在克隆的origin那個——,這是標準的第一個遠程名稱,它們main變成 our origin/main,它們的dev turns into our origin/dev`,等等。
這意味著我們的分支名稱是ours。我們不必使用與其他 Git 存盤庫相同的名稱。我們通常做的,只是理智,但我們并不需要。
這也間接地告訴我們什么是“遠程”:遠程是一個短名稱,它存盤一個 URL——我們從中克隆的 URL,originfor——并且還為遠程跟蹤名稱提供前綴。將origin在origin/dev來自遠程名字origin。2
當你運行時:
git fetch origin
您的 Git 軟體,在您的存盤庫中運行,在某處呼叫其他一些 Git 軟體(位于名稱下存盤的 URL)origin,并使用該 URL 將其連接到某個其他存盤庫。其他軟體(實際上是“其他 Git”)讀出他們的提交——特別是哈希 ID——和分支名稱,并將它們發送到“我們的 Git”(我們的軟體在我們的存盤庫中作業)。我們的 Git 和他們的 Git 有一個涉及哈希 ID 的小型對話,以便我們的 Git 可以看到他們有哪些提交,而我們沒有。
然后我們的 Git 將帶來他們擁有的任何(對我們來說是新的)提交,而我們沒有。這包括我們手動、小心地從我們的 Git 存盤庫中丟棄的任何提交,因為我們發現它們在某些方面很糟糕:3所以在這方面,這就像與可能攜帶一些病毒的 Git 進行 Git-sex,我們只會繼續被重新感染,直到他們也放棄那個錯誤的提交。但大多數情況下這是好的,因為大多數情況下我們確實希望他們擁有的每一次提交,我們都沒有。
但是:怎么樣upstream?嗯,這個詞有一個小問題,上游,因為 Git 使用這個詞來表示別的東西。4 但在這種情況下,upstreamGitHub 這個名字特別鼓勵人們在他們的 Git 存盤庫中用作第二個遠程。我們可以有不止一個遙控器!
使用,我們創建了第二個名為 的遙控器。在那之后:git remote add upstream urlupstream
git fetch upstream
使用保存的 URL 呼叫其他一些 Git,就像git fetch origin那樣。無論托管站點是 GitHub 還是其他一些站點,我們的 Git 和他們的 Git 都像以前一樣進行著相同的對話。我們的 Git 會找出他們有哪些我們沒有的提交,將這些提交下載到我們的 Git 存盤庫中,并創建或更新遠程跟蹤名稱,如upstream/main和upstream/dev。我們將為upstream/*另一個 git 中存盤在 name 下的 URL 中的每個分支名稱獲取一個名稱upstream。
這就是它的全部內容。不過,有一個特別的地方讓人們在這里絆倒。假設您git clone有一個存盤庫,因此您現在擁有origin/main和origin/feature/tall. 但是該origin存盤庫是從其他某個存盤庫分叉出來的,因此您git remote add可以添加您的fork2或upstream您想呼叫的任何內容,然后運行:
git fetch fork2
或者不管你叫它什么。你現在有fork2/main和fork2/feature/tall。所以你有origin/feature/tall和fork2/feature/tall。
你還沒有制作你自己的feature/tall。 你跑:
git switch feature/tall
或者:
git checkout feature/tall
expecting your Git to create your feature/tall from ... well, wait: are you expecting your new branch name, feature/tall, to spring from origin/feature/tall and use that as its upstream setting? Or are you expecting your new branch name, feature/tall, to spring from fork2/feature/tall and use that as its upstream? Or perhaps you need two feature/tall branches, one to go with origin/feature/tall and one to go with fork2/feature/tall.
You can't call both feature/tall. This means that if you do want two branch names, one for each remote-tracking name, you will be forced to break the usual "my name = my remote-tracking name, minus the remote" setup that you're used to. The bottom line is that as soon as you have two or more remotes, your Git life gets more complicated. There's no way around this: you must understand what remotes, and remote-tracking names, are and do.
1您可以隨時修改此行為git clone,并且存盤庫中通常會有垃圾和/或丟棄的提交,這些提交稍后git clone會被維護命令清理并且通常不會復制這些。所以這只是一個近似值,有助于理解事物。
2像往常一樣在GIT中,通過該處理git fetch origin在它們的結果dev變得origin/dev完全沒有直接的。你可以用它做各種瘋狂的事情。不過,為了理智,在任何普通用戶克隆中做任何奇怪和瘋狂的事情都是不明智的:讓他們dev成為你的origin/dev.
3例如,也許我們小心地丟棄了一個意外提交,該提交添加了一個阻塞磁盤的 TB 級資料庫。哎呀,又來了!
4特別是,Git 允許每個分支名稱存盤單個上游名稱。通常我們將分支的上游設定br1為origin/br1:origin對應于其分支名稱的遠程跟蹤名稱br1。這樣我們的分支名稱br1就可以很容易地參考我們的origin/br1,這是我們的副本——我們 Git 的記憶——他們的分支名稱br1。
這是不是在所有同一個遠程命名upstream。如果 GitHub 鼓勵人們使用第二個遠程名稱fork2或類似名稱,那可能會有所幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/372652.html
