diff: Add ostree_diff_dirs_with_options(), expose via cmdline

The first options are owner_uid/owner_gid, which makes it possible to use diff
on local files where --owner-uid/gid have been passed to commit.

Closes: #740
Approved by: cgwalters
This commit is contained in:
Erik Larsson 2017-02-08 21:59:38 +01:00 committed by Atomic Bot
parent 5d413dff88
commit e665e51408
7 changed files with 119 additions and 5 deletions

View File

@ -172,6 +172,7 @@ OstreeDiffItem
ostree_diff_item_ref
ostree_diff_item_unref
ostree_diff_dirs
ostree_diff_dirs_with_options
ostree_diff_print
<SUBSECTION Standard>
ostree_diff_item_get_type

View File

@ -78,6 +78,20 @@ Boston, MA 02111-1307, USA.
Print filesystem diff.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--owner-uid</option></term>
<listitem><para>
Use file ownership user id for local files.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--owner-gid</option></term>
<listitem><para>
Use file ownership group id for local files.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -389,6 +389,7 @@ global:
LIBOSTREE_2017.4 {
global:
ostree_check_version;
ostree_diff_dirs_with_options;
} LIBOSTREE_2017.3;
/* Stub section for the stable release *after* this development one; don't

View File

@ -225,6 +225,37 @@ ostree_diff_dirs (OstreeDiffFlags flags,
GPtrArray *added,
GCancellable *cancellable,
GError **error)
{
return ostree_diff_dirs_with_options (flags, a, b, modified,
removed, added, NULL,
cancellable, error);
}
/**
* ostree_diff_dirs_with_options:
* @flags: Flags
* @a: First directory path, or %NULL
* @b: First directory path
* @modified: (element-type OstreeDiffItem): Modified files
* @removed: (element-type Gio.File): Removed files
* @added: (element-type Gio.File): Added files
* @cancellable: Cancellable
* @options: (allow-none): Options
* @error: Error
*
* Compute the difference between directory @a and @b as 3 separate
* sets of #OstreeDiffItem in @modified, @removed, and @added.
*/
gboolean
ostree_diff_dirs_with_options (OstreeDiffFlags flags,
GFile *a,
GFile *b,
GPtrArray *modified,
GPtrArray *removed,
GPtrArray *added,
OstreeDiffDirsOptions *options,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
GError *temp_error = NULL;
@ -233,6 +264,10 @@ ostree_diff_dirs (OstreeDiffFlags flags,
g_autoptr(GFile) child_b = NULL;
g_autoptr(GFileInfo) child_a_info = NULL;
g_autoptr(GFileInfo) child_b_info = NULL;
OstreeDiffDirsOptions default_opts = OSTREE_DIFF_DIRS_OPTIONS_INIT;
if (!options)
options = &default_opts;
if (a == NULL)
{
@ -316,6 +351,11 @@ ostree_diff_dirs (OstreeDiffFlags flags,
}
else
{
if (options->owner_uid >= 0)
g_file_info_set_attribute_uint32 (child_b_info, "unix::uid", options->owner_uid);
if (options->owner_gid >= 0)
g_file_info_set_attribute_uint32 (child_b_info, "unix::gid", options->owner_gid);
child_b_type = g_file_info_get_file_type (child_b_info);
if (child_a_type != child_b_type)
{
@ -337,8 +377,9 @@ ostree_diff_dirs (OstreeDiffFlags flags,
if (child_a_type == G_FILE_TYPE_DIRECTORY)
{
if (!ostree_diff_dirs (flags, child_a, child_b, modified,
removed, added, cancellable, error))
if (!ostree_diff_dirs_with_options (flags, child_a, child_b, modified,
removed, added, options,
cancellable, error))
goto out;
}
}

View File

@ -71,6 +71,42 @@ gboolean ostree_diff_dirs (OstreeDiffFlags flags,
GCancellable *cancellable,
GError **error);
/**
* OstreeDiffDirsOptions:
*
* An extensible options structure controlling diff dirs. Make sure
* that owner_uid/gid is set to -1 when not used. This is used by
* ostree_diff_dirs_with_options().
*/
typedef struct {
gint owner_uid;
gint owner_gid;
OstreeRepoDevInoCache *devino_to_csum_cache;
gboolean unused_bools[7];
int unused_ints[6];
gpointer unused_ptrs[7];
} OstreeDiffDirsOptions;
/**
* OSTREE_DIFF_DIRS_OPTIONS_INIT:
*
* Use this to initialize an `OstreeDiffDirsOptions` structure.
*/
#define OSTREE_DIFF_DIRS_OPTIONS_INIT { .owner_uid = -1, .owner_gid = -1, }
_OSTREE_PUBLIC
gboolean ostree_diff_dirs_with_options (OstreeDiffFlags flags,
GFile *a,
GFile *b,
GPtrArray *modified,
GPtrArray *removed,
GPtrArray *added,
OstreeDiffDirsOptions *options,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
void ostree_diff_print (GFile *a,
GFile *b,

View File

@ -30,11 +30,15 @@
static gboolean opt_stats;
static gboolean opt_fs_diff;
static gboolean opt_no_xattrs;
static gint opt_owner_uid = -1;
static gint opt_owner_gid = -1;
static GOptionEntry options[] = {
{ "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL },
{ "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL },
{ "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL },
{ "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Use file ownership user id for local files", "UID" },
{ "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Use file ownership group id for local files", "GID" },
{ NULL }
};
@ -177,8 +181,10 @@ ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **
modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
if (!ostree_diff_dirs (diff_flags, srcf, targetf, modified, removed, added, cancellable, error))
OstreeDiffDirsOptions diff_opts = { opt_owner_uid, opt_owner_gid };
if (!ostree_diff_dirs_with_options (diff_flags, srcf, targetf, modified, removed,
added, &diff_opts, cancellable, error))
goto out;
ostree_diff_print (srcf, targetf, modified, removed, added);

View File

@ -19,7 +19,7 @@
set -euo pipefail
echo "1..63"
echo "1..65"
$CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
@ -171,6 +171,21 @@ cd ${test_tmpdir}
assert_file_has_content diff-test2-2 'A *oh-look-a-file$'
echo "ok diff cwd"
cd ${test_tmpdir}/checkout-test2-4
$OSTREE diff test2 ./ > ${test_tmpdir}/diff-test2
assert_file_empty ${test_tmpdir}/diff-test2
$OSTREE diff test2 --owner-uid=$((`id -u`+1)) ./ > ${test_tmpdir}/diff-test2
assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet$'
assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/message$'
assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/another/tree/green$'
echo "ok diff file with different uid"
$OSTREE diff test2 --owner-gid=$((`id -g`+1)) ./ > ${test_tmpdir}/diff-test2
assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet$'
assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/message$'
assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/another/tree/green$'
echo "ok diff file with different gid"
cd ${test_tmpdir}/checkout-test2-4
rm four
mkdir four