pythonpython-3.xgitgitpythondulwich

Working with branches in Dulwich (access objects / checkout)


I have a problem with Dulwich (switched to it from GitPython because of the well-known Windows bug with opened files in .git folder).

I'm trying to get a file from another branch of currently opened repo (its state from last commit). In GitPython this task can be solved in nice and easy manner:

file_object = repo.heads[BRANCH].commit.tree[FILENAME]

But I didn't found any comfortable way to deal with branches in Dulwich.

While writing this question I've found a get_refs method which returns dictionary with all refs and the commits they're pointed. Now I think I can get SHA of the last commit but the refs are very unfriendly to work with - I need to use such form to get a commit:

commit_id = repo.get_refs()[b"refs/heads/develop"]

After that I can get my file in this way:

    tree_path = porcelain.path_to_tree_path(REPO_ROOT, os.path.join(REPO_ROOT, FILENAME))
    _, object_sha = tree_lookup_path(repo.get_object, repo[commit_id].tree, tree_path)
    file_object = repo[object_sha].data

Is there a proper (more "pythonic"/"gitonic") way to get the needed version of a file without checking out a branch fully? Some staged/unstaged files can be stored in repo at the moment of program running and I suppose they will interrupt the checkout process.
Now the main problem for me is the need to "pack" usual branch name to "refs/heads/" form.
And if there is no more accurate way to get this information - I hope my question may help someone in future :)

Python: 3.6.1
Dulwich: 0.19.6


Solution

  • In recent versions of dulwich, you can use get_object_by_path (from dulwich.porcelain):

    print get_object_by_path(x, "some/file/path", "somebranch").data
    

    In older versions the shortest way to do this is (where x is a repository)::

    mode, object_sha = tree_lookup_path(
          x.__getitem__, x['refs/heads/master'].tree, 'some/file/path')
    x[object_sha].data