简体   繁体   中英

Fetch file, modify contents, and commit with JGit

I am trying to write code which can fetch file contents from repository, make some changes to file contents and write back to file and commit it.

I was able to get contents, but have no clue on how to write contents to the same file.

Here is the code which I am using

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));
    }
}

I am trying to checkout my file:

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();

which throws InvalidPathException

The designated way to modify files in Git is to checkout a commit into the work directory, change the file and then add it to the index and commit the changes.

In JGit this roughly looks like this:

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();

If that's not what you want and you really know what you are doing , you can use the lower-level JGit API to compose a commit object as described here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM