diff options
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java | 62 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java | 47 |
2 files changed, 103 insertions, 6 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java new file mode 100644 index 0000000000..c2833a1614 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 Ericsson + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.errors; + +import java.io.IOException; + +/** + * Thrown when an operation was canceled + * + * @since 4.7 + */ +public class CancelledException extends IOException { + private static final long serialVersionUID = 1L; + + /** + * @param message + */ + public CancelledException(String message) { + super(message); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java index 04973f180a..e69bbe0a4d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java @@ -76,6 +76,7 @@ import java.util.regex.Pattern; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.dircache.DirCacheIterator; +import org.eclipse.jgit.errors.CancelledException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -270,6 +271,7 @@ public class GC { prunePreserved(); long packExpireDate = getPackExpireDate(); oldPackLoop: for (PackFile oldPack : oldPacks) { + checkCancelled(); String oldName = oldPack.getPackName(); // check whether an old pack file is also among the list of new // pack files. Then we must not delete it. @@ -383,6 +385,7 @@ public class GC { pm.beginTask(JGitText.get().pruneLoosePackedObjects, fanout.length); try { for (String d : fanout) { + checkCancelled(); pm.update(1); if (d.length() != 2) continue; @@ -390,6 +393,7 @@ public class GC { if (entries == null) continue; for (String e : entries) { + checkCancelled(); if (e.length() != Constants.OBJECT_ID_STRING_LENGTH - 2) continue; ObjectId id; @@ -401,11 +405,13 @@ public class GC { continue; } boolean found = false; - for (PackFile p : packs) + for (PackFile p : packs) { + checkCancelled(); if (p.hasObject(id)) { found = true; break; } + } if (found) FileUtils.delete(objdb.fileFor(id), FileUtils.RETRY | FileUtils.SKIP_MISSING @@ -446,6 +452,7 @@ public class GC { fanout.length); try { for (String d : fanout) { + checkCancelled(); pm.update(1); if (d.length() != 2) continue; @@ -453,6 +460,7 @@ public class GC { if (entries == null) continue; for (File f : entries) { + checkCancelled(); String fName = f.getName(); if (fName.length() != Constants.OBJECT_ID_STRING_LENGTH - 2) continue; @@ -481,6 +489,8 @@ public class GC { if (deletionCandidates.isEmpty()) return; + checkCancelled(); + // From the set of current refs remove all those which have been handled // during last repack(). Only those refs will survive which have been // added or modified since the last repack. Only these can save existing @@ -510,11 +520,14 @@ public class GC { // leave this method. ObjectWalk w = new ObjectWalk(repo); try { - for (Ref cr : newRefs) + for (Ref cr : newRefs) { + checkCancelled(); w.markStart(w.parseAny(cr.getObjectId())); + } if (lastPackedRefs != null) - for (Ref lpr : lastPackedRefs) + for (Ref lpr : lastPackedRefs) { w.markUninteresting(w.parseAny(lpr.getObjectId())); + } removeReferenced(deletionCandidates, w); } finally { w.dispose(); @@ -532,11 +545,15 @@ public class GC { ObjectWalk w = new ObjectWalk(repo); try { for (Ref ar : getAllRefs()) - for (ObjectId id : listRefLogObjects(ar, lastRepackTime)) + for (ObjectId id : listRefLogObjects(ar, lastRepackTime)) { + checkCancelled(); w.markStart(w.parseAny(id)); + } if (lastPackedRefs != null) - for (Ref lpr : lastPackedRefs) + for (Ref lpr : lastPackedRefs) { + checkCancelled(); w.markUninteresting(w.parseAny(lpr.getObjectId())); + } removeReferenced(deletionCandidates, w); } finally { w.dispose(); @@ -545,6 +562,8 @@ public class GC { if (deletionCandidates.isEmpty()) return; + checkCancelled(); + // delete all candidates which have survived: these are unreferenced // loose objects. Make a last check, though, to avoid deleting objects // that could have been referenced while the candidates list was being @@ -613,6 +632,7 @@ public class GC { IncorrectObjectTypeException, IOException { RevObject ro = w.next(); while (ro != null) { + checkCancelled(); if (id2File.remove(ro.getId()) != null) if (id2File.isEmpty()) return; @@ -620,6 +640,7 @@ public class GC { } ro = w.nextObject(); while (ro != null) { + checkCancelled(); if (id2File.remove(ro.getId()) != null) if (id2File.isEmpty()) return; @@ -653,6 +674,7 @@ public class GC { pm.beginTask(JGitText.get().packRefs, refs.size()); try { for (Ref ref : refs) { + checkCancelled(); if (!ref.isSymbolic() && ref.getStorage().isLoose()) refsToBePacked.add(ref.getName()); pm.update(1); @@ -691,6 +713,7 @@ public class GC { RefDatabase refdb = repo.getRefDatabase(); for (Ref ref : refsBefore) { + checkCancelled(); nonHeads.addAll(listRefLogObjects(ref, 0)); if (ref.isSymbolic() || ref.getObjectId() == null) continue; @@ -705,9 +728,11 @@ public class GC { } List<ObjectIdSet> excluded = new LinkedList<ObjectIdSet>(); - for (final PackFile f : repo.getObjectDatabase().getPacks()) + for (final PackFile f : repo.getObjectDatabase().getPacks()) { + checkCancelled(); if (f.shouldBeKept()) excluded.add(f.getIndex()); + } tagTargets.addAll(allHeads); nonHeads.addAll(indexObjects); @@ -805,6 +830,7 @@ public class GC { all.addAll(refs); // add additional refs which start with refs/ for (Ref r : addl) { + checkCancelled(); if (r.getName().startsWith(Constants.R_REFS)) { all.add(r); } @@ -842,6 +868,7 @@ public class GC { Set<ObjectId> ret = new HashSet<ObjectId>(); while (treeWalk.next()) { + checkCancelled(); ObjectId objectId = treeWalk.getObjectId(0); switch (treeWalk.getRawMode(0) & FileMode.TYPE_MASK) { case FileMode.TYPE_MISSING: @@ -869,6 +896,7 @@ public class GC { private PackFile writePack(@NonNull Set<? extends ObjectId> want, @NonNull Set<? extends ObjectId> have, Set<ObjectId> tagTargets, List<ObjectIdSet> excludeObjects) throws IOException { + checkCancelled(); File tmpPack = null; Map<PackExt, File> tmpExts = new TreeMap<PackExt, File>( new Comparator<PackExt>() { @@ -900,6 +928,7 @@ public class GC { pw.preparePack(pm, want, have); if (pw.getObjectCount() == 0) return null; + checkCancelled(); // create temporary files String id = pw.computeName().getName(); @@ -1016,6 +1045,12 @@ public class GC { return new File(packdir, "pack-" + name + ext); //$NON-NLS-1$ } + private void checkCancelled() throws CancelledException { + if (pm.isCancelled()) { + throw new CancelledException(JGitText.get().operationCanceled); + } + } + /** * A class holding statistical data for a FileRepository regarding how many * objects are stored as loose or packed objects |