ot-builtin-commit.c: add --skip-list option
This was already supported by the commit modifier API, just needed to expose it. This will also be used to test the libarchive API in a future test. Closes: #275 Approved by: cgwalters
This commit is contained in:
parent
b1d3dd151c
commit
b717fd2c18
|
|
@ -72,7 +72,6 @@ test_scripts = \
|
||||||
tests/test-repo-checkout-subpath.sh \
|
tests/test-repo-checkout-subpath.sh \
|
||||||
tests/test-reset-nonlinear.sh \
|
tests/test-reset-nonlinear.sh \
|
||||||
tests/test-oldstyle-partial.sh \
|
tests/test-oldstyle-partial.sh \
|
||||||
tests/test-setuid.sh \
|
|
||||||
tests/test-delta.sh \
|
tests/test-delta.sh \
|
||||||
tests/test-xattrs.sh \
|
tests/test-xattrs.sh \
|
||||||
tests/test-auto-summary.sh \
|
tests/test-auto-summary.sh \
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,15 @@ Boston, MA 02111-1307, USA.
|
||||||
<term><option>--statoverride</option>="PATH"</term>
|
<term><option>--statoverride</option>="PATH"</term>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
File containing list of modifications to make permissions.
|
File containing list of modifications to make permissions (file mode, followed by space, followed by file path).
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--skip-list</option>="PATH"</term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
File containing list of file paths to skip (one path per line).
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ static char *opt_parent;
|
||||||
static gboolean opt_orphan;
|
static gboolean opt_orphan;
|
||||||
static char *opt_branch;
|
static char *opt_branch;
|
||||||
static char *opt_statoverride_file;
|
static char *opt_statoverride_file;
|
||||||
|
static char *opt_skiplist_file;
|
||||||
static char **opt_metadata_strings;
|
static char **opt_metadata_strings;
|
||||||
static char **opt_detached_metadata_strings;
|
static char **opt_detached_metadata_strings;
|
||||||
static gboolean opt_link_checkout_speedup;
|
static gboolean opt_link_checkout_speedup;
|
||||||
|
|
@ -84,6 +85,7 @@ static GOptionEntry options[] = {
|
||||||
{ "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
|
{ "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
|
||||||
{ "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
|
{ "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
|
||||||
{ "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &opt_statoverride_file, "File containing list of modifications to make to permissions", "PATH" },
|
{ "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &opt_statoverride_file, "File containing list of modifications to make to permissions", "PATH" },
|
||||||
|
{ "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "PATH" },
|
||||||
{ "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, "Output more information in a KEY: VALUE format", NULL },
|
{ "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, "Output more information in a KEY: VALUE format", NULL },
|
||||||
{ "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "GPG Key ID to sign the commit with", "KEY-ID"},
|
{ "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "GPG Key ID to sign the commit with", "KEY-ID"},
|
||||||
{ "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
|
{ "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
|
||||||
|
|
@ -95,65 +97,85 @@ static GOptionEntry options[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_statoverride_file (GHashTable **out_mode_add,
|
parse_file_by_line (const char *path,
|
||||||
|
gboolean (*cb)(const char*, void*, GError**),
|
||||||
|
void *cbdata,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gsize len;
|
|
||||||
char **iter = NULL; /* nofree */
|
|
||||||
g_autoptr(GHashTable) ret_hash = NULL;
|
|
||||||
g_autoptr(GFile) path = NULL;
|
|
||||||
g_autofree char *contents = NULL;
|
g_autofree char *contents = NULL;
|
||||||
|
g_autoptr(GFile) file = NULL;
|
||||||
char **lines = NULL;
|
char **lines = NULL;
|
||||||
|
|
||||||
path = g_file_new_for_path (opt_statoverride_file);
|
file = g_file_new_for_path (path);
|
||||||
|
if (!g_file_load_contents (file, cancellable, &contents, NULL, NULL, error))
|
||||||
if (!g_file_load_contents (path, cancellable, &contents, &len, NULL,
|
|
||||||
error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
||||||
lines = g_strsplit (contents, "\n", -1);
|
lines = g_strsplit (contents, "\n", -1);
|
||||||
|
for (char **iter = lines; iter && *iter; iter++)
|
||||||
for (iter = lines; iter && *iter; iter++)
|
|
||||||
{
|
{
|
||||||
const char *line = *iter;
|
/* skip empty lines at least */
|
||||||
|
if (**iter == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
if (*line == '+')
|
if (!cb (*iter, cbdata, error))
|
||||||
{
|
|
||||||
const char *spc;
|
|
||||||
guint mode_add;
|
|
||||||
|
|
||||||
spc = strchr (line + 1, ' ');
|
|
||||||
if (!spc)
|
|
||||||
{
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
||||||
"Malformed statoverride file");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode_add = (guint32)(gint32)g_ascii_strtod (line + 1, NULL);
|
|
||||||
g_hash_table_insert (ret_hash,
|
|
||||||
g_strdup (spc + 1),
|
|
||||||
GUINT_TO_POINTER((gint32)mode_add));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
ot_transfer_out_value (out_mode_add, &ret_hash);
|
out:
|
||||||
out:
|
|
||||||
g_strfreev (lines);
|
g_strfreev (lines);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_statoverride_line (const char *line,
|
||||||
|
void *data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GHashTable *files = data;
|
||||||
|
const char *spc;
|
||||||
|
guint mode_add;
|
||||||
|
|
||||||
|
spc = strchr (line, ' ');
|
||||||
|
if (spc == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Malformed statoverride file (no space found)");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode_add = (guint32)(gint32)g_ascii_strtod (line, NULL);
|
||||||
|
g_hash_table_insert (files, g_strdup (spc + 1),
|
||||||
|
GUINT_TO_POINTER((gint32)mode_add));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_skiplist_line (const char *line,
|
||||||
|
void *data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GHashTable *files = data;
|
||||||
|
g_hash_table_add (files, g_strdup (line));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CommitFilterData {
|
||||||
|
GHashTable *mode_adds;
|
||||||
|
GHashTable *skip_list;
|
||||||
|
};
|
||||||
|
|
||||||
static OstreeRepoCommitFilterResult
|
static OstreeRepoCommitFilterResult
|
||||||
commit_filter (OstreeRepo *self,
|
commit_filter (OstreeRepo *self,
|
||||||
const char *path,
|
const char *path,
|
||||||
GFileInfo *file_info,
|
GFileInfo *file_info,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GHashTable *mode_adds = user_data;
|
struct CommitFilterData *data = user_data;
|
||||||
|
GHashTable *mode_adds = data->mode_adds;
|
||||||
|
GHashTable *skip_list = data->skip_list;
|
||||||
gpointer value;
|
gpointer value;
|
||||||
|
|
||||||
if (opt_owner_uid >= 0)
|
if (opt_owner_uid >= 0)
|
||||||
|
|
@ -170,6 +192,12 @@ commit_filter (OstreeRepo *self,
|
||||||
g_hash_table_remove (mode_adds, path);
|
g_hash_table_remove (mode_adds, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_list && g_hash_table_contains (skip_list, path))
|
||||||
|
{
|
||||||
|
g_hash_table_remove (skip_list, path);
|
||||||
|
return OSTREE_REPO_COMMIT_FILTER_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
return OSTREE_REPO_COMMIT_FILTER_ALLOW;
|
return OSTREE_REPO_COMMIT_FILTER_ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,9 +338,11 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
||||||
glnx_unref_object OstreeMutableTree *mtree = NULL;
|
glnx_unref_object OstreeMutableTree *mtree = NULL;
|
||||||
g_autofree char *tree_type = NULL;
|
g_autofree char *tree_type = NULL;
|
||||||
g_autoptr(GHashTable) mode_adds = NULL;
|
g_autoptr(GHashTable) mode_adds = NULL;
|
||||||
|
g_autoptr(GHashTable) skip_list = NULL;
|
||||||
OstreeRepoCommitModifierFlags flags = 0;
|
OstreeRepoCommitModifierFlags flags = 0;
|
||||||
OstreeRepoCommitModifier *modifier = NULL;
|
OstreeRepoCommitModifier *modifier = NULL;
|
||||||
OstreeRepoTransactionStats stats;
|
OstreeRepoTransactionStats stats;
|
||||||
|
struct CommitFilterData filter_data = { 0, };
|
||||||
|
|
||||||
context = g_option_context_new ("[PATH] - Commit a new revision");
|
context = g_option_context_new ("[PATH] - Commit a new revision");
|
||||||
|
|
||||||
|
|
@ -324,7 +354,17 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
||||||
|
|
||||||
if (opt_statoverride_file)
|
if (opt_statoverride_file)
|
||||||
{
|
{
|
||||||
if (!parse_statoverride_file (&mode_adds, cancellable, error))
|
mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
if (!parse_file_by_line (opt_statoverride_file, handle_statoverride_line,
|
||||||
|
mode_adds, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_skiplist_file)
|
||||||
|
{
|
||||||
|
skip_list = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
if (!parse_file_by_line (opt_skiplist_file, handle_skiplist_line,
|
||||||
|
skip_list, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,9 +399,13 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
||||||
|| opt_owner_uid >= 0
|
|| opt_owner_uid >= 0
|
||||||
|| opt_owner_gid >= 0
|
|| opt_owner_gid >= 0
|
||||||
|| opt_statoverride_file != NULL
|
|| opt_statoverride_file != NULL
|
||||||
|
|| opt_skiplist_file != NULL
|
||||||
|| opt_no_xattrs)
|
|| opt_no_xattrs)
|
||||||
{
|
{
|
||||||
modifier = ostree_repo_commit_modifier_new (flags, commit_filter, mode_adds, NULL);
|
filter_data.mode_adds = mode_adds;
|
||||||
|
filter_data.skip_list = skip_list;
|
||||||
|
modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
|
||||||
|
&filter_data, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_parent)
|
if (opt_parent)
|
||||||
|
|
@ -491,6 +535,22 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_list && g_hash_table_size (skip_list) > 0)
|
||||||
|
{
|
||||||
|
GHashTableIter hash_iter;
|
||||||
|
gpointer key;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&hash_iter, skip_list);
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next (&hash_iter, &key, NULL))
|
||||||
|
{
|
||||||
|
g_printerr ("Unmatched skip-list path: %s\n", (char*)key);
|
||||||
|
}
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Unmatched skip-list paths");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
|
if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "1..54"
|
echo "1..55"
|
||||||
|
|
||||||
$OSTREE checkout test2 checkout-test2
|
$OSTREE checkout test2 checkout-test2
|
||||||
echo "ok checkout"
|
echo "ok checkout"
|
||||||
|
|
@ -179,13 +179,31 @@ cd ${test_tmpdir}/checkout-test2-4
|
||||||
$OSTREE commit -b test2 -s "no xattrs" --no-xattrs
|
$OSTREE commit -b test2 -s "no xattrs" --no-xattrs
|
||||||
echo "ok commit with no xattrs"
|
echo "ok commit with no xattrs"
|
||||||
|
|
||||||
|
# NB: The + is optional, but we need to make sure we support it
|
||||||
cd ${test_tmpdir}
|
cd ${test_tmpdir}
|
||||||
cat > test-statoverride.txt <<EOF
|
cat > test-statoverride.txt <<EOF
|
||||||
+2048 /a/nested/3
|
+1048 /a/nested/2
|
||||||
|
2048 /a/nested/3
|
||||||
EOF
|
EOF
|
||||||
cd ${test_tmpdir}/checkout-test2-4
|
cd ${test_tmpdir}/checkout-test2-4
|
||||||
$OSTREE commit -b test2 -s "with statoverride" --statoverride=../test-statoverride.txt
|
$OSTREE commit -b test2-override -s "with statoverride" --statoverride=../test-statoverride.txt
|
||||||
echo "ok commit statoverridde"
|
cd ${test_tmpdir}
|
||||||
|
$OSTREE checkout test2-override checkout-test2-override
|
||||||
|
test -g checkout-test2-override/a/nested/2
|
||||||
|
test -u checkout-test2-override/a/nested/3
|
||||||
|
echo "ok commit statoverride"
|
||||||
|
|
||||||
|
cd ${test_tmpdir}
|
||||||
|
cat > test-skiplist.txt <<EOF
|
||||||
|
/a/nested/3
|
||||||
|
EOF
|
||||||
|
cd ${test_tmpdir}/checkout-test2-4
|
||||||
|
assert_has_file a/nested/3
|
||||||
|
$OSTREE commit -b test2-skiplist -s "with skiplist" --skip-list=../test-skiplist.txt
|
||||||
|
cd ${test_tmpdir}
|
||||||
|
$OSTREE checkout test2-skiplist checkout-test2-skiplist
|
||||||
|
assert_not_has_file checkout-test2-skiplist/a/nested/3
|
||||||
|
echo "ok commit skiplist"
|
||||||
|
|
||||||
cd ${test_tmpdir}
|
cd ${test_tmpdir}
|
||||||
$OSTREE prune
|
$OSTREE prune
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
|
||||||
#
|
|
||||||
# This library is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
|
||||||
# License as published by the Free Software Foundation; either
|
|
||||||
# version 2 of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This library is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public
|
|
||||||
# License along with this library; if not, write to the
|
|
||||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
# Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
echo "1..1"
|
|
||||||
|
|
||||||
. $(dirname $0)/libtest.sh
|
|
||||||
|
|
||||||
setup_test_repository "bare"
|
|
||||||
|
|
||||||
cd ${test_tmpdir}
|
|
||||||
cat > test-statoverride.txt <<EOF
|
|
||||||
+2048 /abinary
|
|
||||||
EOF
|
|
||||||
$OSTREE checkout test2 test2-checkout
|
|
||||||
touch test2-checkout/abinary
|
|
||||||
chmod a+x test2-checkout/abinary
|
|
||||||
(cd test2-checkout && $OSTREE commit -b test2 -s "with statoverride" --statoverride=../test-statoverride.txt)
|
|
||||||
rm -rf test2-checkout
|
|
||||||
$OSTREE checkout test2 test2-checkout
|
|
||||||
test -u test2-checkout/abinary
|
|
||||||
|
|
||||||
echo "ok"
|
|
||||||
Loading…
Reference in New Issue