Merge "Introduce components for new image diff UI"
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index e02dc21..52c282e 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -190,6 +190,13 @@
+
Changes occurring in projects starting with 'PREFIX'.
+[[parentof]]
+parentof:'ID'::
+Changes which are parent to the change specified by 'ID'. Change 'ID' can be
+specified as a legacy numerical 'ID' such as 15183, or a Change-Id that can be
+picked from the commit message. This operator will return immediate parents
+and will not return grand parents or higher level ancestors of the given change.
+
[[parentproject]]
parentproject:'PROJECT'::
+
diff --git a/java/com/google/gerrit/server/patch/AutoMerger.java b/java/com/google/gerrit/server/patch/AutoMerger.java
index fe915c5..ac37411 100644
--- a/java/com/google/gerrit/server/patch/AutoMerger.java
+++ b/java/com/google/gerrit/server/patch/AutoMerger.java
@@ -109,6 +109,7 @@
ActionType.GIT_UPDATE,
"createAutoMerge",
() -> createAutoMergeCommit(repo, rw, ins, merge, mergeStrategy))
+ .defaultTimeoutMultiplier(2)
.call();
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 68a90d2..4e3edcd 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -173,6 +173,7 @@
public static final String FIELD_MESSAGE = "message";
public static final String FIELD_OWNER = "owner";
public static final String FIELD_OWNERIN = "ownerin";
+ public static final String FIELD_PARENTOF = "parentof";
public static final String FIELD_PARENTPROJECT = "parentproject";
public static final String FIELD_PATH = "path";
public static final String FIELD_PENDING_REVIEWER = "pendingreviewer";
@@ -735,6 +736,16 @@
}
@Operator
+ public Predicate<ChangeData> parentof(String value) throws QueryParseException {
+ List<ChangeData> changes = parseChangeData(value);
+ List<Predicate<ChangeData>> or = new ArrayList<>(changes.size());
+ for (ChangeData c : changes) {
+ or.add(new ParentOfPredicate(value, c, args.repoManager));
+ }
+ return Predicate.or(or);
+ }
+
+ @Operator
public Predicate<ChangeData> parentproject(String name) {
return new ParentProjectPredicate(args.projectCache, args.childProjects, name);
}
@@ -1560,14 +1571,18 @@
}
private List<Change> parseChange(String value) throws QueryParseException {
+ return asChanges(parseChangeData(value));
+ }
+
+ private List<ChangeData> parseChangeData(String value) throws QueryParseException {
if (PAT_LEGACY_ID.matcher(value).matches()) {
Optional<Change.Id> id = Change.Id.tryParse(value);
if (!id.isPresent()) {
throw error("Invalid change id " + value);
}
- return asChanges(args.queryProvider.get().byLegacyChangeId(id.get()));
+ return args.queryProvider.get().byLegacyChangeId(id.get());
} else if (PAT_CHANGE_ID.matcher(value).matches()) {
- List<Change> changes = asChanges(args.queryProvider.get().byKeyPrefix(parseChangeId(value)));
+ List<ChangeData> changes = args.queryProvider.get().byKeyPrefix(parseChangeId(value));
if (changes.isEmpty()) {
throw error("Change " + value + " not found");
}
diff --git a/java/com/google/gerrit/server/query/change/ParentOfPredicate.java b/java/com/google/gerrit/server/query/change/ParentOfPredicate.java
new file mode 100644
index 0000000..e48d586
--- /dev/null
+++ b/java/com/google/gerrit/server/query/change/ParentOfPredicate.java
@@ -0,0 +1,62 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.query.change;
+
+import com.google.common.collect.Sets;
+import com.google.gerrit.entities.PatchSet;
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.index.query.Matchable;
+import com.google.gerrit.index.query.OperatorPredicate;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import java.io.IOException;
+import java.util.Set;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+public class ParentOfPredicate extends OperatorPredicate<ChangeData>
+ implements Matchable<ChangeData> {
+ protected final Set<RevCommit> parents;
+
+ public ParentOfPredicate(String value, ChangeData change, GitRepositoryManager repoManager) {
+ super(ChangeQueryBuilder.FIELD_PARENTOF, value);
+ this.parents = getParents(change, repoManager);
+ }
+
+ @Override
+ public boolean match(ChangeData changeData) {
+ return changeData.patchSets().stream().anyMatch(ps -> parents.contains(ps.commitId()));
+ }
+
+ @Override
+ public int getCost() {
+ return 1;
+ }
+
+ protected Set<RevCommit> getParents(ChangeData change, GitRepositoryManager repoManager) {
+ PatchSet ps = change.currentPatchSet();
+ try (Repository repo = repoManager.openRepository(change.project());
+ RevWalk walk = new RevWalk(repo)) {
+ RevCommit c = walk.parseCommit(ps.commitId());
+ return Sets.newHashSet(c.getParents());
+ } catch (IOException e) {
+ throw new StorageException(
+ String.format(
+ "Loading commit %s for ps %d of change %d failed.",
+ ps.commitId(), ps.id().get(), ps.id().changeId().get()),
+ e);
+ }
+ }
+}
diff --git a/java/com/google/gerrit/server/restapi/change/PostReview.java b/java/com/google/gerrit/server/restapi/change/PostReview.java
index 562bdf8..73b38b2 100644
--- a/java/com/google/gerrit/server/restapi/change/PostReview.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReview.java
@@ -1228,9 +1228,10 @@
}
private boolean isReviewer(ChangeContext ctx) {
- ChangeData cd = changeDataFactory.create(ctx.getNotes());
- ReviewerSet reviewers = cd.reviewers();
- return reviewers.byState(REVIEWER).contains(ctx.getAccountId());
+ return approvalsUtil
+ .getReviewers(ctx.getNotes())
+ .byState(REVIEWER)
+ .contains(ctx.getAccountId());
}
private boolean updateLabels(ProjectState projectState, ChangeContext ctx)
diff --git a/java/com/google/gerrit/server/submit/MergeOp.java b/java/com/google/gerrit/server/submit/MergeOp.java
index 871d8d2..4e732a4 100644
--- a/java/com/google/gerrit/server/submit/MergeOp.java
+++ b/java/com/google/gerrit/server/submit/MergeOp.java
@@ -549,8 +549,8 @@
.listener(retryTracker)
// Up to the entire submit operation is retried, including possibly many projects.
// Multiply the timeout by the number of projects we're actually attempting to
- // submit.
- .defaultTimeoutMultiplier(filteredNoteDbChangeSet.projects().size())
+ // submit. Times 2 to retry more persistently, to increase success rate.
+ .defaultTimeoutMultiplier(filteredNoteDbChangeSet.projects().size() * 2)
// By default, we only retry lock failures. Here it's better to also retry unexpected
// runtime exceptions.
.retryOn(t -> t instanceof RuntimeException)
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 7efcb4b..48bd321 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -705,6 +705,24 @@
}
@Test
+ public void byParentOf() throws Exception {
+ TestRepository<Repo> repo1 = createProject("repo1");
+ RevCommit commit1 = repo1.parseBody(repo1.commit().message("message").create());
+ Change change1 = insert(repo1, newChangeForCommit(repo1, commit1));
+ RevCommit commit2 = repo1.parseBody(repo1.commit(commit1));
+ Change change2 = insert(repo1, newChangeForCommit(repo1, commit2));
+ RevCommit commit3 = repo1.parseBody(repo1.commit(commit1, commit2));
+ Change change3 = insert(repo1, newChangeForCommit(repo1, commit3));
+
+ assertQuery("parentof:" + change1.getId().get());
+ assertQuery("parentof:" + change1.getKey().get());
+ assertQuery("parentof:" + change2.getId().get(), change1);
+ assertQuery("parentof:" + change2.getKey().get(), change1);
+ assertQuery("parentof:" + change3.getId().get(), change2, change1);
+ assertQuery("parentof:" + change3.getKey().get(), change2, change1);
+ }
+
+ @Test
public void byParentProject() throws Exception {
TestRepository<Repo> repo1 = createProject("repo1");
TestRepository<Repo> repo2 = createProject("repo2", "repo1");
diff --git a/modules/jgit b/modules/jgit
index 4560bdf..9bfb0f3 160000
--- a/modules/jgit
+++ b/modules/jgit
@@ -1 +1 @@
-Subproject commit 4560bdf7e2e3c16a7c7bb3f2fcf067bb1eee26fb
+Subproject commit 9bfb0f3a4ec856dcbebb477a1ee8803a3c47c194
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-runs.ts b/polygerrit-ui/app/elements/checks/gr-checks-runs.ts
index 71ad041..f8584bc 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-runs.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-runs.ts
@@ -111,6 +111,9 @@
.chip.placeholder {
border-left: var(--thick-border) solid var(--border-color);
}
+ .chip.placeholder iron-icon {
+ display: none;
+ }
.chip.error iron-icon {
color: var(--error-foreground);
}
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
index 43f8a2b..97d5271 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
@@ -93,6 +93,7 @@
'onlyextensions:',
'owner:',
'ownerin:',
+ 'parentof:',
'parentproject:',
'project:',
'projects:',
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
index 76bbd67..55408c0 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
@@ -23,12 +23,12 @@
font-size: var(--font-size-normal);
font-weight: var(--font-weight-normal);
line-height: var(--line-height-normal);
- /* Explicitly set the background color of the diff to be white. We
+ /* Explicitly set the background color of the diff. We
* cannot use the diff content type ab because of the skip chunk preceding
* it, diff processor assumes the chunk of type skip/ab can be collapsed
* and hides our diff behind context control buttons.
* */
- --dark-add-highlight-color: white;
+ --dark-add-highlight-color: var(--background-color-primary);
}
gr-button {
margin-left: var(--spacing-m);