Skip to content

Commit 4e8ae79

Browse files
authored
STRY50557163 : [Delta-Loading]Find the delta of changes between currently loaded application files and new changes applied while Import from SC (#4)
[Delta-Loading]Find the delta of changes between currently loaded application files and new changes applied while Import from SC This is a customization in the JGIT to filter out the noise and reduce the source control app install on the service now instance. The customization ONLY includes changes to DiffCommand and DiffFormatter and we exposed a new method and the purpose is to not break existing JGIT in any way.
1 parent 45b0d04 commit 4e8ae79

File tree

4 files changed

+275
-5
lines changed

4 files changed

+275
-5
lines changed

org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.io.IOException;
5252
import java.io.OutputStream;
5353
import java.util.List;
54+
import java.util.regex.Pattern;
5455

5556
import org.eclipse.jgit.diff.DiffEntry;
5657
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
@@ -129,7 +130,7 @@ public void testDiffCached() throws Exception {
129130
+ "@@ -0,0 +1 @@\n"
130131
+ "+folder\n"
131132
+ "\\ No newline at end of file\n";
132-
assertEquals(expected.toString(), actual);
133+
assertEquals(expected, actual);
133134
}
134135

135136
@Test
@@ -177,7 +178,7 @@ public void testDiffTwoCommits() throws Exception {
177178
+ "\\ No newline at end of file\n"
178179
+ "+folder change\n"
179180
+ "\\ No newline at end of file\n";
180-
assertEquals(expected.toString(), actual);
181+
assertEquals(expected, actual);
181182
}
182183

183184
@Test
@@ -199,7 +200,7 @@ public void testDiffWithPrefixes() throws Exception {
199200
+ "+++ new/test.txt\n" + "@@ -1 +1 @@\n" + "-test\n"
200201
+ "\\ No newline at end of file\n" + "+test change\n"
201202
+ "\\ No newline at end of file\n";
202-
assertEquals(expected.toString(), actual);
203+
assertEquals(expected, actual);
203204
}
204205

205206
@Test
@@ -221,7 +222,7 @@ public void testDiffWithNegativeLineCount() throws Exception {
221222
+ "index f55b5c9..c5ec8fd 100644\n" + "--- a/test.txt\n"
222223
+ "+++ b/test.txt\n" + "@@ -4,3 +4,3 @@\n" + " 3\n" + "-4\n"
223224
+ "+4a\n" + " 5\n";
224-
assertEquals(expected.toString(), actual);
225+
assertEquals(expected, actual);
225226
}
226227

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

245+
@Test
246+
/**
247+
* Setting a delta filter Pattern (applies to any file) with regex that matches the
248+
* change: diff skipped.
249+
*/
250+
public void testDiffModified_anyDeltaFilter() throws Exception {
251+
write(new File(db.getWorkTree(), "test.txt"), "test");
252+
File folder = new File(db.getWorkTree(), "folder");
253+
folder.mkdir();
254+
write(new File(folder, "folder.txt"), "folder");
255+
Git git = new Git(db);
256+
git.add().addFilepattern(".").call();
257+
git.commit().setMessage("Initial commit").call();
258+
write(new File(folder, "folder.txt"), "folderchange");
259+
260+
OutputStream out = new ByteArrayOutputStream();
261+
Pattern deltaFilterPattern = Pattern.compile("change");
262+
List<DiffEntry> entries = git.diff().setDeltaFilterPattern(deltaFilterPattern).setOutputStream(out).call();
263+
assertEquals(0, entries.size());
264+
265+
assertEquals("", out.toString());
266+
}
267+
244268
private AbstractTreeIterator getTreeIterator(String name)
245269
throws IOException {
246270
final ObjectId id = db.resolve(name);

org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import java.io.ByteArrayOutputStream;
4949
import java.io.File;
50+
import java.util.regex.Pattern;
5051

5152
import org.eclipse.jgit.api.Git;
5253
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
@@ -343,6 +344,187 @@ public void testDiff() throws Exception {
343344
assertEquals(expected, actual);
344345
}
345346

347+
@Test
348+
public void testDiffDeltaFilter_emptyFilter() throws Exception {
349+
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
350+
File folder = new File(db.getDirectory().getParent(), "folder");
351+
FileUtils.mkdir(folder);
352+
write(new File(folder, "folder.txt"), "folder");
353+
Git git = new Git(db);
354+
git.add().addFilepattern(".").call();
355+
git.commit().setMessage("Initial commit").call();
356+
write(new File(folder, "folder.txt"), "folder change");
357+
358+
ByteArrayOutputStream os = new ByteArrayOutputStream();
359+
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
360+
dfmt.setRepository(db);
361+
dfmt.setPathFilter(PathFilter.create("folder"));
362+
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
363+
FileTreeIterator newTree = new FileTreeIterator(db);
364+
365+
//testing an empty delta filter
366+
Pattern deltaFilterPattern = Pattern.compile("");
367+
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
368+
dfmt.flush();
369+
370+
String actual = os.toString("UTF-8");
371+
String expected =
372+
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
373+
+ "index 0119635..95c4c65 100644\n"
374+
+ "--- a/folder/folder.txt\n" + "+++ b/folder/folder.txt\n"
375+
+ "@@ -1 +1 @@\n" + "-folder\n"
376+
+ "\\ No newline at end of file\n" + "+folder change\n"
377+
+ "\\ No newline at end of file\n";
378+
379+
assertEquals(expected, actual);
380+
}
381+
382+
@Test
383+
/**
384+
* This is an ADD file, the file content matches the filter: diff unchanged.
385+
*/
386+
public void testDiffDeltaFilter_addFile() throws Exception {
387+
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
388+
File folder = new File(db.getDirectory().getParent(), "folder");
389+
FileUtils.mkdir(folder);
390+
Git git = new Git(db);
391+
git.add().addFilepattern(".").call();
392+
git.commit().setMessage("Initial commit").call();
393+
write(new File(folder, "folder.txt"), "change");
394+
395+
ByteArrayOutputStream os = new ByteArrayOutputStream();
396+
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
397+
dfmt.setRepository(db);
398+
dfmt.setPathFilter(PathFilter.create("folder"));
399+
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
400+
FileTreeIterator newTree = new FileTreeIterator(db);
401+
402+
//testing a delta filter with one regex
403+
Pattern deltaFilterPattern = Pattern.compile("change");
404+
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
405+
dfmt.flush();
406+
407+
String actual = os.toString("UTF-8");
408+
String expected =
409+
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
410+
+ "new file mode 100644\n"
411+
+ "index 0000000..8013df8\n"
412+
+ "--- /dev/null\n"
413+
+ "+++ b/folder/folder.txt\n"
414+
+ "@@ -0,0 +1 @@\n"
415+
+ "+change\n"
416+
+ "\\ No newline at end of file\n";
417+
418+
assertEquals(expected, actual);
419+
}
420+
421+
@Test
422+
/**
423+
* This is an DELETE file, the file content matches the filter: diff unchanged.
424+
*/
425+
public void testDiffDeltaFilter_deleteFile() throws Exception {
426+
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
427+
File folder = new File(db.getDirectory().getParent(), "folder");
428+
FileUtils.mkdir(folder);
429+
write(new File(folder, "folder.txt"), "change");
430+
Git git = new Git(db);
431+
git.add().addFilepattern(".").call();
432+
git.commit().setMessage("Initial commit").call();
433+
new File(folder, "folder.txt").delete();
434+
435+
ByteArrayOutputStream os = new ByteArrayOutputStream();
436+
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
437+
dfmt.setRepository(db);
438+
dfmt.setPathFilter(PathFilter.create("folder"));
439+
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
440+
FileTreeIterator newTree = new FileTreeIterator(db);
441+
442+
//testing a delta filter with one regex
443+
Pattern deltaFilterPattern = Pattern.compile("change");
444+
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
445+
dfmt.flush();
446+
447+
String actual = os.toString("UTF-8");
448+
String expected =
449+
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
450+
+ "deleted file mode 100644\n"
451+
+ "index 8013df8..0000000\n"
452+
+ "--- a/folder/folder.txt\n"
453+
+ "+++ /dev/null\n"
454+
+ "@@ -1 +0,0 @@\n"
455+
+ "-change\n"
456+
+ "\\ No newline at end of file\n";
457+
458+
assertEquals(expected, actual);
459+
}
460+
461+
@Test
462+
/**
463+
* Filter for any file matches the content of the changed file: diff skipped.
464+
*/
465+
public void testDiffDeltaFilter_filteredModifiedFile() throws Exception {
466+
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
467+
File folder = new File(db.getDirectory().getParent(), "folder");
468+
FileUtils.mkdir(folder);
469+
write(new File(folder, "folder.txt"), "folder");
470+
Git git = new Git(db);
471+
git.add().addFilepattern(".").call();
472+
git.commit().setMessage("Initial commit").call();
473+
write(new File(folder, "folder.txt"), "folderchange");
474+
475+
ByteArrayOutputStream os = new ByteArrayOutputStream();
476+
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
477+
dfmt.setRepository(db);
478+
dfmt.setPathFilter(PathFilter.create("folder"));
479+
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
480+
FileTreeIterator newTree = new FileTreeIterator(db);
481+
482+
//testing a delta filter with one regex (ANY)
483+
Pattern deltaFilterPattern = Pattern.compile("change");
484+
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
485+
dfmt.flush();
486+
487+
assertEquals("", os.toString("UTF-8"));
488+
}
489+
490+
@Test
491+
/**
492+
* The filter doesn't match any change: diff unchanged.
493+
*/
494+
public void testDiffDeltaFilter_filterNoMatch() throws Exception {
495+
write(new File(db.getDirectory().getParent(), "test.txt"), "test");
496+
File folder = new File(db.getDirectory().getParent(), "folder");
497+
FileUtils.mkdir(folder);
498+
write(new File(folder, "folder.txt"), "folder");
499+
Git git = new Git(db);
500+
git.add().addFilepattern(".").call();
501+
git.commit().setMessage("Initial commit").call();
502+
write(new File(folder, "folder.txt"), "folderchange");
503+
504+
ByteArrayOutputStream os = new ByteArrayOutputStream();
505+
DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));
506+
dfmt.setRepository(db);
507+
dfmt.setPathFilter(PathFilter.create("folder"));
508+
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
509+
FileTreeIterator newTree = new FileTreeIterator(db);
510+
511+
//testing a delta filter with one regex (ANY)
512+
Pattern deltaFilterPattern = Pattern.compile("xxxx");
513+
dfmt.format(dfmt.scan(oldTree, newTree), deltaFilterPattern);
514+
dfmt.flush();
515+
516+
String actual = os.toString("UTF-8");
517+
String expected =
518+
"diff --git a/folder/folder.txt b/folder/folder.txt\n"
519+
+ "index 0119635..0b099ef 100644\n"
520+
+ "--- a/folder/folder.txt\n" + "+++ b/folder/folder.txt\n"
521+
+ "@@ -1 +1 @@\n" + "-folder\n"
522+
+ "\\ No newline at end of file\n" + "+folderchange\n"
523+
+ "\\ No newline at end of file\n";
524+
525+
assertEquals(expected, actual);
526+
}
527+
346528
@Test
347529
public void testDiffRootNullToTree() throws Exception {
348530
write(new File(db.getDirectory().getParent(), "test.txt"), "test");

org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import java.io.IOException;
4949
import java.io.OutputStream;
5050
import java.util.List;
51+
import java.util.Map;
52+
import java.util.regex.Pattern;
5153

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

9597
private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
9698

99+
private Pattern deltaFilterPattern = null;
100+
97101
/**
98102
* @param repo
99103
*/
100104
protected DiffCommand(Repository repo) {
101105
super(repo);
102106
}
103107

108+
109+
104110
/**
105111
* Executes the {@code Diff} command with all the options and parameters
106112
* collected by the setter methods (e.g. {@link #setCached(boolean)} of this
107113
* class. Each instance of this class should only be used for one invocation
108114
* of the command. Don't call this method twice on an instance.
109115
*
116+
* Team-Devatscale SC customization to filter some files based on a regex pattern.
117+
* This filter will not be applied if showNameAndStatusOnly is set to true
110118
* @return a DiffEntry for each path which is different
111119
*/
112120
public List<DiffEntry> call() throws GitAPIException {
@@ -149,7 +157,9 @@ public List<DiffEntry> call() throws GitAPIException {
149157
diffFmt.setNewPrefix(destinationPrefix);
150158
if (sourcePrefix != null)
151159
diffFmt.setOldPrefix(sourcePrefix);
152-
diffFmt.format(result);
160+
161+
diffFmt.format(result, this.getDeltaFilterPattern());
162+
153163
diffFmt.flush();
154164
return result;
155165
}
@@ -274,4 +284,20 @@ public DiffCommand setProgressMonitor(ProgressMonitor monitor) {
274284
this.monitor = monitor;
275285
return this;
276286
}
287+
288+
public Pattern getDeltaFilterPattern() {
289+
return deltaFilterPattern;
290+
}
291+
292+
/**
293+
* Set the given delta filter regex pattern. Used only for Source Control.
294+
*
295+
* @param deltaFilterPattern
296+
* the filter pattern
297+
* @return this instance
298+
*/
299+
public DiffCommand setDeltaFilterPattern(Pattern deltaFilterPattern) {
300+
this.deltaFilterPattern = deltaFilterPattern;
301+
return this;
302+
}
277303
}

org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@
6060
import java.io.OutputStream;
6161
import java.util.Collection;
6262
import java.util.Collections;
63+
import java.util.Iterator;
6364
import java.util.List;
65+
import java.util.regex.Pattern;
6466

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

146148
private ContentSource.Pair source;
147149

150+
private static final String EMPTY_STRING = "";
151+
152+
153+
148154
/**
149155
* Create a new formatter with a default level of context.
150156
*
@@ -651,6 +657,38 @@ public void format(List<? extends DiffEntry> entries) throws IOException {
651657
format(ent);
652658
}
653659

660+
/**
661+
* Format the diff entries by filtering out the noise from the given delta filter pattern
662+
* The filter acts only for files that have MODIFY change Type.
663+
* If there are no changes detected, we will remove the diff entry.
664+
* @param entries
665+
* @param deltaFilterPattern
666+
* @throws IOException
667+
*/
668+
669+
public void format(List<? extends DiffEntry> entries, Pattern deltaFilterPattern) throws IOException {
670+
if (deltaFilterPattern == null) {
671+
format(entries);
672+
return;
673+
}
674+
Iterator<? extends DiffEntry> diIterator = entries.iterator();
675+
while (diIterator.hasNext()) {
676+
DiffEntry diffEntry = diIterator.next();
677+
if (MODIFY.equals(diffEntry.changeType)) {
678+
FormatResult res = createFormatResult(diffEntry);
679+
String aContent = new String(res.a.content);
680+
String bContent = new String(res.b.content);
681+
aContent = deltaFilterPattern.matcher(aContent).replaceAll(EMPTY_STRING);
682+
bContent = deltaFilterPattern.matcher(bContent).replaceAll(EMPTY_STRING);
683+
if (!aContent.equals(bContent))
684+
format(res.header, res.a, res.b);
685+
else
686+
diIterator.remove();
687+
} else format(diffEntry);
688+
}
689+
}
690+
691+
654692
/**
655693
* Format a patch script for one file entry.
656694
*

0 commit comments

Comments
 (0)