use of com.google.gerrit.entities.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.id().get() > 1) {
try {
Collection<PatchSet> patchSetCollection = change.patchSets();
PatchSet priorPs = patch;
for (PatchSet ps : patchSetCollection) {
if (ps.id().get() < patch.id().get() && (ps.id().get() > priorPs.id().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, priorPs.commitId(), patch.commitId());
}
} catch (StorageException e) {
// Do nothing; assume we have a complex change
logger.atWarning().withCause(e).log("Unable to get change kind for patchSet %s of change %s", patch.number(), change.getId());
}
}
logger.atFine().log("Change kind for patchSet %s of change %s: %s", patch.number(), change.getId(), kind);
return kind;
}
use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.
the class ConsistencyChecker method checkPatchSets.
private boolean checkPatchSets() {
List<PatchSet> all;
try {
// Iterate in descending order.
all = PS_ID_ORDER.sortedCopy(psUtil.byChange(notes));
} catch (StorageException e) {
ProblemInfo problem = problem("Failed to look up patch sets");
logger.atWarning().withCause(e).log("Error in consistency check of change %s: %s", notes.getChangeId(), problem);
return false;
}
patchSetsBySha = MultimapBuilder.hashKeys(all.size()).treeSetValues(PS_ID_ORDER).build();
Map<String, Ref> refs;
try {
refs = repo.getRefDatabase().exactRef(all.stream().map(ps -> ps.id().toRefName()).toArray(String[]::new));
} catch (IOException e) {
ProblemInfo problem = problem("Error reading refs");
logger.atWarning().withCause(e).log("Error in consistency check of change %s: %s", notes.getChangeId(), problem);
refs = Collections.emptyMap();
}
List<DeletePatchSetFromDbOp> deletePatchSetOps = new ArrayList<>();
for (PatchSet ps : all) {
// Check revision format.
int psNum = ps.id().get();
String refName = ps.id().toRefName();
ObjectId objId = ps.commitId();
patchSetsBySha.put(objId, ps);
// Check ref existence.
ProblemInfo refProblem = null;
Ref ref = refs.get(refName);
if (ref == null) {
refProblem = problem("Ref missing: " + refName);
} else if (!objId.equals(ref.getObjectId())) {
String actual = ref.getObjectId() != null ? ref.getObjectId().name() : "null";
refProblem = problem(String.format("Expected %s to point to %s, found %s", ref.getName(), objId.name(), actual));
}
// Check object existence.
RevCommit psCommit = parseCommit(objId, String.format("patch set %d", psNum));
if (psCommit == null) {
if (fix != null && fix.deletePatchSetIfCommitMissing) {
deletePatchSetOps.add(new DeletePatchSetFromDbOp(lastProblem(), ps.id()));
}
continue;
} else if (refProblem != null && fix != null) {
fixPatchSetRef(refProblem, ps);
}
if (ps.id().equals(change().currentPatchSetId())) {
currPsCommit = psCommit;
}
}
// Delete any bad patch sets found above, in a single update.
deletePatchSets(deletePatchSetOps);
// Check for duplicates.
for (Map.Entry<ObjectId, Collection<PatchSet>> e : patchSetsBySha.asMap().entrySet()) {
if (e.getValue().size() > 1) {
problem(String.format("Multiple patch sets pointing to %s: %s", e.getKey().name(), Collections2.transform(e.getValue(), PatchSet::number)));
}
}
return currPs != null && currPsCommit != null;
}
use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.
the class Revisions method loadEdit.
// TODO(issue-15517): Fix the JdkObsolete issue with Date once JGit's PersonIdent class supports
// Instants
@SuppressWarnings("JdkObsolete")
private ImmutableList<RevisionResource> loadEdit(ChangeResource change, @Nullable ObjectId commitId) throws AuthException, IOException {
Optional<ChangeEdit> edit = editUtil.byChange(change.getNotes(), change.getUser());
if (edit.isPresent()) {
RevCommit editCommit = edit.get().getEditCommit();
PatchSet ps = PatchSet.builder().id(PatchSet.id(change.getId(), 0)).commitId(editCommit).uploader(change.getUser().getAccountId()).createdOn(editCommit.getCommitterIdent().getWhen().toInstant()).build();
if (commitId == null || editCommit.equals(commitId)) {
return ImmutableList.of(new RevisionResource(change, ps, edit));
}
}
return ImmutableList.of();
}
use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.
the class Submit method unmergeableChanges.
public Collection<ChangeData> unmergeableChanges(ChangeSet cs) throws IOException {
Set<ChangeData> mergeabilityMap = new HashSet<>();
Set<ObjectId> outDatedPatchsets = new HashSet<>();
for (ChangeData change : cs.changes()) {
mergeabilityMap.add(change);
// Add all the patchsets commit ids except the current patchset.
outDatedPatchsets.addAll(change.notes().getPatchSets().values().stream().map(p -> p.commitId()).collect(Collectors.toSet()));
outDatedPatchsets.remove(change.currentPatchSet().commitId());
}
ListMultimap<BranchNameKey, ChangeData> cbb = cs.changesByBranch();
for (BranchNameKey branch : cbb.keySet()) {
Collection<ChangeData> targetBranch = cbb.get(branch);
HashMap<Change.Id, RevCommit> commits = findCommits(targetBranch, branch.project());
Set<ObjectId> allParents = Sets.newHashSetWithExpectedSize(cs.size());
for (RevCommit commit : commits.values()) {
for (RevCommit parent : commit.getParents()) {
allParents.add(parent.getId());
}
}
for (ChangeData change : targetBranch) {
RevCommit commit = commits.get(change.getId());
boolean isMergeCommit = commit.getParentCount() > 1;
boolean isLastInChain = !allParents.contains(commit.getId());
if (Arrays.stream(commit.getParents()).anyMatch(c -> outDatedPatchsets.contains(c.getId())) && !isCherryPickSubmit(change)) {
// cherry-pick.
continue;
}
// Recheck mergeability rather than using value stored in the index,
// which may be stale.
// TODO(dborowitz): This is ugly; consider providing a way to not read
// stored fields from the index in the first place.
change.setMergeable(null);
Boolean mergeable = change.isMergeable();
if (mergeable == null) {
// Skip whole check, cannot determine if mergeable
return null;
}
if (mergeable) {
mergeabilityMap.remove(change);
}
if (isLastInChain && isMergeCommit && mergeable) {
for (ChangeData c : targetBranch) {
mergeabilityMap.remove(c);
}
break;
}
}
}
return mergeabilityMap;
}
use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.
the class Revert method apply.
@Override
public Response<ChangeInfo> apply(ChangeResource rsrc, RevertInput input) throws IOException, RestApiException, UpdateException, NoSuchChangeException, PermissionBackendException, NoSuchProjectException, ConfigInvalidException {
Change change = rsrc.getChange();
if (!change.isMerged()) {
throw new ResourceConflictException("change is " + ChangeUtil.status(change));
}
contributorAgreements.check(rsrc.getProject(), rsrc.getUser());
permissionBackend.user(rsrc.getUser()).ref(change.getDest()).check(CREATE_CHANGE);
projectCache.get(rsrc.getProject()).orElseThrow(illegalState(rsrc.getProject())).checkStatePermitsWrite();
rsrc.permissions().check(REVERT);
ChangeNotes notes = rsrc.getNotes();
Change.Id changeIdToRevert = notes.getChangeId();
PatchSet.Id patchSetId = notes.getChange().currentPatchSetId();
PatchSet patch = psUtil.get(notes, patchSetId);
if (patch == null) {
throw new ResourceNotFoundException(changeIdToRevert.toString());
}
return Response.ok(json.noOptions().format(rsrc.getProject(), commitUtil.createRevertChange(notes, rsrc.getUser(), input, TimeUtil.now())));
}
Aggregations