JGit:是否有一种线程安全的方式来添加和更新文件

时间:2013-05-17 12:34:01

标签: multithreading git jgit

在JGit中添加或更新文件的简便方法如下:

  git.add().addFilepattern(file).call()

但是假设该文件存在于Git工作目录中。 如果我有一个多线程设置(使用Scala和Akka),有没有办法只在裸存储库上工作,直接将数据写入JGit,避免必须首先在工作目录中写入文件?

要获取文件,这似乎适用于:

  git.getRepository().open(objId).getBytes()

是否有类似添加或更新文件的内容?

1 个答案:

答案 0 :(得分:3)

“添加”是一种将文件放在索引中的高级抽象。在裸存储库中,您缺少索引,因此这不是功能之间的1:1对应关系。相反,您可以在新提交中创建文件。为此,您将使用ObjectInserter将对象添加到存储库(请每个线程一个)。然后你会:

  1. 通过插入字节(或提供InputStream),将文件内容作为blob添加到存储库。

  2. 使用TreeFormatter创建包含新文件的树。

  3. 使用CommitBuilder创建指向树的提交。

  4. 例如,要创建一个仅包含 文件的新提交(没有父级):

    ObjectInserter repoInserter = repository.newObjectInserter();
    ObjectId blobId;
    
    try
    {
        // Add a blob to the repository
        ObjectId blobId = repoInserter.insert(OBJ_BLOB, "Hello World!\n".getBytes());
    
        // Create a tree that contains the blob as file "hello.txt"
        TreeFormatter treeFormatter = new TreeFormatter();
        treeFormatter.append("hello.txt", FileMode.TYPE_FILE, blobId);
        ObjectId treeId = treeFormatter.insertTo(repoInserter);
    
        // Create a commit that contains this tree
        CommitBuilder commit = new CommitBuilder();
        PersonIdent ident = new PersonIdent("Me", "me@example.com");
        commit.setCommitter(ident);
        commit.setAuthor(ident);
        commit.setMessage("This is a new commit!");
        commit.setTreeId(treeId);
    
        ObjectId commitId = repositoryInserter.insert(commit);
    
        repoInserter.flush();
    }
    finally
    {
        repoInserter.release();
    }
    

    现在您可以git checkout将提交ID返回为commitId