Merge branch 'stable-2.15'
* stable-2.15: Detect RawInput correctly Remove unnecessary 'algorithm' parameter of PatchListKey Remove some more false negatives for edits due to rebase Remove some false negatives for edits due to rebase Change-Id: I1a95b209c2091d4993e7cc590f5177a877136be5
This commit is contained in:
@@ -19,7 +19,6 @@ import static org.eclipse.jgit.lib.ObjectIdSerializer.readWithoutMarker;
|
||||
import static org.eclipse.jgit.lib.ObjectIdSerializer.write;
|
||||
import static org.eclipse.jgit.lib.ObjectIdSerializer.writeWithoutMarker;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
@@ -41,7 +40,6 @@ public class DiffSummaryKey implements Serializable {
|
||||
private transient Whitespace whitespace;
|
||||
|
||||
public static DiffSummaryKey fromPatchListKey(PatchListKey plk) {
|
||||
Preconditions.checkArgument(plk.getAlgorithm() == PatchListKey.Algorithm.OPTIMIZED_DIFF);
|
||||
return new DiffSummaryKey(
|
||||
plk.getOldId(), plk.getParentNum(), plk.getNewId(), plk.getWhitespace());
|
||||
}
|
||||
@@ -54,8 +52,7 @@ public class DiffSummaryKey implements Serializable {
|
||||
}
|
||||
|
||||
PatchListKey toPatchListKey() {
|
||||
return new PatchListKey(
|
||||
oldId, parentNum, newId, whitespace, PatchListKey.Algorithm.OPTIMIZED_DIFF);
|
||||
return new PatchListKey(oldId, parentNum, newId, whitespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -163,10 +163,10 @@ class EditTransformer {
|
||||
while (origIndex < originalEdits.size() && transIndex < transformingEdits.size()) {
|
||||
ContextAwareEdit originalEdit = originalEdits.get(origIndex);
|
||||
Edit transformingEdit = transformingEdits.get(transIndex);
|
||||
if (transformingEdit.getEndA() < sideStrategy.getBegin(originalEdit)) {
|
||||
if (transformingEdit.getEndA() <= sideStrategy.getBegin(originalEdit)) {
|
||||
shiftedAmount = transformingEdit.getEndB() - transformingEdit.getEndA();
|
||||
transIndex++;
|
||||
} else if (sideStrategy.getEnd(originalEdit) < transformingEdit.getBeginA()) {
|
||||
} else if (sideStrategy.getEnd(originalEdit) <= transformingEdit.getBeginA()) {
|
||||
resultingEdits.add(sideStrategy.create(originalEdit, shiftedAmount, adjustedFilePath));
|
||||
origIndex++;
|
||||
} else {
|
||||
|
@@ -16,8 +16,10 @@ package com.google.gerrit.server.patch;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.eclipse.jgit.diff.Edit;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
@@ -27,17 +29,22 @@ public abstract class IntraLineDiffArgs {
|
||||
Text aText,
|
||||
Text bText,
|
||||
List<Edit> edits,
|
||||
Set<Edit> editsDueToRebase,
|
||||
Project.NameKey project,
|
||||
ObjectId commit,
|
||||
String path) {
|
||||
return new AutoValue_IntraLineDiffArgs(
|
||||
aText, bText, deepCopyEdits(edits), project, commit, path);
|
||||
aText, bText, deepCopyEdits(edits), deepCopyEdits(editsDueToRebase), project, commit, path);
|
||||
}
|
||||
|
||||
private static ImmutableList<Edit> deepCopyEdits(List<Edit> edits) {
|
||||
return edits.stream().map(IntraLineDiffArgs::copy).collect(ImmutableList.toImmutableList());
|
||||
}
|
||||
|
||||
private static ImmutableSet<Edit> deepCopyEdits(Set<Edit> edits) {
|
||||
return edits.stream().map(IntraLineDiffArgs::copy).collect(ImmutableSet.toImmutableSet());
|
||||
}
|
||||
|
||||
private static Edit copy(Edit edit) {
|
||||
return new Edit(edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB());
|
||||
}
|
||||
@@ -48,6 +55,8 @@ public abstract class IntraLineDiffArgs {
|
||||
|
||||
public abstract ImmutableList<Edit> edits();
|
||||
|
||||
public abstract ImmutableSet<Edit> editsDueToRebase();
|
||||
|
||||
public abstract Project.NameKey project();
|
||||
|
||||
public abstract ObjectId commit();
|
||||
|
@@ -21,7 +21,7 @@ import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
@AutoValue
|
||||
public abstract class IntraLineDiffKey implements Serializable {
|
||||
public static final long serialVersionUID = 8L;
|
||||
public static final long serialVersionUID = 11L;
|
||||
|
||||
public static IntraLineDiffKey create(ObjectId aId, ObjectId bId, Whitespace whitespace) {
|
||||
return new AutoValue_IntraLineDiffKey(aId, bId, whitespace);
|
||||
|
@@ -17,6 +17,7 @@ package com.google.gerrit.server.patch;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gerrit.server.config.ConfigUtil;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.inject.Inject;
|
||||
@@ -77,7 +78,9 @@ class IntraLineLoader implements Callable<IntraLineDiff> {
|
||||
public IntraLineDiff call() throws Exception {
|
||||
Future<IntraLineDiff> result =
|
||||
diffExecutor.submit(
|
||||
() -> IntraLineLoader.compute(args.aText(), args.bText(), args.edits()));
|
||||
() ->
|
||||
IntraLineLoader.compute(
|
||||
args.aText(), args.bText(), args.edits(), args.editsDueToRebase()));
|
||||
try {
|
||||
return result.get(timeoutMillis, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException | TimeoutException e) {
|
||||
@@ -104,10 +107,13 @@ class IntraLineLoader implements Callable<IntraLineDiff> {
|
||||
}
|
||||
}
|
||||
|
||||
static IntraLineDiff compute(Text aText, Text bText, ImmutableList<Edit> immutableEdits)
|
||||
throws Exception {
|
||||
static IntraLineDiff compute(
|
||||
Text aText,
|
||||
Text bText,
|
||||
ImmutableList<Edit> immutableEdits,
|
||||
ImmutableSet<Edit> immutableEditsDueToRebase) {
|
||||
List<Edit> edits = new ArrayList<>(immutableEdits);
|
||||
combineLineEdits(edits, aText, bText);
|
||||
combineLineEdits(edits, immutableEditsDueToRebase, aText, bText);
|
||||
|
||||
for (int i = 0; i < edits.size(); i++) {
|
||||
Edit e = edits.get(i);
|
||||
@@ -256,11 +262,18 @@ class IntraLineLoader implements Callable<IntraLineDiff> {
|
||||
return new IntraLineDiff(edits);
|
||||
}
|
||||
|
||||
private static void combineLineEdits(List<Edit> edits, Text a, Text b) {
|
||||
private static void combineLineEdits(
|
||||
List<Edit> edits, ImmutableSet<Edit> editsDueToRebase, Text a, Text b) {
|
||||
for (int j = 0; j < edits.size() - 1; ) {
|
||||
Edit c = edits.get(j);
|
||||
Edit n = edits.get(j + 1);
|
||||
|
||||
if (editsDueToRebase.contains(c) || editsDueToRebase.contains(n)) {
|
||||
// Don't combine any edits which were identified as being introduced by a rebase as we would
|
||||
// lose that information because of the combination.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Combine edits that are really close together. Right now our rule
|
||||
// is, coalesce two line edits which are only one line apart if that
|
||||
// common context line is either a "pointless line", or is identical
|
||||
|
@@ -32,19 +32,7 @@ import org.eclipse.jgit.lib.AnyObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
public class PatchListKey implements Serializable {
|
||||
public static final long serialVersionUID = 28L;
|
||||
|
||||
// TODO(aliceks): Get rid of this enum and the parameter in the PatchListKey as we only use one of
|
||||
// its values.
|
||||
public enum Algorithm {
|
||||
PURE_TREE_DIFF,
|
||||
OPTIMIZED_DIFF
|
||||
}
|
||||
|
||||
private static final ImmutableBiMap<Algorithm, Character> ALGORITHM_TYPES =
|
||||
ImmutableBiMap.of(
|
||||
Algorithm.PURE_TREE_DIFF, 'T',
|
||||
Algorithm.OPTIMIZED_DIFF, 'O');
|
||||
public static final long serialVersionUID = 30L;
|
||||
|
||||
public static final ImmutableBiMap<Whitespace, Character> WHITESPACE_TYPES =
|
||||
ImmutableBiMap.of(
|
||||
@@ -55,20 +43,19 @@ public class PatchListKey implements Serializable {
|
||||
|
||||
static {
|
||||
checkState(WHITESPACE_TYPES.size() == Whitespace.values().length);
|
||||
checkState(ALGORITHM_TYPES.size() == Algorithm.values().length);
|
||||
}
|
||||
|
||||
public static PatchListKey againstDefaultBase(AnyObjectId newId, Whitespace ws) {
|
||||
return new PatchListKey(null, newId, ws, Algorithm.OPTIMIZED_DIFF);
|
||||
return new PatchListKey(null, newId, ws);
|
||||
}
|
||||
|
||||
public static PatchListKey againstParentNum(int parentNum, AnyObjectId newId, Whitespace ws) {
|
||||
return new PatchListKey(parentNum, newId, ws, Algorithm.OPTIMIZED_DIFF);
|
||||
return new PatchListKey(parentNum, newId, ws);
|
||||
}
|
||||
|
||||
public static PatchListKey againstCommit(
|
||||
AnyObjectId otherCommitId, AnyObjectId newId, Whitespace whitespace) {
|
||||
return new PatchListKey(otherCommitId, newId, whitespace, Algorithm.OPTIMIZED_DIFF);
|
||||
return new PatchListKey(otherCommitId, newId, whitespace);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,34 +80,25 @@ public class PatchListKey implements Serializable {
|
||||
|
||||
private transient ObjectId newId;
|
||||
private transient Whitespace whitespace;
|
||||
private transient Algorithm algorithm;
|
||||
|
||||
private PatchListKey(AnyObjectId a, AnyObjectId b, Whitespace ws, Algorithm algorithm) {
|
||||
private PatchListKey(AnyObjectId a, AnyObjectId b, Whitespace ws) {
|
||||
oldId = a != null ? a.copy() : null;
|
||||
newId = b.copy();
|
||||
whitespace = ws;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
private PatchListKey(int parentNum, AnyObjectId b, Whitespace ws, Algorithm algorithm) {
|
||||
private PatchListKey(int parentNum, AnyObjectId b, Whitespace ws) {
|
||||
this.parentNum = Integer.valueOf(parentNum);
|
||||
newId = b.copy();
|
||||
whitespace = ws;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
/** For use only by DiffSummaryKey. */
|
||||
PatchListKey(
|
||||
ObjectId oldId,
|
||||
Integer parentNum,
|
||||
ObjectId newId,
|
||||
Whitespace whitespace,
|
||||
Algorithm algorithm) {
|
||||
PatchListKey(ObjectId oldId, Integer parentNum, ObjectId newId, Whitespace whitespace) {
|
||||
this.oldId = oldId;
|
||||
this.parentNum = parentNum;
|
||||
this.newId = newId;
|
||||
this.whitespace = whitespace;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
/** Old side commit, or null to assume ancestor or combined merge. */
|
||||
@@ -144,13 +122,9 @@ public class PatchListKey implements Serializable {
|
||||
return whitespace;
|
||||
}
|
||||
|
||||
public Algorithm getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(oldId, parentNum, newId, whitespace, algorithm);
|
||||
return Objects.hash(oldId, parentNum, newId, whitespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,8 +134,7 @@ public class PatchListKey implements Serializable {
|
||||
return Objects.equals(oldId, k.oldId)
|
||||
&& Objects.equals(parentNum, k.parentNum)
|
||||
&& Objects.equals(newId, k.newId)
|
||||
&& whitespace == k.whitespace
|
||||
&& algorithm == k.algorithm;
|
||||
&& whitespace == k.whitespace;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -179,8 +152,6 @@ public class PatchListKey implements Serializable {
|
||||
n.append(" ");
|
||||
}
|
||||
n.append(whitespace.name());
|
||||
n.append(" ");
|
||||
n.append(algorithm.name());
|
||||
n.append("]");
|
||||
return n.toString();
|
||||
}
|
||||
@@ -194,7 +165,6 @@ public class PatchListKey implements Serializable {
|
||||
throw new IOException("Invalid whitespace type: " + whitespace);
|
||||
}
|
||||
out.writeChar(c);
|
||||
out.writeChar(ALGORITHM_TYPES.get(algorithm));
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException {
|
||||
@@ -207,7 +177,5 @@ public class PatchListKey implements Serializable {
|
||||
if (whitespace == null) {
|
||||
throw new IOException("Invalid whitespace type code: " + t);
|
||||
}
|
||||
char algorithmCharacter = in.readChar();
|
||||
algorithm = ALGORITHM_TYPES.inverse().get(algorithmCharacter);
|
||||
}
|
||||
}
|
||||
|
@@ -187,12 +187,10 @@ public class PatchListLoader implements Callable<PatchList> {
|
||||
List<DiffEntry> diffEntries = df.scan(aTree, bTree);
|
||||
|
||||
Multimap<String, ContextAwareEdit> editsDueToRebasePerFilePath = ImmutableMultimap.of();
|
||||
if (key.getAlgorithm() == PatchListKey.Algorithm.OPTIMIZED_DIFF) {
|
||||
EditsDueToRebaseResult editsDueToRebaseResult =
|
||||
determineEditsDueToRebase(aCommit, b, diffEntries, df, rw);
|
||||
diffEntries = editsDueToRebaseResult.getRelevantOriginalDiffEntries();
|
||||
editsDueToRebasePerFilePath = editsDueToRebaseResult.getEditsDueToRebasePerFilePath();
|
||||
}
|
||||
|
||||
List<PatchListEntry> entries = new ArrayList<>();
|
||||
entries.add(
|
||||
|
@@ -16,6 +16,7 @@ package com.google.gerrit.server.patch;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gerrit.common.data.CommentDetail;
|
||||
import com.google.gerrit.common.data.PatchScript;
|
||||
import com.google.gerrit.common.data.PatchScript.DisplayMethod;
|
||||
@@ -135,6 +136,7 @@ class PatchScriptBuilder {
|
||||
b.resolve(a, bId);
|
||||
|
||||
edits = new ArrayList<>(content.getEdits());
|
||||
ImmutableSet<Edit> editsDueToRebase = content.getEditsDueToRebase();
|
||||
|
||||
if (!isModify(content)) {
|
||||
intralineDifferenceIsPossible = false;
|
||||
@@ -142,7 +144,8 @@ class PatchScriptBuilder {
|
||||
IntraLineDiff d =
|
||||
patchListCache.getIntraLineDiff(
|
||||
IntraLineDiffKey.create(a.id, b.id, diffPrefs.ignoreWhitespace),
|
||||
IntraLineDiffArgs.create(a.src, b.src, edits, projectKey, bId, b.path));
|
||||
IntraLineDiffArgs.create(
|
||||
a.src, b.src, edits, editsDueToRebase, projectKey, bId, b.path));
|
||||
if (d != null) {
|
||||
switch (d.getStatus()) {
|
||||
case EDIT_LIST:
|
||||
@@ -214,7 +217,7 @@ class PatchScriptBuilder {
|
||||
a.dst,
|
||||
b.dst,
|
||||
edits,
|
||||
content.getEditsDueToRebase(),
|
||||
editsDueToRebase,
|
||||
a.displayMethod,
|
||||
b.displayMethod,
|
||||
a.mimeType.toString(),
|
||||
|
@@ -801,6 +801,49 @@ public class RevisionDiffIT extends AbstractDaemonTest {
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesDeleted().isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rebaseHunksDirectlyTouchingHunksOfPatchSetsNotModifiedBetweenThemAreIdentified()
|
||||
throws Exception {
|
||||
// Add to hunks in a patch set and remove them in a further patch set to allow rebasing.
|
||||
Function<String, String> contentModification =
|
||||
fileContent ->
|
||||
fileContent.replace("Line 1\n", "Line one\n").replace("Line 3\n", "Line three\n");
|
||||
addModifiedPatchSet(changeId, FILE_NAME, contentModification);
|
||||
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
|
||||
Function<String, String> reverseContentModification =
|
||||
fileContent ->
|
||||
fileContent.replace("Line one\n", "Line 1\n").replace("Line three\n", "Line 3\n");
|
||||
addModifiedPatchSet(changeId, FILE_NAME, reverseContentModification);
|
||||
|
||||
String newFileContent = FILE_CONTENT.replace("Line 2\n", "Line two\n");
|
||||
ObjectId commit2 = addCommit(commit1, FILE_NAME, newFileContent);
|
||||
rebaseChangeOn(changeId, commit2);
|
||||
|
||||
// Add the hunks again and modify another line so that we get a diff for the file.
|
||||
// (Files with only edits due to rebase are filtered out.)
|
||||
addModifiedPatchSet(
|
||||
changeId,
|
||||
FILE_NAME,
|
||||
contentModification.andThen(fileContent -> fileContent.replace("Line 10\n", "Line ten\n")));
|
||||
|
||||
DiffInfo diffInfo =
|
||||
getDiffRequest(changeId, CURRENT, FILE_NAME).withBase(previousPatchSetId).get();
|
||||
assertThat(diffInfo).content().element(0).commonLines().hasSize(1);
|
||||
assertThat(diffInfo).content().element(1).linesOfA().containsExactly("Line 2");
|
||||
assertThat(diffInfo).content().element(1).linesOfB().containsExactly("Line two");
|
||||
assertThat(diffInfo).content().element(1).isDueToRebase();
|
||||
assertThat(diffInfo).content().element(2).commonLines().hasSize(7);
|
||||
assertThat(diffInfo).content().element(3).linesOfA().containsExactly("Line 10");
|
||||
assertThat(diffInfo).content().element(3).linesOfB().containsExactly("Line ten");
|
||||
assertThat(diffInfo).content().element(3).isNotDueToRebase();
|
||||
assertThat(diffInfo).content().element(4).commonLines().hasSize(90);
|
||||
|
||||
Map<String, FileInfo> changedFiles =
|
||||
gApi.changes().id(changeId).current().files(previousPatchSetId);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesInserted().isEqualTo(1);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesDeleted().isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleRebaseEditsMixedWithRegularEditsCanBeIdentified() throws Exception {
|
||||
addModifiedPatchSet(
|
||||
@@ -1210,6 +1253,118 @@ public class RevisionDiffIT extends AbstractDaemonTest {
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesDeleted().isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeNonRebaseHunksAreCombinedForIntralineOptimizations() throws Exception {
|
||||
assume().that(intraline).isTrue();
|
||||
|
||||
String fileContent = FILE_CONTENT.replace("Line 5\n", "{\n");
|
||||
ObjectId commit2 = addCommit(commit1, FILE_NAME, fileContent);
|
||||
rebaseChangeOn(changeId, commit2);
|
||||
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
|
||||
|
||||
addModifiedPatchSet(
|
||||
changeId,
|
||||
FILE_NAME,
|
||||
content -> content.replace("Line 4\n", "Line four\n").replace("Line 6\n", "Line six\n"));
|
||||
|
||||
DiffInfo diffInfo =
|
||||
getDiffRequest(changeId, CURRENT, FILE_NAME).withBase(previousPatchSetId).get();
|
||||
assertThat(diffInfo).content().element(0).commonLines().hasSize(3);
|
||||
assertThat(diffInfo).content().element(1).linesOfA().containsExactly("Line 4", "{", "Line 6");
|
||||
assertThat(diffInfo)
|
||||
.content()
|
||||
.element(1)
|
||||
.linesOfB()
|
||||
.containsExactly("Line four", "{", "Line six");
|
||||
assertThat(diffInfo).content().element(1).isNotDueToRebase();
|
||||
assertThat(diffInfo).content().element(2).commonLines().hasSize(94);
|
||||
|
||||
Map<String, FileInfo> changedFiles =
|
||||
gApi.changes().id(changeId).current().files(previousPatchSetId);
|
||||
// Lines which weren't modified but are included in a hunk due to optimization don't count for
|
||||
// the number of inserted/deleted lines.
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesInserted().isEqualTo(2);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesDeleted().isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeRebaseHunksAreNotCombinedForIntralineOptimizations() throws Exception {
|
||||
assume().that(intraline).isTrue();
|
||||
|
||||
String fileContent = FILE_CONTENT.replace("Line 5\n", "{\n");
|
||||
ObjectId commit2 = addCommit(commit1, FILE_NAME, fileContent);
|
||||
rebaseChangeOn(changeId, commit2);
|
||||
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
|
||||
|
||||
String newFileContent =
|
||||
fileContent.replace("Line 4\n", "Line four\n").replace("Line 6\n", "Line six\n");
|
||||
ObjectId commit3 = addCommit(commit1, FILE_NAME, newFileContent);
|
||||
rebaseChangeOn(changeId, commit3);
|
||||
|
||||
addModifiedPatchSet(
|
||||
changeId, FILE_NAME, content -> content.replace("Line 20\n", "Line twenty\n"));
|
||||
|
||||
DiffInfo diffInfo =
|
||||
getDiffRequest(changeId, CURRENT, FILE_NAME).withBase(previousPatchSetId).get();
|
||||
assertThat(diffInfo).content().element(0).commonLines().hasSize(3);
|
||||
assertThat(diffInfo).content().element(1).linesOfA().containsExactly("Line 4");
|
||||
assertThat(diffInfo).content().element(1).linesOfB().containsExactly("Line four");
|
||||
assertThat(diffInfo).content().element(1).isDueToRebase();
|
||||
assertThat(diffInfo).content().element(2).commonLines().hasSize(1);
|
||||
assertThat(diffInfo).content().element(3).linesOfA().containsExactly("Line 6");
|
||||
assertThat(diffInfo).content().element(3).linesOfB().containsExactly("Line six");
|
||||
assertThat(diffInfo).content().element(3).isDueToRebase();
|
||||
assertThat(diffInfo).content().element(4).commonLines().hasSize(13);
|
||||
assertThat(diffInfo).content().element(5).linesOfA().containsExactly("Line 20");
|
||||
assertThat(diffInfo).content().element(5).linesOfB().containsExactly("Line twenty");
|
||||
assertThat(diffInfo).content().element(5).isNotDueToRebase();
|
||||
assertThat(diffInfo).content().element(6).commonLines().hasSize(80);
|
||||
|
||||
Map<String, FileInfo> changedFiles =
|
||||
gApi.changes().id(changeId).current().files(previousPatchSetId);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesInserted().isEqualTo(1);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesDeleted().isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeRebaseAndNonRebaseHunksAreNotCombinedForIntralineOptimizations()
|
||||
throws Exception {
|
||||
assume().that(intraline).isTrue();
|
||||
|
||||
String fileContent = FILE_CONTENT.replace("Line 5\n", "{\n").replace("Line 7\n", "{\n");
|
||||
ObjectId commit2 = addCommit(commit1, FILE_NAME, fileContent);
|
||||
rebaseChangeOn(changeId, commit2);
|
||||
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
|
||||
|
||||
String newFileContent =
|
||||
fileContent.replace("Line 4\n", "Line four\n").replace("Line 8\n", "Line eight\n");
|
||||
ObjectId commit3 = addCommit(commit1, FILE_NAME, newFileContent);
|
||||
rebaseChangeOn(changeId, commit3);
|
||||
|
||||
addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 6\n", "Line six\n"));
|
||||
|
||||
DiffInfo diffInfo =
|
||||
getDiffRequest(changeId, CURRENT, FILE_NAME).withBase(previousPatchSetId).get();
|
||||
assertThat(diffInfo).content().element(0).commonLines().hasSize(3);
|
||||
assertThat(diffInfo).content().element(1).linesOfA().containsExactly("Line 4");
|
||||
assertThat(diffInfo).content().element(1).linesOfB().containsExactly("Line four");
|
||||
assertThat(diffInfo).content().element(1).isDueToRebase();
|
||||
assertThat(diffInfo).content().element(2).commonLines().hasSize(1);
|
||||
assertThat(diffInfo).content().element(3).linesOfA().containsExactly("Line 6");
|
||||
assertThat(diffInfo).content().element(3).linesOfB().containsExactly("Line six");
|
||||
assertThat(diffInfo).content().element(3).isNotDueToRebase();
|
||||
assertThat(diffInfo).content().element(4).commonLines().hasSize(1);
|
||||
assertThat(diffInfo).content().element(5).linesOfA().containsExactly("Line 8");
|
||||
assertThat(diffInfo).content().element(5).linesOfB().containsExactly("Line eight");
|
||||
assertThat(diffInfo).content().element(5).isDueToRebase();
|
||||
assertThat(diffInfo).content().element(6).commonLines().hasSize(92);
|
||||
|
||||
Map<String, FileInfo> changedFiles =
|
||||
gApi.changes().id(changeId).current().files(previousPatchSetId);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesInserted().isEqualTo(1);
|
||||
assertThat(changedFiles.get(FILE_NAME)).linesDeleted().isEqualTo(1);
|
||||
}
|
||||
|
||||
private void assertDiffForNewFile(
|
||||
PushOneCommit.Result pushResult, String path, String expectedContentSideB) throws Exception {
|
||||
DiffInfo diff =
|
||||
|
@@ -21,6 +21,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||
import com.google.gerrit.acceptance.NoHttpd;
|
||||
@@ -39,7 +40,9 @@ import com.google.gerrit.server.patch.Text;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.eclipse.jgit.diff.Edit;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
@@ -186,19 +189,26 @@ public class PatchListCacheIT extends AbstractDaemonTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void harmfulMutationsOfEditsAreNotPossibleForIntraLineDiffArgsAndCachedValue()
|
||||
throws Exception {
|
||||
public void harmfulMutationsOfEditsAreNotPossibleForIntraLineDiffArgsAndCachedValue() {
|
||||
String a = "First line\nSecond line\n";
|
||||
String b = "1st line\n2nd line\n";
|
||||
Text aText = new Text(a.getBytes(UTF_8));
|
||||
Text bText = new Text(b.getBytes(UTF_8));
|
||||
Edit inputEdit = new Edit(0, 2, 0, 2);
|
||||
List<Edit> inputEdits = new ArrayList<>(ImmutableList.of(inputEdit));
|
||||
Set<Edit> inputEditsDueToRebase = new HashSet<>(ImmutableSet.of(inputEdit));
|
||||
|
||||
IntraLineDiffKey diffKey =
|
||||
IntraLineDiffKey.create(ObjectId.zeroId(), ObjectId.zeroId(), Whitespace.IGNORE_NONE);
|
||||
IntraLineDiffArgs diffArgs =
|
||||
IntraLineDiffArgs.create(aText, bText, inputEdits, project, ObjectId.zeroId(), "file.txt");
|
||||
IntraLineDiffArgs.create(
|
||||
aText,
|
||||
bText,
|
||||
inputEdits,
|
||||
inputEditsDueToRebase,
|
||||
project,
|
||||
ObjectId.zeroId(),
|
||||
"file.txt");
|
||||
IntraLineDiff intraLineDiff = patchListCache.getIntraLineDiff(diffKey, diffArgs);
|
||||
|
||||
Edit outputEdit = Iterables.getOnlyElement(intraLineDiff.getEdits());
|
||||
@@ -206,9 +216,11 @@ public class PatchListCacheIT extends AbstractDaemonTest {
|
||||
outputEdit.shift(5);
|
||||
inputEdit.shift(7);
|
||||
inputEdits.add(new Edit(43, 47, 50, 51));
|
||||
inputEditsDueToRebase.add(new Edit(53, 57, 60, 61));
|
||||
|
||||
Edit originalEdit = new Edit(0, 2, 0, 2);
|
||||
assertThat(diffArgs.edits()).containsExactly(originalEdit);
|
||||
assertThat(diffArgs.editsDueToRebase()).containsExactly(originalEdit);
|
||||
assertThat(intraLineDiff.getEdits()).containsExactly(originalEdit);
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.List;
|
||||
import org.eclipse.jgit.diff.Edit;
|
||||
import org.eclipse.jgit.diff.EditList;
|
||||
@@ -149,7 +150,8 @@ public class IntraLineLoaderTest {
|
||||
Text aText = new Text(a.getBytes(UTF_8));
|
||||
Text bText = new Text(b.getBytes(UTF_8));
|
||||
|
||||
IntraLineDiff diff = IntraLineLoader.compute(aText, bText, ImmutableList.of(lines));
|
||||
IntraLineDiff diff =
|
||||
IntraLineLoader.compute(aText, bText, ImmutableList.of(lines), ImmutableSet.of());
|
||||
|
||||
assertThat(diff.getStatus()).isEqualTo(IntraLineDiff.Status.EDIT_LIST);
|
||||
List<Edit> actualEdits = diff.getEdits();
|
||||
|
Reference in New Issue
Block a user