Search in sources :

Example 61 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class ChangeEditUtil method publish.

/**
   * Promote change edit to patch set, by squashing the edit into its parent.
   *
   * @param updateFactory factory for creating updates.
   * @param ctl the {@code ChangeControl} of the change to which the change edit belongs
   * @param edit change edit to publish
   * @param notify Notify handling that defines to whom email notifications should be sent after the
   *     change edit is published.
   * @param accountsToNotify Accounts that should be notified after the change edit is published.
   * @throws IOException
   * @throws OrmException
   * @throws UpdateException
   * @throws RestApiException
   */
public void publish(BatchUpdate.Factory updateFactory, ChangeControl ctl, final ChangeEdit edit, NotifyHandling notify, ListMultimap<RecipientType, Account.Id> accountsToNotify) throws IOException, OrmException, RestApiException, UpdateException {
    Change change = edit.getChange();
    try (Repository repo = gitManager.openRepository(change.getProject());
        ObjectInserter oi = repo.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = new RevWalk(reader)) {
        PatchSet basePatchSet = edit.getBasePatchSet();
        if (!basePatchSet.getId().equals(change.currentPatchSetId())) {
            throw new ResourceConflictException("only edit for current patch set can be published");
        }
        RevCommit squashed = squashEdit(rw, oi, edit.getEditCommit(), basePatchSet);
        PatchSet.Id psId = ChangeUtil.nextPatchSetId(repo, change.currentPatchSetId());
        PatchSetInserter inserter = patchSetInserterFactory.create(ctl, psId, squashed).setNotify(notify).setAccountsToNotify(accountsToNotify);
        StringBuilder message = new StringBuilder("Patch Set ").append(inserter.getPatchSetId().get()).append(": ");
        // Previously checked that the base patch set is the current patch set.
        ObjectId prior = ObjectId.fromString(basePatchSet.getRevision().get());
        ChangeKind kind = changeKindCache.getChangeKind(change.getProject(), rw, repo.getConfig(), prior, squashed);
        if (kind == ChangeKind.NO_CODE_CHANGE) {
            message.append("Commit message was updated.");
            inserter.setDescription("Edit commit message");
        } else {
            message.append("Published edit on patch set ").append(basePatchSet.getPatchSetId()).append(".");
        }
        try (BatchUpdate bu = updateFactory.create(db.get(), change.getProject(), ctl.getUser(), TimeUtil.nowTs())) {
            bu.setRepository(repo, rw, oi);
            bu.addOp(change.getId(), inserter.setDraft(change.getStatus() == Status.DRAFT || basePatchSet.isDraft()).setMessage(message.toString()));
            bu.addOp(change.getId(), new BatchUpdateOp() {

                @Override
                public void updateRepo(RepoContext ctx) throws Exception {
                    ctx.addRefUpdate(edit.getEditCommit().copy(), ObjectId.zeroId(), edit.getRefName());
                }
            });
            bu.execute();
        }
        indexer.index(db.get(), inserter.getChange());
    }
}
Also used : RepoContext(com.google.gerrit.server.update.RepoContext) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Change(com.google.gerrit.reviewdb.client.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) OrmException(com.google.gwtorm.server.OrmException) UpdateException(com.google.gerrit.server.update.UpdateException) AuthException(com.google.gerrit.extensions.restapi.AuthException) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) IOException(java.io.IOException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PatchSetInserter(com.google.gerrit.server.change.PatchSetInserter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevCommit(org.eclipse.jgit.revwalk.RevCommit) ChangeKind(com.google.gerrit.extensions.client.ChangeKind) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp)

Example 62 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class CreateMergePatchSet method applyImpl.

@Override
protected Response<ChangeInfo> applyImpl(BatchUpdate.Factory updateFactory, ChangeResource rsrc, MergePatchSetInput in) throws OrmException, IOException, InvalidChangeOperationException, RestApiException, UpdateException, PermissionBackendException {
    rsrc.permissions().database(db).check(ChangePermission.ADD_PATCH_SET);
    MergeInput merge = in.merge;
    if (merge == null || Strings.isNullOrEmpty(merge.source)) {
        throw new BadRequestException("merge.source must be non-empty");
    }
    ChangeControl ctl = rsrc.getControl();
    PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
    ProjectControl projectControl = ctl.getProjectControl();
    Change change = ctl.getChange();
    Project.NameKey project = change.getProject();
    Branch.NameKey dest = change.getDest();
    try (Repository git = gitManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = new RevWalk(reader)) {
        RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
        if (!projectControl.canReadCommit(db.get(), git, sourceCommit)) {
            throw new ResourceNotFoundException("cannot find source commit: " + merge.source + " to merge.");
        }
        RevCommit currentPsCommit = rw.parseCommit(ObjectId.fromString(ps.getRevision().get()));
        Timestamp now = TimeUtil.nowTs();
        IdentifiedUser me = user.get().asIdentifiedUser();
        PersonIdent author = me.newCommitterIdent(now, serverTimeZone);
        RevCommit newCommit = createMergeCommit(in, projectControl, dest, git, oi, rw, currentPsCommit, sourceCommit, author, ObjectId.fromString(change.getKey().get().substring(1)));
        PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.getId());
        PatchSetInserter psInserter = patchSetInserterFactory.create(ctl, nextPsId, newCommit);
        try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) {
            bu.setRepository(git, rw, oi);
            bu.addOp(ctl.getId(), psInserter.setMessage("Uploaded patch set " + nextPsId.get() + ".").setDraft(ps.isDraft()).setNotify(NotifyHandling.NONE).setCheckAddPatchSetPermission(false));
            bu.execute();
        }
        ChangeJson json = jsonFactory.create(ListChangesOption.CURRENT_REVISION);
        return Response.ok(json.format(psInserter.getChange()));
    }
}
Also used : MergeInput(com.google.gerrit.extensions.common.MergeInput) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Change(com.google.gerrit.reviewdb.client.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) ProjectControl(com.google.gerrit.server.project.ProjectControl) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) ChangeControl(com.google.gerrit.server.project.ChangeControl) Branch(com.google.gerrit.reviewdb.client.Branch) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 63 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class GetBlame method apply.

@Override
public Response<List<BlameInfo>> apply(FileResource resource) throws RestApiException, OrmException, IOException, InvalidChangeOperationException {
    if (!allowBlame) {
        throw new BadRequestException("blame is disabled");
    }
    Project.NameKey project = resource.getRevision().getChange().getProject();
    try (Repository repository = repoManager.openRepository(project);
        ObjectInserter ins = repository.newObjectInserter();
        ObjectReader reader = ins.newReader();
        RevWalk revWalk = new RevWalk(reader)) {
        String refName = resource.getRevision().getEdit().isPresent() ? resource.getRevision().getEdit().get().getRefName() : resource.getRevision().getPatchSet().getRefName();
        Ref ref = repository.findRef(refName);
        if (ref == null) {
            throw new ResourceNotFoundException("unknown ref " + refName);
        }
        ObjectId objectId = ref.getObjectId();
        RevCommit revCommit = revWalk.parseCommit(objectId);
        RevCommit[] parents = revCommit.getParents();
        String path = resource.getPatchKey().getFileName();
        List<BlameInfo> result;
        if (!base) {
            result = blame(revCommit, path, repository, revWalk);
        } else if (parents.length == 0) {
            throw new ResourceNotFoundException("Initial commit doesn't have base");
        } else if (parents.length == 1) {
            result = blame(parents[0], path, repository, revWalk);
        } else if (parents.length == 2) {
            ObjectId automerge = autoMerger.merge(repository, revWalk, ins, revCommit, mergeStrategy);
            result = blame(automerge, path, repository, revWalk);
        } else {
            throw new ResourceNotFoundException("Cannot generate blame for merge commit with more than 2 parents");
        }
        Response<List<BlameInfo>> r = Response.ok(result);
        if (resource.isCacheable()) {
            r.caching(CacheControl.PRIVATE(7, TimeUnit.DAYS));
        }
        return r;
    }
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BlameInfo(com.google.gerrit.extensions.common.BlameInfo) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ArrayList(java.util.ArrayList) List(java.util.List) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 64 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project indy by Commonjava.

the class GitManager method verifyChangesExist.

private boolean verifyChangesExist(final Collection<String> paths) throws GitSubsystemException {
    return lockAnd(me -> {
        try {
            final DiffFormatter formatter = new DiffFormatter(System.out);
            formatter.setRepository(repo);
            final ObjectId oid = repo.resolve(Constants.HEAD);
            if (oid == null) {
                return true;
            }
            final RevWalk walk = new RevWalk(repo);
            final RevCommit commit = walk.parseCommit(oid);
            final RevTree treeWalk = walk.parseTree(commit);
            final List<TreeFilter> filters = new ArrayList<>();
            for (final String path : paths) {
                filters.add(PathFilter.create(path));
            }
            filters.add(TreeFilter.ANY_DIFF);
            walk.setTreeFilter(AndTreeFilter.create(filters));
            final CanonicalTreeParser tree = new CanonicalTreeParser();
            final ObjectReader oldReader = repo.newObjectReader();
            try {
                tree.reset(oldReader, treeWalk.getId());
            } finally {
                oldReader.release();
            }
            walk.dispose();
            final FileTreeIterator files = new FileTreeIterator(repo);
            final List<DiffEntry> entries = formatter.scan(tree, files);
            return entries != null && !entries.isEmpty();
        } catch (final IOException e) {
            throw new GitSubsystemException("Failed to scan for actual changes among: %s. Reason: %s", e, paths, e.getMessage());
        }
    });
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) JoinString(org.commonjava.maven.atlas.ident.util.JoinString) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) CanonicalTreeParser(org.eclipse.jgit.treewalk.CanonicalTreeParser) TreeFilter(org.eclipse.jgit.treewalk.filter.TreeFilter) AndTreeFilter(org.eclipse.jgit.treewalk.filter.AndTreeFilter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) FileTreeIterator(org.eclipse.jgit.treewalk.FileTreeIterator) RevTree(org.eclipse.jgit.revwalk.RevTree) RevCommit(org.eclipse.jgit.revwalk.RevCommit) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Example 65 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class ReceiveCommits method insertChangesAndPatchSets.

private void insertChangesAndPatchSets() {
    ReceiveCommand magicBranchCmd = magicBranch != null ? magicBranch.cmd : null;
    if (magicBranchCmd != null && magicBranchCmd.getResult() != NOT_ATTEMPTED) {
        logWarn(String.format("Skipping change updates on %s because ref update failed: %s %s", project.getName(), magicBranchCmd.getResult(), Strings.nullToEmpty(magicBranchCmd.getMessage())));
        return;
    }
    try (BatchUpdate bu = batchUpdateFactory.create(db, project.getNameKey(), user.materializedCopy(), TimeUtil.nowTs());
        ObjectInserter ins = repo.newObjectInserter();
        ObjectReader reader = ins.newReader();
        RevWalk rw = new RevWalk(reader)) {
        bu.setRepository(repo, rw, ins).updateChangesInParallel();
        bu.setRequestId(receiveId);
        bu.setRefLogMessage("push");
        logDebug("Adding {} replace requests", newChanges.size());
        for (ReplaceRequest replace : replaceByChange.values()) {
            replace.addOps(bu, replaceProgress);
        }
        logDebug("Adding {} create requests", newChanges.size());
        for (CreateRequest create : newChanges) {
            create.addOps(bu);
        }
        logDebug("Adding {} group update requests", newChanges.size());
        updateGroups.forEach(r -> r.addOps(bu));
        logDebug("Adding {} additional ref updates", actualCommands.size());
        actualCommands.forEach(c -> bu.addRepoOnlyOp(new UpdateOneRefOp(c)));
        logDebug("Executing batch");
        try {
            bu.execute();
        } catch (UpdateException e) {
            throw INSERT_EXCEPTION.apply(e);
        }
        if (magicBranchCmd != null) {
            magicBranchCmd.setResult(OK);
        }
        for (ReplaceRequest replace : replaceByChange.values()) {
            String rejectMessage = replace.getRejectMessage();
            if (rejectMessage == null) {
                if (replace.inputCommand.getResult() == NOT_ATTEMPTED) {
                    // Not necessarily the magic branch, so need to set OK on the original value.
                    replace.inputCommand.setResult(OK);
                }
            } else {
                logDebug("Rejecting due to message from ReplaceOp");
                reject(replace.inputCommand, rejectMessage);
            }
        }
    } catch (ResourceConflictException e) {
        addMessage(e.getMessage());
        reject(magicBranchCmd, "conflict");
    } catch (RestApiException | IOException err) {
        logError("Can't insert change/patch set for " + project.getName(), err);
        reject(magicBranchCmd, "internal server error: " + err.getMessage());
    }
    if (magicBranch != null && magicBranch.submit) {
        try {
            submit(newChanges, replaceByChange.values());
        } catch (ResourceConflictException e) {
            addMessage(e.getMessage());
            reject(magicBranchCmd, "conflict");
        } catch (RestApiException | OrmException e) {
            logError("Error submitting changes to " + project.getName(), e);
            reject(magicBranchCmd, "error during submit");
        }
    }
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) OrmException(com.google.gwtorm.server.OrmException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) UpdateException(com.google.gerrit.server.update.UpdateException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException)

Aggregations

ObjectReader (org.eclipse.jgit.lib.ObjectReader)115 RevWalk (org.eclipse.jgit.revwalk.RevWalk)69 ObjectId (org.eclipse.jgit.lib.ObjectId)59 RevCommit (org.eclipse.jgit.revwalk.RevCommit)56 Repository (org.eclipse.jgit.lib.Repository)47 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)31 CanonicalTreeParser (org.eclipse.jgit.treewalk.CanonicalTreeParser)26 IOException (java.io.IOException)24 Test (org.junit.Test)23 BatchUpdate (com.google.gerrit.server.update.BatchUpdate)20 RevTree (org.eclipse.jgit.revwalk.RevTree)19 DiffEntry (org.eclipse.jgit.diff.DiffEntry)18 Ref (org.eclipse.jgit.lib.Ref)17 PersonIdent (org.eclipse.jgit.lib.PersonIdent)14 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)13 TestRepository (org.eclipse.jgit.junit.TestRepository)12 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)11 Change (com.google.gerrit.reviewdb.client.Change)10 Map (java.util.Map)10 GerritPersonIdent (com.google.gerrit.server.GerritPersonIdent)9