diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index 9a1516464c..3c0bf10e53 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -201,8 +201,16 @@ checkout_file_from_input_at (OstreeRepo *self, while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { - glnx_set_error_from_errno (error); - goto out; + if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES) + { + ret = TRUE; + goto out; + } + else + { + glnx_set_error_from_errno (error); + goto out; + } } if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) @@ -240,6 +248,11 @@ checkout_file_from_input_at (OstreeRepo *self, while (G_UNLIKELY (fd == -1 && errno == EINTR)); if (fd == -1) { + if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES) + { + ret = TRUE; + goto out; + } glnx_set_error_from_errno (error); goto out; } @@ -362,6 +375,12 @@ checkout_file_hardlink (OstreeRepo *self, { ret_was_supported = FALSE; } + else if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES) + { + /* In this mode, we keep existing content. Still need to mark the hardlink as supported. + */ + ret_was_supported = TRUE; + } else if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES) { /* Idiocy, from man rename(2) @@ -573,6 +592,7 @@ checkout_one_file_at (OstreeRepo *repo, /* Fall back to copy if we couldn't hardlink */ if (need_copy) { + g_assert (!options->no_copy_fallback); if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs, cancellable, error)) goto out; @@ -653,7 +673,9 @@ checkout_tree_at (OstreeRepo *self, while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { - if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES) + if (errno == EEXIST && + (options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES + || options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES)) did_exist = TRUE; else { diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 648bd12909..0d13e5700c 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -723,10 +723,12 @@ typedef enum { * OstreeRepoCheckoutOverwriteMode: * @OSTREE_REPO_CHECKOUT_OVERWRITE_NONE: No special options * @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES: When layering checkouts, overwrite earlier files, but keep earlier directories + * @OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES: Only add new files/directories */ typedef enum { OSTREE_REPO_CHECKOUT_OVERWRITE_NONE = 0, - OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES = 1 + OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES = 1, + OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES = 2, } OstreeRepoCheckoutOverwriteMode; _OSTREE_PUBLIC