Merge "Add --other-branches option to the /changes/<id>/revisions/<id>/mergeable"

This commit is contained in:
Shawn Pearce 2014-05-05 23:59:30 +00:00 committed by Gerrit Code Review
commit bc9512985c
2 changed files with 84 additions and 23 deletions

View File

@ -1793,6 +1793,34 @@ As response a link:#mergeable-info[MergeableInfo] entity is returned.
}
----
If the `other-branches` parameter is specified, the mergeability will also be
checked for all other branches.
.Request
----
GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/revisions/current/mergeable?other-branches HTTP/1.0
----
The response will then contain a list of all other branches where this changes
could merge cleanly.
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json;charset=UTF-8
)]}'
{
submit_type: "MERGE_IF_NECESSARY",
mergeable: true,
mergeable_into: [
"refs/heads/stable-2.7",
"refs/heads/stable-2.8",
]
}
----
[[get-submit-type]]
=== Get Submit Type
--
@ -3115,15 +3143,17 @@ to the value descriptions.
The `MergeableInfo` entity contains information about the mergeability of a
change.
[options="header",width="50%",cols="1,6"]
[options="header",width="50%",cols="1,^1,5"]
|============================
|Field Name |Description
|`submit_type`|
|Field Name ||Description
|`submit_type` ||
Submit type used for this change, can be `MERGE_IF_NECESSARY`,
`FAST_FORWARD_ONLY`, `REBASE_IF_NECESSARY`, `MERGE_ALWAYS` or
`CHERRY_PICK`.
|`mergeable` |
|`mergeable` ||
`true` if this change is cleanly mergeable, `false` otherwise
|`mergeable_into`|optional|
A list of other branch names where this change could merge cleanly
[[restore-input]]
=== RestoreInput

View File

@ -46,12 +46,15 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -61,8 +64,13 @@ public class Mergeable implements RestReadView<RevisionResource> {
public static class MergeableInfo {
public SubmitType submitType;
public boolean mergeable;
public List<String> mergeableInto;
}
@Option(name = "--other-branches", aliases = {"-o"},
usage = "test mergeability for other branches too")
private boolean otherBranches;
private final TestSubmitType.Get submitType;
private final GitRepositoryManager gitManager;
private final SubmitStrategyFactory submitStrategyFactory;
@ -113,6 +121,18 @@ public class Mergeable implements RestReadView<RevisionResource> {
result.mergeable =
refresh(change, ps, result.submitType, git, refs, ref);
}
if (otherBranches) {
result.mergeableInto = new ArrayList<>();
for (Ref r : refs.values()) {
if (r.getName().startsWith(Constants.R_HEADS)
&& !r.getName().equals(ref.getName())) {
if (isMergeable(change, ps, SubmitType.CHERRY_PICK, git, refs, r)) {
result.mergeableInto.add(r.getName());
}
}
}
}
} finally {
git.close();
}
@ -136,6 +156,36 @@ public class Mergeable implements RestReadView<RevisionResource> {
Repository git,
Map<String, Ref> refs,
final Ref ref) throws IOException, OrmException {
final boolean mergeable = isMergeable(change, ps, type, git, refs, ref);
Change c = db.get().changes().atomicUpdate(
change.getId(),
new AtomicUpdate<Change>() {
@Override
public Change update(Change c) {
if (c.getStatus().isOpen()
&& ps.getId().equals(c.currentPatchSetId())) {
c.setMergeable(mergeable);
c.setLastSha1MergeTested(toRevId(ref));
return c;
} else {
return null;
}
}
});
if (c != null) {
indexer.index(db.get(), c);
}
return mergeable;
}
private boolean isMergeable(Change change,
final PatchSet ps,
SubmitType type,
Repository git,
Map<String, Ref> refs,
final Ref ref) throws IOException, OrmException {
RevWalk rw = new RevWalk(git) {
@Override
protected CodeReviewCommit createCommit(AnyObjectId id) {
@ -176,25 +226,6 @@ public class Mergeable implements RestReadView<RevisionResource> {
accepted,
change.getDest()).dryRun(tip, rev);
}
Change c = db.get().changes().atomicUpdate(
change.getId(),
new AtomicUpdate<Change>() {
@Override
public Change update(Change c) {
if (c.getStatus().isOpen()
&& ps.getId().equals(c.currentPatchSetId())) {
c.setMergeable(mergeable);
c.setLastSha1MergeTested(toRevId(ref));
return c;
} else {
return null;
}
}
});
if (c != null) {
indexer.index(db.get(), c);
}
return mergeable;
} catch (MergeException | IOException | NoSuchProjectException e) {
log.error(String.format(