From 6590c0a92ac987489dfa49281a20e5ea956e043d Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Wed, 11 May 2016 22:36:10 +0200 Subject: [PATCH] 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 --- .../internal/storage/dfs/DfsGarbageCollector.java | 7 ++++++- .../eclipse/jgit/internal/storage/file/GC.java | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) 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; -- 2.39.5