簡體   English   中英

如何在不分離 HEAD 的情況下克隆 master 並在 pygit2 中簽出另一個分支

[英]How to clone master and checkout another branch in pygit2 without detached HEAD

使用 pygit2 這對我來說很好用:

  1. 克隆 repo 的 master 分支
  2. 創建一個分支
  3. 做一些改變
  4. 將分支推送到原點

這對我來說失敗了:

  1. 克隆 repo 的 master 分支
  2. 簽出現有分支

我總是以分離的 HEAD 結束。 在沒有分離 HEAD 的情況下進行結賬有什么技巧嗎? 我現在已經花了一天多的時間,我知道必須有一種方法可以正確地做到這一點,但是我在網上看到的每個例子都在做我在下面做的事情......

這是我的精簡測試用例,每次嘗試的每個分支都失敗:

repo = pygit2.clone_repository(url,dir,bare=False,checkout_branch="master",callbacks=RemoteCallbacks())
checkout_branch = repo.branches["origin/{0}".format(branch))
ref = repo.lookup_reference(checkout_branch.name)
repo.checkout(ref)

雖然 pygit2 可能會帶來額外的麻煩,但從這個事實開始:當你克隆一個存儲庫時,你首先得到所有其他 Git 的提交,而不是它的分支 然后,就在命令行git clone命令向您返回提示之前,它根據您提供的-b參數為您創建一個分支 如果你沒有提供-b參數,它——你自己的 Git——會詢問另一個Git他們推薦的分支名稱,並根據該名稱創建一個分支。

結果是,如果他們他們的Git 中有分支branch1branch2branch3mainxyzzy ,並且您指定-b main或不指定任何內容而他們推薦他們的main ,則您的 Git 現在正好有一個分支你的倉庫——你倉庫的克隆——那是名為main的分支。 你的 Git 創建了這個作為你的main 這不是他們的main 他們的分支名稱是他們的

如果您希望將分支命名為fredbarneybettywilma而不是它們的名稱,您可以這樣做。 為了防止你的git clone創建任何分支,你可以在你的git clone命令中添加-n選項:現在你得到了他們的所有提交,根本沒有分支,現在你可以選擇一個不匹配的名稱他們的名字。

但是:他們的分支名稱會發生​​什么變化? 答案是:您的 Git 使用它們的分支名稱,例如branch1branch2以及main等,並將它們更改為遠程跟蹤名稱 您的 Git 在這里使用的遠程跟蹤名稱是origin/branch1origin/branch2origin/main等。

這些遠程跟蹤名稱與其分支名稱相匹配,並帶有明顯的替換。 但它們不是分支名稱。 它們是遠程跟蹤名稱。 有什么不同? 這就是你看到的那個分離的 HEAD 使用遠程跟蹤名稱意味着我不打算進行任何新的提交 使用分支名稱意味着我確實打算進行新的提交 如果您打算進行新的提交,您應該使用分支名稱,而不是遠程跟蹤名稱。

一般來說,這可能意味着您必須要求您的 Git 在您自己的本地存儲庫中創建一個新的分支名稱 你是怎樣做的? 好吧,在復雜的設置中這一切都會變得有點復雜,但我們從這個開始:檢查分支名稱X 的請求,對於任何X ,如果沒有名為X 的分支,則無法繼續......所以如果你的 Git 這樣做沒有一個X呢,你的Git會先檢查,看看你有origin/ X ,如果是的話,你的Git會從你創建X origin/ X Git 將此稱為“DWIM 模式”,意思是“按我的意思做(不是我說的)”。 git checkout命令有一個新標志--no-guess ,以禁用這種猜測你的意思。 使用:

git checkout --no-guess branch1

在抱怨沒有branch1可以檢查之前,不會查看您是否有origin/branch1 默認是先檢查:沒有branch1嗎? 檢查origin/branch1 ,如果是這樣,創建branch1使用origin/branch1 ,以同樣的方式git clone創建你的mainorigin/main ,你從他們的Git的有main

這有點迂回,但在大多數情況下,對於大多數用戶來說,它往往效果很好。 只要他們不運行git checkout origin/branch1 ,就是這樣。

我想我已經通過在運行結帳之前添加以下內容解決了這個問題。 這假設您要簽出遠程已存在的分支:

if not checkout_branch in repo.branches.local:
    remote_branch = "origin/" + checkout_branch
    if not remote_branch in repo.branches.remote:
        # handle a fatal error here
        pass
    (commit, reference) = repo.resolve_refish(remote_branch)
    repo.create_reference("refs/heads/" + checkout_branch,commit.hex)

暫無
暫無

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

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