aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit
diff options
context:
space:
mode:
authorChristian Halstrick <christian.halstrick@sap.com>2010-11-26 00:30:08 +0100
committerChristian Halstrick <christian.halstrick@sap.com>2010-11-26 00:30:08 +0100
commit049827d7080201fe24f2728b26d681434327f72a (patch)
treeffb4bc655c9ea98ed62e8194ecd6acca407cd912 /org.eclipse.jgit/src/org/eclipse/jgit
parent7e298c9ed538dd8d5207adce3497b4a1df701dc5 (diff)
downloadjgit-049827d7080201fe24f2728b26d681434327f72a.tar.gz
jgit-049827d7080201fe24f2728b26d681434327f72a.zip
Make diff algorithm configurable
The diff algorithm which is used by Merge, Cherry-Pick, Rebase should be configurable. A new configuration parameter "diff.algorithm" is introduced which currently accepts the values "myers" or "histogram". Based on this parameter for example the ResolveMerger will choose a diff algorithm. The reason for this is bug 331078. This bug shows that JGit is more compatible with C Git when histogram diff is in place. But since histogram diff is quite new we need an easy way to fall back to Myers diff. Bug: 331078 Change-Id: I2549c992e478d991c61c9508ad826d1a9e539ae3 Signed-off-by: Christian Halstrick <christian.halstrick@sap.com> Signed-off-by: Philipp Thun <philipp.thun@sap.com>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java32
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java29
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java11
5 files changed, 78 insertions, 10 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
index f6859a29c3..b20e3258b6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
@@ -54,6 +54,38 @@ package org.eclipse.jgit.diff;
*/
public abstract class DiffAlgorithm {
/**
+ * Supported diff algorithm
+ */
+ public enum SupportedAlgorithm {
+ /**
+ * Myers diff algorithm
+ */
+ MYERS,
+
+ /**
+ * Histogram diff algorithm
+ */
+ HISTOGRAM
+ }
+
+ /**
+ * @param alg
+ * the diff algorithm for which an implementation should be
+ * returned
+ * @return an implementation of the specified diff algorithm
+ */
+ public static DiffAlgorithm getAlgorithm(SupportedAlgorithm alg) {
+ switch (alg) {
+ case MYERS:
+ return MyersDiff.INSTANCE;
+ case HISTOGRAM:
+ return new HistogramDiff();
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
* Compare two sequences and identify a list of edits between them.
*
* @param <S>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index be9a86eda9..fa0cb9c473 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -63,6 +63,7 @@ import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.JGitText;
+import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.errors.CorruptObjectException;
@@ -70,6 +71,7 @@ import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
@@ -118,7 +120,7 @@ public class DiffFormatter {
private int abbreviationLength = 7;
- private DiffAlgorithm diffAlgorithm = new HistogramDiff();
+ private DiffAlgorithm diffAlgorithm;
private RawTextComparator comparator = RawTextComparator.DEFAULT;
@@ -178,6 +180,12 @@ public class DiffFormatter {
setNewPrefix("");
}
setDetectRenames(dc.isRenameDetectionEnabled());
+
+ diffAlgorithm = DiffAlgorithm.getAlgorithm(db.getConfig().getEnum(
+ ConfigConstants.CONFIG_DIFF_SECTION, null,
+ ConfigConstants.CONFIG_KEY_ALGORITHM,
+ SupportedAlgorithm.HISTOGRAM));
+
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index 4ca11d0faf..9f742062b3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -57,6 +57,12 @@ public class ConfigConstants {
/** The "remote" section */
public static final String CONFIG_REMOTE_SECTION = "remote";
+ /** The "diff" section */
+ public static final String CONFIG_DIFF_SECTION = "diff";
+
+ /** The "algorithm" key */
+ public static final String CONFIG_KEY_ALGORITHM = "algorithm";
+
/** The "autocrlf" key */
public static final String CONFIG_KEY_AUTOCRLF = "autocrlf";
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
index aee0ba940a..62febd62c2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
@@ -47,6 +47,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import org.eclipse.jgit.diff.DiffAlgorithm;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.EditList;
import org.eclipse.jgit.diff.MyersDiff;
@@ -56,15 +57,27 @@ import org.eclipse.jgit.merge.MergeChunk.ConflictState;
/**
* Provides the merge algorithm which does a three-way merge on content provided
- * as RawText. Makes use of {@link MyersDiff} to compute the diffs.
+ * as RawText. By default {@link MyersDiff} is used as diff algorithm.
*/
public final class MergeAlgorithm {
+ private final DiffAlgorithm diffAlg;
/**
- * Since this class provides only static methods I add a private default
- * constructor to prevent instantiation.
+ * Creates a new MergeAlgorithm which uses {@link MyersDiff} as diff
+ * algorithm
*/
- private MergeAlgorithm() {
+ public MergeAlgorithm() {
+ this(MyersDiff.INSTANCE);
+ }
+
+ /**
+ * Creates a new MergeAlgorithm
+ *
+ * @param diff
+ * the diff algorithm used by this merge
+ */
+ public MergeAlgorithm(DiffAlgorithm diff) {
+ this.diffAlg = diff;
}
// An special edit which acts as a sentinel value by marking the end the
@@ -83,16 +96,16 @@ public final class MergeAlgorithm {
* @param theirs the second sequence to be merged
* @return the resulting content
*/
- public static <S extends Sequence> MergeResult<S> merge(
+ public <S extends Sequence> MergeResult<S> merge(
SequenceComparator<S> cmp, S base, S ours, S theirs) {
List<S> sequences = new ArrayList<S>(3);
sequences.add(base);
sequences.add(ours);
sequences.add(theirs);
- MergeResult result = new MergeResult<S>(sequences);
- EditList oursEdits = MyersDiff.INSTANCE.diff(cmp, base, ours);
+ MergeResult<S> result = new MergeResult<S>(sequences);
+ EditList oursEdits = diffAlg.diff(cmp, base, ours);
Iterator<Edit> baseToOurs = oursEdits.iterator();
- EditList theirsEdits = MyersDiff.INSTANCE.diff(cmp, base, theirs);
+ EditList theirsEdits = diffAlg.diff(cmp, base, theirs);
Iterator<Edit> baseToTheirs = theirsEdits.iterator();
int current = 0; // points to the next line (first line is 0) of base
// which was not handled yet
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index a6119edfae..a1bda41284 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -58,6 +58,8 @@ import java.util.List;
import java.util.Map;
import org.eclipse.jgit.JGitText;
+import org.eclipse.jgit.diff.DiffAlgorithm;
+import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.diff.Sequence;
@@ -71,6 +73,7 @@ import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.IndexWriteException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
@@ -136,6 +139,7 @@ public class ResolveMerger extends ThreeWayMerger {
private WorkingTreeIterator workingTreeIterator;
+ private MergeAlgorithm mergeAlgorithm;
/**
* @param local
@@ -143,6 +147,11 @@ public class ResolveMerger extends ThreeWayMerger {
*/
protected ResolveMerger(Repository local, boolean inCore) {
super(local);
+ SupportedAlgorithm diffAlg = local.getConfig().getEnum(
+ ConfigConstants.CONFIG_DIFF_SECTION, null,
+ ConfigConstants.CONFIG_KEY_ALGORITHM,
+ SupportedAlgorithm.HISTOGRAM);
+ mergeAlgorithm = new MergeAlgorithm(DiffAlgorithm.getAlgorithm(diffAlg));
commitNames = new String[] { "BASE", "OURS", "THEIRS" };
oi = getObjectInserter();
this.inCore = inCore;
@@ -459,7 +468,7 @@ public class ResolveMerger extends ThreeWayMerger {
MergeFormatter fmt = new MergeFormatter();
// do the merge
- MergeResult<RawText> result = MergeAlgorithm.merge(
+ MergeResult<RawText> result = mergeAlgorithm.merge(
RawTextComparator.DEFAULT,
getRawText(base.getEntryObjectId(), db),
getRawText(ours.getEntryObjectId(), db),