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);