use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.
the class ChangeQueryBuilder method destination.
@Operator
public Predicate<ChangeData> destination(String value) throws QueryParseException {
// [name=]<name>[,user=<user>] || [user=<user>,][name=]<name>
PredicateArgs inputArgs = new PredicateArgs(value);
String name = null;
Account.Id account = null;
try (Repository git = args.repoManager.openRepository(args.allUsersName)) {
// [name=]<name>
if (inputArgs.keyValue.containsKey(ARG_ID_NAME)) {
name = inputArgs.keyValue.get(ARG_ID_NAME).value();
} else if (inputArgs.positional.size() == 1) {
name = Iterables.getOnlyElement(inputArgs.positional);
} else if (inputArgs.positional.size() > 1) {
throw new QueryParseException("Error parsing named destination: " + value);
}
// [,user=<user>]
if (inputArgs.keyValue.containsKey(ARG_ID_USER)) {
Set<Account.Id> accounts = parseAccount(inputArgs.keyValue.get(ARG_ID_USER).value());
if (accounts != null && accounts.size() > 1) {
throw error(String.format("\"%s\" resolves to multiple accounts", inputArgs.keyValue.get(ARG_ID_USER)));
}
account = (accounts == null ? self() : Iterables.getOnlyElement(accounts));
} else {
account = self();
}
VersionedAccountDestinations d = VersionedAccountDestinations.forUser(account);
d.load(args.allUsersName, git);
Set<BranchNameKey> destinations = d.getDestinationList().getDestinations(name);
if (destinations != null && !destinations.isEmpty()) {
return new DestinationPredicate(destinations, value);
}
} catch (RepositoryNotFoundException e) {
throw new QueryParseException("Unknown named destination (no " + args.allUsersName + " repo): " + name, e);
} catch (IOException | ConfigInvalidException e) {
throw new QueryParseException("Error parsing named destination: " + value, e);
}
throw new QueryParseException("Unknown named destination: " + name);
}
use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.
the class RevertSubmission method revertSubmission.
private RevertSubmissionInfo revertSubmission(List<ChangeData> changeData, RevertInput revertInput) throws RestApiException, IOException, UpdateException, ConfigInvalidException, StorageException, PermissionBackendException {
Multimap<BranchNameKey, ChangeData> changesPerProjectAndBranch = ArrayListMultimap.create();
changeData.stream().forEach(c -> changesPerProjectAndBranch.put(c.change().getDest(), c));
cherryPickInput = createCherryPickInput(revertInput);
Instant timestamp = TimeUtil.now();
for (BranchNameKey projectAndBranch : changesPerProjectAndBranch.keySet()) {
cherryPickInput.base = null;
Project.NameKey project = projectAndBranch.project();
cherryPickInput.destination = projectAndBranch.branch();
if (revertInput.workInProgress) {
cherryPickInput.notify = firstNonNull(cherryPickInput.notify, NotifyHandling.OWNER);
}
Collection<ChangeData> changesInProjectAndBranch = changesPerProjectAndBranch.get(projectAndBranch);
// Sort the changes topologically.
Iterator<PatchSetData> sortedChangesInProjectAndBranch = sorter.sort(changesInProjectAndBranch).iterator();
Set<ObjectId> commitIdsInProjectAndBranch = changesInProjectAndBranch.stream().map(c -> c.currentPatchSet().commitId()).collect(Collectors.toSet());
revertAllChangesInProjectAndBranch(revertInput, project, sortedChangesInProjectAndBranch, commitIdsInProjectAndBranch, timestamp);
}
results.sort(Comparator.comparing(c -> c.revertOf));
RevertSubmissionInfo revertSubmissionInfo = new RevertSubmissionInfo();
revertSubmissionInfo.revertChanges = results;
return revertSubmissionInfo;
}
use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.
the class Rebase method findBaseRev.
private ObjectId findBaseRev(Repository repo, RevWalk rw, RevisionResource rsrc, RebaseInput input) throws RestApiException, IOException, NoSuchChangeException, AuthException, PermissionBackendException {
BranchNameKey destRefKey = rsrc.getChange().getDest();
if (input == null || input.base == null) {
return rebaseUtil.findBaseRevision(rsrc.getPatchSet(), destRefKey, repo, rw);
}
Change change = rsrc.getChange();
String str = input.base.trim();
if (str.equals("")) {
// Remove existing dependency to other patch set.
Ref destRef = repo.exactRef(destRefKey.branch());
if (destRef == null) {
throw new ResourceConflictException("can't rebase onto tip of branch " + destRefKey.branch() + "; branch doesn't exist");
}
return destRef.getObjectId();
}
Base base;
try {
base = rebaseUtil.parseBase(rsrc, str);
if (base == null) {
throw new ResourceConflictException("base revision is missing from the destination branch: " + str);
}
} catch (NoSuchChangeException e) {
throw new UnprocessableEntityException(String.format("Base change not found: %s", input.base), e);
}
PatchSet.Id baseId = base.patchSet().id();
if (change.getId().equals(baseId.changeId())) {
throw new ResourceConflictException("cannot rebase change onto itself");
}
permissionBackend.user(rsrc.getUser()).change(base.notes()).check(ChangePermission.READ);
Change baseChange = base.notes().getChange();
if (!baseChange.getProject().equals(change.getProject())) {
throw new ResourceConflictException("base change is in wrong project: " + baseChange.getProject());
} else if (!baseChange.getDest().equals(change.getDest())) {
throw new ResourceConflictException("base change is targeting wrong branch: " + baseChange.getDest());
} else if (baseChange.isAbandoned()) {
throw new ResourceConflictException("base change is abandoned: " + baseChange.getKey());
} else if (isMergedInto(rw, rsrc.getPatchSet(), base.patchSet())) {
throw new ResourceConflictException("base change " + baseChange.getKey() + " is a descendant of the current change - recursion not allowed");
}
return base.patchSet().commitId();
}
use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.
the class MergeOp method validateChangeList.
private BranchBatch validateChangeList(OpenRepo or, Collection<ChangeData> submitted) {
logger.atFine().log("Validating %d changes", submitted.size());
Set<CodeReviewCommit> toSubmit = new LinkedHashSet<>(submitted.size());
SetMultimap<ObjectId, PatchSet.Id> revisions = getRevisions(or, submitted);
SubmitType submitType = null;
ChangeData choseSubmitTypeFrom = null;
for (ChangeData cd : submitted) {
Change.Id changeId = cd.getId();
ChangeNotes notes;
Change chg;
SubmitType st;
try {
notes = cd.notes();
chg = cd.change();
st = getSubmitType(cd);
} catch (StorageException e) {
commitStatus.logProblem(changeId, e);
continue;
}
if (st == null) {
commitStatus.logProblem(changeId, "No submit type for change");
continue;
}
if (submitType == null) {
submitType = st;
choseSubmitTypeFrom = cd;
} else if (st != submitType) {
commitStatus.problem(changeId, String.format("Change has submit type %s, but previously chose submit type %s " + "from change %s in the same batch", st, submitType, choseSubmitTypeFrom.getId()));
continue;
}
if (chg.currentPatchSetId() == null) {
String msg = "Missing current patch set on change";
logger.atSevere().log("%s %s", msg, changeId);
commitStatus.problem(changeId, msg);
continue;
}
PatchSet ps;
BranchNameKey destBranch = chg.getDest();
try {
ps = cd.currentPatchSet();
} catch (StorageException e) {
commitStatus.logProblem(changeId, e);
continue;
}
if (ps == null) {
commitStatus.logProblem(changeId, "Missing patch set on change");
continue;
}
ObjectId id = ps.commitId();
if (!revisions.containsEntry(id, ps.id())) {
if (revisions.containsValue(ps.id())) {
// TODO This is actually an error, the patch set ref exists but points to a revision that
// is different from the revision that we have stored for the patch set in the change
// meta data.
commitStatus.logProblem(changeId, "Revision " + id.name() + " of patch set " + ps.number() + " does not match the revision of the patch set ref " + ps.id().toRefName());
continue;
}
// The patch set ref is not found but we want to merge the change. We can't safely do that
// if the patch set ref is missing. In a cluster setups with multiple primary nodes this can
// indicate a replication lag (e.g. the change meta data was already replicated, but the
// replication of the patch set ref is still pending).
commitStatus.logProblem(changeId, "Patch set ref " + ps.id().toRefName() + " not found. Expected patch set ref of " + ps.number() + " to point to revision " + id.name());
continue;
}
CodeReviewCommit commit;
try {
commit = or.rw.parseCommit(id);
} catch (IOException e) {
commitStatus.logProblem(changeId, e);
continue;
}
commit.setNotes(notes);
commit.setPatchsetId(ps.id());
commitStatus.put(commit);
MergeValidators mergeValidators = mergeValidatorsFactory.create();
try {
mergeValidators.validatePreMerge(or.repo, or.rw, commit, or.project, destBranch, ps.id(), caller);
} catch (MergeValidationException mve) {
commitStatus.problem(changeId, mve.getMessage());
continue;
}
commit.add(or.canMergeFlag);
toSubmit.add(commit);
}
logger.atFine().log("Submitting on this run: %s", toSubmit);
return new AutoValue_MergeOp_BranchBatch(submitType, ImmutableSet.copyOf(toSubmit));
}
use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.
the class MergeOp method integrateIntoHistory.
private void integrateIntoHistory(ChangeSet cs, SubmissionExecutor submissionExecutor) throws RestApiException, UpdateException {
checkArgument(!cs.furtherHiddenChanges(), "cannot integrate hidden changes into history");
logger.atFine().log("Beginning merge attempt on %s", cs);
Map<BranchNameKey, BranchBatch> toSubmit = new HashMap<>();
ListMultimap<BranchNameKey, ChangeData> cbb;
try {
cbb = cs.changesByBranch();
} catch (StorageException e) {
throw new StorageException("Error reading changes to submit", e);
}
Set<BranchNameKey> branches = cbb.keySet();
for (BranchNameKey branch : branches) {
OpenRepo or = openRepo(branch.project());
if (or != null) {
toSubmit.put(branch, validateChangeList(or, cbb.get(branch)));
}
}
// Done checks that don't involve running submit strategies.
commitStatus.maybeFailVerbose();
try {
SubscriptionGraph subscriptionGraph = subscriptionGraphFactory.compute(branches, orm);
SubmoduleCommits submoduleCommits = submoduleCommitsFactory.create(orm);
UpdateOrderCalculator updateOrderCalculator = new UpdateOrderCalculator(subscriptionGraph);
List<SubmitStrategy> strategies = getSubmitStrategies(toSubmit, updateOrderCalculator, submoduleCommits, subscriptionGraph, dryrun);
this.allProjects = updateOrderCalculator.getProjectsInOrder();
List<BatchUpdate> batchUpdates = orm.batchUpdates(allProjects);
// Group batch updates by project
Map<Project.NameKey, BatchUpdate> batchUpdatesByProject = batchUpdates.stream().collect(Collectors.toMap(b -> b.getProject(), Function.identity()));
for (Map.Entry<Change.Id, ChangeData> entry : cs.changesById().entrySet()) {
Project.NameKey project = entry.getValue().project();
Change.Id changeId = entry.getKey();
ChangeData cd = entry.getValue();
batchUpdatesByProject.get(project).addOp(changeId, storeSubmitRequirementsOpFactory.create(cd.submitRequirementsIncludingLegacy().values(), cd));
}
try {
submissionExecutor.setAdditionalBatchUpdateListeners(ImmutableList.of(new SubmitStrategyListener(submitInput, strategies, commitStatus)));
submissionExecutor.execute(batchUpdates);
} finally {
// If the BatchUpdate fails it can be that merging some of the changes was actually
// successful. This is why we must to collect the updated changes also when an
// exception was thrown.
strategies.forEach(s -> updatedChanges.putAll(s.getUpdatedChanges()));
// Do not leave executed BatchUpdates in the OpenRepos
if (!dryrun) {
orm.resetUpdates(ImmutableSet.copyOf(this.allProjects));
}
}
} catch (NoSuchProjectException e) {
throw new ResourceNotFoundException(e.getMessage());
} catch (IOException e) {
throw new StorageException(e);
} catch (SubmoduleConflictException e) {
throw new IntegrationConflictException(e.getMessage(), e);
} catch (UpdateException e) {
if (e.getCause() instanceof LockFailureException) {
// as to be unnoticeable, assuming RetryHelper is retrying sufficiently.
throw e;
}
// inner IntegrationConflictException to a ResourceConflictException.
if (e.getCause() instanceof IntegrationConflictException) {
throw (IntegrationConflictException) e.getCause();
}
throw new MergeUpdateException(genericMergeError(cs), e);
}
}
Aggregations