[英]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.