Search in sources :

Example 46 with RevTree

use of org.eclipse.jgit.revwalk.RevTree in project gerrit by GerritCodeReview.

the class VersionedMetaData method openUpdate.

/**
 * Open a batch of updates to the same metadata ref.
 *
 * <p>This allows making multiple commits to a single metadata ref, at the end of which is a
 * single ref update. For batching together updates to multiple refs (each consisting of one or
 * more commits against their respective refs), create the {@link MetaDataUpdate} with a {@link
 * BatchRefUpdate}.
 *
 * <p>A ref update produced by this {@link BatchMetaDataUpdate} is only committed if there is no
 * associated {@link BatchRefUpdate}. As a result, the configured ref updated event is not fired
 * if there is an associated batch.
 *
 * <p>If object inserter, reader and revwalk are provided, then the updates are not flushed,
 * allowing callers the flexibility to flush only once after several updates.
 *
 * @param update helper info about the update.
 * @param objInserter Shared object inserter.
 * @param objReader Shared object reader.
 * @param revWalk Shared rev walk.
 * @throws IOException if the update failed.
 */
public BatchMetaDataUpdate openUpdate(MetaDataUpdate update, ObjectInserter objInserter, ObjectReader objReader, RevWalk revWalk) throws IOException {
    final Repository db = update.getRepository();
    inserter = objInserter == null ? db.newObjectInserter() : objInserter;
    reader = objReader == null ? inserter.newReader() : objReader;
    final RevWalk rw = revWalk == null ? new RevWalk(reader) : revWalk;
    final RevTree tree = revision != null ? rw.parseTree(revision) : null;
    newTree = readTree(tree);
    return new BatchMetaDataUpdate() {

        RevCommit src = revision;

        AnyObjectId srcTree = tree;

        @Override
        public void write(CommitBuilder commit) throws IOException {
            write(VersionedMetaData.this, commit);
        }

        private boolean doSave(VersionedMetaData config, CommitBuilder commit) throws IOException {
            DirCache nt = config.newTree;
            ObjectReader r = config.reader;
            ObjectInserter i = config.inserter;
            RevCommit c = config.revision;
            try {
                config.newTree = newTree;
                config.reader = reader;
                config.inserter = inserter;
                config.revision = src;
                return config.onSave(commit);
            } catch (ConfigInvalidException e) {
                throw new IOException("Cannot update " + getRefName() + " in " + db.getDirectory() + ": " + e.getMessage(), e);
            } finally {
                config.newTree = nt;
                config.reader = r;
                config.inserter = i;
                config.revision = c;
            }
        }

        @Override
        public void write(VersionedMetaData config, CommitBuilder commit) throws IOException {
            checkSameRef(config);
            if (!doSave(config, commit)) {
                return;
            }
            ObjectId res = newTree.writeTree(inserter);
            if (res.equals(srcTree) && !update.allowEmpty() && (commit.getTreeId() == null)) {
                // If there are no changes to the content, don't create the commit.
                return;
            }
            // the tree for the updated DirCache.
            if (commit.getTreeId() == null) {
                commit.setTreeId(res);
            } else {
                // In this case, the caller populated the tree without using DirCache.
                res = commit.getTreeId();
            }
            if (src != null) {
                commit.addParentId(src);
            }
            if (update.insertChangeId()) {
                commit.setMessage(ChangeIdUtil.insertId(commit.getMessage(), CommitMessageUtil.generateChangeId()));
            }
            src = rw.parseCommit(inserter.insert(commit));
            srcTree = res;
        }

        private void checkSameRef(VersionedMetaData other) {
            String thisRef = VersionedMetaData.this.getRefName();
            String otherRef = other.getRefName();
            checkArgument(otherRef.equals(thisRef), "cannot add %s for %s to %s on %s", other.getClass().getSimpleName(), otherRef, BatchMetaDataUpdate.class.getSimpleName(), thisRef);
        }

        @Override
        public RevCommit createRef(String refName) throws IOException {
            if (Objects.equals(src, revision)) {
                return revision;
            }
            return updateRef(ObjectId.zeroId(), src, refName);
        }

        @Override
        public RevCommit commit() throws IOException {
            return commitAt(revision);
        }

        @Override
        public RevCommit commitAt(ObjectId expected) throws IOException {
            if (Objects.equals(src, expected)) {
                return revision;
            }
            return updateRef(MoreObjects.firstNonNull(expected, ObjectId.zeroId()), src, getRefName());
        }

        @Override
        public void close() {
            newTree = null;
            if (revWalk == null) {
                rw.close();
            }
            if (objInserter == null && inserter != null) {
                inserter.close();
                inserter = null;
            }
            if (objReader == null && reader != null) {
                reader.close();
                reader = null;
            }
        }

        private RevCommit updateRef(AnyObjectId oldId, AnyObjectId newId, String refName) throws IOException {
            BatchRefUpdate bru = update.getBatch();
            if (bru != null) {
                bru.addCommand(new ReceiveCommand(oldId.toObjectId(), newId.toObjectId(), refName));
                if (objInserter == null) {
                    inserter.flush();
                }
                revision = rw.parseCommit(newId);
                return revision;
            }
            RefUpdate ru = db.updateRef(refName);
            ru.setExpectedOldObjectId(oldId);
            ru.setNewObjectId(newId);
            ru.setRefLogIdent(update.getCommitBuilder().getAuthor());
            String message = update.getCommitBuilder().getMessage();
            if (message == null) {
                message = "meta data update";
            }
            try (BufferedReader reader = new BufferedReader(new StringReader(message))) {
                // read the subject line and use it as reflog message
                ru.setRefLogMessage("commit: " + reader.readLine(), true);
            }
            logger.atFine().log("Saving commit '%s' on project '%s'", message.trim(), projectName);
            inserter.flush();
            RefUpdate.Result result = ru.update();
            switch(result) {
                case NEW:
                case FAST_FORWARD:
                    revision = rw.parseCommit(ru.getNewObjectId());
                    update.fireGitRefUpdatedEvent(ru);
                    logger.atFine().log("Saved commit '%s' as revision '%s' on project '%s'", message.trim(), revision.name(), projectName);
                    return revision;
                case LOCK_FAILURE:
                    throw new LockFailureException(errorMsg(ru, db.getDirectory()), ru);
                case FORCED:
                case IO_FAILURE:
                case NOT_ATTEMPTED:
                case NO_CHANGE:
                case REJECTED:
                case REJECTED_CURRENT_BRANCH:
                case RENAMED:
                case REJECTED_MISSING_OBJECT:
                case REJECTED_OTHER_REASON:
                default:
                    throw new GitUpdateFailureException(errorMsg(ru, db.getDirectory()), ru);
            }
        }
    };
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) GitUpdateFailureException(com.google.gerrit.git.GitUpdateFailureException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) LockFailureException(com.google.gerrit.git.LockFailureException) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) DirCache(org.eclipse.jgit.dircache.DirCache) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) BufferedReader(java.io.BufferedReader) StringReader(java.io.StringReader) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevTree(org.eclipse.jgit.revwalk.RevTree) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate)

Example 47 with RevTree

use of org.eclipse.jgit.revwalk.RevTree in project gerrit by GerritCodeReview.

the class AbstractSubmoduleSubscription method expectToHaveSubmoduleState.

protected void expectToHaveSubmoduleState(TestRepository<?> repo, String branch, Project.NameKey submodule, ObjectId expectedId) throws Exception {
    ObjectId commitId = repo.git().fetch().setRemote("origin").call().getAdvertisedRef("refs/heads/" + branch).getObjectId();
    RevWalk rw = repo.getRevWalk();
    RevCommit c = rw.parseCommit(commitId);
    rw.parseBody(c.getTree());
    RevTree tree = c.getTree();
    RevObject actualId = repo.get(tree, submodule.get());
    assertThat(actualId).isEqualTo(expectedId);
}
Also used : AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) RevObject(org.eclipse.jgit.revwalk.RevObject) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevTree(org.eclipse.jgit.revwalk.RevTree) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 48 with RevTree

use of org.eclipse.jgit.revwalk.RevTree in project gitblit by gitblit.

the class JGitUtils method getNotesOnCommit.

/**
 * Returns the list of notes entered about the commit from the refs/notes
 * namespace. If the repository does not exist or is empty, an empty list is
 * returned.
 *
 * @param repository
 * @param commit
 * @return list of notes
 */
public static List<GitNote> getNotesOnCommit(Repository repository, RevCommit commit) {
    List<GitNote> list = new ArrayList<GitNote>();
    if (!hasCommits(repository)) {
        return list;
    }
    List<RefModel> noteBranches = getNoteBranches(repository, true, -1);
    for (RefModel notesRef : noteBranches) {
        RevTree notesTree = JGitUtils.getCommit(repository, notesRef.getName()).getTree();
        // flat notes list
        String notePath = commit.getName();
        String text = getStringContent(repository, notesTree, notePath);
        if (!StringUtils.isEmpty(text)) {
            List<RevCommit> history = getRevLog(repository, notesRef.getName(), notePath, 0, -1);
            RefModel noteRef = new RefModel(notesRef.displayName, null, history.get(history.size() - 1));
            GitNote gitNote = new GitNote(noteRef, text);
            list.add(gitNote);
            continue;
        }
        // folder structure
        StringBuilder sb = new StringBuilder(commit.getName());
        sb.insert(2, '/');
        notePath = sb.toString();
        text = getStringContent(repository, notesTree, notePath);
        if (!StringUtils.isEmpty(text)) {
            List<RevCommit> history = getRevLog(repository, notesRef.getName(), notePath, 0, -1);
            RefModel noteRef = new RefModel(notesRef.displayName, null, history.get(history.size() - 1));
            GitNote gitNote = new GitNote(noteRef, text);
            list.add(gitNote);
        }
    }
    return list;
}
Also used : RefModel(com.gitblit.models.RefModel) ArrayList(java.util.ArrayList) GitNote(com.gitblit.models.GitNote) RevTree(org.eclipse.jgit.revwalk.RevTree) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 49 with RevTree

use of org.eclipse.jgit.revwalk.RevTree in project gitblit by gitblit.

the class BranchTicketService method readTicketsFile.

/**
 * Reads a file from the tickets branch.
 *
 * @param db
 * @param file
 * @return the file content or null
 */
private String readTicketsFile(Repository db, String file) {
    RevWalk rw = null;
    try {
        ObjectId treeId = db.resolve(BRANCH + "^{tree}");
        if (treeId == null) {
            return null;
        }
        rw = new RevWalk(db);
        RevTree tree = rw.lookupTree(treeId);
        if (tree != null) {
            return JGitUtils.getStringContent(db, tree, file, Constants.ENCODING);
        }
    } catch (IOException e) {
        log.error("failed to read " + file, e);
    } finally {
        if (rw != null) {
            rw.close();
        }
    }
    return null;
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevTree(org.eclipse.jgit.revwalk.RevTree)

Example 50 with RevTree

use of org.eclipse.jgit.revwalk.RevTree in project gitblit by gitblit.

the class DiffUtils method getDiff.

/**
 * Returns the diff between two commits for the specified file.
 *
 * @param repository
 * @param baseCommit
 *            if base commit is null the diff is to the primary parent of
 *            the commit.
 * @param commit
 * @param path
 *            if the path is specified, the diff is restricted to that file
 *            or folder. if unspecified, the diff is for the entire commit.
 * @param comparator
 * @param outputType
 * @param handler
 *            to use for rendering binary diffs if {@code outputType} is {@link DiffOutputType#HTML HTML}.
 *            May be {@code null}, resulting in the default behavior.
 * @param tabLength
 * @return the diff
 */
public static DiffOutput getDiff(Repository repository, RevCommit baseCommit, RevCommit commit, String path, DiffComparator comparator, DiffOutputType outputType, final BinaryDiffHandler handler, int tabLength) {
    DiffStat stat = null;
    String diff = null;
    try {
        ByteArrayOutputStream os = null;
        DiffFormatter df;
        switch(outputType) {
            case HTML:
                df = new GitBlitDiffFormatter(commit.getName(), repository, path, handler, tabLength);
                break;
            case PLAIN:
            default:
                os = new ByteArrayOutputStream();
                df = new DiffFormatter(os);
                break;
        }
        df.setRepository(repository);
        df.setDiffComparator((comparator == null ? DiffComparator.SHOW_WHITESPACE : comparator).textComparator);
        df.setDetectRenames(true);
        RevTree commitTree = commit.getTree();
        RevTree baseTree;
        if (baseCommit == null) {
            if (commit.getParentCount() > 0) {
                final RevWalk rw = new RevWalk(repository);
                RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
                rw.dispose();
                baseTree = parent.getTree();
            } else {
                // FIXME initial commit. no parent?!
                baseTree = commitTree;
            }
        } else {
            baseTree = baseCommit.getTree();
        }
        List<DiffEntry> diffEntries = df.scan(baseTree, commitTree);
        if (path != null && path.length() > 0) {
            for (DiffEntry diffEntry : diffEntries) {
                if (diffEntry.getNewPath().equalsIgnoreCase(path)) {
                    df.format(diffEntry);
                    break;
                }
            }
        } else {
            df.format(diffEntries);
        }
        df.flush();
        if (df instanceof GitBlitDiffFormatter) {
            // workaround for complex private methods in DiffFormatter
            diff = ((GitBlitDiffFormatter) df).getHtml();
            stat = ((GitBlitDiffFormatter) df).getDiffStat();
        } else {
            diff = os.toString();
        }
    } catch (Throwable t) {
        LOGGER.error("failed to generate commit diff!", t);
    }
    return new DiffOutput(outputType, diff, stat);
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevTree(org.eclipse.jgit.revwalk.RevTree) RevCommit(org.eclipse.jgit.revwalk.RevCommit) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Aggregations

RevTree (org.eclipse.jgit.revwalk.RevTree)54 RevWalk (org.eclipse.jgit.revwalk.RevWalk)41 RevCommit (org.eclipse.jgit.revwalk.RevCommit)28 ObjectId (org.eclipse.jgit.lib.ObjectId)27 ObjectReader (org.eclipse.jgit.lib.ObjectReader)19 IOException (java.io.IOException)16 Repository (org.eclipse.jgit.lib.Repository)13 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)13 DiffEntry (org.eclipse.jgit.diff.DiffEntry)9 RevObject (org.eclipse.jgit.revwalk.RevObject)9 CanonicalTreeParser (org.eclipse.jgit.treewalk.CanonicalTreeParser)9 IncorrectObjectTypeException (org.eclipse.jgit.errors.IncorrectObjectTypeException)7 File (java.io.File)6 AnyObjectId (org.eclipse.jgit.lib.AnyObjectId)6 ObjectLoader (org.eclipse.jgit.lib.ObjectLoader)6 Ref (org.eclipse.jgit.lib.Ref)6 ArrayList (java.util.ArrayList)3 DiffFormatter (org.eclipse.jgit.diff.DiffFormatter)3 RawTextComparator (org.eclipse.jgit.diff.RawTextComparator)3 DirCache (org.eclipse.jgit.dircache.DirCache)3