繁体   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