获取文件,修改内容并使用JGit进行提交

时间:2015-03-19 16:10:37

标签: 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));
    }
}

我正在尝试查看我的文件:

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

1 个答案:

答案 0 :(得分:1)

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

在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