java - 使用 JGit 获取文件、修改内容并提交

标签 java git git-commit jgit

我正在尝试编写可以从存储库获取文件内容、对文件内容进行一些更改、写回文件并提交的代码。

我能够获取内容,但不知道如何将内容写入同一文件。

这是我正在使用的代码

public void test() {
    String filename = "test.txt";
    Repository repository = openRepository();
    try {
        ObjectId lastCommitId = repository.resolve(Constants.HEAD);
         RevWalk revWalk = new RevWalk(repository);
            RevCommit commit = revWalk.parseCommit(lastCommitId);
            // and using commit's tree find the path
            RevTree tree = commit.getTree();

            // Here i was able to get data using reader
            ObjectReader reader = repository.newObjectReader();
            ObjectInserter writer = repository.newObjectInserter();
            String data = null;
            try {

                commitNewData(filename, "Hello");
            } catch (GitAPIException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            finally {
                reader.release();
            }

            revWalk.dispose();

            repository.close();


    } catch (RevisionSyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (AmbiguousObjectException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IncorrectObjectTypeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public Repository openRepository(){
    try{
        Repository repository = new FileRepository("c:\\gitest\\.git");
        return repository;
    }catch(Exception e){

    }
    return null;
}

public void commitNewData(String filename, String data) throws IOException, ConcurrentRefUpdateException {
    Repository repository = openRepository();
    ObjectInserter inserter = repository.newObjectInserter();

    PrincipalID principal = new PrincipalID("me@test.com");
    PersonIdent author = new PersonIdent(principal.getLocalID(), principal.getID());
    PersonIdent committer = new PersonIdent("Sample Data", "raviteja.bellam@msci.com");

    try {
        // get head commit
        ObjectId lastCommitId = repository.resolve(Constants.HEAD + "^{commit}");

        // Get bytes
        byte[] bytes = data.getBytes(Charset.forName("UTF-8"));
        System.out.printf("Data: %s", data);

        // Create new object hash
        ObjectId resultObjectId = inserter.insert(Constants.OBJ_BLOB, bytes);
        System.out.printf("BlobId: %s", resultObjectId.toString());

        // create tree
        TreeFormatter treeFormatter = new TreeFormatter();
        treeFormatter.append(filename, FileMode.REGULAR_FILE, resultObjectId);
        // add existing entries to the tree
        addExistingEntriesToTree(repository, lastCommitId, treeFormatter);
        ObjectId treeId = treeFormatter.insertTo(inserter);
        System.out.printf("TreeId: %s", treeId.toString());

        // insert tree to the commit
        CommitBuilder builder = new CommitBuilder();
        builder.setParentId(lastCommitId);
        builder.setCommitter(committer);
        builder.setAuthor(author);
        builder.setTreeId(treeId);
        builder.setMessage(String.format("Updated %s", filename));
        ObjectId commitId = null;
        // insert commit
        try{
            commitId = inserter.insert(builder);
        }catch(Exception e){
            System.out.println(e);
        }

        System.out.printf("CommitId: %s", commitId.toString());

        // update the ref
        RevWalk rw = new RevWalk(repository);
        RevCommit revCommit = rw.parseCommit(commitId);
        RefUpdate ru = repository.updateRef(Constants.HEAD);
        ru.setNewObjectId(commitId);
        ru.setRefLogMessage(String.format("commit: %s", revCommit.getShortMessage()), false);
        ru.setExpectedOldObjectId(lastCommitId);
        RefUpdate.Result rc = ru.forceUpdate();
        RepositoryState state = repository.getRepositoryState();
        switch (rc) {
            case NEW:
            case FORCED:
            case FAST_FORWARD: {
                if (state == RepositoryState.MERGING_RESOLVED) {
                    // Commit was successful. Now delete the files
                    // used for merge commits
                    repository.writeMergeCommitMsg(null);
                    repository.writeMergeHeads(null);
                } else if (state == RepositoryState.CHERRY_PICKING_RESOLVED) {
                    repository.writeMergeCommitMsg(null);
                    repository.writeCherryPickHead(null);
                } else if (state == RepositoryState.REVERTING_RESOLVED) {
                    repository.writeMergeCommitMsg(null);
                    repository.writeRevertHead(null);
                }
                break;
                //return revCommit;
            }
            case REJECTED:
            case LOCK_FAILURE:
                throw new ConcurrentRefUpdateException(
                        JGitText.get().couldNotLockHEAD, ru.getRef(),
                        rc);
            default:
                throw new JGitInternalException(MessageFormat.format(
                        JGitText.get().updatingRefFailed,
                        Constants.HEAD, commitId.toString(), rc));
        } 


        inserter.flush();
    } finally {
        inserter.release();
    }
}

protected void addExistingEntriesToTree(Repository repository, ObjectId lastCommitId, TreeFormatter treeFormatter) throws IOException {
    RevWalk revWalk = new RevWalk(repository);
    // get last commit
    RevCommit commit = revWalk.parseCommit(lastCommitId);
    // get it's tree
    RevTree tree = commit.getTree();

    // now walk the tree
    TreeWalk treeWalk = new TreeWalk(repository);
    treeWalk.addTree(tree);
    //treeWalk.setRecursive(true);
    while (treeWalk.next()) {
        treeFormatter.append(treeWalk.getNameString(), treeWalk.getFileMode(0), treeWalk.getObjectId(0));
    }
}

我正在尝试 checkout 我的文件:

Repository repository = new FileRepository("c:\\Users\\gitest\\.git");
Git git = new Git(repository);
CheckoutCommand checkout = git.checkout();
        //checkout.addPath("test.txt");
checkout.setName("master");
        //checkout.setName("test.txt");
Ref ref = checkout.call();

抛出InvalidPathException

最佳答案

在 Git 中修改文件的指定方法是将提交 check out 到工作目录中,更改文件,然后将其添加到索引并提交更改。

在 JGit 中,大致如下所示:

Git git = new Git( repository );
git.checkout().setName( <commit-id> ).call(); // likely already done
// modify file
git.add().addFilepattern( "/repo-relative/path/to/file" ).call();
git.commit().setMessage( "Modify file" ).call();

如果这不是您想要的,并且您确实知道自己在做什么,您可以使用较低级别的 JGit API 来组成提交对象 as described here .

关于java - 使用 JGit 获取文件、修改内容并提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29149653/

相关文章:

git - 如何检查提交的 child ?

GIT:我是否需要在 checkout 另一个分支之前提交我的分支,那么存储呢?

java - 通过派生类访问Java中定义的静态内部类

java - 使用扫描仪时出现意外的线条打印

ruby - 混帐 & ruby : How can I unset the GIT_DIR variable from inside a ruby script?

Git Clone 在 OS X Yosemite 上因 sslRead() 错误而失败

Git 提交不会覆盖 git blame 中的原始作者

java - 为什么在 Java 7 中没有正确设置文件写入权限?

java - 替换 Java 中过时的 Hashtable 类

php - 我的公司是 Rackspace Cloud 客户端(免费提供给我们),我正在尝试找到一些设置版本控制的方法