diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 68008c55..62da0e35 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -770,6 +770,28 @@ write_object (OstreeRepo *self, cancellable, error)) goto out; + + if (objtype == OSTREE_OBJECT_TYPE_COMMIT) + { + GError *local_error = NULL; + /* If we are writing a commit, be sure there is no tombstone for it. + We may have deleted the commit and now we are trying to pull it again. */ + if (!ostree_repo_delete_object (self, + OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, + actual_checksum, + cancellable, + &local_error)) + { + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + g_clear_error (&local_error); + else + { + g_propagate_error (error, local_error); + goto out; + } + } + } + if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { if (G_UNLIKELY (file_object_length > OSTREE_MAX_METADATA_WARN_SIZE)) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 43dcb2b4..1f1cba29 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3202,6 +3202,30 @@ ostree_repo_delete_object (OstreeRepo *self, goto out; } + /* If the repository is configured to use tombstone commits, create one when deleting a commit. */ + if (objtype == OSTREE_OBJECT_TYPE_COMMIT) + { + gboolean tombstone_commits = FALSE; + GKeyFile *readonly_config = ostree_repo_get_config (self); + if (!ot_keyfile_get_boolean_with_default (readonly_config, "core", "tombstone-commits", FALSE, + &tombstone_commits, error)) + goto out; + + if (tombstone_commits) + { + g_autoptr(GVariantBuilder) builder = NULL; + builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (builder, "{sv}", "commit", g_variant_new_bytestring (sha256)); + if (!ostree_repo_write_metadata_trusted (self, + OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, + sha256, + g_variant_builder_end (builder), + cancellable, + error)) + goto out; + } + } + ret = TRUE; out: return ret;