Add 'Parent $x' options to diff for merge commits

Add 'Parent $x' options to the diff base drop down for merge commits.
This way users are able to see changes brought by merge commit in
addition to the merge conflicts resolution.

Two main challenges of this change are:
* server: enable commenting on a Parent-N of a merge commit
* client: pass around the diff-base info which for merge commits can be:
  Auto-Merge, Parent-1, Parent-2, ... , Parent-N

Currently the patch_comments.side field uses two values:
1 = REVISION
0 = PARENT

For non-merge commits, side == 0 means comment of the Base (the parent)
of this patch-set.  For a merge commit, side == 0 means comment on the
Auto-Merge of this (merge) patch-set.

This change uses side == -N to store comment on the Parent-N of this (merge)
patch-set. For Parent-1 the side is -1, for Parent-2 the side is -2, etc..
This avoids need for a schema migration.

In NoteDb the parent number is stored in a new field: "Parent-number: 1".

CommentInfo was extended with the new "parent" field which is 1-based
parent number.  Some REST API endpoints expose a new --parent option to
enable referencing a specific parent of a merge commit.

On the client side we typically pass around two PatchSet.Id's: base and
revision to represent the state of the UI. The base had two meanings:
* when it was non-null it was representing another patch-set
* when it was null it represented the parent for a non-merge commit and
  the auto-merge for a merge commit.

For a merge commit we need to also pass around Parent-N as (diff) base for a
merge commit. To keep the number of changes minimal this change proposes
(re)using the base patch-set for that where its patch-set number is negative.
Therefore, when base is not null but its patch-set number is negative (-N) it
represents Parent-N of the patch-set represented by the revision patch-set.
This is also expressed in the client URL token which uses negative numbers
for parent(s) of a merge commit. For example: -1..2 represents comparison
of the second patch-set against its first parent. -2..2 would represent
comparison of the patch-set 2 against its second parent.

I experimented with introducing a DiffBase class which would be a combination
of a base patch-set plus a parent number:

  class DiffBase {
    PatchSet.Id base;
    int parent;
  }

which would avoid the ugliness of using a base with negative patch-set number.
However, this produced neither a smaller nor a more elegant change. The number
of changed files actually increased and, still, all places where base is used
had to handle the case where base is null and parent is greater than zero.

Bug: Issue 106
Change-Id: If0d7b13fad9051ec2943f6d51c99e84f7d2af708
Also-by: Dariusz Luksza <dariusz@luksza.org>
Also-by: Saša Živkov <zivkov@gmail.com>
This commit is contained in:
Dawid Grzegorczyk
2015-11-07 11:26:02 +01:00
committed by Saša Živkov
parent 38f96373e0
commit 5904524de6
42 changed files with 942 additions and 183 deletions

View File

@@ -16,6 +16,22 @@ package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.client.Comment;
import java.util.Objects;
public class DraftInput extends Comment {
public String tag;
@Override
public boolean equals(Object o) {
if (super.equals(o)) {
DraftInput di = (DraftInput) o;
return Objects.equals(tag, di.tag);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), tag);
}
}

View File

@@ -34,6 +34,11 @@ public interface FileApi {
*/
DiffInfo diff(String base) throws RestApiException;
/**
* @param parent 1-based parent number to diff against
*/
DiffInfo diff(int parent) throws RestApiException;
/**
* Creates a request to retrieve the diff. On the returned request formatting
* options for the diff can be set.
@@ -105,6 +110,11 @@ public interface FileApi {
throw new NotImplementedException();
}
@Override
public DiffInfo diff(int parent) throws RestApiException {
throw new NotImplementedException();
}
@Override
public DiffRequest diffRequest() throws RestApiException {
throw new NotImplementedException();

View File

@@ -46,6 +46,7 @@ public interface RevisionApi {
Map<String, FileInfo> files() throws RestApiException;
Map<String, FileInfo> files(String base) throws RestApiException;
Map<String, FileInfo> files(int parentNum) throws RestApiException;
FileApi file(String path);
MergeableInfo mergeable() throws RestApiException;
MergeableInfo mergeableOtherBranches() throws RestApiException;
@@ -146,6 +147,11 @@ public interface RevisionApi {
throw new NotImplementedException();
}
@Override
public Map<String, FileInfo> files(int parentNum) throws RestApiException {
throw new NotImplementedException();
}
@Override
public Map<String, FileInfo> files() throws RestApiException {
throw new NotImplementedException();

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.extensions.client;
import java.sql.Timestamp;
import java.util.Objects;
public abstract class Comment {
/**
@@ -27,6 +28,7 @@ public abstract class Comment {
public String id;
public String path;
public Side side;
public Integer parent;
public Integer line;
public Range range;
public String inReplyTo;
@@ -38,5 +40,49 @@ public abstract class Comment {
public int startCharacter;
public int endLine;
public int endCharacter;
@Override
public boolean equals(Object o) {
if (o instanceof Range) {
Range r = (Range) o;
return Objects.equals(startLine, r.startLine)
&& Objects.equals(startCharacter, r.startCharacter)
&& Objects.equals(endLine, r.endLine)
&& Objects.equals(endCharacter, r.endCharacter);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(startLine, startCharacter, endLine, endCharacter);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o != null && getClass() == o.getClass()) {
Comment c = (Comment) o;
return Objects.equals(patchSet, c.patchSet)
&& Objects.equals(id, c.id)
&& Objects.equals(path, c.path)
&& Objects.equals(side, c.side)
&& Objects.equals(parent, c.parent)
&& Objects.equals(line, c.line)
&& Objects.equals(range, c.range)
&& Objects.equals(inReplyTo, c.inReplyTo)
&& Objects.equals(updated, c.updated)
&& Objects.equals(message, c.message);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(patchSet, id, path, side, parent, line, range,
inReplyTo, updated, message);
}
}

View File

@@ -19,11 +19,10 @@ public enum Side {
REVISION;
public static Side fromShort(short s) {
switch (s) {
case 0:
return PARENT;
case 1:
return REVISION;
if (s <= 0) {
return PARENT;
} else if (s == 1) {
return REVISION;
}
return null;
}

View File

@@ -16,7 +16,24 @@ package com.google.gerrit.extensions.common;
import com.google.gerrit.extensions.client.Comment;
import java.util.Objects;
public class CommentInfo extends Comment {
public AccountInfo author;
public String tag;
@Override
public boolean equals(Object o) {
if (super.equals(o)) {
CommentInfo ci = (CommentInfo) o;
return Objects.equals(author, ci.author)
&& Objects.equals(tag, ci.tag);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), author, tag);
}
}