From: Christian Halstrick Date: Wed, 11 May 2016 20:36:10 +0000 (+0200) Subject: GC should not pack objects only referenced by ORIG_HEAD,... X-Git-Tag: v4.4.0.201605250940-rc1~2^2~8 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6590c0a92ac987489dfa49281a20e5ea956e043d;p=jgit.git GC should not pack objects only referenced by ORIG_HEAD,... There are references which are returned by RefDatabase.getAdditionalRefs() which are allowed to point to non-existing objects. These refs should not save objects from being garbage collected. Examples for these references are ORIG_HEAD, MERGE_HEAD, FETCH_HEAD and CHERRY_PICK_HEAD. Native git will not take these references into account when doing a gc and therefore these references may point to non-existing objects after a gc. Teach JGit's GC to behave the same: ignore additional refs if they don't start with "refs/". Examples for refs returned by getAdditionalRefs() which do start with "refs/" are the bootstrap refs when using reftree's (see commit 115f1ad3974d1162b33d1c8eff466019d1f249f3). See also http://article.gmane.org/gmane.comp.version-control.git/294126. Bug: 479697 Change-Id: I10e40589f13e72aacdd9f86f3b44696fd1cd068a Signed-off-by: Matthias Sohn --- diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index 33be3b15a8..dc91a70866 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java @@ -241,7 +241,12 @@ public class DfsGarbageCollector { if (!addl.isEmpty()) { List all = new ArrayList<>(refs.size() + addl.size()); all.addAll(refs); - all.addAll(addl); + // add additional refs which start with refs/ + for (Ref r : addl) { + if (r.getName().startsWith(Constants.R_REFS)) { + all.add(r); + } + } return all; } return refs; 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 9cdb753221..c998ebe960 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 @@ -655,8 +655,12 @@ public class GC { } /** - * Returns a collection of all refs and additional refs (e.g. FETCH_HEAD, - * MERGE_HEAD, ...) + * Returns a collection of all refs and additional refs. + * + * Additional refs which don't start with "refs/" are not returned because + * they should not save objects from being garbage collected. Examples for + * such references are ORIG_HEAD, MERGE_HEAD, FETCH_HEAD and + * CHERRY_PICK_HEAD. * * @return a collection of refs pointing to live objects. * @throws IOException @@ -668,7 +672,12 @@ public class GC { if (!addl.isEmpty()) { List all = new ArrayList<>(refs.size() + addl.size()); all.addAll(refs); - all.addAll(addl); + // add additional refs which start with refs/ + for (Ref r : addl) { + if (r.getName().startsWith(Constants.R_REFS)) { + all.add(r); + } + } return all; } return refs;