]> source.dussan.org Git - jgit.git/commitdiff
log: Add whitespace ignore options 53/1053/1
authorShawn O. Pearce <spearce@spearce.org>
Sun, 4 Jul 2010 00:32:47 +0000 (17:32 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Sun, 4 Jul 2010 00:32:47 +0000 (17:32 -0700)
Similar to what we did with diff, implement whitespace ignore options
for log too.  This requires us to define some means of creating any
RawText object type at will inside of DiffFormatter, so we define a
new factory interface to construct RawText instances on demand.

Unfortunately we have to copy the entire block of common options.
args4j only processes the options/arguments on the one command class
and Java doesn't support multiple inheritance.

Change-Id: Ia16cd3a11b850fffae9fbe7b721d7e43f1d0e8a5
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextIgnoreAllWhitespace.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextIgnoreLeadingWhitespace.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextIgnoreTrailingWhitespace.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextIgnoreWhitespaceChange.java

index 67357be1daffdacddc408565be7492b34bd84210..e879d6b605cc113208a4c89c146dd925f82e5aa4 100644 (file)
@@ -68,6 +68,7 @@ metaVar_gitDir=GIT_DIR
 metaVar_hostName=HOSTNAME
 metaVar_linesOfContext=lines
 metaVar_message=message
+metaVar_n=n
 metaVar_name=name
 metaVar_object=object
 metaVar_op=OP
@@ -171,6 +172,7 @@ usage_produceAnEclipseIPLog=Produce an Eclipse IP log
 usage_pruneStaleTrackingRefs=prune stale tracking refs
 usage_recurseIntoSubtrees=recurse into subtrees
 usage_recordChangesToRepository=Record changes to the repository
+usage_renameLimit=limit size of rename matrix
 usage_setTheGitRepositoryToOperateOn=set the git repository to operate on
 usage_showRefNamesMatchingCommits=Show ref names matching commits
 usage_showPatch=display patch
index 32499618dfaa4b06d48af53394fdbab8465c7593..77ed73048d7a4ec1ae37f5fc2957d7b75713db98 100644 (file)
@@ -53,12 +53,12 @@ import java.util.List;
 
 import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffFormatter;
-import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.diff.RawTextIgnoreAllWhitespace;
 import org.eclipse.jgit.diff.RawTextIgnoreLeadingWhitespace;
 import org.eclipse.jgit.diff.RawTextIgnoreTrailingWhitespace;
 import org.eclipse.jgit.diff.RawTextIgnoreWhitespaceChange;
 import org.eclipse.jgit.diff.RenameDetector;
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.TextProgressMonitor;
 import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
@@ -70,6 +70,9 @@ import org.kohsuke.args4j.Option;
 
 @Command(common = true, usage = "usage_ShowDiffs")
 class Diff extends TextBuiltin {
+       private final DiffFormatter diffFmt = new DiffFormatter( //
+                       new BufferedOutputStream(System.out));
+
        @Argument(index = 0, metaVar = "metaVar_treeish", required = true)
        void tree_0(final AbstractTreeIterator c) {
                trees.add(c);
@@ -81,45 +84,55 @@ class Diff extends TextBuiltin {
        @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = PathTreeFilterHandler.class)
        private TreeFilter pathFilter = TreeFilter.ALL;
 
+       // BEGIN -- Options shared with Log
+       @Option(name = "-p", usage = "usage_showPatch")
+       boolean showPatch;
+
        @Option(name = "-M", usage = "usage_detectRenames")
        private boolean detectRenames;
 
+       @Option(name = "-l", usage = "usage_renameLimit")
+       private Integer renameLimit;
+
        @Option(name = "--name-status", usage = "usage_nameStatus")
        private boolean showNameAndStatusOnly;
 
        @Option(name = "--ignore-space-at-eol")
-       private boolean ignoreWsTrailing;
+       void ignoreSpaceAtEol(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreTrailingWhitespace.FACTORY);
+       }
 
        @Option(name = "--ignore-leading-space")
-       private boolean ignoreWsLeading;
+       void ignoreLeadingSpace(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreLeadingWhitespace.FACTORY);
+       }
 
        @Option(name = "-b", aliases = { "--ignore-space-change" })
-       private boolean ignoreWsChange;
+       void ignoreSpaceChange(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreWhitespaceChange.FACTORY);
+       }
 
        @Option(name = "-w", aliases = { "--ignore-all-space" })
-       private boolean ignoreWsAll;
+       void ignoreAllSpace(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreAllWhitespace.FACTORY);
+       }
 
        @Option(name = "-U", aliases = { "--unified" }, metaVar = "metaVar_linesOfContext")
        void unified(int lines) {
-               fmt.setContext(lines);
+               diffFmt.setContext(lines);
        }
 
-       private DiffFormatter fmt = new DiffFormatter( //
-                       new BufferedOutputStream(System.out)) {
-               @Override
-               protected RawText newRawText(byte[] raw) {
-                       if (ignoreWsAll)
-                               return new RawTextIgnoreAllWhitespace(raw);
-                       else if (ignoreWsTrailing)
-                               return new RawTextIgnoreTrailingWhitespace(raw);
-                       else if (ignoreWsChange)
-                               return new RawTextIgnoreWhitespaceChange(raw);
-                       else if (ignoreWsLeading)
-                               return new RawTextIgnoreLeadingWhitespace(raw);
-                       else
-                               return new RawText(raw);
-               }
-       };
+       @Option(name = "--abbrev", metaVar = "n")
+       void abbrev(int lines) {
+               diffFmt.setAbbreviationLength(lines);
+       }
+
+       @Option(name = "--full-index")
+       void abbrev(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setAbbreviationLength(Constants.OBJECT_ID_STRING_LENGTH);
+       }
+
+       // END -- Options shared with Log
 
        @Override
        protected void run() throws Exception {
@@ -130,9 +143,9 @@ class Diff extends TextBuiltin {
                        out.flush();
 
                } else {
-                       fmt.setRepository(db);
-                       fmt.format(files);
-                       fmt.flush();
+                       diffFmt.setRepository(db);
+                       diffFmt.format(files);
+                       diffFmt.flush();
                }
        }
 
@@ -173,6 +186,8 @@ class Diff extends TextBuiltin {
                List<DiffEntry> files = DiffEntry.scan(walk);
                if (detectRenames) {
                        RenameDetector rd = new RenameDetector(db);
+                       if (renameLimit != null)
+                               rd.setRenameLimit(renameLimit.intValue());
                        rd.addAll(files);
                        files = rd.compute(new TextProgressMonitor());
                }
index aa4e8ae3cb14b79d62ba04ef769b57a1ec4236b9..83ef6eb87507b79163cf51073698f062057e0efa 100644 (file)
@@ -60,8 +60,13 @@ import java.util.TimeZone;
 
 import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawTextIgnoreAllWhitespace;
+import org.eclipse.jgit.diff.RawTextIgnoreLeadingWhitespace;
+import org.eclipse.jgit.diff.RawTextIgnoreTrailingWhitespace;
+import org.eclipse.jgit.diff.RawTextIgnoreWhitespaceChange;
 import org.eclipse.jgit.diff.RenameDetector;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.TextProgressMonitor;
@@ -78,27 +83,63 @@ class Log extends RevWalkTextBuiltin {
 
        private final DateFormat fmt;
 
+       private final DiffFormatter diffFmt = new DiffFormatter( //
+                       new BufferedOutputStream(System.out));
+
        private Map<AnyObjectId, Set<Ref>> allRefsByPeeledObjectId;
 
        @Option(name="--decorate", usage="usage_showRefNamesMatchingCommits")
        private boolean decorate;
 
+       // BEGIN -- Options shared with Diff
+       @Option(name = "-p", usage = "usage_showPatch")
+       boolean showPatch;
+
        @Option(name = "-M", usage = "usage_detectRenames")
        private boolean detectRenames;
 
+       @Option(name = "-l", usage = "usage_renameLimit")
+       private Integer renameLimit;
+
        @Option(name = "--name-status", usage = "usage_nameStatus")
        private boolean showNameAndStatusOnly;
 
-       @Option(name = "-p", usage = "usage_showPatch")
-       private boolean showPatch;
+       @Option(name = "--ignore-space-at-eol")
+       void ignoreSpaceAtEol(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreTrailingWhitespace.FACTORY);
+       }
+
+       @Option(name = "--ignore-leading-space")
+       void ignoreLeadingSpace(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreLeadingWhitespace.FACTORY);
+       }
+
+       @Option(name = "-b", aliases = { "--ignore-space-change" })
+       void ignoreSpaceChange(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreWhitespaceChange.FACTORY);
+       }
+
+       @Option(name = "-w", aliases = { "--ignore-all-space" })
+       void ignoreAllSpace(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setRawTextFactory(RawTextIgnoreAllWhitespace.FACTORY);
+       }
 
        @Option(name = "-U", aliases = { "--unified" }, metaVar = "metaVar_linesOfContext")
        void unified(int lines) {
                diffFmt.setContext(lines);
        }
 
-       private DiffFormatter diffFmt = new DiffFormatter( //
-                       new BufferedOutputStream(System.out));
+       @Option(name = "--abbrev", metaVar = "metaVar_n")
+       void abbrev(int lines) {
+               diffFmt.setAbbreviationLength(lines);
+       }
+
+       @Option(name = "--full-index")
+       void abbrev(@SuppressWarnings("unused") boolean on) {
+               diffFmt.setAbbreviationLength(Constants.OBJECT_ID_STRING_LENGTH);
+       }
+
+       // END -- Options shared with Diff
 
        Log() {
                fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US);
@@ -147,7 +188,7 @@ class Log extends RevWalkTextBuiltin {
                }
 
                out.println();
-               if (c.getParentCount() > 0 && (showNameAndStatusOnly || showPatch))
+               if (c.getParentCount() == 1 && (showNameAndStatusOnly || showPatch))
                        showDiff(c);
                out.flush();
        }
@@ -163,6 +204,8 @@ class Log extends RevWalkTextBuiltin {
                List<DiffEntry> files = DiffEntry.scan(tw);
                if (detectRenames) {
                        RenameDetector rd = new RenameDetector(db);
+                       if (renameLimit != null)
+                               rd.setRenameLimit(renameLimit.intValue());
                        rd.addAll(files);
                        files = rd.compute(new TextProgressMonitor());
                }
@@ -175,5 +218,6 @@ class Log extends RevWalkTextBuiltin {
                        diffFmt.format(files);
                        diffFmt.flush();
                }
+               out.println();
        }
 }
index afe7a8c05e51b0a477d8220e099c6a99f55ac2ee..50fadfa81270037517c8c8c61af69961dfc1adb6 100644 (file)
@@ -6,6 +6,7 @@ JRELacksMD5Implementation=JRE lacks MD5 implementation
 URINotSupported=URI not supported: {0}
 URLNotFound={0} not found
 aNewObjectIdIsRequired=A NewObjectId is required.
+abbreviationLengthMustBeNonNegative=Abbreviation length must not be negative.
 advertisementCameBefore=advertisement of {0}^{} came before {1}
 advertisementOfCameBefore=advertisement of {0}^{} came before {1}
 amazonS3ActionFailed={0} of '{1}' failed: {2} {3}
index 1f21b4a026add9e9f210e997b17396c1fa287559..f46461be6925190766d5762e31e537d841457771 100644 (file)
@@ -66,6 +66,7 @@ public class JGitText extends TranslationBundle {
        /***/ public String URINotSupported;
        /***/ public String URLNotFound;
        /***/ public String aNewObjectIdIsRequired;
+       /***/ public String abbreviationLengthMustBeNonNegative;
        /***/ public String advertisementCameBefore;
        /***/ public String advertisementOfCameBefore;
        /***/ public String amazonS3ActionFailed;
index e114b9220949cb245a4e4bcc85c2100c165bf7f8..c12c54b05b17bb87640c32df3dd7cd90223884a7 100644 (file)
@@ -73,6 +73,10 @@ public class DiffFormatter {
 
        private int context;
 
+       private int abbreviationLength;
+
+       private RawText.Factory rawTextFactory = RawText.FACTORY;
+
        /**
         * Create a new formatter with a default level of context.
         *
@@ -84,6 +88,7 @@ public class DiffFormatter {
        public DiffFormatter(OutputStream out) {
                this.out = out;
                setContext(3);
+               setAbbreviationLength(8);
        }
 
        /** @return the stream we are outputting data to. */
@@ -116,6 +121,36 @@ public class DiffFormatter {
                context = lineCount;
        }
 
+       /**
+        * Change the number of digits to show in an ObjectId.
+        *
+        * @param count
+        *            number of digits to show in an ObjectId.
+        */
+       public void setAbbreviationLength(final int count) {
+               if (count < 0)
+                       throw new IllegalArgumentException(
+                                       JGitText.get().abbreviationLengthMustBeNonNegative);
+               abbreviationLength = count;
+       }
+
+       /**
+        * Set the helper that constructs difference output.
+        *
+        * @param type
+        *            the factory to create different output. Different types of
+        *            factories can produce different whitespace behavior, for
+        *            example.
+        * @see RawText#FACTORY
+        * @see RawTextIgnoreAllWhitespace#FACTORY
+        * @see RawTextIgnoreLeadingWhitespace#FACTORY
+        * @see RawTextIgnoreTrailingWhitespace#FACTORY
+        * @see RawTextIgnoreWhitespaceChange#FACTORY
+        */
+       public void setRawTextFactory(RawText.Factory type) {
+               rawTextFactory = type;
+       }
+
        /**
         * Flush the underlying output stream of this formatter.
         *
@@ -143,24 +178,13 @@ public class DiffFormatter {
        /**
         * Format a patch script for one file entry.
         *
-        * @param entry
+        * @param ent
         *            the entry to be formatted.
         * @throws IOException
         *             a file's content cannot be read, or the output stream cannot
         *             be written to.
         */
-       public void format(DiffEntry entry) throws IOException {
-               if (entry instanceof FileHeader) {
-                       format(
-                                       (FileHeader) entry, //
-                                       newRawText(open(entry.getOldMode(), entry.getOldId())),
-                                       newRawText(open(entry.getNewMode(), entry.getNewId())));
-               } else {
-                       formatAndDiff(entry);
-               }
-       }
-
-       private void formatAndDiff(DiffEntry ent) throws IOException {
+       public void format(DiffEntry ent) throws IOException {
                String oldName = quotePath("a/" + ent.getOldName());
                String newName = quotePath("b/" + ent.getNewName());
                out.write(encode("diff --git " + oldName + " " + newName + "\n"));
@@ -250,27 +274,16 @@ public class DiffFormatter {
                                out.write(encodeASCII("Binary files differ\n"));
 
                        } else {
-                               RawText a = newRawText(aRaw);
-                               RawText b = newRawText(bRaw);
+                               RawText a = rawTextFactory.create(aRaw);
+                               RawText b = rawTextFactory.create(bRaw);
                                formatEdits(a, b, new MyersDiff(a, b).getEdits());
                        }
                }
        }
 
-       /**
-        * Construct a RawText sequence for use with {@link MyersDiff}.
-        *
-        * @param content
-        *            text to be compared.
-        * @return the raw text instance to handle the content.
-        */
-       protected RawText newRawText(byte[] content) {
-               return new RawText(content);
-       }
-
        private String format(AbbreviatedObjectId oldId) {
                if (oldId.isComplete() && db != null)
-                       oldId = oldId.toObjectId().abbreviate(db, 8);
+                       oldId = oldId.toObjectId().abbreviate(db, abbreviationLength);
                return oldId.name();
        }
 
index c01cb7ad8e9d633d0d494f5834224f2c9b64c3b4..574d2edf9176354a46ac510df9a2982e6782bd6d 100644 (file)
@@ -65,6 +65,25 @@ import org.eclipse.jgit.util.RawParseUtils;
  * they are converting from "line number" to "element index".
  */
 public class RawText implements Sequence {
+       /** Creates a RawText instance. */
+       public static interface Factory {
+               /**
+                * Construct a RawText instance for the content.
+                *
+                * @param input
+                *            the content array.
+                * @return a RawText instance wrapping this content.
+                */
+               RawText create(byte[] input);
+       }
+
+       /** Creates RawText that does not treat whitespace specially. */
+       public static final Factory FACTORY = new Factory() {
+               public RawText create(byte[] input) {
+                       return new RawText(input);
+               }
+       };
+
        /** Number of bytes to check for heuristics in {@link #isBinary(byte[])} */
        private static final int FIRST_FEW_BYTES = 8000;
 
index f72259605e6c18a997b8707084542f0899debe7e..211618a3fb66d4f2fb32287ac4dfdab596330992 100644 (file)
@@ -51,6 +51,13 @@ import static org.eclipse.jgit.util.RawCharUtil.trimTrailingWhitespace;
  * A version of {@link RawText} that ignores all whitespace.
  */
 public class RawTextIgnoreAllWhitespace extends RawText {
+       /** Creates RawText that ignores all whitespace. */
+       @SuppressWarnings("hiding")
+       public static final Factory FACTORY = new Factory() {
+               public RawText create(byte[] input) {
+                       return new RawTextIgnoreAllWhitespace(input);
+               }
+       };
 
        /**
         * Create a new sequence from an existing content byte array.
index 1d928766a9fdd917830b97bb7782a19deb15f26b..23778973b701fed2a4a6b706074b7c2ab6026ee7 100644 (file)
@@ -50,6 +50,13 @@ import static org.eclipse.jgit.util.RawCharUtil.trimLeadingWhitespace;
  * A version of {@link RawText} that ignores leading whitespace.
  */
 public class RawTextIgnoreLeadingWhitespace extends RawText {
+       /** Creates RawText that ignores only leading whitespace. */
+       @SuppressWarnings("hiding")
+       public static final Factory FACTORY = new Factory() {
+               public RawText create(byte[] input) {
+                       return new RawTextIgnoreLeadingWhitespace(input);
+               }
+       };
 
        /**
         * Create a new sequence from an existing content byte array.
index b9095940cfaa2a0cbb5610ea9d16c9460ee52d80..3feb2e783acfbc6f6b85f4a6e4d1009bbb77ec2d 100644 (file)
@@ -50,6 +50,13 @@ import static org.eclipse.jgit.util.RawCharUtil.trimTrailingWhitespace;
  * A version of {@link RawText} that ignores trailing whitespace.
  */
 public class RawTextIgnoreTrailingWhitespace extends RawText {
+       /** Creates RawText that ignores only trailing whitespace. */
+       @SuppressWarnings("hiding")
+       public static final Factory FACTORY = new Factory() {
+               public RawText create(byte[] input) {
+                       return new RawTextIgnoreTrailingWhitespace(input);
+               }
+       };
 
        /**
         * Create a new sequence from an existing content byte array.
index 399f038bca64594e5bbec2081e8df22fcb79e91b..e6bd8e98b792357c689de14262113db257d735bc 100644 (file)
 package org.eclipse.jgit.diff;
 
 import static org.eclipse.jgit.util.RawCharUtil.isWhitespace;
-import static org.eclipse.jgit.util.RawCharUtil.trimTrailingWhitespace;
 import static org.eclipse.jgit.util.RawCharUtil.trimLeadingWhitespace;
+import static org.eclipse.jgit.util.RawCharUtil.trimTrailingWhitespace;
 
 /**
  * A version of {@link RawText} that ignores changes in the amount of
  * whitespace, as well as trailing whitespace.
  */
 public class RawTextIgnoreWhitespaceChange extends RawText {
+       /** Creates RawText that ignores only whitespace changes. */
+       @SuppressWarnings("hiding")
+       public static final Factory FACTORY = new Factory() {
+               public RawText create(byte[] input) {
+                       return new RawTextIgnoreWhitespaceChange(input);
+               }
+       };
 
        /**
         * Create a new sequence from an existing content byte array.