[英]How to clone master and checkout another branch in pygit2 without detached HEAD
使用 pygit2 這對我來說很好用:
這對我來說失敗了:
我總是以分離的 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 中有分支branch1
、 branch2
、 branch3
、 main
和xyzzy
,並且您指定-b main
或不指定任何內容而他們推薦他們的main
,則您的 Git 現在正好有一個分支你的倉庫——你的倉庫的克隆——那是名為main
的分支。 你的 Git 創建了這個作為你的main
; 這不是他們的main
。 他們的分支名稱是他們的。
如果您希望將分支命名為fred
、 barney
、 betty
和wilma
而不是它們的名稱,您可以這樣做。 為了防止你的git clone
創建任何分支,你可以在你的git clone
命令中添加-n
選項:現在你得到了他們的所有提交,根本沒有分支,現在你可以選擇一個不匹配的名稱他們的名字。
但是:他們的分支名稱會發生什么變化? 答案是:您的 Git 使用它們的分支名稱,例如branch1
和branch2
以及main
等,並將它們更改為遠程跟蹤名稱。 您的 Git 在這里使用的遠程跟蹤名稱是origin/branch1
、 origin/branch2
、 origin/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
創建你的main
從origin/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.