Question

I'm working with dulwich on a project where I need to clone repositories sometimes by commit ID, sometimes by tag, sometimes by branch name. I'm having trouble with the tag case which seems to work for some repositories, but not for others.

Here's the "clone" helper function I wrote:

from dulwich import index
from dulwich.client import get_transport_and_path
from dulwich.repo import Repo


def clone(repo_url, ref, folder):
    is_commit = False
    if not ref.startswith('refs/'):
        is_commit = True
    rep = Repo.init(folder)
    client, relative_path = get_transport_and_path(repo_url)

    remote_refs = client.fetch(relative_path, rep)
    for k, v in remote_refs.iteritems():
        try:
            rep.refs.add_if_new(k, v)
        except:
            pass

    if ref.startswith('refs/tags'):
        ref = rep.ref(ref)
        is_commit = True

    if is_commit:
        rep['HEAD'] = rep.commit(ref)
    else:
        rep['HEAD'] = remote_refs[ref]
    indexfile = rep.index_path()
    tree = rep["HEAD"].tree
    index.build_index_from_tree(rep.path, indexfile, rep.object_store, tree)
    return rep, folder

Oddly, I am able to do

 clone('git://github.com/dotcloud/docker-py', 'refs/tags/0.2.0', '/tmp/a')

But

clone('git://github.com/dotcloud/docker-registry', 'refs/tags/0.6.0', '/tmp/b')

fails with

NotCommitError: object debd567e95df51f8ac91d0bb69ca35037d957ee6
type commit
[...]
 is not a commit

Both refs are tags, so I'm not sure what I'm doing wrong, or why the code behaves differently on both repositories. Would appreciate any help to sort this out!

Était-ce utile?

La solution

refs/tags/0.6.0 is an annotated tag. This means that the ref for it points to a Tag object (which then has a reference to a commit object), rather than directly to a Commit object.

In this line:

if is_commit:
     rep['HEAD'] = rep.commit(ref)
 else:
     rep['HEAD'] = remote_refs[ref]

you probably just want to do something like:

if isinstance(rep[ref], Tag):
     rep['HEAD'] = rep[ref].object[1]
else:
     rep['HEAD'] = rep[ref]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top