Example usage for org.eclipse.jgit.lib ObjectId fromString

List of usage examples for org.eclipse.jgit.lib ObjectId fromString

Introduction

In this page you can find the example usage for org.eclipse.jgit.lib ObjectId fromString.

Prototype

public static ObjectId fromString(String str) 

Source Link

Document

Convert an ObjectId from hex characters.

Usage

From source file:com.google.gerrit.server.git.MergedByPushOp.java

License:Apache License

private PatchSetInfo getPatchSetInfo(ChangeContext ctx) throws IOException {
    RevWalk rw = ctx.getRevWalk();//from  w  ww.jav  a  2  s  .  c  om
    RevCommit commit = rw.parseCommit(ObjectId.fromString(checkNotNull(patchSet).getRevision().get()));
    return patchSetInfoFactory.get(rw, commit, psId);
}

From source file:com.google.gerrit.server.git.MergeOp.java

License:Apache License

private ListMultimap<SubmitType, ChangeData> validateChangeList(List<ChangeData> submitted)
        throws MergeException {
    logDebug("Validating {} changes", submitted.size());
    ListMultimap<SubmitType, ChangeData> toSubmit = ArrayListMultimap.create();

    Map<String, Ref> allRefs;
    try {/*from   w w  w  .  ja  v a2s  . c  o  m*/
        allRefs = repo.getRefDatabase().getRefs(ALL);
    } catch (IOException e) {
        throw new MergeException(e.getMessage(), e);
    }

    Set<ObjectId> tips = new HashSet<>();
    for (Ref r : allRefs.values()) {
        tips.add(r.getObjectId());
    }

    for (ChangeData cd : submitted) {
        ChangeControl ctl;
        Change chg;
        try {
            ctl = cd.changeControl();
            // Reload change in case index was stale.
            chg = cd.reloadChange();
        } catch (OrmException e) {
            throw new MergeException("Failed to validate changes", e);
        }
        Change.Id changeId = cd.getId();
        if (chg.getStatus() != Change.Status.NEW) {
            logDebug("Change {} is not new: {}", changeId, chg.getStatus());
            continue;
        }
        if (chg.currentPatchSetId() == null) {
            logError("Missing current patch set on change " + changeId);
            commits.put(changeId, CodeReviewCommit.noPatchSet(ctl));
            continue;
        }

        PatchSet ps;
        Branch.NameKey destBranch = chg.getDest();
        try {
            ps = cd.currentPatchSet();
        } catch (OrmException e) {
            throw new MergeException("Cannot query the database", e);
        }
        if (ps == null || ps.getRevision() == null || ps.getRevision().get() == null) {
            logError("Missing patch set or revision on change " + changeId);
            commits.put(changeId, CodeReviewCommit.noPatchSet(ctl));
            continue;
        }

        String idstr = ps.getRevision().get();
        ObjectId id;
        try {
            id = ObjectId.fromString(idstr);
        } catch (IllegalArgumentException iae) {
            logError("Invalid revision on patch set " + ps.getId());
            commits.put(changeId, CodeReviewCommit.noPatchSet(ctl));
            continue;
        }

        if (!tips.contains(id)) {
            // TODO Technically the proper way to do this test is to use a
            // RevWalk on "$id --not --all" and test for an empty set. But
            // that is way slower than looking for a ref directly pointing
            // at the desired tip. We should always have a ref available.
            //
            // TODO this is actually an error, the branch is gone but we
            // want to merge the issue. We can't safely do that if the
            // tip is not reachable.
            //
            logError("Revision " + idstr + " of patch set " + ps.getId() + " is not contained in any ref");
            commits.put(changeId, CodeReviewCommit.revisionGone(ctl));
            continue;
        }

        CodeReviewCommit commit;
        try {
            commit = rw.parseCommit(id);
        } catch (IOException e) {
            logError("Invalid commit " + idstr + " on patch set " + ps.getId(), e);
            commits.put(changeId, CodeReviewCommit.revisionGone(ctl));
            continue;
        }

        // TODO(dborowitz): Consider putting ChangeData in CodeReviewCommit.
        commit.setControl(ctl);
        commit.setPatchsetId(ps.getId());
        commits.put(changeId, commit);

        MergeValidators mergeValidators = mergeValidatorsFactory.create();
        try {
            mergeValidators.validatePreMerge(repo, commit, destProject, destBranch, ps.getId());
        } catch (MergeValidationException mve) {
            logDebug("Revision {} of patch set {} failed validation: {}", idstr, ps.getId(), mve.getStatus());
            commit.setStatusCode(mve.getStatus());
            continue;
        }

        SubmitType submitType;
        submitType = getSubmitType(commit.getControl(), ps);
        if (submitType == null) {
            logError("No submit type for revision " + idstr + " of patch set " + ps.getId());
            commit.setStatusCode(CommitMergeStatus.NO_SUBMIT_TYPE);
            continue;
        }

        commit.add(canMergeFlag);
        toSubmit.put(submitType, cd);
    }
    logDebug("Submitting on this run: {}", toSubmit);
    return toSubmit;
}

From source file:com.google.gerrit.server.git.MergeSuperSet.java

License:Apache License

private ChangeSet completeChangeSetWithoutTopic(ReviewDb db, ChangeSet changes)
        throws MissingObjectException, IncorrectObjectTypeException, IOException, OrmException {
    List<ChangeData> ret = new ArrayList<>();

    Multimap<Project.NameKey, Change.Id> pc = changes.changesByProject();
    for (Project.NameKey project : pc.keySet()) {
        try (Repository repo = repoManager.openRepository(project);
                RevWalk rw = CodeReviewCommit.newRevWalk(repo)) {
            for (Change.Id cId : pc.get(project)) {
                ChangeData cd = changeDataFactory.create(db, cId);

                SubmitTypeRecord r = new SubmitRuleEvaluator(cd).getSubmitType();
                if (r.status != SubmitTypeRecord.Status.OK) {
                    logErrorAndThrow("Failed to get submit type for " + cd.getId());
                }//from   ww w.  ja v  a  2  s  . c  o  m
                if (r.type == SubmitType.CHERRY_PICK) {
                    ret.add(cd);
                    continue;
                }

                // Get the underlying git commit object
                PatchSet ps = cd.currentPatchSet();
                String objIdStr = ps.getRevision().get();
                RevCommit commit = rw.parseCommit(ObjectId.fromString(objIdStr));

                // Collect unmerged ancestors
                Branch.NameKey destBranch = cd.change().getDest();
                repo.getRefDatabase().refresh();
                Ref ref = repo.getRefDatabase().getRef(destBranch.get());

                rw.reset();
                rw.sort(RevSort.TOPO);
                rw.markStart(commit);
                if (ref != null) {
                    RevCommit head = rw.parseCommit(ref.getObjectId());
                    rw.markUninteresting(head);
                }

                List<String> hashes = new ArrayList<>();
                for (RevCommit c : rw) {
                    hashes.add(c.name());
                }

                if (!hashes.isEmpty()) {
                    // Merged changes are ok to exclude
                    Iterable<ChangeData> destChanges = queryProvider.get()
                            .byCommitsOnBranchNotMerged(cd.change().getDest(), hashes);
                    for (ChangeData chd : destChanges) {
                        ret.add(chd);
                    }
                }
            }
        }
    }

    return new ChangeSet(ret);
}

From source file:com.google.gerrit.server.git.RebaseIfNecessary.java

License:Apache License

@Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip, final List<CodeReviewCommit> toMerge)
        throws MergeException {
    CodeReviewCommit newMergeTip = mergeTip;
    sort(toMerge);/*from  ww w . j a va  2 s .c  o m*/

    while (!toMerge.isEmpty()) {
        final CodeReviewCommit n = toMerge.remove(0);

        if (newMergeTip == null) {
            // The branch is unborn. Take a fast-forward resolution to
            // create the branch.
            //
            newMergeTip = n;
            n.statusCode = CommitMergeStatus.CLEAN_MERGE;

        } else if (n.getParentCount() == 0) {
            // Refuse to merge a root commit into an existing branch,
            // we cannot obtain a delta for the rebase to apply.
            //
            n.statusCode = CommitMergeStatus.CANNOT_REBASE_ROOT;

        } else if (n.getParentCount() == 1) {
            if (args.mergeUtil.canFastForward(args.mergeSorter, newMergeTip, args.rw, n)) {
                newMergeTip = n;
                n.statusCode = CommitMergeStatus.CLEAN_MERGE;

            } else {
                try {
                    final IdentifiedUser uploader = args.identifiedUserFactory
                            .create(args.mergeUtil.getSubmitter(n.patchsetId).getAccountId());
                    final PatchSet newPatchSet = rebaseChange.rebase(args.repo, args.rw, args.inserter,
                            n.patchsetId, n.change, uploader, newMergeTip, args.mergeUtil, committerIdent,
                            false, false, ValidatePolicy.NONE);
                    List<PatchSetApproval> approvals = Lists.newArrayList();
                    for (PatchSetApproval a : args.mergeUtil.getApprovalsForCommit(n)) {
                        approvals.add(new PatchSetApproval(newPatchSet.getId(), a));
                    }
                    args.db.patchSetApprovals().insert(approvals);
                    newMergeTip = (CodeReviewCommit) args.rw
                            .parseCommit(ObjectId.fromString(newPatchSet.getRevision().get()));
                    newMergeTip.copyFrom(n);
                    newMergeTip.patchsetId = newPatchSet.getId();
                    newMergeTip.change = args.db.changes().get(newPatchSet.getId().getParentKey());
                    newMergeTip.statusCode = CommitMergeStatus.CLEAN_REBASE;
                    newCommits.put(newPatchSet.getId().getParentKey(), newMergeTip);
                    setRefLogIdent(args.mergeUtil.getSubmitter(n.patchsetId));
                } catch (PathConflictException e) {
                    n.statusCode = CommitMergeStatus.PATH_CONFLICT;
                } catch (NoSuchChangeException e) {
                    throw new MergeException("Cannot rebase " + n.name(), e);
                } catch (OrmException e) {
                    throw new MergeException("Cannot rebase " + n.name(), e);
                } catch (IOException e) {
                    throw new MergeException("Cannot rebase " + n.name(), e);
                } catch (InvalidChangeOperationException e) {
                    throw new MergeException("Cannot rebase " + n.name(), e);
                }
            }

        } else if (n.getParentCount() > 1) {
            // There are multiple parents, so this is a merge commit. We
            // don't want to rebase the merge as clients can't easily
            // rebase their history with that merge present and replaced
            // by an equivalent merge with a different first parent. So
            // instead behave as though MERGE_IF_NECESSARY was configured.
            //
            try {
                if (args.rw.isMergedInto(newMergeTip, n)) {
                    newMergeTip = n;
                } else {
                    newMergeTip = args.mergeUtil.mergeOneCommit(args.myIdent, args.repo, args.rw, args.inserter,
                            args.canMergeFlag, args.destBranch, newMergeTip, n);
                }
                final PatchSetApproval submitApproval = args.mergeUtil.markCleanMerges(args.rw,
                        args.canMergeFlag, newMergeTip, args.alreadyAccepted);
                setRefLogIdent(submitApproval);
            } catch (IOException e) {
                throw new MergeException("Cannot merge " + n.name(), e);
            }
        }

        args.alreadyAccepted.add(newMergeTip);
    }

    return newMergeTip;
}

From source file:com.google.gerrit.server.git.ReceiveCommitsAdvertiseRefsHook.java

License:Apache License

private Set<ObjectId> advertiseHistory(Iterable<Ref> sending, BaseReceivePack rp) {
    Set<ObjectId> toInclude = Sets.newHashSet();

    // Advertise some recent open changes, in case a commit is based one.
    final int limit = 32;
    try {/*from  w w  w.  ja  v a 2 s.c  o  m*/
        Set<PatchSet.Id> toGet = Sets.newHashSetWithExpectedSize(limit);
        for (ChangeData cd : queryProvider.get().enforceVisibility(true).setLimit(limit)
                .byProjectOpen(projectName)) {
            PatchSet.Id id = cd.change().currentPatchSetId();
            if (id != null) {
                toGet.add(id);
            }
        }
        for (PatchSet ps : db.patchSets().get(toGet)) {
            if (ps.getRevision() != null && ps.getRevision().get() != null) {
                toInclude.add(ObjectId.fromString(ps.getRevision().get()));
            }
        }
    } catch (OrmException err) {
        log.error("Cannot list open changes of " + projectName, err);
    }

    // Size of an additional ".have" line.
    final int haveLineLen = 4 + Constants.OBJECT_ID_STRING_LENGTH + 1 + 5 + 1;

    // Maximum number of bytes to "waste" in the advertisement with
    // a peek at this repository's current reachable history.
    final int maxExtraSize = 8192;

    // Number of recent commits to advertise immediately, hoping to
    // show a client a nearby merge base.
    final int base = 64;

    // Number of commits to skip once base has already been shown.
    final int step = 16;

    // Total number of commits to extract from the history.
    final int max = maxExtraSize / haveLineLen;

    // Scan history until the advertisement is full.
    Set<ObjectId> alreadySending = Sets.newHashSet();
    RevWalk rw = rp.getRevWalk();
    for (Ref ref : sending) {
        try {
            if (ref.getObjectId() != null) {
                alreadySending.add(ref.getObjectId());
                rw.markStart(rw.parseCommit(ref.getObjectId()));
            }
        } catch (IOException badCommit) {
            continue;
        }
    }

    int stepCnt = 0;
    RevCommit c;
    try {
        while ((c = rw.next()) != null && toInclude.size() < max) {
            if (alreadySending.contains(c) || toInclude.contains(c) || c.getParentCount() > 1) {
                // Do nothing
            } else if (toInclude.size() < base) {
                toInclude.add(c);
            } else {
                stepCnt = ++stepCnt % step;
                if (stepCnt == 0) {
                    toInclude.add(c);
                }
            }
        }
    } catch (IOException err) {
        log.error("Error trying to advertise history on " + projectName, err);
    }
    rw.reset();
    return toInclude;
}

From source file:com.google.gerrit.server.git.strategy.RebaseIfNecessary.java

License:Apache License

@Override
protected MergeTip _run(final CodeReviewCommit branchTip, final Collection<CodeReviewCommit> toMerge)
        throws MergeException {
    MergeTip mergeTip = new MergeTip(branchTip, toMerge);
    List<CodeReviewCommit> sorted = sort(toMerge);
    while (!sorted.isEmpty()) {
        CodeReviewCommit n = sorted.remove(0);

        if (mergeTip.getCurrentTip() == null) {
            // The branch is unborn. Take a fast-forward resolution to
            // create the branch.
            //// w ww . j av a 2 s  .com
            n.setStatusCode(CommitMergeStatus.CLEAN_MERGE);
            mergeTip.moveTipTo(n, n);

        } else if (n.getParentCount() == 0) {
            // Refuse to merge a root commit into an existing branch,
            // we cannot obtain a delta for the rebase to apply.
            //
            n.setStatusCode(CommitMergeStatus.CANNOT_REBASE_ROOT);

        } else if (n.getParentCount() == 1) {
            if (args.mergeUtil.canFastForward(args.mergeSorter, mergeTip.getCurrentTip(), args.rw, n)) {
                n.setStatusCode(CommitMergeStatus.CLEAN_MERGE);
                mergeTip.moveTipTo(n, n);

            } else {
                try {
                    PatchSet newPatchSet = rebaseChange.rebase(args.repo, args.rw, args.inserter, n.change(),
                            n.getPatchsetId(), args.caller, mergeTip.getCurrentTip(), args.mergeUtil,
                            args.serverIdent.get(), false, ValidatePolicy.NONE);
                    List<PatchSetApproval> approvals = Lists.newArrayList();
                    for (PatchSetApproval a : args.approvalsUtil.byPatchSet(args.db, n.getControl(),
                            n.getPatchsetId())) {
                        approvals.add(new PatchSetApproval(newPatchSet.getId(), a));
                    }
                    // rebaseChange.rebase() may already have copied some approvals,
                    // use upsert, not insert, to avoid constraint violation on database
                    args.db.patchSetApprovals().upsert(approvals);
                    CodeReviewCommit newTip = args.rw
                            .parseCommit(ObjectId.fromString(newPatchSet.getRevision().get()));
                    mergeTip.moveTipTo(newTip, newTip);
                    n.change().setCurrentPatchSet(
                            patchSetInfoFactory.get(mergeTip.getCurrentTip(), newPatchSet.getId()));
                    mergeTip.getCurrentTip().copyFrom(n);
                    mergeTip.getCurrentTip()
                            .setControl(args.changeControlFactory.controlFor(n.change(), args.caller));
                    mergeTip.getCurrentTip().setPatchsetId(newPatchSet.getId());
                    mergeTip.getCurrentTip().setStatusCode(CommitMergeStatus.CLEAN_REBASE);
                    newCommits.put(newPatchSet.getId().getParentKey(), mergeTip.getCurrentTip());
                    setRefLogIdent();
                } catch (MergeConflictException e) {
                    n.setStatusCode(CommitMergeStatus.REBASE_MERGE_CONFLICT);
                } catch (NoSuchChangeException | OrmException | IOException
                        | InvalidChangeOperationException e) {
                    throw new MergeException("Cannot rebase " + n.name(), e);
                }
            }

        } else if (n.getParentCount() > 1) {
            // There are multiple parents, so this is a merge commit. We
            // don't want to rebase the merge as clients can't easily
            // rebase their history with that merge present and replaced
            // by an equivalent merge with a different first parent. So
            // instead behave as though MERGE_IF_NECESSARY was configured.
            //
            try {
                if (args.rw.isMergedInto(mergeTip.getCurrentTip(), n)) {
                    mergeTip.moveTipTo(n, n);
                } else {
                    PersonIdent myIdent = args.serverIdent.get();
                    mergeTip.moveTipTo(args.mergeUtil.mergeOneCommit(myIdent, myIdent, args.repo, args.rw,
                            args.inserter, args.canMergeFlag, args.destBranch, mergeTip.getCurrentTip(), n), n);
                }
                args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag, mergeTip.getCurrentTip(),
                        args.alreadyAccepted);
                setRefLogIdent();
            } catch (IOException e) {
                throw new MergeException("Cannot merge " + n.name(), e);
            }
        }

        args.alreadyAccepted.add(mergeTip.getCurrentTip());
    }

    return mergeTip;
}

From source file:com.google.gerrit.server.index.change.StalenessCheckerTest.java

License:Apache License

@Test
public void refStateToByteArray() {
    assertThat(new String(RefState.create("refs/heads/foo", ObjectId.fromString(SHA1)).toByteArray(P1), UTF_8))
            .isEqualTo(P1 + ":refs/heads/foo:" + SHA1);
    assertThat(new String(RefState.create("refs/heads/foo", (ObjectId) null).toByteArray(P1), UTF_8))
            .isEqualTo(P1 + ":refs/heads/foo:" + ObjectId.zeroId().name());
}

From source file:com.google.gerrit.server.mail.PatchSetNotificationSender.java

License:Apache License

public void send(final ChangeNotes notes, final ChangeUpdate update, final boolean newChange,
        final IdentifiedUser currentUser, final Change updatedChange, final PatchSet updatedPatchSet,
        final LabelTypes labelTypes) throws OrmException, IOException {
    try (Repository git = repoManager.openRepository(updatedChange.getProject())) {
        final RevCommit commit;
        try (RevWalk revWalk = new RevWalk(git)) {
            commit = revWalk.parseCommit(ObjectId.fromString(updatedPatchSet.getRevision().get()));
        }/* w w w.  ja  v a2 s .  co  m*/
        final PatchSetInfo info = patchSetInfoFactory.get(commit, updatedPatchSet.getId());
        final List<FooterLine> footerLines = commit.getFooterLines();
        final Account.Id me = currentUser.getAccountId();
        final MailRecipients recipients = getRecipientsFromFooters(accountResolver, updatedPatchSet,
                footerLines);
        recipients.remove(me);

        if (newChange) {
            approvalsUtil.addReviewers(db.get(), update, labelTypes, updatedChange, updatedPatchSet, info,
                    recipients.getReviewers(), Collections.<Account.Id>emptySet());
            try {
                CreateChangeSender cm = createChangeSenderFactory.create(updatedChange.getId());
                cm.setFrom(me);
                cm.setPatchSet(updatedPatchSet, info);
                cm.addReviewers(recipients.getReviewers());
                cm.addExtraCC(recipients.getCcOnly());
                cm.send();
            } catch (Exception e) {
                log.error("Cannot send email for new change " + updatedChange.getId(), e);
            }
        } else {
            approvalsUtil.addReviewers(db.get(), update, labelTypes, updatedChange, updatedPatchSet, info,
                    recipients.getReviewers(), approvalsUtil.getReviewers(db.get(), notes).values());
            final ChangeMessage msg = new ChangeMessage(
                    new ChangeMessage.Key(updatedChange.getId(), ChangeUtil.messageUUID(db.get())), me,
                    updatedPatchSet.getCreatedOn(), updatedPatchSet.getId());
            msg.setMessage("Uploaded patch set " + updatedPatchSet.getPatchSetId() + ".");
            try {
                ReplacePatchSetSender cm = replacePatchSetFactory.create(updatedChange.getId());
                cm.setFrom(me);
                cm.setPatchSet(updatedPatchSet, info);
                cm.setChangeMessage(msg);
                cm.addReviewers(recipients.getReviewers());
                cm.addExtraCC(recipients.getCcOnly());
                cm.send();
            } catch (Exception e) {
                log.error("Cannot send email for new patch set " + updatedPatchSet.getId(), e);
            }
        }
    }
}

From source file:com.google.gerrit.server.notedb.ChangeNotesTest.java

License:Apache License

@Test
public void patchLineCommentsDeleteAllDrafts() throws Exception {
    Change c = newChange();/*  www .  ja  v a 2  s.  c  o m*/
    String uuid = "uuid";
    String rev = "abcd1234abcd1234abcd1234abcd1234abcd1234";
    ObjectId objId = ObjectId.fromString(rev);
    CommentRange range = new CommentRange(1, 1, 2, 1);
    PatchSet.Id psId = c.currentPatchSetId();
    String filename = "filename";
    short side = (short) 1;

    ChangeUpdate update = newUpdate(c, otherUser);
    Timestamp now = TimeUtil.nowTs();
    PatchLineComment comment = newComment(psId, filename, uuid, range, range.getEndLine(), otherUser, null, now,
            "comment on ps1", side, rev, Status.DRAFT);
    update.setPatchSetId(psId);
    update.upsertComment(comment);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertThat(notes.getDraftComments(otherUserId)).hasSize(1);
    assertThat(notes.getDraftCommentNotes().getNoteMap().contains(objId)).isTrue();

    update = newUpdate(c, otherUser);
    now = TimeUtil.nowTs();
    update.setPatchSetId(psId);
    update.deleteComment(comment);
    update.commit();

    notes = newNotes(c);
    assertThat(notes.getDraftComments(otherUserId)).isEmpty();
    assertThat(notes.getDraftCommentNotes().getNoteMap()).isNull();
}

From source file:com.google.gerrit.server.notedb.ChangeNotesTest.java

License:Apache License

@Test
public void patchLineCommentsDeleteAllDraftsForOneRevision() throws Exception {
    Change c = newChange();//from  w  w  w.  java 2  s. c o  m
    String uuid = "uuid";
    String rev1 = "abcd1234abcd1234abcd1234abcd1234abcd1234";
    String rev2 = "abcd4567abcd4567abcd4567abcd4567abcd4567";
    ObjectId objId1 = ObjectId.fromString(rev1);
    ObjectId objId2 = ObjectId.fromString(rev2);
    CommentRange range = new CommentRange(1, 1, 2, 1);
    PatchSet.Id ps1 = c.currentPatchSetId();
    String filename = "filename1";
    short side = (short) 1;

    ChangeUpdate update = newUpdate(c, otherUser);
    Timestamp now = TimeUtil.nowTs();
    PatchLineComment comment1 = newComment(ps1, filename, uuid, range, range.getEndLine(), otherUser, null, now,
            "comment on ps1", side, rev1, Status.DRAFT);
    update.setPatchSetId(ps1);
    update.upsertComment(comment1);
    update.commit();

    incrementPatchSet(c);
    PatchSet.Id ps2 = c.currentPatchSetId();

    update = newUpdate(c, otherUser);
    now = TimeUtil.nowTs();
    PatchLineComment comment2 = newComment(ps2, filename, uuid, range, range.getEndLine(), otherUser, null, now,
            "comment on ps2", side, rev2, Status.DRAFT);
    update.setPatchSetId(ps2);
    update.upsertComment(comment2);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertThat(notes.getDraftComments(otherUserId)).hasSize(2);

    update = newUpdate(c, otherUser);
    now = TimeUtil.nowTs();
    update.setPatchSetId(ps2);
    update.deleteComment(comment2);
    update.commit();

    notes = newNotes(c);
    assertThat(notes.getDraftComments(otherUserId)).hasSize(1);
    NoteMap noteMap = notes.getDraftCommentNotes().getNoteMap();
    assertThat(noteMap.contains(objId1)).isTrue();
    assertThat(noteMap.contains(objId2)).isFalse();
}