static char **opt_metadata_strings;
static char **opt_metadata_variants;
static char **opt_detached_metadata_strings;
+static char **opt_metadata_keep;
static gboolean opt_link_checkout_speedup;
static gboolean opt_skip_if_unchanged;
static gboolean opt_tar_autocreate_parents;
{ "tree", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_trees, "Overlay the given argument as a tree", "dir=PATH or tar=TARFILE or ref=COMMIT" },
{ "add-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_strings, "Add a key/value pair to metadata", "KEY=VALUE" },
{ "add-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_variants, "Add a key/value pair to metadata, where the KEY is a string, an VALUE is g_variant_parse() formatted", "KEY=VALUE" },
+ { "keep-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_keep, "Keep metadata KEY and its associated VALUE from parent", "KEY" },
{ "add-detached-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_detached_metadata_strings, "Add a key/value pair to detached metadata", "KEY=VALUE" },
{ "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Set file ownership user id", "UID" },
{ "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Set file ownership group id", "GID" },
}
}
- if (opt_metadata_strings || opt_metadata_variants)
+ if (!parent && opt_metadata_keep)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Either --branch or --parent must be specified when using "
+ "--keep-metadata");
+ goto out;
+ }
+
+ if (opt_metadata_strings || opt_metadata_variants || opt_metadata_keep)
{
g_autoptr(GVariantBuilder) builder =
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
!parse_keyvalue_strings (builder, opt_metadata_variants, TRUE, error))
goto out;
+ if (opt_metadata_keep)
+ {
+ g_assert (parent);
+
+ g_autoptr(GVariant) parent_commit = NULL;
+ if (!ostree_repo_load_commit (repo, parent, &parent_commit, NULL, error))
+ goto out;
+
+ g_auto(GVariantDict) dict;
+ g_variant_dict_init (&dict, g_variant_get_child_value (parent_commit, 0));
+ for (char **keyp = opt_metadata_keep; keyp && *keyp; keyp++)
+ {
+ const char *key = *keyp;
+ g_autoptr(GVariant) val = g_variant_dict_lookup_value (&dict, key, NULL);
+ if (!val)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Missing metadata key '%s' from commit '%s'", key, parent);
+ goto out;
+ }
+
+ g_variant_builder_add (builder, "{sv}", key, val);
+ }
+ }
+
metadata = g_variant_ref_sink (g_variant_builder_end (builder));
}
set -euo pipefail
-echo "1..$((78 + ${extra_basic_tests:-0}))"
+echo "1..$((79 + ${extra_basic_tests:-0}))"
CHECKOUT_U_ARG=""
CHECKOUT_H_ARGS="-H"
assert_file_has_content test2-meta "HANCOCK"
echo "ok metadata commit with strings"
+$OSTREE commit ${COMMIT_ARGS} -b test2 --tree=ref=test2 \
+ --add-detached-metadata-string=SIGNATURE=HANCOCK \
+ --keep-metadata=KITTENS --keep-metadata=SOMENUM
+if $OSTREE show --print-metadata-key=FOO test2; then
+ assert_not_reached "FOO was kept without explicit --keep-metadata?"
+fi
+$OSTREE show --print-metadata-key=KITTENS test2 > test2-meta
+assert_file_has_content test2-meta "CUTE"
+$OSTREE show -B --print-metadata-key=SOMENUM test2 > test2-meta
+assert_file_has_content test2-meta "uint64 42"
+echo "ok keep metadata from parent"
+
cd ${test_tmpdir}
$OSTREE show --print-metadata-key=ostree.ref-binding test2 > test2-ref-binding
assert_file_has_content test2-ref-binding 'test2'