Search in sources :

Example 46 with PatchSet

use of com.google.gerrit.reviewdb.client.PatchSet in project gerrit by GerritCodeReview.

the class CreateChange method applyImpl.

@Override
protected Response<ChangeInfo> applyImpl(BatchUpdate.Factory updateFactory, TopLevelResource parent, ChangeInput input) throws OrmException, IOException, InvalidChangeOperationException, RestApiException, UpdateException, PermissionBackendException {
    if (Strings.isNullOrEmpty(input.project)) {
        throw new BadRequestException("project must be non-empty");
    }
    if (Strings.isNullOrEmpty(input.branch)) {
        throw new BadRequestException("branch must be non-empty");
    }
    if (Strings.isNullOrEmpty(input.subject)) {
        throw new BadRequestException("commit message must be non-empty");
    }
    if (input.status != null) {
        if (input.status != ChangeStatus.NEW && input.status != ChangeStatus.DRAFT) {
            throw new BadRequestException("unsupported change status");
        }
        if (!allowDrafts && input.status == ChangeStatus.DRAFT) {
            throw new MethodNotAllowedException("draft workflow is disabled");
        }
    }
    String refName = RefNames.fullName(input.branch);
    ProjectResource rsrc = projectsCollection.parse(input.project);
    Capable r = rsrc.getControl().canPushToAtLeastOneRef();
    if (r != Capable.OK) {
        throw new AuthException(r.getMessage());
    }
    RefControl refControl = rsrc.getControl().controlForRef(refName);
    if (!refControl.canUpload() || !refControl.isVisible()) {
        throw new AuthException("cannot upload review");
    }
    Project.NameKey project = rsrc.getNameKey();
    try (Repository git = gitManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = new RevWalk(reader)) {
        ObjectId parentCommit;
        List<String> groups;
        if (input.baseChange != null) {
            List<ChangeControl> ctls = changeFinder.find(input.baseChange, rsrc.getControl().getUser());
            if (ctls.size() != 1) {
                throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
            }
            ChangeControl ctl = Iterables.getOnlyElement(ctls);
            if (!ctl.isVisible(db.get())) {
                throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
            }
            PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
            parentCommit = ObjectId.fromString(ps.getRevision().get());
            groups = ps.getGroups();
        } else {
            Ref destRef = git.getRefDatabase().exactRef(refName);
            if (destRef != null) {
                if (Boolean.TRUE.equals(input.newBranch)) {
                    throw new ResourceConflictException(String.format("Branch %s already exists.", refName));
                }
                parentCommit = destRef.getObjectId();
            } else {
                if (Boolean.TRUE.equals(input.newBranch)) {
                    parentCommit = null;
                } else {
                    throw new UnprocessableEntityException(String.format("Branch %s does not exist.", refName));
                }
            }
            groups = Collections.emptyList();
        }
        RevCommit mergeTip = parentCommit == null ? null : rw.parseCommit(parentCommit);
        Timestamp now = TimeUtil.nowTs();
        IdentifiedUser me = user.get().asIdentifiedUser();
        PersonIdent author = me.newCommitterIdent(now, serverTimeZone);
        AccountState account = accountCache.get(me.getAccountId());
        GeneralPreferencesInfo info = account.getAccount().getGeneralPreferencesInfo();
        ObjectId treeId = mergeTip == null ? emptyTreeId(oi) : mergeTip.getTree();
        ObjectId id = ChangeIdUtil.computeChangeId(treeId, mergeTip, author, author, input.subject);
        String commitMessage = ChangeIdUtil.insertId(input.subject, id);
        if (Boolean.TRUE.equals(info.signedOffBy)) {
            commitMessage += String.format("%s%s", SIGNED_OFF_BY_TAG, account.getAccount().getNameEmail(anonymousCowardName));
        }
        RevCommit c;
        if (input.merge != null) {
            // create a merge commit
            if (!(submitType.equals(SubmitType.MERGE_ALWAYS) || submitType.equals(SubmitType.MERGE_IF_NECESSARY))) {
                throw new BadRequestException("Submit type: " + submitType + " is not supported");
            }
            c = newMergeCommit(git, oi, rw, rsrc.getControl(), mergeTip, input.merge, author, commitMessage);
        } else {
            // create an empty commit
            c = newCommit(oi, rw, author, mergeTip, commitMessage);
        }
        Change.Id changeId = new Change.Id(seq.nextChangeId());
        ChangeInserter ins = changeInserterFactory.create(changeId, c, refName);
        ins.setMessage(String.format("Uploaded patch set %s.", ins.getPatchSetId().get()));
        String topic = input.topic;
        if (topic != null) {
            topic = Strings.emptyToNull(topic.trim());
        }
        ins.setTopic(topic);
        ins.setDraft(input.status == ChangeStatus.DRAFT);
        ins.setPrivate(input.isPrivate != null && input.isPrivate);
        ins.setWorkInProgress(input.workInProgress != null && input.workInProgress);
        ins.setGroups(groups);
        ins.setNotify(input.notify);
        ins.setAccountsToNotify(notifyUtil.resolveAccounts(input.notifyDetails));
        try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) {
            bu.setRepository(git, rw, oi);
            bu.insertChange(ins);
            bu.execute();
        }
        ChangeJson json = jsonFactory.noOptions();
        return Response.created(json.format(ins.getChange()));
    } catch (IllegalArgumentException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Capable(com.google.gerrit.common.data.Capable) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ChangeControl(com.google.gerrit.server.project.ChangeControl) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevCommit(org.eclipse.jgit.revwalk.RevCommit) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) AccountState(com.google.gerrit.server.account.AccountState) Change(com.google.gerrit.reviewdb.client.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) GeneralPreferencesInfo(com.google.gerrit.extensions.client.GeneralPreferencesInfo) ProjectResource(com.google.gerrit.server.project.ProjectResource) ObjectId(org.eclipse.jgit.lib.ObjectId)

Example 47 with PatchSet

use of com.google.gerrit.reviewdb.client.PatchSet in project gerrit by GerritCodeReview.

the class ChangeKindCacheImpl method getChangeKindInternal.

private static ChangeKind getChangeKindInternal(ChangeKindCache cache, @Nullable RevWalk rw, @Nullable Config repoConfig, ChangeData change, PatchSet patch) {
    ChangeKind kind = ChangeKind.REWORK;
    // the repository.
    if (patch.getId().get() > 1) {
        try {
            Collection<PatchSet> patchSetCollection = change.patchSets();
            PatchSet priorPs = patch;
            for (PatchSet ps : patchSetCollection) {
                if (ps.getId().get() < patch.getId().get() && (ps.getId().get() > priorPs.getId().get() || priorPs == patch)) {
                    // We only want the previous patch set, so walk until the last one
                    priorPs = ps;
                }
            }
            // and deletes the draft.
            if (priorPs != patch) {
                kind = cache.getChangeKind(change.project(), rw, repoConfig, ObjectId.fromString(priorPs.getRevision().get()), ObjectId.fromString(patch.getRevision().get()));
            }
        } catch (OrmException e) {
            // Do nothing; assume we have a complex change
            log.warn("Unable to get change kind for patchSet " + patch.getPatchSetId() + "of change " + change.getId(), e);
        }
    }
    return kind;
}
Also used : OrmException(com.google.gwtorm.server.OrmException) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) ChangeKind(com.google.gerrit.extensions.client.ChangeKind)

Example 48 with PatchSet

use of com.google.gerrit.reviewdb.client.PatchSet in project gerrit by GerritCodeReview.

the class ChangeJson method loadPatchSets.

private Map<PatchSet.Id, PatchSet> loadPatchSets(ChangeData cd, Optional<PatchSet.Id> limitToPsId) throws OrmException {
    Collection<PatchSet> src;
    if (has(ALL_REVISIONS) || has(MESSAGES)) {
        src = cd.patchSets();
    } else {
        PatchSet ps;
        if (limitToPsId.isPresent()) {
            ps = cd.patchSet(limitToPsId.get());
            if (ps == null) {
                throw new OrmException("missing patch set " + limitToPsId.get());
            }
        } else {
            ps = cd.currentPatchSet();
            if (ps == null) {
                throw new OrmException("missing current patch set for change " + cd.getId());
            }
        }
        src = Collections.singletonList(ps);
    }
    Map<PatchSet.Id, PatchSet> map = Maps.newHashMapWithExpectedSize(src.size());
    for (PatchSet patchSet : src) {
        map.put(patchSet.getId(), patchSet);
    }
    return map;
}
Also used : OrmException(com.google.gwtorm.server.OrmException) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) ObjectId(org.eclipse.jgit.lib.ObjectId)

Example 49 with PatchSet

use of com.google.gerrit.reviewdb.client.PatchSet in project gerrit by GerritCodeReview.

the class ChangeNotesParser method updatePatchSetStates.

private void updatePatchSetStates() {
    Set<PatchSet.Id> missing = new TreeSet<>(ReviewDbUtil.intKeyOrdering());
    for (Iterator<PatchSet> it = patchSets.values().iterator(); it.hasNext(); ) {
        PatchSet ps = it.next();
        if (ps.getRevision().equals(PARTIAL_PATCH_SET)) {
            missing.add(ps.getId());
            it.remove();
        }
    }
    for (Map.Entry<PatchSet.Id, PatchSetState> e : patchSetStates.entrySet()) {
        switch(e.getValue()) {
            case PUBLISHED:
            default:
                break;
            case DELETED:
                patchSets.remove(e.getKey());
                break;
            case DRAFT:
                PatchSet ps = patchSets.get(e.getKey());
                if (ps != null) {
                    ps.setDraft(true);
                }
                break;
        }
    }
    // Post-process other collections to remove items corresponding to deleted
    // (or otherwise missing) patch sets. This is safer than trying to prevent
    // insertion, as it will also filter out items racily added after the patch
    // set was deleted.
    changeMessagesByPatchSet.keys().retainAll(patchSets.keySet());
    int pruned = pruneEntitiesForMissingPatchSets(allChangeMessages, ChangeMessage::getPatchSetId, missing);
    pruned += pruneEntitiesForMissingPatchSets(comments.values(), c -> new PatchSet.Id(id, c.key.patchSetId), missing);
    pruned += pruneEntitiesForMissingPatchSets(approvals.values(), PatchSetApproval::getPatchSetId, missing);
    if (!missing.isEmpty()) {
        log.warn("ignoring {} additional entities due to missing patch sets: {}", pruned, missing);
    }
}
Also used : PatchLineComment(com.google.gerrit.reviewdb.client.PatchLineComment) FOOTER_SUBMITTED_WITH(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBMITTED_WITH) ListMultimap(com.google.common.collect.ListMultimap) MultimapBuilder(com.google.common.collect.MultimapBuilder) LoggerFactory(org.slf4j.LoggerFactory) FOOTER_HASHTAGS(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_HASHTAGS) HashBasedTable(com.google.common.collect.HashBasedTable) PatchSetApproval(com.google.gerrit.reviewdb.client.PatchSetApproval) ReviewerSet(com.google.gerrit.server.ReviewerSet) FooterKey(org.eclipse.jgit.revwalk.FooterKey) FOOTER_ASSIGNEE(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_ASSIGNEE) Comment(com.google.gerrit.reviewdb.client.Comment) InvalidObjectIdException(org.eclipse.jgit.errors.InvalidObjectIdException) FOOTER_PATCH_SET_DESCRIPTION(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET_DESCRIPTION) Tables(com.google.common.collect.Tables) Locale(java.util.Locale) Map(java.util.Map) GitDateParser(org.eclipse.jgit.util.GitDateParser) ParseException(java.text.ParseException) Splitter(com.google.common.base.Splitter) NoteMap(org.eclipse.jgit.notes.NoteMap) LinkedListMultimap(com.google.common.collect.LinkedListMultimap) Timer1(com.google.gerrit.metrics.Timer1) FOOTER_WORK_IN_PROGRESS(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_WORK_IN_PROGRESS) CHANGES(com.google.gerrit.server.notedb.NoteDbTable.CHANGES) ImmutableSet(com.google.common.collect.ImmutableSet) FOOTER_SUBJECT(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBJECT) ChangeMessage(com.google.gerrit.reviewdb.client.ChangeMessage) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) RawParseUtils(org.eclipse.jgit.util.RawParseUtils) ChangeNotesRevWalk(com.google.gerrit.server.notedb.ChangeNotesCommit.ChangeNotesRevWalk) Set(java.util.Set) ReviewerStatusUpdate(com.google.gerrit.server.ReviewerStatusUpdate) LabelType(com.google.gerrit.common.data.LabelType) Collectors.joining(java.util.stream.Collectors.joining) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) PersonIdent(org.eclipse.jgit.lib.PersonIdent) List(java.util.List) FOOTER_STATUS(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_STATUS) RefNames(com.google.gerrit.reviewdb.client.RefNames) AutoValue(com.google.auto.value.AutoValue) Optional(java.util.Optional) FOOTER_LABEL(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_LABEL) LabelId(com.google.gerrit.reviewdb.client.LabelId) FOOTER_READ_ONLY_UNTIL(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_READ_ONLY_UNTIL) FOOTER_SUBMISSION_ID(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBMISSION_ID) FOOTER_COMMIT(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_COMMIT) FOOTER_CHANGE_ID(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_CHANGE_ID) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) Change(com.google.gerrit.reviewdb.client.Change) HashMap(java.util.HashMap) Function(java.util.function.Function) TreeSet(java.util.TreeSet) Enums(com.google.common.base.Enums) SubmitRecord(com.google.gerrit.common.data.SubmitRecord) ArrayList(java.util.ArrayList) FOOTER_TAG(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_TAG) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) FOOTER_REAL_USER(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_REAL_USER) Lists(com.google.common.collect.Lists) Charset(java.nio.charset.Charset) Account(com.google.gerrit.reviewdb.client.Account) FOOTER_BRANCH(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_BRANCH) FOOTER_PATCH_SET(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET) FOOTER_GROUPS(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_GROUPS) FOOTER_PRIVATE(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PRIVATE) FOOTER_TOPIC(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_TOPIC) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) FOOTER_CURRENT(com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_CURRENT) ReviewDbUtil(com.google.gerrit.reviewdb.server.ReviewDbUtil) IOException(java.io.IOException) Ints(com.google.common.primitives.Ints) ObjectId(org.eclipse.jgit.lib.ObjectId) Address(com.google.gerrit.server.mail.Address) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) LabelVote(com.google.gerrit.server.util.LabelVote) ReviewerByEmailSet(com.google.gerrit.server.ReviewerByEmailSet) Table(com.google.common.collect.Table) Collections(java.util.Collections) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevId(com.google.gerrit.reviewdb.client.RevId) TreeSet(java.util.TreeSet) ChangeMessage(com.google.gerrit.reviewdb.client.ChangeMessage) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) LabelId(com.google.gerrit.reviewdb.client.LabelId) ObjectId(org.eclipse.jgit.lib.ObjectId) RevId(com.google.gerrit.reviewdb.client.RevId) Map(java.util.Map) NoteMap(org.eclipse.jgit.notes.NoteMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Example 50 with PatchSet

use of com.google.gerrit.reviewdb.client.PatchSet in project gerrit by GerritCodeReview.

the class ChangeBundle method changeMessagesMatch.

private static boolean changeMessagesMatch(ChangeBundle bundleA, ChangeMessage a, ChangeBundle bundleB, ChangeMessage b) {
    List<String> tempDiffs = new ArrayList<>();
    String temp = "temp";
    // ReviewDb allows timestamps before patch set was created, but NoteDb
    // truncates this to the patch set creation timestamp.
    Timestamp ta = a.getWrittenOn();
    Timestamp tb = b.getWrittenOn();
    PatchSet psa = bundleA.patchSets.get(a.getPatchSetId());
    PatchSet psb = bundleB.patchSets.get(b.getPatchSetId());
    boolean excludePatchSet = false;
    boolean excludeWrittenOn = false;
    if (bundleA.source == REVIEW_DB && bundleB.source == NOTE_DB) {
        excludePatchSet = a.getPatchSetId() == null;
        excludeWrittenOn = psa != null && psb != null && ta.before(psa.getCreatedOn()) && tb.equals(psb.getCreatedOn());
    } else if (bundleA.source == NOTE_DB && bundleB.source == REVIEW_DB) {
        excludePatchSet = b.getPatchSetId() == null;
        excludeWrittenOn = psa != null && psb != null && tb.before(psb.getCreatedOn()) && ta.equals(psa.getCreatedOn());
    }
    List<String> exclude = Lists.newArrayList("key");
    if (excludePatchSet) {
        exclude.add("patchset");
    }
    if (excludeWrittenOn) {
        exclude.add("writtenOn");
    }
    diffColumnsExcluding(tempDiffs, ChangeMessage.class, temp, bundleA, a, bundleB, b, exclude);
    return tempDiffs.isEmpty();
}
Also used : ArrayList(java.util.ArrayList) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Timestamp(java.sql.Timestamp)

Aggregations

PatchSet (com.google.gerrit.reviewdb.client.PatchSet)124 Change (com.google.gerrit.reviewdb.client.Change)51 Test (org.junit.Test)44 ObjectId (org.eclipse.jgit.lib.ObjectId)35 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)27 RevCommit (org.eclipse.jgit.revwalk.RevCommit)26 Repository (org.eclipse.jgit.lib.Repository)21 RevId (com.google.gerrit.reviewdb.client.RevId)20 ChangeControl (com.google.gerrit.server.project.ChangeControl)20 ChangeData (com.google.gerrit.server.query.change.ChangeData)19 OrmException (com.google.gwtorm.server.OrmException)19 Timestamp (java.sql.Timestamp)18 RevWalk (org.eclipse.jgit.revwalk.RevWalk)15 Project (com.google.gerrit.reviewdb.client.Project)14 PatchSetApproval (com.google.gerrit.reviewdb.client.PatchSetApproval)11 TestChanges.newPatchSet (com.google.gerrit.testutil.TestChanges.newPatchSet)11 IOException (java.io.IOException)11 ArrayList (java.util.ArrayList)11 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)10 Account (com.google.gerrit.reviewdb.client.Account)10