如何使用Gitpython从特定分支克隆Git仓库

13

2
没有所谓的“从分支克隆”。当你克隆时,你会克隆整个仓库。clone -b 的作用是,在克隆整个仓库后,检出特定的分支而不是默认分支(通常为master)。所以,为什么不在克隆后直接进行分支检出,而要寻找一些奇怪的东西呢? - Mark Adelsberger
@MarkAdelsberger "是的,但是" git clone --single-branch - Michał Politowski
@MichałPolitowski - 哦,是的。那个。我忘了它,因为它只会给我带来麻烦。现在我只使用该标志的否定形式(用于创建不受限制的浅层存储库)。好吧,我仍然认为OP 可能只是想检出分支,并混淆了术语,因为问题中指定的CLI命令确实克隆了整个存储库。 - Mark Adelsberger
@MarkAdelsberger 如何在Python函数中切换到另一个分支。而且 clone -b 可以克隆特定的分支,如果存在的话。 - Antony
1
@Antro - 如果我知道Python命令,我会发布答案而不是评论。而且,clone -b并没有克隆特定的分支,它只是检出特定的分支。 - Mark Adelsberger
@MarkAdelsberger 我对git不是很了解。对于我可能造成的任何误解,非常抱歉。感谢您的澄清。 - Antony
4个回答

25

只需传递分支名称参数,例如:-

repo = Repo.clone_from(
    'http://user:password@github.com/user/project.git',
    '/home/antro/Project/',
    branch='master'
)

了解更多信息,请点击此处


1
如何添加“--single-branch”选项? - Lei Yang

3

以下是来自toanant的回答:

这对我来说有效,使用--single-branch选项。

repo = Repo.clone_from(
    'http://user:password@github.com/user/project.git --single-branch',
    '/home/antro/Project/',
    branch='master'
)

3

GitPython 在内部使用关键字参数转换:

# cmd.py
def transform_kwarg(self, name: str, value: Any, split_single_char_options: bool) -> List[str]:
    if len(name) == 1:
        if value is True:
            return ["-%s" % name]
        elif value not in (False, None):
            if split_single_char_options:
                return ["-%s" % name, "%s" % value]
            else:
                return ["-%s%s" % (name, value)]
    else:
        if value is True:
            return ["--%s" % dashify(name)]
        elif value is not False and value is not None:
            return ["--%s=%s" % (dashify(name), value)]
    return []

生成的命令部分列表将被传递给subprocess.Popen,因此您不需要在repo URL中添加--single-branch。如果添加了该参数,将会向Popen传递一个奇怪的列表。例如:

['-v', '--branch=my-branch', 'https://github.com/me/my-project.git --single-branch', '/tmp/clone/here']

然而,有了这个新信息,你可以通过使用kwargs传递任何你喜欢的gitCLI flags。你可能会问自己,“如何将破折号传递给像single-branch这样的关键字?”在Python中是不行的。你将在上面的代码中看到一个dashify函数,它将任何标志从single_branch=True转换为single-branch,然后转换为--single-branch

完整示例:

以下是一个有用的示例,使用GitHub的个人访问令牌克隆单个浅层分支:

repo_url = "https://github.com/me/private-project.git"
branch = "wip-branch"
# Notice the trailing : below
credentials = base64.b64encode(f"{GHE_TOKEN}:".encode("latin-1")).decode("latin-1")
Repo.clone_from(
    url=repo_url,
    c=f"http.{repo_url}/.extraheader=AUTHORIZATION: basic {credentials}",
    single_branch=True,
    depth=1,
    to_path=f"/clone/to/here",
    branch=branch,
)

Popen接收到的命令列表如下:

['git', 'clone', '-v', '-c', 'http.https://github.com/me/private-project.git/.extraheader=AUTHORIZATION: basic XTE...UwNTo=', '--single-branch', '--depth=1', '--bare', '--branch=wip-branch', 'https://github.com/me/private-project.git', '/clone/to/here']

(提示:请不要将您的个人令牌作为URL的一部分发送,@符号之前。)

谢谢你提供的示例和解释。我想了解为什么要执行 credentials = base64.b64encode(f"{GHE_TOKEN}:".encode("latin-1")).decode("latin-1") - cybervedaa
1
啊,如果我没记错的话,b64encode 的结果是字节。RFC 规范要求授权头使用 latin-1(ascii)编码。因此,我首先将令牌编码为 latin-1,以确保它可以正确解码,然后运行 base64 以获取字节,最后将其解码回 ascii,以确保 HTTP 标头接受它。第一个 latin-1 可能可以跳过,但它是用户输入,所以狡猾的、不可见的 UTF-8 空格可能会进入令牌。有些人会给他们的代码/字符串加水印或添加不可见字符来尝试缓冲区溢出,所以我也养成了防御性编程的习惯。好问题。 - Drakes

0

对于--single-branch选项,您只需将single_branch参数传递给Repo.clone_from()方法:

Repo.clone_from(repo, path, single_branch=True, b='branch')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接