[英]“git fetch” remote refs of remotes
我希望能夠將所有正在進行的分支從存儲庫移到存儲庫,並能夠刪除舊的分支而不丟失任何提交。 有沒有辦法可以從遠程存儲庫中獲取遠程分支?
# A: Create a repo with two branches
> mkdir a ; cd a ; git init
> echo initial > file_master ; git add file_master ; git commit -am "initial"
> git checkout -b mybranch
> echo test > file_mybranch ; git add file_mybranch ; git commit -am "test"
> git checkout master
# B: Clone
> git clone . ../b ; cd ../b
> git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/mybranch
# if I wanted, I could delete a and checkout remotes/origin/mybranch
# C: Clone of clone, but it's missing mybranch
> git clone . ../c ; cd ../c
> git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
# no remotes/origin/mybranch - it's a remote of origin
# if I delete a and b I lose mybranch for good
>git ls-remote
7505fa4ec342ff85095737d27df0a5062c53d4d5 HEAD
7505fa4ec342ff85095737d27df0a5062c53d4d5 refs/heads/master
7505fa4ec342ff85095737d27df0a5062c53d4d5 refs/remotes/origin/HEAD
7505fa4ec342ff85095737d27df0a5062c53d4d5 refs/remotes/origin/master
dfd057c18baa4227905999b32bffdecf639185f7 refs/remotes/origin/mybranch
# there it is, but I don't have it locally
重申一下,在存儲庫B中,我可以安全地rm -rf ../a
,然后git checkout remotes/origin/mybranch
,我將擁有file_mybranch
。 我想要的是在存儲庫C中進行此提交。 我的問題是: 如何從B將分支的remotes/origin/mybranch
指向的提交放入C ? 可以說我已經刪除了A。
顯然有嚴重的Git命名問題在這里,因為這個問題旅行的人所有的時間 。 根本問題是“分支”一詞令人困惑。 這並不意味着您認為它有用! 另請參見“分支”到底是什么意思?
當您使用git clone <url>
或git clone <path>
或類似方法克隆存儲庫時,您不會獲得上游存儲庫的確切副本。 相反,您會得到一份經過一些故意更改的副本:
origin
,設置為保存原始URL。 git checkout somebranch
的等效git checkout somebranch
。 git clone
這個git checkout
命令的名字取決於一些棘手的事情。 您獲得的特定RTB 集取決於您要克隆的存儲庫中的哪些分支 。 假設您要克隆的存儲庫具有三個實際分支,分別稱為master
, develop
和mybranch
。 這意味着,在克隆不完善的副本中,您將獲得其中三個RTB事物(不是分支),它們分別是origin/master
, origin/develop
和origin/mybranch
。
git checkout
命令將自動創建分支 假設您有一個完全沒有分支的存儲庫,例如git clone
創建的分支之一,並且從一頂帽子中挑選了一個分支名稱,其中包括可能的名稱: master
, develop
和mybranch
。 為了真實起見,讓我們使用Git通常選擇的master
。 您說服git clone
命令將此名稱傳遞給git checkout
:
git checkout master
現在,問題是, 沒有master
分支,因為根本沒有分支。 因此,Git無法將其檢出。 但是,這是第一個棘手的部分,您的Git 可以掃描您所有的實時出價,尋找名稱類似於 master
實時出價。 就是這樣: origin/master
聞起來像master
一樣,Git會在副本中創建一個新的分支,稱為master
,使用origin/master
作為該新分支的哈希ID。
那是git clone
的最后一步:它簽出一些分支,並在此過程中最終創建該分支。 您可以使用-b
選擇哪個分支,但只有一個名稱:您可以讓Git運行git checkout master
,也可以讓Git運行git checkout mybranch
,但不能同時運行它們。 你只有一個!
如果不提供-b
參數,則您的Git會從在另一個Git上看到的完整分支名稱中選擇一個。 它通常采master
,但也有通過其他的Git給你的Git暗示這名挑規則。 最重要的規則是,你的Git會詢問哪些分支已經簽出了其他的Git(或者更准確地說,檢查其HEAD
設置)。
如果使用git clone --mirror
,則將獲得完美的副本。 問題在於,這個完美的副本沒有工作樹:這就是Git所說的“裸”克隆。
這樣做的原因是,這樣的克隆被設置成為一個盲目的復制所有的時間 :每次運行時git fetch
鏡中的克隆,你更新它完全匹配無論是在其他存儲庫。 這意味着您將放棄在任何分支上完成的所有工作,並再次奴隸地匹配另一個存儲庫的分支。 為了確保您不會丟失這種工作,Git會阻止您使用精確副本進行工作。
克隆時,您會得到不完美的副本,Git會簽出一個分支,並通過重命名所有分支來從Git制作的RTB復制該分支。
現在,您可以在其余所有RTB上運行git checkout
,也就是說,除了git clone
已對其運行git checkout
RTB之外的所有RTB。 最簡單的方法是僅對所有名稱運行它:畢竟再次運行git checkout master
並沒有什么壞處。
要提取所有名稱,您可以使用git for-each-ref
(腳本的意思是)或git branch -r
(不是很多)。 您將需要按摩一下名稱以去除origin/
零件,然后運行git checkout
。
(或者,您可以簡單地在需要它們之前就不花心去檢查它們。不要重新克隆不完美的副本:重新克隆原件-假設您仍然有並且可以拿到它。)
如果您仍然有副本,但沒有原始副本,並且想要第二個副本與第一個副本完全相同 (直到擁有相同的分支和相同的實時出價),則需要使用一個或多個技巧,因為未設置Git要做到這一點。 一個訣竅是無論如何都要進行鏡像克隆:
$ git clone --mirror url-of-copy mirror-clone-dir
現在,您具有該副本的完全相同的副本,只是副本本身是一個空克隆。 現在,您可以將其從裸克隆轉換為非裸克隆(例如,請參見如何將裸git存儲庫轉換為普通的(就地)存儲庫? ),但是還應該更新其remote.origin.fetch
設置:
$ cd mirror-clone-dir
$ git config --get remote.origin.fetch
+refs/*:refs/*
$ git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
(然后是其余的轉換)。 或者,您可以從普通克隆開始,然后再運行一個命令:
$ git clone <url-of-copy> new-clone-dir
[the usual messages]
$ cd new-clone-dir
$ git fetch origin '+refs/remotes/origin/*:refs/remotes/origin/*'
請注意,最后一步將用副本的遠程跟蹤分支替換所有現有的遠程跟蹤分支(“ RTB”)。 換句話說,您失去了副本分支的記憶,將Git的“我在url副本中看到的內容”替換為“我從url副本中獲得的內容, 它們已被列為它們的內存”。記住他們在原始作品中看到的內容 。”
從字面上看,您不能同時獲得兩者,至少不能使用這些實時出價工具:要么擁有分支並記住他們的分支,要么擁有分支並記住他們對別人分支的記憶。 但是,您確實還有一些其他選擇:
如果真正的原件仍然存在,請將其添加為第二個遙控器,然后從中獲取:
$ git remote add real-source <url> $ git fetch real-source
現在您不僅擁有origin/master
而且擁有real-source/master
。
如果不是這樣,則將副本添加為第二個遠程對象(在相同的存儲庫中使用兩個名稱沒有什么害處),然后使用相同的git fetch
技巧從副本中填充其他RTB集:
$ git remote add r2 <url-of-copy> $ git fetch r2 '+refs/remotes/origin/*:refs/remotes/r2/*'
現在,您有兩個遠程origin/master
: origin/master
記住“在來源上看到的master
,重命名為origin/master
”,而r2/master
記住“在r2上看到的origin / master(與URL相同的URL),重命名為r2/master
”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.