prune: add --delete-commit
authorGiuseppe Scrivano <gscrivan@redhat.com>
Thu, 5 Nov 2015 12:28:37 +0000 (13:28 +0100)
committerGiuseppe Scrivano <gscrivan@redhat.com>
Mon, 16 Nov 2015 09:57:33 +0000 (10:57 +0100)
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
doc/ostree-prune.xml
src/ostree/ot-builtin-fsck.c
src/ostree/ot-builtin-prune.c
src/ostree/ot-main.c
src/ostree/ot-main.h

index 523b7225cc1ae55122e066b574e3914dc9f5efdf..91caa8130e641e5de5f7d04dc3641b7cbaa7e24d 100644 (file)
@@ -81,6 +81,14 @@ Boston, MA 02111-1307, USA.
                 </para></listitem>
             </varlistentry>
 
+            <varlistentry>
+                <term><option>--delete-commit</option>=COMMIT</term>
+
+                <listitem><para>
+                    Specify a COMMIT to delete.
+                </para></listitem>
+            </varlistentry>
+
             <varlistentry>
                 <term><option>--depth</option>=DEPTH</term>
 
index d16ead840b5523e1d4feaefb67b99ff63b71c986..b19268361baf53cef966d5fec2cfb3f0240e98d9 100644 (file)
@@ -310,18 +310,8 @@ ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **
       guint i;
       if (tombstones->len)
         {
-          GError *temp_error = NULL;
-          gboolean tombstone_commits = FALSE;
-          GKeyFile *config = ostree_repo_get_config (repo);
-          tombstone_commits = g_key_file_get_boolean (config, "core", "tombstone-commits", &temp_error);
-          /* tombstone_commits is FALSE either if it is not found or it is really set to FALSE in the config file.  */
-          if (!tombstone_commits)
-            {
-              g_clear_error (&temp_error);
-              g_key_file_set_boolean (config, "core", "tombstone-commits", TRUE);
-              if (!ostree_repo_write_config (repo, config, error))
-                goto out;
-            }
+          if (!ot_enable_tombstone_commits (repo, error))
+            goto out;
         }
       for (i = 0; i < tombstones->len; i++)
         {
index 571d1a1828756d90d8af1d890f28dcc506c30392..44868a142d2e539baf70d5494cd24d93f82a2a6e 100644 (file)
 #include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
+#include "otutil.h"
 
 static gboolean opt_no_prune;
 static gint opt_depth = -1;
 static gboolean opt_refs_only;
+static char *opt_delete_commit;
 
 static GOptionEntry options[] = {
   { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Only display unreachable objects; don't delete", NULL },
   { "refs-only", 0, 0, G_OPTION_ARG_NONE, &opt_refs_only, "Only compute reachability via refs", NULL },
   { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Only traverse DEPTH parents for each commit (default: -1=infinite)", "DEPTH" },
+  { "delete-commit", 0, 0, G_OPTION_ARG_STRING, &opt_delete_commit, "Specify a commit to delete", "COMMIT" },
   { NULL }
 };
 
@@ -57,6 +60,41 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError *
   if (!opt_no_prune && !ostree_ensure_repo_writable (repo, error))
     goto out;
 
+  if (opt_delete_commit)
+    {
+      g_autoptr(GHashTable) refs = NULL;
+      GHashTableIter hashiter;
+      gpointer hashkey, hashvalue;
+
+      if (opt_no_prune)
+        {
+          ot_util_usage_error (context, "Cannot specify both --delete-commit and --no-prune", error);
+          goto out;
+        }
+
+      if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error))
+        goto out;
+
+      g_hash_table_iter_init (&hashiter, refs);
+      while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
+        {
+          const char *ref = hashkey;
+          const char *commit = hashvalue;
+          if (g_strcmp0 (commit, opt_delete_commit) == 0)
+            {
+              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Commit '%s' is referenced by '%s'", opt_delete_commit, ref);
+              goto out;
+            }
+        }
+
+      if (!ot_enable_tombstone_commits (repo, error))
+        goto out;
+
+      if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, opt_delete_commit, cancellable, error))
+        goto out;
+    }
+
   if (opt_refs_only)
     pruneflags |= OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY;
   if (opt_no_prune)
index d3a7fd457ae7b0aca9e38d2f6feae8218b08eee4..44e1bd49e5045c0bd0e88f642771459c6878f87b 100644 (file)
@@ -419,3 +419,24 @@ ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result)
   g_print ("%s", buffer->str);
   g_string_free (buffer, TRUE);
 }
+
+gboolean
+ot_enable_tombstone_commits (OstreeRepo *repo, GError **error)
+{
+  gboolean ret = FALSE;
+  gboolean tombstone_commits = FALSE;
+  GKeyFile *config = ostree_repo_get_config (repo);
+
+  tombstone_commits = g_key_file_get_boolean (config, "core", "tombstone-commits", NULL);
+  /* tombstone_commits is FALSE either if it is not found or it is really set to FALSE in the config file.  */
+  if (!tombstone_commits)
+    {
+      g_key_file_set_boolean (config, "core", "tombstone-commits", TRUE);
+      if (!ostree_repo_write_config (repo, config, error))
+        goto out;
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
index d893b736a52bb83f218f572e56dfb463d6881636..32620c5289006bbfbaa614b59b4e6c69a9a2120c 100644 (file)
@@ -63,3 +63,5 @@ gboolean ostree_admin_option_context_parse (GOptionContext *context,
 gboolean ostree_ensure_repo_writable (OstreeRepo *repo, GError **error);
 
 void ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result);
+
+gboolean ot_enable_tombstone_commits (OstreeRepo *repo, GError **error);