]> source.dussan.org Git - jgit.git/commitdiff
FileRepository: Support extensions.refsBackendType = RefTree 70/62970/15
authorShawn Pearce <spearce@spearce.org>
Sat, 9 Jan 2016 20:51:14 +0000 (12:51 -0800)
committerShawn Pearce <spearce@spearce.org>
Mon, 11 Jan 2016 23:27:07 +0000 (15:27 -0800)
This experimental code can be enabled in $GIT_DIR/config:

  [core]
    repositoryformatversion = 1

  [extensions]
    refsBackendType = RefTree

When these are set the repository will read references from the
RefTree rooted by the $GIT_DIR/refs/txn/committed reference.

Update debug-rebuild-ref-tree to rebuild refs/txn/committed only from
the bootstrap layer.  This avoids misuse by rebuilding using packed-refs
and $GIT_DIR/refs tree.

Change-Id: Icf600e4a36b2f7867822a7ab1f1617d73c710a4b

org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildRefTree.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java

index 6af4ce1dd1573eb3ca966b538d46b91a1e918a5e..78ca1a7128300a5428bd5a0cef3fd80be7bf5092 100644 (file)
@@ -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)));
index 280d6040cc6844b36a117a1edcc652c63149c57d..6c8ee737d2b9d108eec21d308c5afc3eda4c09c7 100644 (file)
@@ -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 {
index 490cbcaa81e072739e6fe60c0f59a5b49d0f822c..4f45cbee5c767fa3f4d07406362b40fdcd03d5ec 100644 (file)
@@ -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)));
index 983216e30483f011deaf043d585fc86ee483aec3..dc60311102f227d7b456c827d2fb3ca82faa7e8d 100644 (file)
@@ -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.
         *