[ostree] repo: Add a new iterator traversal API for commits



commit 0f74ed62b72a659191bf070911133d731ecd59da
Author: Colin Walters <walters verbum org>
Date:   Wed Feb 11 03:25:17 2015 -0500

    repo: Add a new iterator traversal API for commits
    
    This is a more optimized version of the GFile * APIs, and is now used
    internally by the previous ostree_repo_traverse().

 src/libostree/ostree-repo-private.h  |    9 +
 src/libostree/ostree-repo-traverse.c |  441 ++++++++++++++++++++++++++--------
 src/libostree/ostree-repo.h          |   53 ++++
 3 files changed, 408 insertions(+), 95 deletions(-)
---
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index d7ea7ac..c4db502 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -154,6 +154,15 @@ _ostree_repo_file_new_root (OstreeRepo  *repo,
                             const char  *contents_checksum,
                             const char  *metadata_checksum);
 
+gboolean
+_ostree_repo_traverse_dirtree_internal (OstreeRepo      *repo,
+                                        const char      *dirtree_checksum,
+                                        int              recursion_depth,
+                                        GHashTable      *inout_reachable,
+                                        GHashTable      *inout_content_names,
+                                        GCancellable    *cancellable,
+                                        GError         **error);
+
 OstreeRepoCommitFilterResult
 _ostree_repo_commit_modifier_apply (OstreeRepo               *self,
                                     OstreeRepoCommitModifier *modifier,
diff --git a/src/libostree/ostree-repo-traverse.c b/src/libostree/ostree-repo-traverse.c
index 122fcce..6638b6b 100644
--- a/src/libostree/ostree-repo-traverse.c
+++ b/src/libostree/ostree-repo-traverse.c
@@ -26,6 +26,261 @@
 #include "otutil.h"
 #include "libgsystem.h"
 
+struct _OstreeRepoRealCommitTraverseIter {
+  gboolean initialized;
+  OstreeRepo *repo;
+  GVariant *commit;
+  GVariant *current_dir;
+  const char *name;
+  OstreeRepoCommitIterResult state;
+  guint idx;
+  char checksum_content[65];
+  char checksum_meta[65];
+};
+
+/**
+ * ostree_repo_commit_traverse_iter_init_commit:
+ * @iter: An iter
+ * @repo: A repo
+ * @commit: Variant of type %OSTREE_OBJECT_TYPE_COMMIT
+ * @flags: Flags
+ * @error: Error
+ *
+ * Initialize (in place) an iterator over the root of a commit object.
+ */
+gboolean
+ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter   *iter,
+                                              OstreeRepo                     *repo,
+                                              GVariant                       *commit,
+                                              OstreeRepoCommitTraverseFlags   flags,
+                                              GError                        **error)
+{
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+  gboolean ret = FALSE;
+  const guchar *csum;
+  gs_unref_variant GVariant *meta_csum_bytes = NULL;
+  gs_unref_variant GVariant *content_csum_bytes = NULL;
+
+  memset (real, 0, sizeof (*real));
+  real->initialized = TRUE;
+  real->repo = g_object_ref (repo);
+  real->commit = g_variant_ref (commit);
+  real->current_dir = NULL;
+  real->idx = 0;
+
+  g_variant_get_child (commit, 6, "@ay", &content_csum_bytes);
+  csum = ostree_checksum_bytes_peek_validate (content_csum_bytes, error);
+  if (!csum)
+    goto out;
+  ostree_checksum_inplace_from_bytes (csum, real->checksum_content);
+
+  g_variant_get_child (commit, 7, "@ay", &meta_csum_bytes);
+  csum = ostree_checksum_bytes_peek_validate (meta_csum_bytes, error);
+  if (!csum)
+    goto out;
+  ostree_checksum_inplace_from_bytes (csum, real->checksum_meta);
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+/**
+ * ostree_repo_commit_traverse_iter_init_dirtree:
+ * @iter: An iter
+ * @repo: A repo
+ * @commit: Variant of type %OSTREE_OBJECT_TYPE_DIR_TREE
+ * @flags: Flags
+ * @error: Error
+ *
+ * Initialize (in place) an iterator over a directory tree.
+ */
+gboolean
+ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter   *iter,
+                                               OstreeRepo                     *repo,
+                                               GVariant                       *dirtree,
+                                               OstreeRepoCommitTraverseFlags   flags,
+                                               GError                        **error)
+{
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+
+  memset (real, 0, sizeof (*real));
+  real->initialized = TRUE;
+  real->repo = g_object_ref (repo);
+  real->current_dir = g_variant_ref (dirtree);
+  real->idx = 0;
+
+  return TRUE;
+}
+
+/**
+ * ostree_repo_commit_traverse_iter_next:
+ * @iter: An iter
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Step the interator to the next item.  Files will be returned first,
+ * then subdirectories.  Call this in a loop; upon encountering
+ * %OSTREE_REPO_COMMIT_ITER_RESULT_END, there will be no more files or
+ * directories.  If %OSTREE_REPO_COMMIT_ITER_RESULT_DIR is returned,
+ * then call ostree_repo_commit_traverse_iter_get_dir() to retrieve
+ * data for that directory.  Similarly, if
+ * %OSTREE_REPO_COMMIT_ITER_RESULT_FILE is returned, call
+ * ostree_repo_commit_traverse_iter_get_file().
+ * 
+ * If %OSTREE_REPO_COMMIT_ITER_RESULT_ERROR is returned, it is a
+ * program error to call any further API on @iter except for
+ * ostree_repo_commit_traverse_iter_clear().
+ */
+OstreeRepoCommitIterResult
+ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter,
+                                       GCancellable                 *cancellable,
+                                       GError                      **error)
+{
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+  OstreeRepoCommitIterResult res = OSTREE_REPO_COMMIT_ITER_RESULT_ERROR;
+
+  if (!real->current_dir)
+    {
+      if (!ostree_repo_load_variant (real->repo, OSTREE_OBJECT_TYPE_DIR_TREE,
+                                     real->checksum_content,
+                                     &real->current_dir,
+                                     error))
+        goto out;
+      res = OSTREE_REPO_COMMIT_ITER_RESULT_DIR;
+    }
+  else
+    {
+      guint nfiles;
+      guint ndirs;
+      guint idx;
+      const guchar *csum;
+      gs_unref_variant GVariant *content_csum_v = NULL;
+      gs_unref_variant GVariant *meta_csum_v = NULL;
+      gs_unref_variant GVariant *files_variant = NULL;
+      gs_unref_variant GVariant *dirs_variant = NULL;
+
+      files_variant = g_variant_get_child_value (real->current_dir, 0);
+      dirs_variant = g_variant_get_child_value (real->current_dir, 1);
+
+      nfiles = g_variant_n_children (files_variant);
+      ndirs = g_variant_n_children (dirs_variant);
+      if (real->idx < nfiles)
+        {
+          idx = real->idx;
+          g_variant_get_child (files_variant, idx, "(&s ay)",
+                               &real->name,
+                               &content_csum_v);
+
+          csum = ostree_checksum_bytes_peek_validate (content_csum_v, error);
+          if (!csum)
+            goto out;
+          ostree_checksum_inplace_from_bytes (csum, real->checksum_content);
+
+          res = OSTREE_REPO_COMMIT_ITER_RESULT_FILE;
+
+          real->idx++;
+        }
+      else if (real->idx < nfiles + ndirs)
+        {
+          idx = real->idx - nfiles;
+
+          g_variant_get_child (dirs_variant, idx, "(&s ay@ay)",
+                               &real->name, &content_csum_v, &meta_csum_v);
+
+          csum = ostree_checksum_bytes_peek_validate (content_csum_v, error);
+          if (!csum)
+            goto out;
+          ostree_checksum_inplace_from_bytes (csum, real->checksum_content);
+
+          csum = ostree_checksum_bytes_peek_validate (meta_csum_v, error);
+          if (!csum)
+            goto out;
+          ostree_checksum_inplace_from_bytes (csum, real->checksum_meta);
+          
+          res = OSTREE_REPO_COMMIT_ITER_RESULT_DIR;
+
+          real->idx++;
+        }
+      else
+        res = OSTREE_REPO_COMMIT_ITER_RESULT_END;
+    }
+  
+  real->state = res;
+ out:
+  return res;
+}
+
+/**
+ * ostree_repo_commit_traverse_iter_get_file:
+ * @iter: An iter
+ * @out_name: (out) (transfer none): Name of current file
+ * @out_checksum: (out) (transfer none): Checksum of current file
+ *
+ * Return information on the current file.  This function may only be
+ * called if %OSTREE_REPO_COMMIT_ITER_RESULT_FILE was returned from
+ * ostree_repo_commit_traverse_iter_next().
+ */
+void
+ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter,
+                                           char                        **out_name,
+                                           char                        **out_checksum)
+{
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+  *out_name = (char*)real->name;
+  *out_checksum = (char*)real->checksum_content;
+}
+
+/**
+ * ostree_repo_commit_traverse_iter_get_dir:
+ * @iter: An iter
+ * @out_name: (out) (transfer none): Name of current dir
+ * @out_content_checksum: (out) (transfer none): Checksum of current content
+ * @out_meta_checksum: (out) (transfer none): Checksum of current metadata
+ *
+ * Return information on the current directory.  This function may
+ * only be called if %OSTREE_REPO_COMMIT_ITER_RESULT_DIR was returned
+ * from ostree_repo_commit_traverse_iter_next().
+ */
+void
+ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter,
+                                          char                        **out_name,
+                                          char                        **out_content_checksum,
+                                          char                        **out_meta_checksum)
+{
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+  *out_name = (char*)real->name;
+  *out_content_checksum = (char*)real->checksum_content;
+  *out_meta_checksum = (char*)real->checksum_meta;
+}
+
+void
+ostree_repo_commit_traverse_iter_clear (OstreeRepoCommitTraverseIter *iter)
+{
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+  g_clear_pointer (&real->commit, g_variant_unref);
+  g_clear_pointer (&real->current_dir, g_variant_unref);
+}
+
+void
+ostree_repo_commit_traverse_iter_cleanup (void *p)
+{
+  OstreeRepoCommitTraverseIter *iter = p;
+  struct _OstreeRepoRealCommitTraverseIter *real =
+    (struct _OstreeRepoRealCommitTraverseIter*)iter;
+  if (real->initialized)
+    {
+      ostree_repo_commit_traverse_iter_clear (iter);
+      real->initialized = FALSE;
+    }
+}
+
 /**
  * ostree_repo_traverse_new_reachable:
  *
@@ -42,82 +297,68 @@ ostree_repo_traverse_new_reachable (void)
 }
 
 static gboolean
-traverse_dirtree_internal (OstreeRepo      *repo,
-                           const char      *dirtree_checksum,
-                           int              recursion_depth,
-                           GHashTable      *inout_reachable,
-                           GCancellable    *cancellable,
-                           GError         **error)
+traverse_dirtree (OstreeRepo           *repo,
+                  const char           *checksum,
+                  GHashTable           *inout_reachable,
+                  GCancellable         *cancellable,
+                  GError              **error);
+
+static gboolean
+traverse_iter (OstreeRepo                          *repo,
+               OstreeRepoCommitTraverseIter        *iter,
+               GHashTable                          *inout_reachable,
+               GCancellable                        *cancellable,
+               GError                             **error)
 {
   gboolean ret = FALSE;
-  int n, i;
-  gs_unref_variant GVariant *key = NULL;
-  gs_unref_variant GVariant *tree = NULL;
-  gs_unref_variant GVariant *files_variant = NULL;
-  gs_unref_variant GVariant *dirs_variant = NULL;
-  gs_unref_variant GVariant *csum_v = NULL;
-  gs_unref_variant GVariant *content_csum_v = NULL;
-  gs_unref_variant GVariant *metadata_csum_v = NULL;
-  gs_free char *tmp_checksum = NULL;
 
-  if (recursion_depth > OSTREE_MAX_RECURSION)
+  while (TRUE)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Maximum recursion limit reached during traversal");
-      goto out;
-    }
-
-  if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &tree, 
error))
-    goto out;
-
-  if (!tree)
-    return TRUE;
+      gs_unref_variant GVariant *key = NULL;
+      OstreeRepoCommitIterResult iterres =
+        ostree_repo_commit_traverse_iter_next (iter, cancellable, error);
+          
+      if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_ERROR)
+        goto out;
+      else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_END)
+        break;
+      else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_FILE)
+        {
+          char *name;
+          char *checksum;
 
-  key = ostree_object_name_serialize (dirtree_checksum, OSTREE_OBJECT_TYPE_DIR_TREE);
-  if (!g_hash_table_lookup (inout_reachable, key))
-    { 
-      g_hash_table_insert (inout_reachable, key, key);
-      key = NULL;
+          ostree_repo_commit_traverse_iter_get_file (iter, &name, &checksum);
 
-      /* PARSE OSTREE_SERIALIZED_TREE_VARIANT */
-      files_variant = g_variant_get_child_value (tree, 0);
-      n = g_variant_n_children (files_variant);
-      for (i = 0; i < n; i++)
-        {
-          const char *filename;
-      
-          g_clear_pointer (&csum_v, (GDestroyNotify) g_variant_unref);
-          g_variant_get_child (files_variant, i, "(&s ay)", &filename, &csum_v);
-          g_free (tmp_checksum);
-          tmp_checksum = ostree_checksum_from_bytes_v (csum_v);
-          key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_FILE);
+          key = ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_FILE);
           g_hash_table_replace (inout_reachable, key, key);
           key = NULL;
         }
-
-      dirs_variant = g_variant_get_child_value (tree, 1);
-      n = g_variant_n_children (dirs_variant);
-      for (i = 0; i < n; i++)
+      else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_DIR)
         {
-          const char *dirname;
-      
-          g_clear_pointer (&content_csum_v, (GDestroyNotify) g_variant_unref);
-          g_clear_pointer (&metadata_csum_v, (GDestroyNotify) g_variant_unref);
-          g_variant_get_child (dirs_variant, i, "(&s ay@ay)",
-                               &dirname, &content_csum_v, &metadata_csum_v);
-      
-          g_free (tmp_checksum);
-          tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v);
-          if (!traverse_dirtree_internal (repo, tmp_checksum, recursion_depth + 1,
-                                          inout_reachable, cancellable, error))
-            goto out;
+          char *name;
+          char *content_checksum;
+          char *meta_checksum;
 
-          g_free (tmp_checksum);
-          tmp_checksum = ostree_checksum_from_bytes_v (metadata_csum_v);
-          key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META);
+          ostree_repo_commit_traverse_iter_get_dir (iter, &name, &content_checksum,
+                                                    &meta_checksum);
+
+          key = ostree_object_name_serialize (meta_checksum, OSTREE_OBJECT_TYPE_DIR_META);
           g_hash_table_replace (inout_reachable, key, key);
           key = NULL;
+
+          key = ostree_object_name_serialize (content_checksum, OSTREE_OBJECT_TYPE_DIR_TREE);
+          if (!g_hash_table_lookup (inout_reachable, key))
+            {
+              g_hash_table_replace (inout_reachable, key, key);
+              key = NULL;
+
+              if (!traverse_dirtree (repo, content_checksum, inout_reachable,
+                                     cancellable, error))
+                goto out;
+            }
         }
+      else
+        g_assert_not_reached ();
     }
 
   ret = TRUE;
@@ -125,6 +366,36 @@ traverse_dirtree_internal (OstreeRepo      *repo,
   return ret;
 }
 
+static gboolean
+traverse_dirtree (OstreeRepo           *repo,
+                  const char           *checksum,
+                  GHashTable           *inout_reachable,
+                  GCancellable         *cancellable,
+                  GError              **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_variant GVariant *dirtree = NULL;
+  ostree_cleanup_repo_commit_traverse_iter
+    OstreeRepoCommitTraverseIter iter = { 0, };
+
+  if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_DIR_TREE,
+                                           checksum, &dirtree,
+                                           error))
+    goto out;
+
+  if (!ostree_repo_commit_traverse_iter_init_dirtree (&iter, repo, dirtree,
+                                                      OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE,
+                                                      error))
+    goto out;
+
+  if (!traverse_iter (repo, &iter, inout_reachable, cancellable, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
 /**
  * ostree_repo_traverse_commit_union: (skip)
  * @repo: Repo
@@ -151,58 +422,38 @@ ostree_repo_traverse_commit_union (OstreeRepo      *repo,
   while (TRUE)
     {
       gboolean recurse = FALSE;
-      gs_unref_variant GVariant *meta_csum_bytes = NULL;
-      gs_unref_variant GVariant *content_csum_bytes = NULL;
       gs_unref_variant GVariant *key = NULL;
       gs_unref_variant GVariant *commit = NULL;
+      ostree_cleanup_repo_commit_traverse_iter
+        OstreeRepoCommitTraverseIter iter = { 0, };
 
       key = ostree_object_name_serialize (commit_checksum, OSTREE_OBJECT_TYPE_COMMIT);
 
       if (g_hash_table_contains (inout_reachable, key))
         break;
 
-      /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */
-      if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit, 
error))
+      if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT,
+                                               commit_checksum, &commit,
+                                               error))
         goto out;
-
+        
       /* Just return if the parent isn't found; we do expect most
        * people to have partial repositories.
        */
       if (!commit)
         break;
-  
-      g_hash_table_add (inout_reachable, key);
-      key = NULL;
 
-      g_variant_get_child (commit, 7, "@ay", &meta_csum_bytes);
-      g_free (tmp_checksum);
-      if (G_UNLIKELY (g_variant_n_children (meta_csum_bytes) == 0))
-        {
-          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "Corrupted commit '%s'; invalid tree metadata",
-                       commit_checksum);
-          goto out;
-        }
-
-      tmp_checksum = ostree_checksum_from_bytes_v (meta_csum_bytes);
-      key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META);
-      g_hash_table_replace (inout_reachable, key, key);
+      g_hash_table_add (inout_reachable, key);
       key = NULL;
 
-      g_variant_get_child (commit, 6, "@ay", &content_csum_bytes);
-      g_free (tmp_checksum);
-      if (G_UNLIKELY (g_variant_n_children (content_csum_bytes) == 0))
-        {
-          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "Corrupted commit '%s'; invalid tree content",
-                       commit_checksum);
-          goto out;
-        }
-
-      tmp_checksum = ostree_checksum_from_bytes_v (content_csum_bytes);
-      if (!traverse_dirtree_internal (repo, tmp_checksum, 0, inout_reachable, cancellable, error))
+      if (!ostree_repo_commit_traverse_iter_init_commit (&iter, repo, commit,
+                                                         OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE,
+                                                         error))
         goto out;
 
+      if (!traverse_iter (repo, &iter, inout_reachable, cancellable, error))
+        goto out;
+      
       if (maxdepth == -1 || maxdepth > 0)
         {
           g_free (tmp_checksum);
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 0ecf9bd..c59364a 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -536,6 +536,59 @@ gboolean ostree_repo_traverse_commit_union (OstreeRepo         *repo,
                                             GCancellable       *cancellable,
                                             GError            **error);
 
+struct _OstreeRepoCommitTraverseIter {
+  gboolean initialized;
+  gpointer dummy[10];
+  char dummy_checksum_data[65*2];
+};
+
+typedef struct _OstreeRepoCommitTraverseIter OstreeRepoCommitTraverseIter;
+
+typedef enum {
+  OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE = (1 << 0)
+} OstreeRepoCommitTraverseFlags;
+
+gboolean
+ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter    *iter,
+                                              OstreeRepo                      *repo,
+                                              GVariant                        *commit,
+                                              OstreeRepoCommitTraverseFlags    flags,
+                                              GError                         **error);
+
+gboolean
+ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter    *iter,
+                                               OstreeRepo                      *repo,
+                                               GVariant                        *dirtree,
+                                               OstreeRepoCommitTraverseFlags    flags,
+                                               GError                         **error);
+
+typedef enum {
+  OSTREE_REPO_COMMIT_ITER_RESULT_ERROR,
+  OSTREE_REPO_COMMIT_ITER_RESULT_END,
+  OSTREE_REPO_COMMIT_ITER_RESULT_FILE,
+  OSTREE_REPO_COMMIT_ITER_RESULT_DIR
+} OstreeRepoCommitIterResult;
+
+OstreeRepoCommitIterResult ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter,
+                                                                  GCancellable       *cancellable,
+                                                                  GError            **error);
+
+void ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter,
+                                                char                        **out_name,
+                                                char                        **out_checksum);
+
+void ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter,
+                                               char                        **out_name,
+                                               char                        **out_content_checksum,
+                                               char                        **out_meta_checksum);
+
+void
+ostree_repo_commit_traverse_iter_clear (OstreeRepoCommitTraverseIter *iter);
+
+void ostree_repo_commit_traverse_iter_cleanup (void *p);
+
+#define ostree_cleanup_repo_commit_traverse_iter __attribute__ 
((cleanup(ostree_repo_commit_traverse_iter_cleanup)))
+
 /**
  * OstreeRepoPruneFlags:
  * @OSTREE_REPO_PRUNE_FLAGS_NONE: No special options for pruning


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]