[英]How to get remote repo branch added to local repo
新創建 - 通過創建一個文件夾並運行命令
git init
簡而言之,從頂部創建一個本地 git 存儲庫。
我這里有一個帶有2 個分支的本地 git 存儲庫(新創建的)。 現在這些分支只是我創建的虛擬分支,對它沒有什么重要的。
$ git branch
* repo2-branch1
repo2-branch2
我這里還有一個來自 Github 的遠程存儲庫(私有),帶有一個分支“TLA1” ,現在還記得我上面提到的帶有這兩個分支的新創建的本地存儲庫嗎? 正如我所提到的,我想要做的是在我新創建的本地存儲庫中添加這個“TLA1”分支作為帶有repo2-branch1
和repo2-branch2
的分支之一。
假設已添加“TLA1”分支。 因此,當我輸入git branch
時,我希望它是這樣的。
$ git branch
* repo2-branch1
repo2-branch2
TLA1
當然,當我輸入git log
時,當我切換到“TLA1”時,我也會有遠程存儲庫中的提交,如圖所示,因為對我來說,這些提交非常重要。
我做了很多研究並發現了這一點,我認為這已經是它了,因為它與我的目標相似。 但是當我嘗試它時,我得到了一個錯誤。
$ git checkout -b TLA1 origin/TLA1
fatal: 'origin/TLA1' is not a commit and a branch 'TLA1' cannot be created from it
我也沒有嘗試過,因為這可能會對我的遠程git reset --hard <remote>/<branch_name>
做一些事情,這似乎不是我找到的解決方案。
有什么解決辦法嗎? 我真的很想在我新創建的存儲庫上有這個分支。
您需要先運行git fetch origin
,然后才能運行git checkout TLA1
。
你走在正確的軌道上,但有很多東西要知道——還有很多人們發現的錯誤的東西,你應該小心。
在您熟練使用Git之前,您需要了解一些東西。 這些虛假聲明 go 如下:
“分支很重要”:這沒有錯,但這也不對。 第一個問題是分支這個詞,它在 Git 中基本上是模棱兩可的。 如果我們堅持使用兩個詞的短語branch name ,我們會得到更有用的東西。 分支名稱很重要,但僅限於人類。 Git 使用它們來幫助我們找到提交; 真正重要的是提交。
“遠程分支”:這個兩個詞的短語,如果有的話,比“分支”這個詞本身更糟糕。 人們用它來表示至少三種不同的東西。 讓我們也避免使用這個短語。 Git 文檔使用術語remote-tracking branch或remote-tracking branch name ,這是git branch -r
列出的名稱。 這句話沒有那么糟糕,但其中的分支一詞毫無意義。 讓我們稱之為遠程跟蹤名稱。
Git 中重要的是提交。 了解這些關於提交的事情:
每個都有一個唯一的 hash ID。 某個提交的 hash ID 表示該提交。 沒有其他提交——在任何地方,在任何Git 存儲庫中——將具有該hash ID。 該提交(在任何Git 存儲庫中的任何位置)將具有該hash ID。
提交是在不同的 Git 克隆之間共享的內容。 分支名稱不共享。 您的 Git 克隆具有您的分支名稱,而其他一些克隆具有其分支名稱。 您可能想使用相同的名稱,以使事情保持直截了當,但這取決於您(盡管 Git 會在這里提供幫助,因為這是很常見的事情)。
每個提交由兩部分組成:
提交的主要數據是所有文件的快照。 這些文件一直被凍結:它們以壓縮、只讀、僅 Git 和去重的形式存儲。 重復數據刪除處理的事實是,大多數時候,大多數新提交大多包含與前一次提交相同的文件。 當然,存儲在提交中的文件被凍結,甚至不能被非 Git 的程序讀取(更不用說寫入)這一事實是一個問題。
提交的另一部分是它的元數據。 這包括提交人的姓名、他們的 email 地址以及提交時的日期和時間戳。 所有這些東西也是只讀的。 對於 Git 本身而言,至關重要的是,Git 將 hash ID 添加到此元數據中,之前的某個或多個提交的 ID。 我們稱這些為提交的父母。
鑒於我們有一些簡單的提交序列:
... <-F <-G <-H
這里的每個字母代表一個實際的 Git hash ID,我們最終得到一個以提交H
結尾的線性提交鏈。 如果我們知道H
的實際 hash ID,我們可以讓 Git 提取此提交(見下文)。 或者,我們可以讓 Git 讀取H
的元數據並向我們展示誰進行了提交......或者使用它來查找H
的父提交G
的實際 hash ID。
由於G
和H
都持有快照,我們可以讓 Git 比較兩個快照。 所有匹配的文件都是無趣的,因為它們匹配。 任何不匹配的文件都更有趣,我們可以讓 Git 找出它們的不同之處並向我們展示不同之處。 這樣,我們就可以看到我們改變了什么。 Git 不存儲更改:它只存儲快照。 但是我們可以將快照視為更改,因為提交有父級。
我們也可以讓 Git go 回到G
,並用它來找到F
,因此將G
視為更改。 從那里,我們可以 go 回到F
,並使用它來找到更早的提交,等等。 但要做到這一切,我們需要鏈中最后一次提交的實際 hash ID。 這就是分支名稱的來源:像repo-branch1
這樣的分支名稱只存儲一些 hash ID。 根據定義,存儲在名稱中的 hash ID 是分支中的最后一次提交。 Git 將從那里開始並向后工作。 在那之后是否有以后的提交也沒關系:
...--E--F <-- br1
\
G--H <-- br2
這里H
是br2
中的最后一次提交(例如F
和G
之后),而提交F
是br1
中的最后一次提交。 通過F
向上提交在兩個分支中,但br1
在F
開始或結束(取決於你如何看待它)並向后工作,而br2
在H
結束並向后工作。
因為提交是只讀的,我們實際上不能直接處理或使用它們。 我們必須選擇一些提交並將其設為當前提交。 當我們這樣做時,Git 將 go 與該提交一起提取到工作區的所有文件,Git 將其稱為工作樹或工作樹。 這些是您可以查看和使用的文件。 它們是普通的日常計算機文件,您計算機上的每個程序都可以使用。 但它們實際上不在Git 中。
我們跑:
git checkout br2
(或 Git 2.23 或更高版本中的git switch br2
)。 Git 使用名稱br2
來查找該分支的最后(或tip )提交(注意模棱兩可的詞,在這種情況下表示某些以H
結尾的提交集)。 Git 然后從該提交中提取文件,以便我們可以查看和使用它們,並使該提交成為當前提交,同時將該分支名稱設為當前分支。 我喜歡這樣畫:
...--E--F <-- br1
\
G--H <-- br2 (HEAD)
特殊名稱HEAD
附加到分支名稱。 這就是“在分支上”的含義:名稱HEAD
定位分支名稱br2
。 分支名稱本身定位提交, H
,它是 Git 提取的一個。
如果我們進行新的提交, Git 將 package 生成快照,添加元數據,將新提交的父級設置為當前提交H
,並使用所有這些來寫出新提交。 這為提交分配了新的、大而丑陋的隨機外觀——但實際上根本不是隨機的——哈希 ID,我將稱之為I
。 由於I
的父母是H
, I
指向H
。 然后 Git 只需將I
的 hash ID 寫入當前名稱br2
,給出:
...--E--F <-- br1
\
G--H--I <-- br2 (HEAD)
因此,分支名稱的特殊功能是,當我們創建它時,它會自動移動以指向新的提交。 Git 通過將名稱HEAD
附加到分支名稱來完成此操作。
Git 有其他名稱(例如標簽名稱和遠程跟蹤名稱)也指向提交(通過存儲提交 hash ID),但您不能將HEAD
附加到它們。
git fetch
遠程跟蹤名稱具有 forms ,例如origin/TLA1
:它們以遠程名稱開頭,例如origin
。 遠程名稱是您使用git remote add
時使用的名稱; origin
只是第一個標准。 如果你使用git clone
來運行git init
和git remote add
等等, git clone
將使用origin
注意:您沒有使用git clone
,因此當您運行git remote add
時,名稱將由您決定。
如上所述,您不能將HEAD
附加到遠程跟蹤名稱。 此外,您通常不會自己創建這些名稱。 您可以使用git branch -r
列出您現在擁有的那些,但如果您不創建它們,您如何獲得它們?
最后一個問題的答案是git fetch
命令創建它們。 git fetch
命令非常復雜(有好有壞),我在這里肯定不會過多介紹,但我們可以這樣簡單地描述它:從中:
首先,您的 Git 的 Git 列出了它們的所有分支名稱、標簽名稱和其他此類名稱。 這些帶有 hash ID — 主要是提交 hash ID,盡管標簽名稱有時會稍微復雜一些。
然后您的 Git 會選擇這些名稱和 hash ID。 您 Git 可以判斷您是否有提交,因為每個 Git 對相同的提交使用相同的隨機外觀但非隨機的 hash ID 。 因此,您的 Git 會立即知道您是否有他們分支的提示提交。
如果你不這樣做,你的 Git 會向他們的 Git 詢問他們的提交。 他們也提供提交的父母,您的 Git 會檢查您是否有這些提交。 通過這種擁有/想要的序列(通過一些重要的優化,避免每次都必須列出每個 hash ID),您的 Git 找出他們有哪些提交,您不需要,您需要,並要求他們.
他們 package 完成所有這些提交並將它們發送給您。 這里的細節可能會有很大差異,但在通常情況下,您會看到“計數”和“壓縮”等,然后您的 Git 會收到一個 package 充滿提交和其他內部 Z0BCC70105AD279503E31FE7B3 對象。 您的 Git 然后將其全部保存在您的存儲庫中。
您現在擁有了之前的所有提交,以及他們沒有的任何提交(除非您的 Git 不想要它們,例如單分支克隆)。
最后,您的 Git 現在創建或更新您的遠程跟蹤名稱。 對於他們擁有的每個分支名稱,您的 Git 會為您的存儲庫創建或更新相應的遠程跟蹤名稱。
這意味着您永遠不會直接獲得他們的分支名稱。 您獲取他們的分支名稱並將它們更改為您的遠程跟蹤名稱。 這充當您的 Git 分支名稱的memory 。 這些是由git fetch
創建或更新的。 在您運行git fetch
之前,您不會有origin/TLA1
。
重要的是提交。 分支名稱和其他名稱可幫助您(和 Git)找到提交。
您可以通過運行git fetch
遠程跟蹤名稱。 您告訴git fetch
要調用的遙控器。 您的 Git 調用該遠程並查看其分支並獲取其提交,除非您已經擁有它們。 然后您的 Git 會根據需要更新或創建遠程跟蹤名稱。 (旁注:您的 Git 不會在此處刪除“死”名稱,除非您告訴它,因此一旦他們刪除了某些分支名稱,您將留下陳舊的遠程跟蹤名稱。)
您可以隨時創建自己的分支名稱,但要創建名稱,您必須有一個提交以使其指向。 因此,您通常希望首先獲得他們最新的: git fetch
,然后是第二個 Git 命令。
另外: git pull
意味着運行git fetch
,然后運行第二個 Git command 。 由於需要這兩個命令來做有用的事情,所以像git pull
這樣的人會運行這兩個命令。 我不喜歡git pull
因為我喜歡在這兩個命令之間插入命令,並且可能使用git pull
為第二個命令提供的相對較薄的選擇集以外的東西,但這取決於你。
您需要先告訴 Git 跟蹤遠程存儲庫。 所以你必須做
git remote add origin <url>
接下來你可以告訴 git 只從遠程獲取一個分支
git fetch origin TLA1
然后就可以切換到分支
git checkout TLA1
將遠程添加到本地存儲庫,然后從中獲取。
git remote add REMOTE_NAME REMOTE_URL
git fetch REMOTE_NAME
git checkout -b branch_name REMOTE_NAME/branch_name
最后一個命令從遠程 ref 創建一個本地分支。
然后 git 分支應該顯示:
git branch
LOCAL1
LOCAL2
branch_name
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.