Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
Expand Down Expand Up @@ -129,7 +130,7 @@ public void testDiffCached() throws Exception {
+ "@@ -0,0 +1 @@\n"
+ "+folder\n"
+ "\\ No newline at end of file\n";
assertEquals(expected.toString(), actual);
assertEquals(expected, actual);
}

@Test
Expand Down Expand Up @@ -177,7 +178,7 @@ public void testDiffTwoCommits() throws Exception {
+ "\\ No newline at end of file\n"
+ "+folder change\n"
+ "\\ No newline at end of file\n";
assertEquals(expected.toString(), actual);
assertEquals(expected, actual);
}

@Test
Expand All @@ -199,7 +200,7 @@ public void testDiffWithPrefixes() throws Exception {
+ "+++ new/test.txt\n" + "@@ -1 +1 @@\n" + "-test\n"
+ "\\ No newline at end of file\n" + "+test change\n"
+ "\\ No newline at end of file\n";
assertEquals(expected.toString(), actual);
assertEquals(expected, actual);
}

@Test
Expand All @@ -221,7 +222,7 @@ public void testDiffWithNegativeLineCount() throws Exception {
+ "index f55b5c9..c5ec8fd 100644\n" + "--- a/test.txt\n"
+ "+++ b/test.txt\n" + "@@ -4,3 +4,3 @@\n" + " 3\n" + "-4\n"
+ "+4a\n" + " 5\n";
assertEquals(expected.toString(), actual);
assertEquals(expected, actual);
}

@Test
Expand All @@ -241,6 +242,29 @@ public void testNoOutputStreamSet() throws Exception {
assertEquals("test.txt", diff.getNewPath());
}

@Test
/**
* Setting a delta filter Pattern (applies to any file) with regex that matches the
* change: diff skipped.
*/
public void testDiffModified_anyDeltaFilter() throws Exception {
write(new File(db.getWorkTree(), "test.txt"), "test");
File folder = new File(db.getWorkTree(), "folder");
folder.mkdir();
write(new File(folder, "folder.txt"), "folder");
Git git = new Git(db);
git.add().addFilepattern(".").call();
git.commit().setMessage("Initial commit").call();
write(new File(folder, "folder.txt"), "folderchange");

OutputStream out = new ByteArrayOutputStream();
Pattern deltaFilterPattern = Pattern.compile("change");
List<DiffEntry> entries = git.diff().setDeltaFilterPattern(deltaFilterPattern).setOutputStream(out).call();
assertEquals(0, entries.size());

assertEquals("", out.toString());
}

private AbstractTreeIterator getTreeIterator(String name)
throws IOException {
final ObjectId id = db.resolve(name);
Expand Down
182 changes: 182 additions & 0 deletions org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.regex.Pattern;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
Expand Down Expand Up @@ -343,6 +344,187 @@ public void testDiff() throws Exception {
assertEquals(expected, actual);
}

@Test
public void testDiffDeltaFilter_emptyFilter() throws Exception {
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
File folder = new File(db.getDirectory().getParent(), "folder");
FileUtils.mkdir(folder);
write(new File(folder, "folder.txt"), "folder");
Git git = new Git(db);
git.add().addFilepattern(".").call();
git.commit().setMessage("Initial commit").call();
write(new File(folder, "folder.txt"), "folder change");

ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
dfmt.setRepository(db);
dfmt.setPathFilter(PathFilter.create("folder"));
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
FileTreeIterator newTree = new FileTreeIterator(db);

//testing an empty delta filter
Pattern deltaFilterPattern = Pattern.compile("");
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
dfmt.flush();

String actual = os.toString("UTF-8");
String expected =
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
+ "index 0119635..95c4c65 100644\n"
+ "--- a/folder/folder.txt\n" + "+++ b/folder/folder.txt\n"
+ "@@ -1 +1 @@\n" + "-folder\n"
+ "\\ No newline at end of file\n" + "+folder change\n"
+ "\\ No newline at end of file\n";

assertEquals(expected, actual);
}

@Test
/**
* This is an ADD file, the file content matches the filter: diff unchanged.
*/
public void testDiffDeltaFilter_addFile() throws Exception {
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
File folder = new File(db.getDirectory().getParent(), "folder");
FileUtils.mkdir(folder);
Git git = new Git(db);
git.add().addFilepattern(".").call();
git.commit().setMessage("Initial commit").call();
write(new File(folder, "folder.txt"), "change");

ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
dfmt.setRepository(db);
dfmt.setPathFilter(PathFilter.create("folder"));
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
FileTreeIterator newTree = new FileTreeIterator(db);

//testing a delta filter with one regex
Pattern deltaFilterPattern = Pattern.compile("change");
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
dfmt.flush();

String actual = os.toString("UTF-8");
String expected =
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
+ "new file mode 100644\n"
+ "index 0000000..8013df8\n"
+ "--- /dev/null\n"
+ "+++ b/folder/folder.txt\n"
+ "@@ -0,0 +1 @@\n"
+ "+change\n"
+ "\\ No newline at end of file\n";

assertEquals(expected, actual);
}

@Test
/**
* This is an DELETE file, the file content matches the filter: diff unchanged.
*/
public void testDiffDeltaFilter_deleteFile() throws Exception {
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
File folder = new File(db.getDirectory().getParent(), "folder");
FileUtils.mkdir(folder);
write(new File(folder, "folder.txt"), "change");
Git git = new Git(db);
git.add().addFilepattern(".").call();
git.commit().setMessage("Initial commit").call();
new File(folder, "folder.txt").delete();

ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
dfmt.setRepository(db);
dfmt.setPathFilter(PathFilter.create("folder"));
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
FileTreeIterator newTree = new FileTreeIterator(db);

//testing a delta filter with one regex
Pattern deltaFilterPattern = Pattern.compile("change");
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
dfmt.flush();

String actual = os.toString("UTF-8");
String expected =
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
+ "deleted file mode 100644\n"
+ "index 8013df8..0000000\n"
+ "--- a/folder/folder.txt\n"
+ "+++ /dev/null\n"
+ "@@ -1 +0,0 @@\n"
+ "-change\n"
+ "\\ No newline at end of file\n";

assertEquals(expected, actual);
}

@Test
/**
* Filter for any file matches the content of the changed file: diff skipped.
*/
public void testDiffDeltaFilter_filteredModifiedFile() throws Exception {
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
File folder = new File(db.getDirectory().getParent(), "folder");
FileUtils.mkdir(folder);
write(new File(folder, "folder.txt"), "folder");
Git git = new Git(db);
git.add().addFilepattern(".").call();
git.commit().setMessage("Initial commit").call();
write(new File(folder, "folder.txt"), "folderchange");

ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
dfmt.setRepository(db);
dfmt.setPathFilter(PathFilter.create("folder"));
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
FileTreeIterator newTree = new FileTreeIterator(db);

//testing a delta filter with one regex (ANY)
Pattern deltaFilterPattern = Pattern.compile("change");
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
dfmt.flush();

assertEquals("", os.toString("UTF-8"));
}

@Test
/**
* The filter doesn't match any change: diff unchanged.
*/
public void testDiffDeltaFilter_filterNoMatch() throws Exception {
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
File folder = new File(db.getDirectory().getParent(), "folder");
FileUtils.mkdir(folder);
write(new File(folder, "folder.txt"), "folder");
Git git = new Git(db);
git.add().addFilepattern(".").call();
git.commit().setMessage("Initial commit").call();
write(new File(folder, "folder.txt"), "folderchange");

ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
dfmt.setRepository(db);
dfmt.setPathFilter(PathFilter.create("folder"));
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
FileTreeIterator newTree = new FileTreeIterator(db);

//testing a delta filter with one regex (ANY)
Pattern deltaFilterPattern = Pattern.compile("xxxx");
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
dfmt.flush();

String actual = os.toString("UTF-8");
String expected =
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
+ "index 0119635..0b099ef 100644\n"
+ "--- a/folder/folder.txt\n" + "+++ b/folder/folder.txt\n"
+ "@@ -1 +1 @@\n" + "-folder\n"
+ "\\ No newline at end of file\n" + "+folderchange\n"
+ "\\ No newline at end of file\n";

assertEquals(expected, actual);
}

@Test
public void testDiffRootNullToTree() throws Exception {
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
Expand Down
28 changes: 27 additions & 1 deletion org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
Expand Down Expand Up @@ -94,19 +96,25 @@ public class DiffCommand extends GitCommand<List<DiffEntry>> {

private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;

private Pattern deltaFilterPattern = null;

/**
* @param repo
*/
protected DiffCommand(Repository repo) {
super(repo);
}



/**
* Executes the {@code Diff} command with all the options and parameters
* collected by the setter methods (e.g. {@link #setCached(boolean)} of this
* class. Each instance of this class should only be used for one invocation
* of the command. Don't call this method twice on an instance.
*
* Team-Devatscale SC customization to filter some files based on a regex pattern.
* This filter will not be applied if showNameAndStatusOnly is set to true
* @return a DiffEntry for each path which is different
*/
public List<DiffEntry> call() throws GitAPIException {
Expand Down Expand Up @@ -149,7 +157,9 @@ public List<DiffEntry> call() throws GitAPIException {
diffFmt.setNewPrefix(destinationPrefix);
if (sourcePrefix != null)
diffFmt.setOldPrefix(sourcePrefix);
diffFmt.format(result);

diffFmt.format(result, this.getDeltaFilterPattern());

diffFmt.flush();
return result;
}
Expand Down Expand Up @@ -274,4 +284,20 @@ public DiffCommand setProgressMonitor(ProgressMonitor monitor) {
this.monitor = monitor;
return this;
}

public Pattern getDeltaFilterPattern() {
return deltaFilterPattern;
}

/**
* Set the given delta filter regex pattern. Used only for Source Control.
*
* @param deltaFilterPattern
* the filter pattern
* @return this instance
*/
public DiffCommand setDeltaFilterPattern(Pattern deltaFilterPattern) {
this.deltaFilterPattern = deltaFilterPattern;
return this;
}
}
38 changes: 38 additions & 0 deletions org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
Expand Down Expand Up @@ -145,6 +147,10 @@ public class DiffFormatter implements AutoCloseable {

private ContentSource.Pair source;

private static final String EMPTY_STRING = "";



/**
* Create a new formatter with a default level of context.
*
Expand Down Expand Up @@ -651,6 +657,38 @@ public void format(List<? extends DiffEntry> entries) throws IOException {
format(ent);
}

/**
* Format the diff entries by filtering out the noise from the given delta filter pattern
* The filter acts only for files that have MODIFY change Type.
* If there are no changes detected, we will remove the diff entry.
* @param entries
* @param deltaFilterPattern
* @throws IOException
*/

public void format(List<? extends DiffEntry> entries, Pattern deltaFilterPattern) throws IOException {
if (deltaFilterPattern == null) {
format(entries);
return;
}
Iterator<? extends DiffEntry> diIterator = entries.iterator();
while (diIterator.hasNext()) {
DiffEntry diffEntry = diIterator.next();
if (MODIFY.equals(diffEntry.changeType)) {
FormatResult res = createFormatResult(diffEntry);
String aContent = new String(res.a.content);
String bContent = new String(res.b.content);
aContent = deltaFilterPattern.matcher(aContent).replaceAll(EMPTY_STRING);
bContent = deltaFilterPattern.matcher(bContent).replaceAll(EMPTY_STRING);
if (!aContent.equals(bContent))
format(res.header, res.a, res.b);
else
diIterator.remove();
} else format(diffEntry);
}
}


/**
* Format a patch script for one file entry.
*
Expand Down