diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildRefTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildRefTree.java index 6af4ce1dd..78ca1a712 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildRefTree.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildRefTree.java @@ -48,6 +48,7 @@ import java.util.List; import java.util.Map; import org.eclipse.jgit.internal.storage.reftree.RefTree; +import org.eclipse.jgit.internal.storage.reftree.RefTreeDatabase; import org.eclipse.jgit.lib.CommitBuilder; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; @@ -59,12 +60,11 @@ import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.pgm.Command; import org.eclipse.jgit.pgm.TextBuiltin; import org.eclipse.jgit.revwalk.RevWalk; -import org.kohsuke.args4j.Argument; @Command(usage = "usage_RebuildRefTree") class RebuildRefTree extends TextBuiltin { - @Argument(index = 0, required = true, metaVar = "metaVar_ref", usage = "usage_updateRef") - String refName; + private String txnNamespace; + private String txnCommitted; @Override protected void run() throws Exception { @@ -72,10 +72,25 @@ class RebuildRefTree extends TextBuiltin { RevWalk rw = new RevWalk(reader); ObjectInserter inserter = db.newObjectInserter()) { RefDatabase refDb = db.getRefDatabase(); + if (refDb instanceof RefTreeDatabase) { + RefTreeDatabase d = (RefTreeDatabase) refDb; + refDb = d.getBootstrap(); + txnNamespace = d.getTxnNamespace(); + txnCommitted = d.getTxnCommitted(); + } else { + RefTreeDatabase d = new RefTreeDatabase(db, refDb); + txnNamespace = d.getTxnNamespace(); + txnCommitted = d.getTxnCommitted(); + } + + errw.format("Rebuilding %s from %s", //$NON-NLS-1$ + txnCommitted, refDb.getClass().getSimpleName()); + errw.println(); + errw.flush(); CommitBuilder b = new CommitBuilder(); - Ref ref = db.getRefDatabase().exactRef(refName); - RefUpdate update = db.updateRef(refName); + Ref ref = refDb.exactRef(txnCommitted); + RefUpdate update = refDb.newUpdate(txnCommitted, true); ObjectId oldTreeId; if (ref != null && ref.getObjectId() != null) { @@ -116,10 +131,10 @@ class RebuildRefTree extends TextBuiltin { = new ArrayList<>(); for (Ref r : refMap.values()) { - if (refName.equals(r.getName())) { + if (r.getName().equals(txnCommitted) + || r.getName().startsWith(txnNamespace)) { continue; } - cmds.add(new org.eclipse.jgit.internal.storage.reftree.Command( null, db.peel(r))); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java index 280d6040c..6c8ee737d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java @@ -104,7 +104,7 @@ public class FileRepositoryBuilderTest extends LocalDiskRepositoryTestCase { Repository r = createWorkRepository(); StoredConfig config = r.getConfig(); config.setLong(ConfigConstants.CONFIG_CORE_SECTION, null, - ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 1); + ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 999999); config.save(); try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index 490cbcaa8..4f45cbee5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -63,6 +63,7 @@ import org.eclipse.jgit.events.ConfigChangedEvent; import org.eclipse.jgit.events.ConfigChangedListener; import org.eclipse.jgit.events.IndexChangedEvent; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.storage.reftree.RefTreeDatabase; import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateHandle; import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateRepository; import org.eclipse.jgit.lib.BaseRepositoryBuilder; @@ -201,7 +202,22 @@ public class FileRepository extends Repository { } }); - refs = new RefDirectory(this); + final long repositoryFormatVersion = getConfig().getLong( + ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 0); + + String reftype = repoConfig.getString( + "extensions", null, "refsBackendType"); //$NON-NLS-1$ //$NON-NLS-2$ + if (repositoryFormatVersion >= 1 && reftype != null) { + if (StringUtils.equalsIgnoreCase(reftype, "reftree")) { //$NON-NLS-1$ + refs = new RefTreeDatabase(this, new RefDirectory(this)); + } else { + throw new IOException(JGitText.get().unknownRepositoryFormat); + } + } else { + refs = new RefDirectory(this); + } + objectDatabase = new ObjectDirectory(repoConfig, // options.getObjectDirectory(), // options.getAlternateObjectDirectories(), // @@ -209,10 +225,7 @@ public class FileRepository extends Repository { new File(getDirectory(), Constants.SHALLOW)); if (objectDatabase.exists()) { - final long repositoryFormatVersion = getConfig().getLong( - ConfigConstants.CONFIG_CORE_SECTION, null, - ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 0); - if (repositoryFormatVersion > 0) + if (repositoryFormatVersion > 1) throw new IOException(MessageFormat.format( JGitText.get().unknownRepositoryFormat2, Long.valueOf(repositoryFormatVersion))); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java index 983216e30..dc6031110 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java @@ -54,6 +54,7 @@ import java.util.Map; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.lib.BatchRefUpdate; +import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.Ref; @@ -88,6 +89,28 @@ public class RefTreeDatabase extends RefDatabase { private final String txnNamespace; private volatile Scanner.Result refs; + /** + * Create a RefTreeDb for a repository. + * + * @param repo + * the repository using references in this database. + * @param bootstrap + * bootstrap reference database storing the references that + * anchor the {@link RefTree}. + */ + public RefTreeDatabase(Repository repo, RefDatabase bootstrap) { + Config cfg = repo.getConfig(); + String committed = cfg.getString("reftree", null, "committedRef"); //$NON-NLS-1$ //$NON-NLS-2$ + if (committed == null || committed.isEmpty()) { + committed = "refs/txn/committed"; //$NON-NLS-1$ + } + + this.repo = repo; + this.bootstrap = bootstrap; + this.txnNamespace = initNamespace(committed); + this.txnCommitted = committed; + } + /** * Create a RefTreeDb for a repository. *