Question

I'm writing a git wrapper for fuse (linux) to access git repositories like normal files and directories.

Accessing folders and files for branches, tags and commits works quite well but I get a strange behaviour when I commit files.

I do the following styff:

  • create a new Blob from a stream (a temporaney file on the disk)
  • create a new TreeDefinition
  • create a new Tree
  • create a new commit in ObjectDatabase
  • update branch refs to the new commit

After that i update the branch refs, i view ONLY the updated file and nothing else!

Here there is the code

        String referenceName = null;
        IEnumerable<Commit> parentCommit = null;

        // Riposiziona il puntatore dello stream all'inizio
        openedHandle.Stream.Seek(0, SeekOrigin.Begin);

        // Crea il blob
        Blob blob = this.repository.ObjectDatabase.CreateBlob(openedHandle.Stream);

        // Acquisisce la path rimuovendo le prime due parti della path
        List<string> pathParts = new List<string>(openedHandle.Path.Split('/'));
        pathParts.RemoveRange(0, 3);

        // Inserisce il blob in un tree
        TreeDefinition treeDefinition = new TreeDefinition();
        treeDefinition.Add(String.Join("/", pathParts), blob, Mode.NonExecutableFile);
        Tree tree = this.repository.ObjectDatabase.CreateTree(treeDefinition);

        // Inizializza l'autore ed il commiter
        Signature committer = new Signature("My Name", "abc@def.tld", DateTime.Now);
        Signature author = committer;

        // Acquisisce l'elenco dei commits
        switch (openedHandle.PathType)
        {
            case PathType.Branches:
                Branch branch = this.GetBranchByPath(openedHandle.Path);
                referenceName = branch.CanonicalName;
                parentCommit = branch.Commits;
                break;

            default:
                throw new Exception("Can update only branches");
        }

        // Crea il commit
        Commit commit = this.repository.ObjectDatabase.CreateCommit(
            author,
            committer,
            (openedHandle.New ? String.Format("{0} created", openedHandle.Path) : String.Format("{0} updated", openedHandle.Path)) + "\r\n",
            false,
            tree,
            parentCommit);

        // Aggiorna il riferimento del target
        this.repository.Refs.UpdateTarget(this.repository.Refs[referenceName], commit.Id);
Was it helpful?

Solution

TreeDefinition treeDefinition = new TreeDefinition() will create an empty TreeDefinition. As such, when you add a Blob to it, the eventually created Tree will only contain one entry.

The TreeDefinition.From() static helper method may help you here. It will allow one to create a TreeDefinition from the actual content of an existing Commit or Tree.

Standard process would be to build a TreeDefinition from a Commit A, update the TreeDefinition (by adding/removing entries from it), create a Tree from it and eventually a new Commit B which parent will be Commit A.

You can take a peek at this test which show case this exact usage (Note: the test doesn't actually update the HEAD reference to make it point to the newly created commit, but your code does already tackle this).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top