You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/12/02 14:27:23 UTC

svn commit: r1717627 - in /subversion/branches/ra-git/subversion/libsvn_fs_git: fs_git.h fsgit-metadata.sql fsgit-queries.sql git-revroot.c gitdb.c

Author: rhuijben
Date: Wed Dec  2 13:27:23 2015
New Revision: 1717627

URL: http://svn.apache.org/viewvc?rev=1717627&view=rev
Log:
On the ra-git branch: Implement basic branch lookup support. This
fixes lookups of branches that aren't touched in the opened revision.

* subversion/libsvn_fs_git/fsgit-metadata.sql
  (TAGMAP,
   I_TAGMAP_RELPATH): Tweak schema.

* subversion/libsvn_fs_git/fsgit-queries.sql
  (STMT_SELECT_BRANCH_NAME,
   STMT_SELECT_BRANCH): New query.

* subversion/libsvn_fs_git/fs_git.h
  (svn_fs_git__db_find_branch): New function.

* subversion/libsvn_fs_git/git-revroot.c
  (git_root_cleanup): Remove function.
  (find_branch): Move function...
  (find_commit): Constify output argument.
  (find_branch): Move here. Fetch and cache commit.
  (fs_git_paths_changed,
   fs_git_node_created_rev): Update caller.
  (svn_fs_git__revision_root): Use standard helper function.

* subversion/libsvn_fs_git/gitdb.c
  ((db_find_branch,
   svn_fs_git__db_find_branch): New function.

Modified:
    subversion/branches/ra-git/subversion/libsvn_fs_git/fs_git.h
    subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-metadata.sql
    subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-queries.sql
    subversion/branches/ra-git/subversion/libsvn_fs_git/git-revroot.c
    subversion/branches/ra-git/subversion/libsvn_fs_git/gitdb.c

Modified: subversion/branches/ra-git/subversion/libsvn_fs_git/fs_git.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_git/fs_git.h?rev=1717627&r1=1717626&r2=1717627&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_git/fs_git.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_git/fs_git.h Wed Dec  2 13:27:23 2015
@@ -133,6 +133,16 @@ svn_fs_git__db_fetch_checksum(svn_checks
                               apr_pool_t *scratch_pool);
 
 svn_error_t *
+svn_fs_git__db_find_branch(const char **branch_path,
+                           const git_oid **oid,
+                           svn_revnum_t *from_rev,
+                           svn_fs_t *fs,
+                           const char *relpath,
+                           svn_revnum_t rev,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
+
+svn_error_t *
 svn_fs_git__db_set_uuid(svn_fs_t *fs,
                         const char *uuid,
                         apr_pool_t *scratch_pool);

Modified: subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-metadata.sql?rev=1717627&r1=1717626&r2=1717627&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-metadata.sql (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-metadata.sql Wed Dec  2 13:27:23 2015
@@ -50,11 +50,11 @@ CREATE UNIQUE INDEX I_REVMAP_RELPATH_ID
 CREATE TABLE TAGMAP (
   /* The revision in which the tag was created */
   revnum INTEGER PRIMARY KEY AUTOINCREMENT,
-
-  name TEXT NOT NULL
+  from_rev INTEGER NOT NULL,
+  relpath TEXT NOT NULL
 );
 
-CREATE UNIQUE INDEX I_TAGMAP_NAME ON TAGMAP (name);
+CREATE UNIQUE INDEX I_TAGMAP_RELPATH ON TAGMAP (relpath);
 
 CREATE TABLE BRANCHMAP (
   id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -62,7 +62,6 @@ CREATE TABLE BRANCHMAP (
   relpath TEXT NOT NULL,
 
   from_rev INTEGER NOT NULL,
-
   to_rev INTEGER NULL
 );
 

Modified: subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-queries.sql?rev=1717627&r1=1717626&r2=1717627&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-queries.sql (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_git/fsgit-queries.sql Wed Dec  2 13:27:23 2015
@@ -62,6 +62,27 @@ WHERE blob_id = ?1
 INSERT INTO CHECKSUMMAP (blob_id, md5_checksum, sha1_checksum)
 VALUES (?1, ?2, ?3)
 
+-- STMT_SELECT_BRANCH_NAME
+SELECT relpath
+FROM REVMAP
+WHERE (relpath <= ?1 AND relpath || '0' > ?1) AND (relpath = ?1 OR relpath || '/' < ?1)
+UNION ALL
+SELECT relpath
+FROM TAGMAP
+WHERE (relpath <= ?1 AND relpath || '0' > ?1) AND (relpath = ?1 OR relpath || '/' < ?1)
+LIMIT 1
+
+-- STMT_SELECT_BRANCH
+SELECT relpath, (SELECT commit_id FROM revmap r WHERE r.revnum=t.revnum),
+       from_rev
+FROM TAGMAP t WHERE relpath = ?1 AND revnum <= ?2
+UNION ALL
+SELECT relpath, commit_id, revnum
+FROM REVMAP
+WHERE relpath = ?1 AND revnum <= ?2
+ORDER BY relpath DESC, revnum DESC
+LIMIT 1
+
 /* Grab all the statements related to the schema.  */
 
 -- include: fsgit-metadata

Modified: subversion/branches/ra-git/subversion/libsvn_fs_git/git-revroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_git/git-revroot.c?rev=1717627&r1=1717626&r2=1717627&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_git/git-revroot.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_git/git-revroot.c Wed Dec  2 13:27:23 2015
@@ -55,20 +55,6 @@ typedef struct svn_fs_git_fs_id_t
   svn_fs_root_t *root;
 } svn_fs_git_fs_id_t;
 
-static apr_status_t
-git_root_cleanup(void *baton)
-{
-  svn_fs_git_root_t *fgr = baton;
-
-  if (fgr->commit)
-    {
-      git_commit_free(fgr->commit);
-      fgr->commit = NULL;
-    }
-
-  return APR_SUCCESS;
-}
-
 /* Helper for get_entry_object */
 static apr_status_t
 cleanup_git_object(void *baton)
@@ -219,46 +205,20 @@ relpath_reverse_split(const char **root,
 }
 
 static svn_error_t *
-find_branch(const git_commit **commit, const char **relpath,
-            svn_fs_root_t *root, const char *path, apr_pool_t *pool)
-{
-  svn_fs_git_root_t *fgr = root->fsap_data;
-
-  if (*path == '/')
-    path++;
-
-  if (fgr->rev_path)
-    {
-      apr_size_t len;
-      len = strlen(fgr->rev_path);
-
-      if (!strncmp(path, fgr->rev_path, len)
-          && (!path[len] || path[len] == '/'))
-        {
-          *commit = fgr->commit;
-          *relpath = path[len] ? &path[len + 1] : "";
-          return SVN_NO_ERROR;
-        }
-    }
-
-  *commit = NULL;
-  *relpath = NULL;
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-find_commit(git_commit **commit, svn_fs_root_t *root,
+find_commit(const git_commit **commit, svn_fs_root_t *root,
             const git_oid *oid, apr_pool_t *result_pool)
 {
   svn_fs_git_fs_t *fgf = root->fs->fsap_data;
+  git_commit *cmt;
 
-  GIT2_ERR(git_commit_lookup(commit, fgf->repos, oid));
+  GIT2_ERR(git_commit_lookup(&cmt, fgf->repos, oid));
 
-  if (commit)
+  if (cmt)
     {
-      apr_pool_cleanup_register(result_pool, *commit, cleanup_git_commit,
+      apr_pool_cleanup_register(result_pool, cmt, cleanup_git_commit,
                                 apr_pool_cleanup_null);
     }
+  *commit = cmt;
   return SVN_NO_ERROR;
 }
 
@@ -310,6 +270,76 @@ find_tree_entry(const git_tree_entry **e
 }
 
 static svn_error_t *
+find_branch(const git_commit **commit, const char **relpath,
+            svn_fs_root_t *root, const char *path, apr_pool_t *pool)
+{
+  svn_fs_git_root_t *fgr = root->fsap_data;
+  const char *branch_path;
+  const git_oid *oid;
+
+  if (*path == '/')
+    path++;
+
+  if (fgr->rev_path)
+    {
+      const char *rp = svn_relpath_skip_ancestor(fgr->rev_path, path);
+
+      if (rp)
+        {
+          *relpath = rp;
+          *commit = fgr->commit;
+          return SVN_NO_ERROR;
+        }
+    }
+
+  if (apr_hash_count(fgr->branch_map))
+    {
+      apr_hash_index_t *hi;
+
+      for (hi = apr_hash_first(pool, fgr->branch_map);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          const char *rp;
+
+          branch_path = apr_hash_this_key(hi);
+          rp = svn_relpath_skip_ancestor(branch_path, path);
+          if (rp)
+            {
+              *relpath = rp;
+              *commit = apr_hash_this_val(hi);
+              return SVN_NO_ERROR;
+            }
+        }
+    }
+
+  SVN_ERR(svn_fs_git__db_find_branch(&branch_path, &oid, NULL,
+                                     root->fs, path, root->rev,
+                                     pool, pool));
+
+  if (branch_path)
+    {
+      apr_pool_t *result_pool = apr_hash_pool_get(fgr->branch_map);
+
+      SVN_ERR(find_commit(commit, root, oid, result_pool));
+
+      if (*commit)
+        {
+          svn_hash_sets(fgr->branch_map,
+                        apr_pstrdup(result_pool, branch_path),
+                        *commit);
+
+          *relpath = svn_relpath_skip_ancestor(branch_path, path);
+          return SVN_NO_ERROR;
+        }
+    }
+
+  *commit = NULL;
+  *relpath = NULL;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 walk_tree_for_changes(apr_hash_t *changed_paths, const char *relpath,
                       svn_fs_root_t *root,
                       const git_tree *new_tree, const git_tree *old_tree,
@@ -456,7 +486,7 @@ fs_git_paths_changed(apr_hash_t **change
   apr_hash_t *changed_paths = apr_hash_make(pool);
   const git_oid *cmt_oid;
   const char *branch_path;
-  git_commit *commit, *parent_commit;
+  const git_commit *commit, *parent_commit;
   git_tree *tree, *parent_tree;
   const git_oid *parent_oid;
 
@@ -722,7 +752,7 @@ fs_git_node_created_rev(svn_revnum_t *re
 
   while (oid_p)
     {
-      git_commit *cmt;
+      const git_commit *cmt;
       git_tree *cmt_tree;
       git_tree_entry *cmt_entry;
 
@@ -1287,7 +1317,6 @@ static const root_vtable_t root_vtable =
 svn_error_t *
 svn_fs_git__revision_root(svn_fs_root_t **root_p, svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool)
 {
-  svn_fs_git_fs_t *fgf = fs->fsap_data;
   svn_fs_root_t *root;
   svn_fs_git_root_t *fgr;
 
@@ -1315,11 +1344,7 @@ svn_fs_git__revision_root(svn_fs_root_t
       SVN_ERR(svn_fs_git__db_fetch_oid(&fgr->exact, &oid, &fgr->rev_path,
                                        fs, rev, pool, pool));
 
-      if (oid)
-        GIT2_ERR(git_commit_lookup(&fgr->commit, fgf->repos, oid));
-
-      apr_pool_cleanup_register(pool, fgr, git_root_cleanup,
-                                apr_pool_cleanup_null);
+      SVN_ERR(find_commit(&fgr->commit, root, oid, pool));
     }
 
   *root_p = root;

Modified: subversion/branches/ra-git/subversion/libsvn_fs_git/gitdb.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_git/gitdb.c?rev=1717627&r1=1717626&r2=1717627&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_git/gitdb.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_git/gitdb.c Wed Dec  2 13:27:23 2015
@@ -74,7 +74,6 @@ svn_fs_git__db_ensure_commit(svn_revnum_
   svn_fs_git_fs_t *fgf = fs->fsap_data;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t got_row;
-  svn_revnum_t new_rev;
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, fgf->sdb, STMT_SELECT_REV_BY_COMMITID));
   SVN_ERR(svn_sqlite__bind_blob(stmt, 1, oid, sizeof(*oid)));
@@ -262,6 +261,87 @@ svn_fs_git__db_fetch_checksum(svn_checks
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+db_find_branch(const char **branch_path,
+               const git_oid **oid,
+               svn_revnum_t *from_rev,
+               svn_fs_t *fs,
+               const char *relpath,
+               svn_revnum_t rev,
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
+{
+  svn_fs_git_fs_t *fgf = fs->fsap_data;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t got_row;
+
+  if (branch_path)
+    *branch_path = NULL;
+  if (oid)
+    *oid = NULL;
+  if (from_rev)
+    *from_rev = SVN_INVALID_REVNUM;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, fgf->sdb,
+                                    STMT_SELECT_BRANCH_NAME));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 1, relpath));
+  SVN_ERR(svn_sqlite__step(&got_row, stmt));
+  if (got_row)
+    {
+      relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
+
+      if (branch_path)
+        *branch_path = apr_pstrdup(result_pool, relpath);
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+  if (!got_row || (!oid && !from_rev))
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, fgf->sdb,
+                                    STMT_SELECT_BRANCH));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 1, relpath));
+  SVN_ERR(svn_sqlite__bind_revnum(stmt, 2, rev));
+  SVN_ERR(svn_sqlite__step(&got_row, stmt));
+
+  if (got_row)
+    {
+      if (oid)
+        {
+          apr_size_t len;
+          *oid = svn_sqlite__column_blob(stmt, 1, &len, result_pool);
+          if (len != sizeof(**oid))
+            *oid = NULL;
+        }
+      if (from_rev)
+        *from_rev = svn_sqlite__column_revnum(stmt, 2);
+    }
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_git__db_find_branch(const char **branch_path,
+                           const git_oid **oid,
+                           svn_revnum_t *from_rev,
+                           svn_fs_t *fs,
+                           const char *relpath,
+                           svn_revnum_t rev,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  svn_fs_git_fs_t *fgf = fs->fsap_data;
+
+  SVN_SQLITE__WITH_LOCK(db_find_branch(branch_path, oid, from_rev,
+                                       fs, relpath, rev,
+                                       result_pool, scratch_pool),
+                        fgf->sdb);
+
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
 svn_fs_git__db_open(svn_fs_t *fs,
                     apr_pool_t *scratch_pool)