Search code examples
gitgitpython

Can a bare repository have an index? Is this a bug?


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.

Solution

  • 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...