[ostree] libostree: Split off -refs.c



commit cb6b69616c7e452599b9e49edf73fcd893fb887e
Author: Colin Walters <walters verbum org>
Date:   Tue Jul 9 19:49:00 2013 -0400

    libostree: Split off -refs.c
    
    Continuing to break up ostree-repo.c.

 Makefile-libostree.am            |    1 +
 src/libostree/ostree-repo-refs.c |  670 ++++++++++++++++++++++++++++++++++++++
 src/libostree/ostree-repo.c      |  646 ------------------------------------
 3 files changed, 671 insertions(+), 646 deletions(-)
---
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index cbe3bb9..1ad3b63 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -33,6 +33,7 @@ libostree_la_SOURCES = src/libostree/ostree.h \
        src/libostree/ostree-repo.c \
        src/libostree/ostree-repo-checkout.c \
        src/libostree/ostree-repo-libarchive.c \
+       src/libostree/ostree-repo-refs.c \
        src/libostree/ostree-repo.h \
        src/libostree/ostree-repo-private.h \
        src/libostree/ostree-repo-file.c \
diff --git a/src/libostree/ostree-repo-refs.c b/src/libostree/ostree-repo-refs.c
new file mode 100644
index 0000000..fb9f361
--- /dev/null
+++ b/src/libostree/ostree-repo-refs.c
@@ -0,0 +1,670 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters verbum org>
+ */
+
+#include "config.h"
+
+#include "ostree-repo-private.h"
+
+static gboolean
+add_ref_to_set (const char       *remote,
+                GFile            *base,
+                GFile            *child,
+                GHashTable       *refs,
+                GCancellable     *cancellable,
+                GError          **error)
+{
+  gboolean ret = FALSE;
+  char *contents;
+  char *relpath;
+  gsize len;
+  GString *refname;
+
+  if (!g_file_load_contents (child, cancellable, &contents, &len, NULL, error))
+    goto out;
+
+  g_strchomp (contents);
+
+  refname = g_string_new ("");
+  if (remote)
+    {
+      g_string_append (refname, remote);
+      g_string_append_c (refname, ':');
+    }
+  relpath = g_file_get_relative_path (base, child);
+  g_string_append (refname, relpath);
+  g_free (relpath);
+          
+  g_hash_table_insert (refs, g_string_free (refname, FALSE), contents);
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+static gboolean
+write_checksum_file (GFile *parentdir,
+                     const char *name,
+                     const char *sha256,
+                     GError **error)
+{
+  gboolean ret = FALSE;
+  gsize bytes_written;
+  int i;
+  gs_unref_object GFile *parent = NULL;
+  gs_unref_object GFile *child = NULL;
+  gs_unref_object GOutputStream *out = NULL;
+  gs_unref_ptrarray GPtrArray *components = NULL;
+
+  if (!ostree_validate_checksum_string (sha256, error))
+    goto out;
+
+  if (ostree_validate_checksum_string (name, NULL))
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Rev name '%s' looks like a checksum", name);
+      goto out;
+    }
+
+  if (!ot_util_path_split_validate (name, &components, error))
+    goto out;
+
+  if (components->len == 0)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Invalid empty ref name");
+      goto out;
+    }
+
+  parent = g_object_ref (parentdir);
+  for (i = 0; i+1 < components->len; i++)
+    {
+      child = g_file_get_child (parent, (char*)components->pdata[i]);
+
+      if (!gs_file_ensure_directory (child, FALSE, NULL, error))
+        goto out;
+
+      g_clear_object (&parent);
+      parent = child;
+      child = NULL;
+    }
+
+  child = g_file_get_child (parent, components->pdata[components->len - 1]);
+  if ((out = (GOutputStream*)g_file_replace (child, NULL, FALSE, 0, NULL, error)) == NULL)
+    goto out;
+  if (!g_output_stream_write_all (out, sha256, strlen (sha256), &bytes_written, NULL, error))
+    goto out;
+  if (!g_output_stream_write_all (out, "\n", 1, &bytes_written, NULL, error))
+    goto out;
+  if (!g_output_stream_close (out, NULL, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+
+static gboolean
+parse_rev_file (OstreeRepo     *self,
+                GFile          *f,
+                char          **sha256,
+                GError        **error) G_GNUC_UNUSED;
+
+static gboolean
+parse_rev_file (OstreeRepo     *self,
+                GFile          *f,
+                char          **sha256,
+                GError        **error)
+{
+  gboolean ret = FALSE;
+  GError *temp_error = NULL;
+  gs_free char *rev = NULL;
+
+  if ((rev = gs_file_load_contents_utf8 (f, NULL, &temp_error)) == NULL)
+    goto out;
+
+  if (rev == NULL)
+    {
+      if (g_error_matches (temp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+        {
+          g_clear_error (&temp_error);
+        }
+      else
+        {
+          g_propagate_error (error, temp_error);
+          goto out;
+        }
+    }
+  else
+    {
+      g_strchomp (rev);
+    }
+
+  if (g_str_has_prefix (rev, "ref: "))
+    {
+      gs_unref_object GFile *ref = NULL;
+      char *ref_sha256;
+      gboolean subret;
+
+      ref = g_file_resolve_relative_path (self->local_heads_dir, rev + 5);
+      subret = parse_rev_file (self, ref, &ref_sha256, error);
+        
+      if (!subret)
+        {
+          g_free (ref_sha256);
+          goto out;
+        }
+      
+      g_free (rev);
+      rev = ref_sha256;
+    }
+  else 
+    {
+      if (!ostree_validate_checksum_string (rev, error))
+        goto out;
+    }
+
+  ot_transfer_out_value(sha256, &rev);
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+static gboolean
+find_ref_in_remotes (OstreeRepo         *self,
+                     const char         *rev,
+                     GFile             **out_file,
+                     GError            **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_object GFileEnumerator *dir_enum = NULL;
+  gs_unref_object GFile *ret_file = NULL;
+
+  dir_enum = g_file_enumerate_children (self->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
+                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                        NULL, error);
+  if (!dir_enum)
+    goto out;
+
+  while (TRUE)
+    {
+      GFileInfo *file_info;
+      GFile *child;
+      if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
+                                       NULL, error))
+        goto out;
+      if (file_info == NULL)
+        break;
+      if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
+        continue;
+
+      g_clear_object (&ret_file);
+      ret_file = g_file_resolve_relative_path (child, rev);
+      if (!g_file_query_exists (ret_file, NULL))
+        g_clear_object (&ret_file);
+      else
+        break;
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_file, &ret_file);
+ out:
+  return ret;
+}
+
+static gboolean
+resolve_refspec (OstreeRepo     *self,
+                 const char     *remote,
+                 const char     *ref,
+                 gboolean        allow_noent,
+                 char          **out_rev,
+                 GError        **error);
+
+static gboolean
+resolve_refspec_fallback (OstreeRepo     *self,
+                          const char     *remote,
+                          const char     *ref,
+                          gboolean        allow_noent,
+                          char          **out_rev,
+                          GCancellable   *cancellable,
+                          GError        **error)
+{
+  gboolean ret = FALSE;
+  gs_free char *ret_rev = NULL;
+
+  if (self->parent_repo)
+    {
+      if (!resolve_refspec (self->parent_repo, remote, ref,
+                            allow_noent, &ret_rev, error))
+        goto out;
+    }
+  else if (!allow_noent)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Refspec '%s%s%s' not found",
+                   remote ? remote : "",
+                   remote ? ":" : "",
+                   ref);
+      goto out;
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_rev, &ret_rev);
+ out:
+  return ret;
+}
+
+static gboolean
+resolve_refspec (OstreeRepo     *self,
+                 const char     *remote,
+                 const char     *ref,
+                 gboolean        allow_noent,
+                 char          **out_rev,
+                 GError        **error)
+{
+  gboolean ret = FALSE;
+  __attribute__((unused)) GCancellable *cancellable = NULL;
+  GError *temp_error = NULL;
+  gs_free char *tmp = NULL;
+  gs_free char *tmp2 = NULL;
+  gs_free char *ret_rev = NULL;
+  gs_unref_object GFile *child = NULL;
+  gs_unref_object GFile *origindir = NULL;
+  
+  g_return_val_if_fail (ref != NULL, FALSE);
+
+  /* We intentionally don't allow a ref that looks like a checksum */
+  if (ostree_validate_checksum_string (ref, NULL))
+    {
+      ret_rev = g_strdup (ref);
+    }
+  else if (remote != NULL)
+    {
+      child = ot_gfile_resolve_path_printf (self->remote_heads_dir, "%s/%s",
+                                            remote, ref);
+      if (!g_file_query_exists (child, NULL))
+        g_clear_object (&child);
+    }
+  else
+    {
+      child = g_file_resolve_relative_path (self->local_heads_dir, ref);
+
+      if (!g_file_query_exists (child, NULL))
+        {
+          g_clear_object (&child);
+
+          child = g_file_resolve_relative_path (self->remote_heads_dir, ref);
+
+          if (!g_file_query_exists (child, NULL))
+            {
+              g_clear_object (&child);
+              
+              if (!find_ref_in_remotes (self, ref, &child, error))
+                goto out;
+            }
+        }
+    }
+
+  if (child)
+    {
+      if ((ret_rev = gs_file_load_contents_utf8 (child, NULL, &temp_error)) == NULL)
+        {
+          g_propagate_error (error, temp_error);
+          g_prefix_error (error, "Couldn't open ref '%s': ", gs_file_get_path_cached (child));
+          goto out;
+        }
+
+      g_strchomp (ret_rev);
+      if (!ostree_validate_checksum_string (ret_rev, error))
+        goto out;
+    }
+  else
+    {
+      if (!resolve_refspec_fallback (self, remote, ref, allow_noent,
+                                     &ret_rev, cancellable, error))
+        goto out;
+    }
+
+  ot_transfer_out_value (out_rev, &ret_rev);
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+gboolean
+ostree_repo_resolve_rev (OstreeRepo     *self,
+                         const char     *refspec,
+                         gboolean        allow_noent,
+                         char          **out_rev,
+                         GError        **error)
+{
+  gboolean ret = FALSE;
+  gs_free char *ret_rev = NULL;
+
+  g_return_val_if_fail (refspec != NULL, FALSE);
+
+  if (ostree_validate_checksum_string (refspec, NULL))
+    {
+      ret_rev = g_strdup (refspec);
+    }
+  else
+    {
+      if (g_str_has_suffix (refspec, "^"))
+        {
+          gs_free char *parent_refspec = NULL;
+          gs_free char *parent_rev = NULL;
+          gs_unref_variant GVariant *commit = NULL;
+          gs_unref_variant GVariant *parent_csum_v = NULL;
+
+          parent_refspec = g_strdup (refspec);
+          parent_refspec[strlen(parent_refspec) - 1] = '\0';
+
+          if (!ostree_repo_resolve_rev (self, parent_refspec, allow_noent, &parent_rev, error))
+            goto out;
+          
+          if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, parent_rev,
+                                         &commit, error))
+            goto out;
+      
+          g_variant_get_child (commit, 1, "@ay", &parent_csum_v);
+          if (g_variant_n_children (parent_csum_v) == 0)
+            {
+              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Commit %s has no parent", parent_rev);
+              goto out;
+            }
+          ret_rev = ostree_checksum_from_bytes_v (parent_csum_v);
+        }
+      else
+        {
+          gs_free char *remote = NULL;
+          gs_free char *ref = NULL;
+
+          if (!ostree_parse_refspec (refspec, &remote, &ref, error))
+            goto out;
+          
+          if (!resolve_refspec (self, remote, ref, allow_noent,
+                                &ret_rev, error))
+            goto out;
+        }
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_rev, &ret_rev);
+ out:
+  return ret;
+}
+
+static gboolean
+enumerate_refs_recurse (OstreeRepo    *repo,
+                        const char    *remote,
+                        GFile         *base,
+                        GFile         *dir,
+                        GHashTable    *refs,
+                        GCancellable  *cancellable,
+                        GError       **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_object GFileEnumerator *enumerator = NULL;
+
+  enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                          cancellable, error);
+  if (!enumerator)
+    goto out;
+
+  while (TRUE)
+    {
+      GFileInfo *file_info = NULL;
+      GFile *child = NULL;
+
+      if (!gs_file_enumerator_iterate (enumerator, &file_info, &child,
+                                       NULL, error))
+        goto out;
+      if (file_info == NULL)
+        break;
+
+      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+        {
+          if (!enumerate_refs_recurse (repo, remote, base, child, refs, cancellable, error))
+            goto out;
+        }
+      else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
+        {
+          if (!add_ref_to_set (remote, base, child, refs,
+                               cancellable, error))
+            goto out;
+        }
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+gboolean
+ostree_repo_list_refs (OstreeRepo       *repo,
+                       const char       *refspec_prefix,
+                       GHashTable      **out_all_refs,
+                       GCancellable     *cancellable,
+                       GError          **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_hashtable GHashTable *ret_all_refs = NULL;
+  gs_free char *remote = NULL;
+  gs_free char *ref_prefix = NULL;
+
+  ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+  if (refspec_prefix)
+    {
+      gs_unref_object GFile *dir = NULL;
+      gs_unref_object GFile *child = NULL;
+      gs_unref_object GFileInfo *info = NULL;
+
+      if (!ostree_parse_refspec (refspec_prefix, &remote, &ref_prefix, error))
+        goto out;
+
+      if (remote)
+        dir = g_file_get_child (repo->remote_heads_dir, remote);
+      else
+        dir = g_object_ref (repo->local_heads_dir);
+
+      child = g_file_resolve_relative_path (dir, ref_prefix);
+      if (!ot_gfile_query_info_allow_noent (child, OSTREE_GIO_FAST_QUERYINFO, 0,
+                                            &info, cancellable, error))
+        goto out;
+
+      if (info)
+        {
+          if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+            {
+              if (!enumerate_refs_recurse (repo, remote, child, child,
+                                           ret_all_refs,
+                                           cancellable, error))
+                goto out;
+            }
+          else
+            {
+              if (!add_ref_to_set (remote, dir, child, ret_all_refs,
+                                   cancellable, error))
+                goto out;
+            }
+        }
+    }
+  else
+    {
+      gs_unref_object GFileEnumerator *remote_enumerator = NULL;
+
+      if (!enumerate_refs_recurse (repo, NULL, repo->local_heads_dir, repo->local_heads_dir,
+                                   ret_all_refs,
+                                   cancellable, error))
+        goto out;
+
+      remote_enumerator = g_file_enumerate_children (repo->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
+                                                     0,
+                                                     cancellable, error);
+
+      while (TRUE)
+        {
+          GFileInfo *info;
+          GFile *child;
+          const char *name;
+
+          if (!gs_file_enumerator_iterate (remote_enumerator, &info, &child,
+                                           cancellable, error))
+            goto out;
+          if (!info)
+            break;
+
+          name = g_file_info_get_name (info);
+          if (!enumerate_refs_recurse (repo, name, child, child,
+                                       ret_all_refs,
+                                       cancellable, error))
+            goto out;
+        }
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_all_refs, &ret_all_refs);
+ out:
+  return ret;
+}
+
+static gboolean
+write_ref_summary (OstreeRepo      *self,
+                   GCancellable    *cancellable,
+                   GError         **error)
+{
+  gboolean ret = FALSE;
+  GHashTableIter hash_iter;
+  gpointer key, value;
+  gsize bytes_written;
+  gs_unref_hashtable GHashTable *all_refs = NULL;
+  gs_unref_object GFile *summary_path = NULL;
+  gs_unref_object GOutputStream *out = NULL;
+  gs_free char *buf = NULL;
+
+  if (!ostree_repo_list_refs (self, NULL, &all_refs, cancellable, error))
+    goto out;
+
+  summary_path = g_file_resolve_relative_path (ostree_repo_get_path (self),
+                                               "refs/summary");
+
+  out = (GOutputStream*) g_file_replace (summary_path, NULL, FALSE, 0, cancellable, error);
+  if (!out)
+    goto out;
+  
+  g_hash_table_iter_init (&hash_iter, all_refs);
+  while (g_hash_table_iter_next (&hash_iter, &key, &value))
+    {
+      const char *name = key;
+      const char *sha256 = value;
+
+      g_free (buf);
+      buf = g_strdup_printf ("%s %s\n", sha256, name);
+      if (!g_output_stream_write_all (out, buf, strlen (buf), &bytes_written, cancellable, error))
+        goto out;
+    }
+
+  if (!g_output_stream_close (out, cancellable, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+gboolean      
+ostree_repo_write_ref (OstreeRepo  *self,
+                       const char  *remote,
+                       const char  *name,
+                       const char  *rev,
+                       GError     **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_object GFile *dir = NULL;
+
+  if (remote == NULL)
+    dir = g_object_ref (self->local_heads_dir);
+  else
+    {
+      dir = g_file_get_child (self->remote_heads_dir, remote);
+      
+      if (rev != NULL)
+        {
+          if (!gs_file_ensure_directory (dir, FALSE, NULL, error))
+            goto out;
+        }
+    }
+
+  if (rev == NULL)
+    {
+      gs_unref_object GFile *child = g_file_resolve_relative_path (dir, name);
+      
+      if (g_file_query_exists (child, NULL))
+        {
+          if (!gs_file_unlink (child, NULL, error))
+            goto out;
+        }
+    }
+  else
+    {
+      if (!write_checksum_file (dir, name, rev, error))
+        goto out;
+      
+      if (rev != NULL)
+        {
+          if (self->mode == OSTREE_REPO_MODE_ARCHIVE
+              || self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
+            {
+              if (!write_ref_summary (self, NULL, error))
+                goto out;
+            }
+        }
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+gboolean
+ostree_repo_write_refspec (OstreeRepo  *self,
+                           const char  *refspec,
+                           const char  *rev,
+                           GError     **error)
+{
+  gboolean ret = FALSE;
+  gs_free char *remote = NULL;
+  gs_free char *ref = NULL;
+
+  if (!ostree_parse_refspec (refspec, &remote, &ref, error))
+    goto out;
+
+  if (!ostree_repo_write_ref (self, remote, ref, rev, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  return ret;
+}
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 2b9ba65..a151b71 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -186,361 +186,6 @@ ostree_repo_new (GFile *path)
 {
   return g_object_new (OSTREE_TYPE_REPO, "path", path, NULL);
 }
-
-static gboolean
-parse_rev_file (OstreeRepo     *self,
-                GFile          *f,
-                char          **sha256,
-                GError        **error) G_GNUC_UNUSED;
-
-static gboolean
-parse_rev_file (OstreeRepo     *self,
-                GFile          *f,
-                char          **sha256,
-                GError        **error)
-{
-  gboolean ret = FALSE;
-  GError *temp_error = NULL;
-  gs_free char *rev = NULL;
-
-  if ((rev = gs_file_load_contents_utf8 (f, NULL, &temp_error)) == NULL)
-    goto out;
-
-  if (rev == NULL)
-    {
-      if (g_error_matches (temp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
-        {
-          g_clear_error (&temp_error);
-        }
-      else
-        {
-          g_propagate_error (error, temp_error);
-          goto out;
-        }
-    }
-  else
-    {
-      g_strchomp (rev);
-    }
-
-  if (g_str_has_prefix (rev, "ref: "))
-    {
-      gs_unref_object GFile *ref = NULL;
-      char *ref_sha256;
-      gboolean subret;
-
-      ref = g_file_resolve_relative_path (self->local_heads_dir, rev + 5);
-      subret = parse_rev_file (self, ref, &ref_sha256, error);
-        
-      if (!subret)
-        {
-          g_free (ref_sha256);
-          goto out;
-        }
-      
-      g_free (rev);
-      rev = ref_sha256;
-    }
-  else 
-    {
-      if (!ostree_validate_checksum_string (rev, error))
-        goto out;
-    }
-
-  ot_transfer_out_value(sha256, &rev);
-  ret = TRUE;
- out:
-  return ret;
-}
-
-static gboolean
-find_ref_in_remotes (OstreeRepo         *self,
-                     const char         *rev,
-                     GFile             **out_file,
-                     GError            **error)
-{
-  gboolean ret = FALSE;
-  gs_unref_object GFileEnumerator *dir_enum = NULL;
-  gs_unref_object GFile *ret_file = NULL;
-
-  dir_enum = g_file_enumerate_children (self->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
-                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                        NULL, error);
-  if (!dir_enum)
-    goto out;
-
-  while (TRUE)
-    {
-      GFileInfo *file_info;
-      GFile *child;
-      if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
-                                       NULL, error))
-        goto out;
-      if (file_info == NULL)
-        break;
-      if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
-        continue;
-
-      g_clear_object (&ret_file);
-      ret_file = g_file_resolve_relative_path (child, rev);
-      if (!g_file_query_exists (ret_file, NULL))
-        g_clear_object (&ret_file);
-      else
-        break;
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value (out_file, &ret_file);
- out:
-  return ret;
-}
-
-static gboolean
-resolve_refspec (OstreeRepo     *self,
-                 const char     *remote,
-                 const char     *ref,
-                 gboolean        allow_noent,
-                 char          **out_rev,
-                 GError        **error);
-
-static gboolean
-resolve_refspec_fallback (OstreeRepo     *self,
-                          const char     *remote,
-                          const char     *ref,
-                          gboolean        allow_noent,
-                          char          **out_rev,
-                          GCancellable   *cancellable,
-                          GError        **error)
-{
-  gboolean ret = FALSE;
-  gs_free char *ret_rev = NULL;
-
-  if (self->parent_repo)
-    {
-      if (!resolve_refspec (self->parent_repo, remote, ref,
-                            allow_noent, &ret_rev, error))
-        goto out;
-    }
-  else if (!allow_noent)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Refspec '%s%s%s' not found",
-                   remote ? remote : "",
-                   remote ? ":" : "",
-                   ref);
-      goto out;
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value (out_rev, &ret_rev);
- out:
-  return ret;
-}
-
-static gboolean
-resolve_refspec (OstreeRepo     *self,
-                 const char     *remote,
-                 const char     *ref,
-                 gboolean        allow_noent,
-                 char          **out_rev,
-                 GError        **error)
-{
-  gboolean ret = FALSE;
-  __attribute__((unused)) GCancellable *cancellable = NULL;
-  GError *temp_error = NULL;
-  gs_free char *tmp = NULL;
-  gs_free char *tmp2 = NULL;
-  gs_free char *ret_rev = NULL;
-  gs_unref_object GFile *child = NULL;
-  gs_unref_object GFile *origindir = NULL;
-  
-  g_return_val_if_fail (ref != NULL, FALSE);
-
-  /* We intentionally don't allow a ref that looks like a checksum */
-  if (ostree_validate_checksum_string (ref, NULL))
-    {
-      ret_rev = g_strdup (ref);
-    }
-  else if (remote != NULL)
-    {
-      child = ot_gfile_resolve_path_printf (self->remote_heads_dir, "%s/%s",
-                                            remote, ref);
-      if (!g_file_query_exists (child, NULL))
-        g_clear_object (&child);
-    }
-  else
-    {
-      child = g_file_resolve_relative_path (self->local_heads_dir, ref);
-
-      if (!g_file_query_exists (child, NULL))
-        {
-          g_clear_object (&child);
-
-          child = g_file_resolve_relative_path (self->remote_heads_dir, ref);
-
-          if (!g_file_query_exists (child, NULL))
-            {
-              g_clear_object (&child);
-              
-              if (!find_ref_in_remotes (self, ref, &child, error))
-                goto out;
-            }
-        }
-    }
-
-  if (child)
-    {
-      if ((ret_rev = gs_file_load_contents_utf8 (child, NULL, &temp_error)) == NULL)
-        {
-          g_propagate_error (error, temp_error);
-          g_prefix_error (error, "Couldn't open ref '%s': ", gs_file_get_path_cached (child));
-          goto out;
-        }
-
-      g_strchomp (ret_rev);
-      if (!ostree_validate_checksum_string (ret_rev, error))
-        goto out;
-    }
-  else
-    {
-      if (!resolve_refspec_fallback (self, remote, ref, allow_noent,
-                                     &ret_rev, cancellable, error))
-        goto out;
-    }
-
-  ot_transfer_out_value (out_rev, &ret_rev);
-  ret = TRUE;
- out:
-  return ret;
-}
-
-gboolean
-ostree_repo_resolve_rev (OstreeRepo     *self,
-                         const char     *refspec,
-                         gboolean        allow_noent,
-                         char          **out_rev,
-                         GError        **error)
-{
-  gboolean ret = FALSE;
-  gs_free char *ret_rev = NULL;
-
-  g_return_val_if_fail (refspec != NULL, FALSE);
-
-  if (ostree_validate_checksum_string (refspec, NULL))
-    {
-      ret_rev = g_strdup (refspec);
-    }
-  else
-    {
-      if (g_str_has_suffix (refspec, "^"))
-        {
-          gs_free char *parent_refspec = NULL;
-          gs_free char *parent_rev = NULL;
-          gs_unref_variant GVariant *commit = NULL;
-          gs_unref_variant GVariant *parent_csum_v = NULL;
-
-          parent_refspec = g_strdup (refspec);
-          parent_refspec[strlen(parent_refspec) - 1] = '\0';
-
-          if (!ostree_repo_resolve_rev (self, parent_refspec, allow_noent, &parent_rev, error))
-            goto out;
-          
-          if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, parent_rev,
-                                         &commit, error))
-            goto out;
-      
-          g_variant_get_child (commit, 1, "@ay", &parent_csum_v);
-          if (g_variant_n_children (parent_csum_v) == 0)
-            {
-              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           "Commit %s has no parent", parent_rev);
-              goto out;
-            }
-          ret_rev = ostree_checksum_from_bytes_v (parent_csum_v);
-        }
-      else
-        {
-          gs_free char *remote = NULL;
-          gs_free char *ref = NULL;
-
-          if (!ostree_parse_refspec (refspec, &remote, &ref, error))
-            goto out;
-          
-          if (!resolve_refspec (self, remote, ref, allow_noent,
-                                &ret_rev, error))
-            goto out;
-        }
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value (out_rev, &ret_rev);
- out:
-  return ret;
-}
-
-
-static gboolean
-write_checksum_file (GFile *parentdir,
-                     const char *name,
-                     const char *sha256,
-                     GError **error)
-{
-  gboolean ret = FALSE;
-  gsize bytes_written;
-  int i;
-  gs_unref_object GFile *parent = NULL;
-  gs_unref_object GFile *child = NULL;
-  gs_unref_object GOutputStream *out = NULL;
-  gs_unref_ptrarray GPtrArray *components = NULL;
-
-  if (!ostree_validate_checksum_string (sha256, error))
-    goto out;
-
-  if (ostree_validate_checksum_string (name, NULL))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Rev name '%s' looks like a checksum", name);
-      goto out;
-    }
-
-  if (!ot_util_path_split_validate (name, &components, error))
-    goto out;
-
-  if (components->len == 0)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Invalid empty ref name");
-      goto out;
-    }
-
-  parent = g_object_ref (parentdir);
-  for (i = 0; i+1 < components->len; i++)
-    {
-      child = g_file_get_child (parent, (char*)components->pdata[i]);
-
-      if (!gs_file_ensure_directory (child, FALSE, NULL, error))
-        goto out;
-
-      g_clear_object (&parent);
-      parent = child;
-      child = NULL;
-    }
-
-  child = g_file_get_child (parent, components->pdata[components->len - 1]);
-  if ((out = (GOutputStream*)g_file_replace (child, NULL, FALSE, 0, NULL, error)) == NULL)
-    goto out;
-  if (!g_output_stream_write_all (out, sha256, strlen (sha256), &bytes_written, NULL, error))
-    goto out;
-  if (!g_output_stream_write_all (out, "\n", 1, &bytes_written, NULL, error))
-    goto out;
-  if (!g_output_stream_close (out, NULL, error))
-    goto out;
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
 /**
  * ostree_repo_get_config:
  * @self:
@@ -1752,297 +1397,6 @@ create_empty_gvariant_dict (void)
   return g_variant_builder_end (&builder);
 }
 
-static gboolean
-add_ref_to_set (const char       *remote,
-                GFile            *base,
-                GFile            *child,
-                GHashTable       *refs,
-                GCancellable     *cancellable,
-                GError          **error)
-{
-  gboolean ret = FALSE;
-  char *contents;
-  char *relpath;
-  gsize len;
-  GString *refname;
-
-  if (!g_file_load_contents (child, cancellable, &contents, &len, NULL, error))
-    goto out;
-
-  g_strchomp (contents);
-
-  refname = g_string_new ("");
-  if (remote)
-    {
-      g_string_append (refname, remote);
-      g_string_append_c (refname, ':');
-    }
-  relpath = g_file_get_relative_path (base, child);
-  g_string_append (refname, relpath);
-  g_free (relpath);
-          
-  g_hash_table_insert (refs, g_string_free (refname, FALSE), contents);
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
-static gboolean
-enumerate_refs_recurse (OstreeRepo    *repo,
-                        const char    *remote,
-                        GFile         *base,
-                        GFile         *dir,
-                        GHashTable    *refs,
-                        GCancellable  *cancellable,
-                        GError       **error)
-{
-  gboolean ret = FALSE;
-  gs_unref_object GFileEnumerator *enumerator = NULL;
-
-  enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
-                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                          cancellable, error);
-  if (!enumerator)
-    goto out;
-
-  while (TRUE)
-    {
-      GFileInfo *file_info = NULL;
-      GFile *child = NULL;
-
-      if (!gs_file_enumerator_iterate (enumerator, &file_info, &child,
-                                       NULL, error))
-        goto out;
-      if (file_info == NULL)
-        break;
-
-      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
-        {
-          if (!enumerate_refs_recurse (repo, remote, base, child, refs, cancellable, error))
-            goto out;
-        }
-      else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
-        {
-          if (!add_ref_to_set (remote, base, child, refs,
-                               cancellable, error))
-            goto out;
-        }
-    }
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
-gboolean
-ostree_repo_list_refs (OstreeRepo       *repo,
-                       const char       *refspec_prefix,
-                       GHashTable      **out_all_refs,
-                       GCancellable     *cancellable,
-                       GError          **error)
-{
-  gboolean ret = FALSE;
-  gs_unref_hashtable GHashTable *ret_all_refs = NULL;
-  gs_free char *remote = NULL;
-  gs_free char *ref_prefix = NULL;
-
-  ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
-  if (refspec_prefix)
-    {
-      gs_unref_object GFile *dir = NULL;
-      gs_unref_object GFile *child = NULL;
-      gs_unref_object GFileInfo *info = NULL;
-
-      if (!ostree_parse_refspec (refspec_prefix, &remote, &ref_prefix, error))
-        goto out;
-
-      if (remote)
-        dir = g_file_get_child (repo->remote_heads_dir, remote);
-      else
-        dir = g_object_ref (repo->local_heads_dir);
-
-      child = g_file_resolve_relative_path (dir, ref_prefix);
-      if (!ot_gfile_query_info_allow_noent (child, OSTREE_GIO_FAST_QUERYINFO, 0,
-                                            &info, cancellable, error))
-        goto out;
-
-      if (info)
-        {
-          if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
-            {
-              if (!enumerate_refs_recurse (repo, remote, child, child,
-                                           ret_all_refs,
-                                           cancellable, error))
-                goto out;
-            }
-          else
-            {
-              if (!add_ref_to_set (remote, dir, child, ret_all_refs,
-                                   cancellable, error))
-                goto out;
-            }
-        }
-    }
-  else
-    {
-      gs_unref_object GFileEnumerator *remote_enumerator = NULL;
-
-      if (!enumerate_refs_recurse (repo, NULL, repo->local_heads_dir, repo->local_heads_dir,
-                                   ret_all_refs,
-                                   cancellable, error))
-        goto out;
-
-      remote_enumerator = g_file_enumerate_children (repo->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
-                                                     0,
-                                                     cancellable, error);
-
-      while (TRUE)
-        {
-          GFileInfo *info;
-          GFile *child;
-          const char *name;
-
-          if (!gs_file_enumerator_iterate (remote_enumerator, &info, &child,
-                                           cancellable, error))
-            goto out;
-          if (!info)
-            break;
-
-          name = g_file_info_get_name (info);
-          if (!enumerate_refs_recurse (repo, name, child, child,
-                                       ret_all_refs,
-                                       cancellable, error))
-            goto out;
-        }
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value (out_all_refs, &ret_all_refs);
- out:
-  return ret;
-}
-
-static gboolean
-write_ref_summary (OstreeRepo      *self,
-                   GCancellable    *cancellable,
-                   GError         **error)
-{
-  gboolean ret = FALSE;
-  GHashTableIter hash_iter;
-  gpointer key, value;
-  gsize bytes_written;
-  gs_unref_hashtable GHashTable *all_refs = NULL;
-  gs_unref_object GFile *summary_path = NULL;
-  gs_unref_object GOutputStream *out = NULL;
-  gs_free char *buf = NULL;
-
-  if (!ostree_repo_list_refs (self, NULL, &all_refs, cancellable, error))
-    goto out;
-
-  summary_path = g_file_resolve_relative_path (ostree_repo_get_path (self),
-                                               "refs/summary");
-
-  out = (GOutputStream*) g_file_replace (summary_path, NULL, FALSE, 0, cancellable, error);
-  if (!out)
-    goto out;
-  
-  g_hash_table_iter_init (&hash_iter, all_refs);
-  while (g_hash_table_iter_next (&hash_iter, &key, &value))
-    {
-      const char *name = key;
-      const char *sha256 = value;
-
-      g_free (buf);
-      buf = g_strdup_printf ("%s %s\n", sha256, name);
-      if (!g_output_stream_write_all (out, buf, strlen (buf), &bytes_written, cancellable, error))
-        goto out;
-    }
-
-  if (!g_output_stream_close (out, cancellable, error))
-    goto out;
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
-gboolean      
-ostree_repo_write_ref (OstreeRepo  *self,
-                       const char  *remote,
-                       const char  *name,
-                       const char  *rev,
-                       GError     **error)
-{
-  gboolean ret = FALSE;
-  gs_unref_object GFile *dir = NULL;
-
-  if (remote == NULL)
-    dir = g_object_ref (self->local_heads_dir);
-  else
-    {
-      dir = g_file_get_child (self->remote_heads_dir, remote);
-      
-      if (rev != NULL)
-        {
-          if (!gs_file_ensure_directory (dir, FALSE, NULL, error))
-            goto out;
-        }
-    }
-
-  if (rev == NULL)
-    {
-      gs_unref_object GFile *child = g_file_resolve_relative_path (dir, name);
-      
-      if (g_file_query_exists (child, NULL))
-        {
-          if (!gs_file_unlink (child, NULL, error))
-            goto out;
-        }
-    }
-  else
-    {
-      if (!write_checksum_file (dir, name, rev, error))
-        goto out;
-      
-      if (rev != NULL)
-        {
-          if (self->mode == OSTREE_REPO_MODE_ARCHIVE
-              || self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
-            {
-              if (!write_ref_summary (self, NULL, error))
-                goto out;
-            }
-        }
-    }
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
-gboolean
-ostree_repo_write_refspec (OstreeRepo  *self,
-                           const char  *refspec,
-                           const char  *rev,
-                           GError     **error)
-{
-  gboolean ret = FALSE;
-  gs_free char *remote = NULL;
-  gs_free char *ref = NULL;
-
-  if (!ostree_parse_refspec (refspec, &remote, &ref, error))
-    goto out;
-
-  if (!ostree_repo_write_ref (self, remote, ref, rev, error))
-    goto out;
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
 gboolean
 ostree_repo_stage_commit (OstreeRepo *self,
                           const char   *branch,



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