5
votes

I tried to clone a repository from git using GitPython in python function. I used GitPython library for cloning from git in my python function and my code snippet as follows:

from git import Repo

Repo.clone_from('http://user:[email protected]/user/project.git', /home/antro/Project/')

It clones from master branch. How do I clone from other branch using GitPython or any other library is available to clone from individual branches? Please let me know.

I am aware of clone by mentioning branch in commandline using

git clone -b branch http://github.com/user/project.git

4
There is no such thing as "cloning from a branch". When you clone, you clone the whole repo. What clone -b does is, after cloning the entire repo, it checks out the specific branch instead of the default branch (which is usually master). So instead of looking for something exotic, why not just do a branch checkout after the clone? - Mark Adelsberger
@MarkAdelsberger "yes, but" git clone --single-branch - Michał Politowski
@MichałPolitowski - Oh, yes. That. I forget about that because it has only ever caused me trouble. Any more I only use the negation of that flag (for making shallow repos that aren't hobbled). Well, I would still take the position that OP probably means just to check out the branch and is conflating terms, since the CLI command specified in the question does clone the whole repo. - Mark Adelsberger
@MarkAdelsberger How to checkout into another branch in python function. and clone -b clones particular branch, it exist - Antony
@Antro - If I knew the python command I'd have posted an answer instead of a comment. And no, clone -b does not clone a particular branch. It checks out a particular branch. - Mark Adelsberger

4 Answers

15
votes

just pass the branch name parameter, e.g. :-

repo = Repo.clone_from(
    'http://user:[email protected]/user/project.git',
    '/home/antro/Project/',
    branch='master'
)

see here for more info

2
votes

From toanant's answer.

This works for me with the --single-branch option

repo = Repo.clone_from(
    'http://user:[email protected]/user/project.git --single-branch',
    '/home/antro/Project/',
    branch='master'
)
0
votes

For --single-branch option, you can just pass a single_branch argument to the Repo.clone_from() method:

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

GitPython uses a keyword args transformation under the hood:

# 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 []

A resulting list of command parts is fed into subprocess.Popen, so you do not want to add --single-branch to the repo URL. If you do, a strange list will be passed to Popen. For example:

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

However, armed with this new information, you can pass any git CLI flags you like just by using the kwargs. You may then ask yourself, "How do I pass in a dash to a keyword like single-branch?" That's a no-go in Python. You will see a dashify function in the above code which transforms any flag from, say, single_branch=True to single-branch, and then to --single-branch.

Full Example:

Here is a useful example for cloning a single, shallow branch using a personal access token from 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,
)

The command list sent to Popen then looks like this:

['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']

(PSA: Please do not actually send your personal tokens as part of the URL before the @.)