Search in sources :

Example 81 with ObjectInserter

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

the class ExternalIdTestUtil method insertExternalId.

private static String insertExternalId(Repository repo, RevWalk rw, PersonIdent ident, ExternalIdInserter extIdInserter) throws IOException {
    ObjectId rev = ExternalIdReader.readRevision(repo);
    NoteMap noteMap = ExternalIdReader.readNoteMap(rw, rev);
    try (ObjectInserter ins = repo.newObjectInserter()) {
        ObjectId noteId = extIdInserter.addNote(ins, noteMap);
        CommitBuilder cb = new CommitBuilder();
        cb.setMessage("Update external IDs");
        cb.setTreeId(noteMap.writeTree(ins));
        cb.setAuthor(ident);
        cb.setCommitter(ident);
        if (!rev.equals(ObjectId.zeroId())) {
            cb.setParentId(rev);
        } else {
            // Ref is currently nonexistent, commit has no parents.
            cb.setParentIds();
        }
        if (cb.getTreeId() == null) {
            if (rev.equals(ObjectId.zeroId())) {
                // No parent, assume empty tree.
                cb.setTreeId(ins.insert(OBJ_TREE, new byte[] {}));
            } else {
                RevCommit p = rw.parseCommit(rev);
                // Copy tree from parent.
                cb.setTreeId(p.getTree());
            }
        }
        ObjectId commitId = ins.insert(cb);
        ins.flush();
        RefUpdate u = repo.updateRef(RefNames.REFS_EXTERNAL_IDS);
        u.setExpectedOldObjectId(rev);
        u.setNewObjectId(commitId);
        RefUpdate.Result res = u.update();
        switch(res) {
            case NEW:
            case FAST_FORWARD:
            case NO_CHANGE:
            case RENAMED:
            case FORCED:
                break;
            case LOCK_FAILURE:
            case IO_FAILURE:
            case NOT_ATTEMPTED:
            case REJECTED:
            case REJECTED_CURRENT_BRANCH:
            case REJECTED_MISSING_OBJECT:
            case REJECTED_OTHER_REASON:
            default:
                throw new IOException("Updating external IDs failed with " + res);
        }
        return noteId.getName();
    }
}
Also used : ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) NoteMap(org.eclipse.jgit.notes.NoteMap) IOException(java.io.IOException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 82 with ObjectInserter

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

the class CommitUtil method createRevertChange.

/**
 * Allows creating a revert change.
 *
 * @param notes ChangeNotes of the change being reverted.
 * @param user Current User performing the revert.
 * @param input the RevertInput entity for conducting the revert.
 * @param timestamp timestamp for the created change.
 * @return ObjectId that represents the newly created commit.
 */
public Change.Id createRevertChange(ChangeNotes notes, CurrentUser user, RevertInput input, Instant timestamp) throws RestApiException, UpdateException, ConfigInvalidException, IOException {
    String message = Strings.emptyToNull(input.message);
    try (Repository git = repoManager.openRepository(notes.getProjectName());
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk revWalk = new RevWalk(reader)) {
        ObjectId generatedChangeId = CommitMessageUtil.generateChangeId();
        ObjectId revCommit = createRevertCommit(message, notes, user, timestamp, oi, revWalk, generatedChangeId);
        return createRevertChangeFromCommit(revCommit, input, notes, user, generatedChangeId, timestamp, oi, revWalk, git);
    } catch (RepositoryNotFoundException e) {
        throw new ResourceNotFoundException(notes.getChangeId().toString(), e);
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RepositoryNotFoundException(org.eclipse.jgit.errors.RepositoryNotFoundException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException)

Example 83 with ObjectInserter

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

the class BanCommit method ban.

/**
 * Bans a list of commits from the given project.
 *
 * <p>The user must be specified, so it can be checked for the {@code BAN_COMMIT} permission.
 */
public BanCommitResult ban(Project.NameKey project, CurrentUser user, List<ObjectId> commitsToBan, String reason) throws AuthException, IOException, PermissionBackendException {
    permissionBackend.user(user).project(project).check(ProjectPermission.BAN_COMMIT);
    final BanCommitResult result = new BanCommitResult();
    NoteMap banCommitNotes = NoteMap.newEmptyMap();
    // Add a note for each banned commit to notes.
    try (Repository repo = repoManager.openRepository(project);
        RevWalk revWalk = new RevWalk(repo);
        ObjectInserter inserter = repo.newObjectInserter()) {
        ObjectId noteId = null;
        for (ObjectId commitToBan : commitsToBan) {
            try {
                revWalk.parseCommit(commitToBan);
            } catch (MissingObjectException e) {
            // Ignore exception, non-existing commits can be banned.
            } catch (IncorrectObjectTypeException e) {
                result.notACommit(commitToBan);
                continue;
            }
            if (noteId == null) {
                noteId = createNoteContent(reason, inserter);
            }
            banCommitNotes.set(commitToBan, noteId);
        }
        NotesBranchUtil notesBranchUtil = notesBranchUtilFactory.create(project, repo, inserter);
        NoteMap newlyCreated = notesBranchUtil.commitNewNotes(banCommitNotes, REFS_REJECT_COMMITS, createPersonIdent(), buildCommitMessage(commitsToBan, reason));
        for (Note n : banCommitNotes) {
            if (newlyCreated.contains(n)) {
                result.commitBanned(n);
            } else {
                result.commitAlreadyBanned(n);
            }
        }
        return result;
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) Note(org.eclipse.jgit.notes.Note) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) NoteMap(org.eclipse.jgit.notes.NoteMap) RevWalk(org.eclipse.jgit.revwalk.RevWalk) MissingObjectException(org.eclipse.jgit.errors.MissingObjectException)

Example 84 with ObjectInserter

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

the class CreateChange method createNewChange.

// TODO(issue-15517): Fix the JdkObsolete issue with Date once JGit's PersonIdent class supports
// Instants
@SuppressWarnings("JdkObsolete")
private ChangeInfo createNewChange(ChangeInput input, IdentifiedUser me, ProjectState projectState, BatchUpdate.Factory updateFactory) throws RestApiException, PermissionBackendException, IOException, ConfigInvalidException, UpdateException {
    logger.atFine().log("Creating new change for target branch %s in project %s" + " (new branch = %s, base change = %s, base commit = %s)", input.branch, projectState.getName(), input.newBranch, input.baseChange, input.baseCommit);
    try (Repository git = gitManager.openRepository(projectState.getNameKey());
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        CodeReviewRevWalk rw = CodeReviewCommit.newRevWalk(reader)) {
        PatchSet basePatchSet = null;
        List<String> groups = Collections.emptyList();
        if (input.baseChange != null) {
            ChangeNotes baseChange = getBaseChange(input.baseChange);
            basePatchSet = psUtil.current(baseChange);
            groups = basePatchSet.groups();
            logger.atFine().log("base patch set = %s (groups = %s)", basePatchSet.id(), groups);
        }
        ObjectId parentCommit = getParentCommit(git, rw, input.branch, input.newBranch, basePatchSet, input.baseCommit, input.merge);
        logger.atFine().log("parent commit = %s", parentCommit != null ? parentCommit.name() : "NULL");
        RevCommit mergeTip = parentCommit == null ? null : rw.parseCommit(parentCommit);
        Instant now = TimeUtil.now();
        PersonIdent committer = me.newCommitterIdent(now, serverTimeZone);
        PersonIdent author = input.author == null ? committer : new PersonIdent(input.author.name, input.author.email, Date.from(now), serverTimeZone);
        String commitMessage = getCommitMessage(input.subject, me);
        CodeReviewCommit c;
        if (input.merge != null) {
            // create a merge commit
            c = newMergeCommit(git, oi, rw, projectState, mergeTip, input.merge, author, committer, commitMessage);
            if (!c.getFilesWithGitConflicts().isEmpty()) {
                logger.atFine().log("merge commit has conflicts in the following files: %s", c.getFilesWithGitConflicts());
            }
        } else {
            // create an empty commit
            c = newCommit(oi, rw, author, committer, mergeTip, commitMessage);
        }
        // Flush inserter so that commit becomes visible to validators
        oi.flush();
        Change.Id changeId = Change.id(seq.nextChangeId());
        ChangeInserter ins = changeInserterFactory.create(changeId, c, input.branch);
        ins.setMessage(messageForNewChange(ins.getPatchSetId(), c));
        ins.setTopic(input.topic);
        ins.setPrivate(input.isPrivate);
        ins.setWorkInProgress(input.workInProgress || !c.getFilesWithGitConflicts().isEmpty());
        ins.setGroups(groups);
        if (input.validationOptions != null) {
            ImmutableListMultimap.Builder<String, String> validationOptions = ImmutableListMultimap.builder();
            input.validationOptions.entrySet().forEach(e -> validationOptions.put(e.getKey(), e.getValue()));
            ins.setValidationOptions(validationOptions.build());
        }
        try (BatchUpdate bu = updateFactory.create(projectState.getNameKey(), me, now)) {
            bu.setRepository(git, rw, oi);
            bu.setNotify(notifyResolver.resolve(firstNonNull(input.notify, NotifyHandling.ALL), input.notifyDetails));
            bu.insertChange(ins);
            bu.execute();
        }
        ChangeInfo changeInfo = jsonFactory.noOptions().format(ins.getChange());
        changeInfo.containsGitConflicts = !c.getFilesWithGitConflicts().isEmpty() ? true : null;
        return changeInfo;
    } catch (InvalidMergeStrategyException | MergeWithConflictsNotSupportedException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : ChangeInfo(com.google.gerrit.extensions.common.ChangeInfo) ObjectId(org.eclipse.jgit.lib.ObjectId) Instant(java.time.Instant) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) Change(com.google.gerrit.entities.Change) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ChangeInserter(com.google.gerrit.server.change.ChangeInserter) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 85 with ObjectInserter

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

the class CreateMergePatchSet method apply.

// TODO(issue-15517): Fix the JdkObsolete issue with Date once JGit's PersonIdent class supports
// Instants
@SuppressWarnings("JdkObsolete")
@Override
public Response<ChangeInfo> apply(ChangeResource rsrc, MergePatchSetInput in) throws IOException, RestApiException, UpdateException, PermissionBackendException {
    // Not allowed to create a new patch set if the current patch set is locked.
    psUtil.checkPatchSetNotLocked(rsrc.getNotes());
    rsrc.permissions().check(ChangePermission.ADD_PATCH_SET);
    if (in.author != null) {
        permissionBackend.currentUser().project(rsrc.getProject()).ref(rsrc.getChange().getDest().branch()).check(RefPermission.FORGE_AUTHOR);
    }
    ProjectState projectState = projectCache.get(rsrc.getProject()).orElseThrow(illegalState(rsrc.getProject()));
    projectState.checkStatePermitsWrite();
    MergeInput merge = in.merge;
    if (merge == null || Strings.isNullOrEmpty(merge.source)) {
        throw new BadRequestException("merge.source must be non-empty");
    }
    if (in.author != null && (Strings.isNullOrEmpty(in.author.email) || Strings.isNullOrEmpty(in.author.name))) {
        throw new BadRequestException("Author must specify name and email");
    }
    in.baseChange = Strings.nullToEmpty(in.baseChange).trim();
    PatchSet ps = psUtil.current(rsrc.getNotes());
    Change change = rsrc.getChange();
    Project.NameKey project = change.getProject();
    BranchNameKey dest = change.getDest();
    try (Repository git = gitManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        CodeReviewRevWalk rw = CodeReviewCommit.newRevWalk(reader)) {
        RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
        if (!commits.canRead(projectState, git, sourceCommit)) {
            throw new ResourceNotFoundException("cannot find source commit: " + merge.source + " to merge.");
        }
        RevCommit currentPsCommit;
        List<String> groups = null;
        if (!in.inheritParent && !in.baseChange.isEmpty()) {
            PatchSet basePS = findBasePatchSet(in.baseChange);
            currentPsCommit = rw.parseCommit(basePS.commitId());
            groups = basePS.groups();
        } else {
            currentPsCommit = rw.parseCommit(ps.commitId());
        }
        Instant now = TimeUtil.now();
        IdentifiedUser me = user.get().asIdentifiedUser();
        PersonIdent author = in.author == null ? me.newCommitterIdent(now, serverTimeZone) : new PersonIdent(in.author.name, in.author.email, Date.from(now), serverTimeZone);
        CodeReviewCommit newCommit = createMergeCommit(in, projectState, dest, git, oi, rw, currentPsCommit, sourceCommit, author, ObjectId.fromString(change.getKey().get().substring(1)));
        oi.flush();
        PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.id());
        PatchSetInserter psInserter = patchSetInserterFactory.create(rsrc.getNotes(), nextPsId, newCommit);
        try (BatchUpdate bu = updateFactory.create(project, me, now)) {
            bu.setRepository(git, rw, oi);
            bu.setNotify(NotifyResolver.Result.none());
            psInserter.setMessage(messageForChange(nextPsId, newCommit)).setWorkInProgress(!newCommit.getFilesWithGitConflicts().isEmpty()).setCheckAddPatchSetPermission(false);
            if (groups != null) {
                psInserter.setGroups(groups);
            }
            bu.addOp(rsrc.getId(), psInserter);
            bu.execute();
        }
        ChangeJson json = jsonFactory.create(ListChangesOption.CURRENT_REVISION);
        ChangeInfo changeInfo = json.format(psInserter.getChange());
        changeInfo.containsGitConflicts = !newCommit.getFilesWithGitConflicts().isEmpty() ? true : null;
        return Response.ok(changeInfo);
    } catch (InvalidMergeStrategyException | MergeWithConflictsNotSupportedException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : MergeInput(com.google.gerrit.extensions.common.MergeInput) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) BranchNameKey(com.google.gerrit.entities.BranchNameKey) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) ChangeJson(com.google.gerrit.server.change.ChangeJson) ChangeInfo(com.google.gerrit.extensions.common.ChangeInfo) Instant(java.time.Instant) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) PatchSet(com.google.gerrit.entities.PatchSet) Change(com.google.gerrit.entities.Change) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) Project(com.google.gerrit.entities.Project) Repository(org.eclipse.jgit.lib.Repository) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) PatchSetInserter(com.google.gerrit.server.change.PatchSetInserter) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) ProjectState(com.google.gerrit.server.project.ProjectState)

Aggregations

ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)108 ObjectId (org.eclipse.jgit.lib.ObjectId)77 RevWalk (org.eclipse.jgit.revwalk.RevWalk)55 Repository (org.eclipse.jgit.lib.Repository)49 RevCommit (org.eclipse.jgit.revwalk.RevCommit)35 IOException (java.io.IOException)31 ObjectReader (org.eclipse.jgit.lib.ObjectReader)31 PersonIdent (org.eclipse.jgit.lib.PersonIdent)30 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)28 BatchUpdate (com.google.gerrit.server.update.BatchUpdate)24 RefUpdate (org.eclipse.jgit.lib.RefUpdate)24 DirCache (org.eclipse.jgit.dircache.DirCache)15 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)14 Change (com.google.gerrit.entities.Change)13 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)13 Change (com.google.gerrit.reviewdb.client.Change)13 DirCacheEntry (org.eclipse.jgit.dircache.DirCacheEntry)13 Ref (org.eclipse.jgit.lib.Ref)13 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)12 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)10