]> source.dussan.org Git - jgit.git/commitdiff
Abort rename detection in a timely manner if cancelled 42/126742/7
authorMatthias Sohn <matthias.sohn@sap.com>
Sat, 21 Jul 2018 19:50:30 +0000 (21:50 +0200)
committerMatthias Sohn <matthias.sohn@sap.com>
Mon, 6 Aug 2018 22:09:43 +0000 (00:09 +0200)
If progress monitor is cancelled break loops in rename detection by
throwing a CanceledException.

Bug: 536324
Change-Id: Ia3511fb749d2a5d45005e72c156b874ab7a0da26
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java

index 826be11d5c5ace12572a493db11dbec503a629af..2150d5ce3e0a3b965366ad349979c1f728bff484 100644 (file)
@@ -579,6 +579,7 @@ remoteNameCantBeNull=Remote name can't be null.
 renameBranchFailedBecauseTag=Can not rename as Ref {0} is a tag
 renameBranchFailedUnknownReason=Rename failed with unknown reason
 renameBranchUnexpectedResult=Unexpected rename result {0}
+renameCancelled=Rename detection was cancelled
 renameFileFailed=Could not rename file {0} to {1}
 renamesAlreadyFound=Renames have already been found.
 renamesBreakingModifies=Breaking apart modified file pairs
index 9cec64567956fd1c83f1ed1ea45e33d55371c99b..8234941668dd3479f088095f114f78addf8969fe 100644 (file)
@@ -52,6 +52,7 @@ import java.util.Collection;
 import java.util.Collections;
 
 import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.api.errors.CanceledException;
 import org.eclipse.jgit.blame.Candidate.BlobCandidate;
 import org.eclipse.jgit.blame.Candidate.ReverseCandidate;
 import org.eclipse.jgit.blame.ReverseWalk.ReverseCommit;
@@ -627,9 +628,15 @@ public class BlameGenerator implements AutoCloseable {
                if (n.sourceCommit == null)
                        return result(n);
 
-               DiffEntry r = findRename(parent, n.sourceCommit, n.sourcePath);
-               if (r == null)
+               DiffEntry r;
+               try {
+                       r = findRename(parent, n.sourceCommit, n.sourcePath);
+                       if (r == null) {
+                               return result(n);
+                       }
+               } catch (CanceledException e) {
                        return result(n);
+               }
 
                if (0 == r.getOldId().prefixCompare(n.sourceBlob)) {
                        // A 100% rename without any content change can also
@@ -687,7 +694,8 @@ public class BlameGenerator implements AutoCloseable {
                return false;
        }
 
-       private boolean processMerge(Candidate n) throws IOException {
+       private boolean processMerge(Candidate n)
+                       throws IOException {
                int pCnt = n.getParentCount();
 
                // If any single parent exactly matches the merge, follow only
@@ -714,9 +722,15 @@ public class BlameGenerator implements AutoCloseable {
                                if (ids != null && ids[pIdx] != null)
                                        continue;
 
-                               DiffEntry r = findRename(parent, n.sourceCommit, n.sourcePath);
-                               if (r == null)
+                               DiffEntry r;
+                               try {
+                                       r = findRename(parent, n.sourceCommit, n.sourcePath);
+                                       if (r == null) {
+                                               continue;
+                                       }
+                               } catch (CanceledException e) {
                                        continue;
+                               }
 
                                if (n instanceof ReverseCandidate) {
                                        if (ids == null)
@@ -1021,7 +1035,7 @@ public class BlameGenerator implements AutoCloseable {
        }
 
        private DiffEntry findRename(RevCommit parent, RevCommit commit,
-                       PathFilter path) throws IOException {
+                       PathFilter path) throws IOException, CanceledException {
                if (renameDetector == null)
                        return null;
 
index 7aaa50030face272afa4232e255da61d05869236..b70ff4b2be03be2cb8ffa53adf9e7747325c3cb3 100644 (file)
@@ -62,6 +62,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import org.eclipse.jgit.api.errors.CanceledException;
 import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.dircache.DirCacheIterator;
@@ -577,7 +578,11 @@ public class DiffFormatter implements AutoCloseable {
                        throws IOException {
                renameDetector.reset();
                renameDetector.addAll(files);
-               return renameDetector.compute(reader, progressMonitor);
+               try {
+                       return renameDetector.compute(reader, progressMonitor);
+               } catch (CanceledException e) {
+                       return Collections.emptyList();
+               }
        }
 
        private boolean isAdd(List<DiffEntry> files) {
index 7bb217d04daaa27f9efe847495b7ff469c1b83da..8336cf249f10bb9f8f18289ff6448e43857c5a28 100644 (file)
@@ -55,6 +55,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 
+import org.eclipse.jgit.api.errors.CanceledException;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.diff.SimilarityIndex.TableFullException;
 import org.eclipse.jgit.internal.JGitText;
@@ -320,7 +321,11 @@ public class RenameDetector {
         *             file contents cannot be read from the repository.
         */
        public List<DiffEntry> compute() throws IOException {
-               return compute(NullProgressMonitor.INSTANCE);
+               try {
+                       return compute(NullProgressMonitor.INSTANCE);
+               } catch (CanceledException e) {
+                       return Collections.emptyList();
+               }
        }
 
        /**
@@ -332,8 +337,11 @@ public class RenameDetector {
         *         representing all files that have been changed.
         * @throws java.io.IOException
         *             file contents cannot be read from the repository.
+        * @throws CanceledException
+        *             if rename detection was cancelled
         */
-       public List<DiffEntry> compute(ProgressMonitor pm) throws IOException {
+       public List<DiffEntry> compute(ProgressMonitor pm)
+                       throws IOException, CanceledException {
                if (!done) {
                        try {
                                return compute(objectReader, pm);
@@ -355,9 +363,11 @@ public class RenameDetector {
         *         representing all files that have been changed.
         * @throws java.io.IOException
         *             file contents cannot be read from the repository.
+        * @throws CanceledException
+        *             if rename detection was cancelled
         */
        public List<DiffEntry> compute(ObjectReader reader, ProgressMonitor pm)
-                       throws IOException {
+                       throws IOException, CanceledException {
                final ContentSource cs = ContentSource.create(reader);
                return compute(new ContentSource.Pair(cs, cs), pm);
        }
@@ -373,9 +383,11 @@ public class RenameDetector {
         *         representing all files that have been changed.
         * @throws java.io.IOException
         *             file contents cannot be read from the repository.
+        * @throws CanceledException
+        *             if rename detection was cancelled
         */
        public List<DiffEntry> compute(ContentSource.Pair reader, ProgressMonitor pm)
-                       throws IOException {
+                       throws IOException, CanceledException {
                if (!done) {
                        done = true;
 
@@ -415,8 +427,15 @@ public class RenameDetector {
                done = false;
        }
 
+       private void advanceOrCancel(ProgressMonitor pm) throws CanceledException {
+               if (pm.isCancelled()) {
+                       throw new CanceledException(JGitText.get().renameCancelled);
+               }
+               pm.update(1);
+       }
+
        private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm)
-                       throws IOException {
+                       throws IOException, CanceledException {
                ArrayList<DiffEntry> newEntries = new ArrayList<>(entries.size());
 
                pm.beginTask(JGitText.get().renamesBreakingModifies, entries.size());
@@ -437,13 +456,13 @@ public class RenameDetector {
                        } else {
                                newEntries.add(e);
                        }
-                       pm.update(1);
+                       advanceOrCancel(pm);
                }
 
                entries = newEntries;
        }
 
-       private void rejoinModifies(ProgressMonitor pm) {
+       private void rejoinModifies(ProgressMonitor pm) throws CanceledException {
                HashMap<String, DiffEntry> nameMap = new HashMap<>();
                ArrayList<DiffEntry> newAdded = new ArrayList<>(added.size());
 
@@ -452,7 +471,7 @@ public class RenameDetector {
 
                for (DiffEntry src : deleted) {
                        nameMap.put(src.oldPath, src);
-                       pm.update(1);
+                       advanceOrCancel(pm);
                }
 
                for (DiffEntry dst : added) {
@@ -468,7 +487,7 @@ public class RenameDetector {
                        } else {
                                newAdded.add(dst);
                        }
-                       pm.update(1);
+                       advanceOrCancel(pm);
                }
 
                added = newAdded;
@@ -498,7 +517,7 @@ public class RenameDetector {
 
        private void findContentRenames(ContentSource.Pair reader,
                        ProgressMonitor pm)
-                       throws IOException {
+                       throws IOException, CanceledException {
                int cnt = Math.max(added.size(), deleted.size());
                if (getRenameLimit() == 0 || cnt <= getRenameLimit()) {
                        SimilarityRenameDetector d;
@@ -516,7 +535,7 @@ public class RenameDetector {
        }
 
        @SuppressWarnings("unchecked")
-       private void findExactRenames(ProgressMonitor pm) {
+       private void findExactRenames(ProgressMonitor pm) throws CanceledException {
                pm.beginTask(JGitText.get().renamesFindingExact, //
                                added.size() + added.size() + deleted.size()
                                                + added.size() * deleted.size());
@@ -562,7 +581,7 @@ public class RenameDetector {
                        } else {
                                left.add(a);
                        }
-                       pm.update(1);
+                       advanceOrCancel(pm);
                }
 
                for (List<DiffEntry> adds : nonUniqueAdds) {
@@ -604,6 +623,10 @@ public class RenameDetector {
                                                int score = SimilarityRenameDetector.nameScore(addedName, deletedName);
                                                matrix[mNext] = SimilarityRenameDetector.encode(score, delIdx, addIdx);
                                                mNext++;
+                                               if (pm.isCancelled()) {
+                                                       throw new CanceledException(
+                                                                       JGitText.get().renameCancelled);
+                                               }
                                        }
                                }
 
@@ -617,7 +640,7 @@ public class RenameDetector {
                                        DiffEntry a = adds.get(addIdx);
 
                                        if (a == null) {
-                                               pm.update(1);
+                                               advanceOrCancel(pm);
                                                continue; // was already matched earlier
                                        }
 
@@ -635,11 +658,12 @@ public class RenameDetector {
 
                                        entries.add(DiffEntry.pair(type, d, a, 100));
                                        adds.set(addIdx, null); // Claim the destination was matched.
-                                       pm.update(1);
+                                       advanceOrCancel(pm);
                                }
                        } else {
                                left.addAll(adds);
                        }
+                       advanceOrCancel(pm);
                }
                added = left;
 
@@ -692,7 +716,8 @@ public class RenameDetector {
 
        @SuppressWarnings("unchecked")
        private HashMap<AbbreviatedObjectId, Object> populateMap(
-                       List<DiffEntry> diffEntries, ProgressMonitor pm) {
+                       List<DiffEntry> diffEntries, ProgressMonitor pm)
+                       throws CanceledException {
                HashMap<AbbreviatedObjectId, Object> map = new HashMap<>();
                for (DiffEntry de : diffEntries) {
                        Object old = map.put(id(de), de);
@@ -706,7 +731,7 @@ public class RenameDetector {
                                ((List<DiffEntry>) old).add(de);
                                map.put(id(de), old);
                        }
-                       pm.update(1);
+                       advanceOrCancel(pm);
                }
                return map;
        }
index 653658be3c50b14d3e9219ad92d9b2479f0082f9..71e391c7373f1e58b69b681815def376a2040d53 100644 (file)
@@ -52,6 +52,7 @@ import java.util.Arrays;
 import java.util.BitSet;
 import java.util.List;
 
+import org.eclipse.jgit.api.errors.CanceledException;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.diff.SimilarityIndex.TableFullException;
 import org.eclipse.jgit.internal.JGitText;
@@ -128,7 +129,7 @@ class SimilarityRenameDetector {
                renameScore = score;
        }
 
-       void compute(ProgressMonitor pm) throws IOException {
+       void compute(ProgressMonitor pm) throws IOException, CanceledException {
                if (pm == null)
                        pm = NullProgressMonitor.INSTANCE;
 
@@ -142,6 +143,9 @@ class SimilarityRenameDetector {
                // we have looked at everything that is above our minimum score.
                //
                for (--mNext; mNext >= 0; mNext--) {
+                       if (pm.isCancelled()) {
+                               throw new CanceledException(JGitText.get().renameCancelled);
+                       }
                        long ent = matrix[mNext];
                        int sIdx = srcFile(ent);
                        int dIdx = dstFile(ent);
@@ -209,7 +213,8 @@ class SimilarityRenameDetector {
                return r;
        }
 
-       private int buildMatrix(ProgressMonitor pm) throws IOException {
+       private int buildMatrix(ProgressMonitor pm)
+                       throws IOException, CanceledException {
                // Allocate for the worst-case scenario where every pair has a
                // score that we need to consider. We might not need that many.
                //
@@ -234,6 +239,10 @@ class SimilarityRenameDetector {
                        SimilarityIndex s = null;
 
                        for (int dstIdx = 0; dstIdx < dsts.size(); dstIdx++) {
+                               if (pm.isCancelled()) {
+                                       throw new CanceledException(JGitText.get().renameCancelled);
+                               }
+
                                DiffEntry dstEnt = dsts.get(dstIdx);
 
                                if (!isFile(dstEnt.newMode)) {
index a3cbc22e82adf697a11ae940ebed005425c1fd4d..2373b97bd1b14c437ef2f6740eafc3c9d2a90783 100644 (file)
@@ -640,6 +640,7 @@ public class JGitText extends TranslationBundle {
        /***/ public String renameBranchFailedBecauseTag;
        /***/ public String renameBranchFailedUnknownReason;
        /***/ public String renameBranchUnexpectedResult;
+       /***/ public String renameCancelled;
        /***/ public String renameFileFailed;
        /***/ public String renamesAlreadyFound;
        /***/ public String renamesBreakingModifies;