checkout: Support --union-identical and --force-copy{,--zerosized}
Actually testing the patch to add `--force-copy-zerosized` to rpm-ostree tripped over the fact that it uses `--union-identical`, and we just hit an assertion failure with that combination. Fix this by copying over the logic we have for the hardlink case. Closes: #1753 Approved by: jlebon
This commit is contained in:
parent
673cacd633
commit
9367a1befe
|
|
@ -196,6 +196,7 @@ static gboolean
|
||||||
create_file_copy_from_input_at (OstreeRepo *repo,
|
create_file_copy_from_input_at (OstreeRepo *repo,
|
||||||
OstreeRepoCheckoutAtOptions *options,
|
OstreeRepoCheckoutAtOptions *options,
|
||||||
CheckoutState *state,
|
CheckoutState *state,
|
||||||
|
const char *checksum,
|
||||||
GFileInfo *file_info,
|
GFileInfo *file_info,
|
||||||
GVariant *xattrs,
|
GVariant *xattrs,
|
||||||
GInputStream *input,
|
GInputStream *input,
|
||||||
|
|
@ -358,8 +359,35 @@ create_file_copy_from_input_at (OstreeRepo *repo,
|
||||||
replace_mode = GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST;
|
replace_mode = GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST;
|
||||||
break;
|
break;
|
||||||
case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL:
|
case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL:
|
||||||
/* We don't support copying in union identical */
|
{
|
||||||
g_assert_not_reached ();
|
replace_mode = GLNX_LINK_TMPFILE_NOREPLACE;
|
||||||
|
struct stat dest_stbuf;
|
||||||
|
if (!glnx_fstatat_allow_noent (destination_dfd, destination_name, &dest_stbuf,
|
||||||
|
AT_SYMLINK_NOFOLLOW, error))
|
||||||
|
return FALSE;
|
||||||
|
if (errno == 0)
|
||||||
|
{
|
||||||
|
/* We do a checksum comparison; see also equivalent code in
|
||||||
|
* checkout_file_hardlink().
|
||||||
|
*/
|
||||||
|
OstreeChecksumFlags flags = 0;
|
||||||
|
if (repo->disable_xattrs)
|
||||||
|
flags |= OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS;
|
||||||
|
|
||||||
|
g_autofree char *actual_checksum = NULL;
|
||||||
|
if (!ostree_checksum_file_at (destination_dfd, destination_name,
|
||||||
|
&dest_stbuf, OSTREE_OBJECT_TYPE_FILE,
|
||||||
|
flags, &actual_checksum, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (g_str_equal (checksum, actual_checksum))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Otherwise, fall through and do the link, we should
|
||||||
|
* get EEXIST.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -773,7 +801,7 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!create_file_copy_from_input_at (repo, options, state, source_info, xattrs, input,
|
if (!create_file_copy_from_input_at (repo, options, state, checksum, source_info, xattrs, input,
|
||||||
destination_dfd, destination_name,
|
destination_dfd, destination_name,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
return glnx_prefix_error (error, "Copy checkout of %s to %s", checksum, destination_name);
|
return glnx_prefix_error (error, "Copy checkout of %s to %s", checksum, destination_name);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "1..$((84 + ${extra_basic_tests:-0}))"
|
echo "1..$((85 + ${extra_basic_tests:-0}))"
|
||||||
|
|
||||||
CHECKOUT_U_ARG=""
|
CHECKOUT_U_ARG=""
|
||||||
CHECKOUT_H_ARGS="-H"
|
CHECKOUT_H_ARGS="-H"
|
||||||
|
|
@ -709,6 +709,20 @@ assert_files_hardlinked tree-with-empty-files/an{,other}emptyfile
|
||||||
rm tree-with-empty-files -rf
|
rm tree-with-empty-files -rf
|
||||||
echo "ok checkout --force-copy-zerosized"
|
echo "ok checkout --force-copy-zerosized"
|
||||||
|
|
||||||
|
# These should merge, they're identical
|
||||||
|
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
|
||||||
|
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
|
||||||
|
echo notempty > tree-with-empty-files/anemptyfile.new && mv tree-with-empty-files/anemptyfile{.new,}
|
||||||
|
$CMD_PREFIX ostree --repo=repo commit --consume -b tree-with-conflicting-empty-files --tree=dir=tree-with-empty-files
|
||||||
|
# Reset back to base
|
||||||
|
rm tree-with-empty-files -rf
|
||||||
|
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
|
||||||
|
if $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-conflicting-empty-files tree-with-empty-files 2>err.txt; then
|
||||||
|
fatal "--union-identical --force-copy-zerosized unexpectedly succeeded with non-identical files"
|
||||||
|
fi
|
||||||
|
assert_file_has_content err.txt 'error:.*File exists'
|
||||||
|
echo "ok checkout --union-identical --force-copy-zerosized"
|
||||||
|
|
||||||
cd ${test_tmpdir}
|
cd ${test_tmpdir}
|
||||||
rm files -rf && mkdir files
|
rm files -rf && mkdir files
|
||||||
mkdir files/worldwritable-dir
|
mkdir files/worldwritable-dir
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue