Получить файл, изменить содержимое и зафиксировать с помощью JGit

1

Я пытаюсь написать код, который может извлекать содержимое файла из репозитория, вносить некоторые изменения в содержимое файла и записывать обратно в файл и фиксировать его.

Я смог получить содержимое, но не знаю, как писать содержимое в тот же файл.

Вот код, который я использую

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 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("[email protected]");
    PersonIdent author = new PersonIdent(principal.getLocalID(), principal.getID());
    PersonIdent committer = new PersonIdent("Sample Data", "[email protected]");

    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 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

Теги:
git-commit
jgit

1 ответ

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

Если это не то, что вам нужно, и вы действительно знаете, что делаете, вы можете использовать API нижнего уровня JGit для создания объекта фиксации, как описано здесь.

  • 0
    Привет Херрманн, спасибо за ответ. я отредактировал мой код выше, в котором я пытаюсь использовать вызовы JGit API более низкого уровня. Состояние Git говорит, что файл был обновлен, но когда я открываю файл, ничего не меняется. можешь сказать мне, где я делаю не так
  • 0
    @ user3833055 Почему обычный способ работы в Git (т.е. извлечение, изменение, фиксация) не работает для вас?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню