From 0aa836c20557f6360b3f82eb0d523916da9e8f63 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Thu, 5 Nov 2015 13:28:37 +0100 Subject: [PATCH] prune: add --delete-commit Signed-off-by: Giuseppe Scrivano --- doc/ostree-prune.xml | 8 ++++++++ src/ostree/ot-builtin-fsck.c | 14 ++----------- src/ostree/ot-builtin-prune.c | 38 +++++++++++++++++++++++++++++++++++ src/ostree/ot-main.c | 21 +++++++++++++++++++ src/ostree/ot-main.h | 2 ++ 5 files changed, 71 insertions(+), 12 deletions(-) diff --git a/doc/ostree-prune.xml b/doc/ostree-prune.xml index 523b7225..91caa813 100644 --- a/doc/ostree-prune.xml +++ b/doc/ostree-prune.xml @@ -81,6 +81,14 @@ Boston, MA 02111-1307, USA. + + =COMMIT + + + Specify a COMMIT to delete. + + + =DEPTH diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index d16ead84..b1926836 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -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++) { diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index 571d1a18..44868a14 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -25,15 +25,18 @@ #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) diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index d3a7fd45..44e1bd49 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -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; +} diff --git a/src/ostree/ot-main.h b/src/ostree/ot-main.h index d893b736..32620c52 100644 --- a/src/ostree/ot-main.h +++ b/src/ostree/ot-main.h @@ -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);