tags:

views:

31

answers:

2

I'm trying to get GitPython 0.3 to commit a file to a repository. Roughly, I'm doing this as follows:

data = ...
istream = repo.odb.store(gitdb.IStream(git.Blob.type, len(data), StringIO(data)))
entry = git.BaseIndexEntry((stat.S_IFREG | 0644, istream.binsha, 0, path))
index = git.IndexFile.from_tree(repo, repo.heads['master'])
index.add([entry])
index.commit(commit_message)

With a non-bare repository, this works as expected. Note that I'm never touching the filesystem explicitly, only Git's object database.

With a bare repository, however, this does not work: the IndexFile.add function is decorated with the git_working_dir decorator:

@git_working_dir
def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=None, 
            write=True):
    """Add files from the working tree, specific blobs or BaseIndexEntries
    to the index. 

This decorator tries to chdir to the repo's working_tree_dir, so that path references can be resolved correctly. However, working_tree_dir is not valid for a bare repository, raising an AssertionError.

Does anyone have an idea why this decorator is here? Is it just for path resolving, or is it impossible to create an index in a bare repository? Is this a bug in GitPython, or in my understanding of Git?


Edit: Similarly, the IndexFile.remove function asserts (via the default_index decorator) that we are the default index. Bare repositories certainly don't have a default index, but can they have no index objects at all?

@post_clear_cache
@default_index
def remove(self, items, working_tree=False, **kwargs):
    """Remove the given items from the index and optionally from
    the working tree as well.
A: 

From the API reference:

git.index.util.git_working_dir(func)

Decorator which changes the current working dir to the one of the git repository in order to assure relative paths are handled correctly

Bare Git repositories don't have a working directory, so the add function is getting hung up on this.

However, a bare Git repo also doesn't have an index [1].

mipadi
It doesn't have a *default* index, for sure, because there's no HEAD to create it from. However, I'm not certain that a bare repo cannot contain index objects, per se.
Thomas
A: 

Upon closer inspection of the IndexFile.add function, I realized that I need only very little of its functionality. In fact, just replacing the add call by these two lines does the trick:

index.entries[index.entry_key(entry)] = git.IndexEntry.from_base(entry)
index.write()

I'm still wondering whether this is a good idea, though...

Thomas