diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index f506545529..650604446d 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -1062,6 +1062,22 @@ checkout_tree_at_recurse (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options if (!glnx_shutil_rm_rf_at (destination_parent_fd, destination_name, cancellable, error)) return FALSE; } + else if (options->process_whiteouts + && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES) + { + /* In this mode, we're flattening in a manner similar to overlayfs, so ensure + * any non-directory content there is gone. / + */ + struct stat stbuf; + if (!glnx_fstatat_allow_noent (destination_parent_fd, destination_name, &stbuf, + AT_SYMLINK_NOFOLLOW, error)) + return FALSE; + if (errno == 0 && !S_ISDIR (stbuf.st_mode)) + { + if (!glnx_shutil_rm_rf_at (destination_parent_fd, destination_name, cancellable, error)) + return FALSE; + } + } /* Create initially with mode 0700, then chown/chmod only when we're * done. This avoids anyone else being able to operate on partially diff --git a/tests/basic-test.sh b/tests/basic-test.sh index 7905e6ee68..c8f853f8d6 100644 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -1159,6 +1159,18 @@ if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper && touch overlay/baz/an assert_has_file overlay-co/baz test -L overlay-co/anewdir + rm overlay-co overlay -rf + mkdir -p overlay/somelink overlay/yet/ovlnewdir + echo ovlnewf > overlay/yet/ovlnewdir/ovlnewf + $OSTREE --repo=repo commit ${COMMIT_ARGS} -b overlay-symlink-convert --tree=dir=overlay + for branch in test2 overlay-symlink-convert; do + $OSTREE --repo=repo checkout --union --whiteouts ${branch} overlay-co + done + test -d overlay-co/somelink || fatal "should replace symlink with dir" + assert_has_dir overlay-co/yet/another + assert_has_dir overlay-co/yet/ovlnewdir + assert_file_has_content overlay-co/yet/ovlnewdir/ovlnewf ovlnewf + rm overlay-co overlay -rf echo "ok whiteouts enabled" # Now double check whiteouts are not processed without --whiteouts