diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 8fe9d765..5f24e7c9 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -975,6 +975,8 @@ ostree_object_type_to_string (OstreeObjectType objtype) return "dirmeta"; case OSTREE_OBJECT_TYPE_COMMIT: return "commit"; + case OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT: + return "tombstone-commit"; default: g_assert_not_reached (); return NULL; diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index 711c6994..637f8172 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -56,15 +56,17 @@ G_BEGIN_DECLS * @OSTREE_OBJECT_TYPE_DIR_TREE: List of children (trees or files), and metadata * @OSTREE_OBJECT_TYPE_DIR_META: Directory metadata * @OSTREE_OBJECT_TYPE_COMMIT: Toplevel object, refers to tree and dirmeta for root + * @OSTREE_OBJECT_TYPE_COMMIT_TOMBSTONE: Toplevel object, refers to a deleted commit * * Enumeration for core object types; %OSTREE_OBJECT_TYPE_FILE is for * content, the other types are metadata. */ typedef enum { - OSTREE_OBJECT_TYPE_FILE = 1, /* .file */ - OSTREE_OBJECT_TYPE_DIR_TREE = 2, /* .dirtree */ - OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */ - OSTREE_OBJECT_TYPE_COMMIT = 4 /* .commit */ + OSTREE_OBJECT_TYPE_FILE = 1, /* .file */ + OSTREE_OBJECT_TYPE_DIR_TREE = 2, /* .dirtree */ + OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */ + OSTREE_OBJECT_TYPE_COMMIT = 4, /* .commit */ + OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT = 5, /* .commit-tombstone */ } OstreeObjectType; /** @@ -73,14 +75,14 @@ typedef enum { * * Returns: %TRUE if object type is metadata */ -#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 4) +#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 5) /** * OSTREE_OBJECT_TYPE_LAST: * * Last valid object type; use this to validate ranges. */ -#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_COMMIT +#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT /** * OSTREE_DIRMETA_GVARIANT_FORMAT: diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 41cc46b6..7ba3ef61 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -58,6 +58,7 @@ typedef struct { gboolean gpg_verify; gboolean gpg_verify_summary; + gboolean has_tombstone_commits; GBytes *summary_data; GBytes *summary_data_sig; @@ -795,12 +796,23 @@ meta_fetch_on_complete (GObject *object, pull_data->maxdepth != 0) { g_clear_error (&local_error); + /* If the remote repo supports tombstone commits, check if the commit was intentionally + deleted. */ + if (pull_data->has_tombstone_commits) + { + enqueue_one_object_request (pull_data, checksum, OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, + FALSE, FALSE); + } } } goto out; } + /* Tombstone commits are always empty, so skip all processing here */ + if (objtype == OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT) + goto out; + fd = openat (pull_data->tmpdir_dfd, temp_path, O_RDONLY | O_CLOEXEC); if (fd == -1) { @@ -1854,7 +1866,11 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error)) goto out; - + + if (!ot_keyfile_get_boolean_with_default (remote_config, "core", "tombstone-commits", FALSE, + &pull_data->has_tombstone_commits, error)) + goto out; + if (pull_data->remote_mode != OSTREE_REPO_MODE_ARCHIVE_Z2) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,