log: Add whitespace ignore options
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>
This commit is contained in:
parent
bd8740dc14
commit
8a0c58394d
|
@ -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
|
||||
|
|
|
@ -53,12 +53,12 @@
|
|||
|
||||
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 @@
|
|||
|
||||
@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 @@ void tree_0(final AbstractTreeIterator c) {
|
|||
@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 @@ protected void run() throws Exception {
|
|||
out.flush();
|
||||
|
||||
} else {
|
||||
fmt.setRepository(db);
|
||||
fmt.format(files);
|
||||
fmt.flush();
|
||||
diffFmt.setRepository(db);
|
||||
diffFmt.format(files);
|
||||
diffFmt.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,6 +186,8 @@ private List<DiffEntry> scan() throws IOException {
|
|||
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());
|
||||
}
|
||||
|
|
|
@ -60,8 +60,13 @@
|
|||
|
||||
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 @@ protected void show(final RevCommit c) throws Exception {
|
|||
}
|
||||
|
||||
out.println();
|
||||
if (c.getParentCount() > 0 && (showNameAndStatusOnly || showPatch))
|
||||
if (c.getParentCount() == 1 && (showNameAndStatusOnly || showPatch))
|
||||
showDiff(c);
|
||||
out.flush();
|
||||
}
|
||||
|
@ -163,6 +204,8 @@ private void showDiff(RevCommit c) throws IOException {
|
|||
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 @@ private void showDiff(RevCommit c) throws IOException {
|
|||
diffFmt.format(files);
|
||||
diffFmt.flush();
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -66,6 +66,7 @@ public static JGitText get() {
|
|||
/***/ public String URINotSupported;
|
||||
/***/ public String URLNotFound;
|
||||
/***/ public String aNewObjectIdIsRequired;
|
||||
/***/ public String abbreviationLengthMustBeNonNegative;
|
||||
/***/ public String advertisementCameBefore;
|
||||
/***/ public String advertisementOfCameBefore;
|
||||
/***/ public String amazonS3ActionFailed;
|
||||
|
|
|
@ -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 void setContext(final int lineCount) {
|
|||
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 void format(List<? extends DiffEntry> entries) throws IOException {
|
|||
/**
|
||||
* 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 @@ private void formatAndDiff(DiffEntry ent) throws IOException {
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,25 @@
|
|||
* 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;
|
||||
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
* 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.
|
||||
|
|
|
@ -50,6 +50,13 @@
|
|||
* 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.
|
||||
|
|
|
@ -50,6 +50,13 @@
|
|||
* 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.
|
||||
|
|
|
@ -45,14 +45,21 @@
|
|||
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.
|
||||
|
|
Loading…
Reference in New Issue