簡體   English   中英

如何從遠程存儲庫正確簽出分支

[英]How to correctly checkout branches from a remote repository

我有這個

    abc@abc-ubuntu:~/project1/wh-app-ios$ git branch -a -v -v
    * master                   1d35af1 [origin/master: ahead 2] Adding 123 to hello
      remotes/gitb/gh-pages    e3dad9d boom
      remotes/gitb/integration 1d3fcd5 Adding 55_Glossary chapter
      remotes/gitb/master      86d1d30 Merge remote-tracking branch 'origin/master'
      remotes/gitb/pt_BR       dc9d991 Revisions at 03, 07, 08, 09, 10, 11 and 50
      remotes/origin/HEAD      -> origin/master
      remotes/origin/master    1ae426b Update README.md

我做

    abc@abc-ubuntu:~/project1/wh-app-ios$ git checkout gitb/master
    Note: checking out 'gitb/master'.

    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.

    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:

      git checkout -b new_branch_name

    HEAD is now at 86d1d30... Merge remote-tracking branch 'origin/master'

然后看我上面的警告消息

    abc@abc-ubuntu:~/project1/wh-app-ios$ git checkout -b mastergitb
    Switched to a new branch 'mastergitb'

現在我在

    abc@abc-ubuntu:~/project1/wh-app-ios$ git branch -a -v -v
      master                   1d35af1 [origin/master: ahead 2] Adding 123 to hello
    * mastergitb               86d1d30 Merge remote-tracking branch 'origin/master'
      remotes/gitb/gh-pages    e3dad9d boom
      remotes/gitb/integration 1d3fcd5 Adding 55_Glossary chapter
      remotes/gitb/master      86d1d30 Merge remote-tracking branch 'origin/master'
      remotes/gitb/pt_BR       dc9d991 Revisions at 03, 07, 08, 09, 10, 11 and 50
      remotes/origin/HEAD      -> origin/master
      remotes/origin/master    1ae426b Update README.md
    abc@abc-ubuntu:~/project1/wh-app-ios$ 

題:

  1. 但顯然mastergitb不會跟蹤gitb / master。 這是為什么 ?

  2. 我是否只是創建了一個名為mastergitb的本地分支,該分支只是gitb / master的副本,但沒有其他關系?

我不確定為什么該消息沒有提及此內容,但是您可以寫

git checkout -t origin/branchname

創建一個名為branchname的本地分支,該分支跟蹤origin/branchname分支名稱( -t--track )。 或者你可以寫

git checkout -b localname -t origin/branchname

創建一個名為localname的本地分支,該分支跟蹤origin/branchname ,因此在您的示例中:

git checkout -b mastergitb -t gitb/master

是的,創建非跟蹤分支正是您所做的。 您可以通過刪除分支並按照以下說明進行修復,或者通過運行git branch --set-upstream mastergitb gitb/master來設置現有分支的上游。

git稱它們為“遠程分支”,這與“本地”分支有很大不同。 我有時認為,如果git使用其他名稱,對人們來說可能更有意義,盡管我實際上沒有更好的名稱。 因此,關於問題2:

我是否只是創建了一個名為mastergitb的本地分支,該分支只是gitb/master的副本,但沒有其他關系?

是的,但是短語“的副本”有點誤導。 假設您創建了一個本地分支, 分支與遠程分支的提交相同

關於git分支要記住的一點是,每個分支名稱都只是提交標簽 使本地分支名稱特別特別(且有用)的原因是它是一個移動標簽,並且會自動移動。 (與“標簽”比較,后者也是特定提交的標簽,但是標簽不會自動移動,人們通常希望它們保持原狀。如果您移動了標簽。)

當您處於“分支”上時(而不是有人提到的“分離的HEAD”有點令人討厭),當您進行新提交時,分支標簽會自動移至新提交。 也就是說,當HEAD是分支bran的名稱時, git commit (以及git merge和其他添加提交的其他方式)將添加新提交,其父指向先前的分支提示,然后移動分支-提示:

C5 -- C6 -- C7   <-- HEAD=bran

變成:

C5 -- C6 -- C7 -- C8   <-- HEAD=bran

但是“遠程分支”卻不能這樣工作。 實際上,您甚至不能像在遠程分支上一樣“發現”:如果git checkout origin/master ,git會將您置於“分離的HEAD”狀態。

但是,另一個有趣的事情是“遠程分支機構” 可以而且確實可以移動 添加提交時,它們不會移動,因為您永遠不會“啟用”它們。 您檢查了一下,馬上就斷頭了。 :-)然后,您可以像使用git checkout -b創建本地分支一樣。 此本地分支設置為指向HEAD命名的提交,這與“遠程分支名稱”所指向的提交相同。 它不是任何東西的副本,因為它只是指向提交的箭頭。

在圖表形式中,它可能看起來像這樣(假設您在“跟蹤” origin/master的本地master上):

       C2        <-- origin/xyz
      /
C0--C1           <-- origin/foo
      \
       C3--C4    <-- origin/bar
         \
          C5     <-- origin/master, HEAD=master

如果您使用git checkout origin/foo ,則git將從底部擦除HEAD= (保留origin/mastermaster都指向提交C5 ),並將HEAD設置為SHA-1哈希以提交C1 它不會設置HEAD=origin/foo (這會使您“在”遠程分支上),而是直接設置為提交哈希(“分離頭”狀態)。

然后,當您git checkout -b localfoo ,git創建一個新的分支名稱localfoo ,將其設置為指向提交C1 ,並設置HEAD=localfoo 現在您“在樹枝上”!

注意:本地分支bran全名是refs/heads/ bran / bran is refs/remotes/ / bran . 遠程分支 / bran的“全名”是refs/remotes/ / bran 也就是說,本地分支始終位於refs/heads/ ,而遠程分支則永遠refs/heads/ 通常,您不考慮所有前端內容,而僅引用branorigin/bran ,但這有時很重要,這使得下面的一些內容更有意義。

除了使localfoo成為“ track”的origin/foo (已經回答)之外,還有另外一項要說明的項目,那就是:“遠程分支”究竟如何移動? 答案是:它們繼續進行git fetch (或git remote update ,它與fetch基本相同)。 當您從遠程獲取(或更新)時,git會聯系該遠程並找到其分支名稱。 使用這些名稱,它找到它們指向的提交。 然后找到父母,以及父母的父母,依此類推。 每當您沒有這些提交時,它就會將它們帶到並塞入您的存儲庫中,以便您“追上”遠程。 然后,它將新引用名稱.git/config文件控制的“遠程分支”類別.git/config

如果您瀏覽.git/config您將看到類似以下內容:

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = ssh://some.where.out.there/some/path/to/repo.git

那條fetch線是獲得“遠程分支”的關鍵。 它說,對於遠程服務器具有的與refs/heads/*匹配的所有內容( 所有本地分支),將refs/heads/替換為refs/remotes/origin/ (保留分支的其余名稱),然后更新這些refs(強制,因為有+號)。 因此,在控制了遠程URL的某人更新了該回購,然后從他們那里fetch信息之后,您便得到了他們的更新,而git則移動了“ remote branch”標簽以進行匹配。

由您決定是否以及何時移動本地分支標簽以匹配自動移動的“遠程分支”標簽。 最簡單的方法是使用“ git merge”,而自動化的簡單方法是使本地分支成為“ tracking branch”。 一旦將本地分支L標記為跟蹤遠程分支rmt / Rgit status就會告訴您它是否在后面, git pull將知道如何調用git merge ,並且可以告訴git merge自動更新(請參閱merge.defaultToUpstream git-merge文檔的CONFIGURATION部分中的merge.defaultToUpstream )。

暫無
暫無

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

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