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_ref
ostree_diff_item_unref ostree_diff_item_unref
ostree_diff_dirs ostree_diff_dirs
ostree_diff_dirs_with_options
ostree_diff_print ostree_diff_print
<SUBSECTION Standard> <SUBSECTION Standard>
ostree_diff_item_get_type ostree_diff_item_get_type

View File

@ -78,6 +78,20 @@ Boston, MA 02111-1307, USA.
Print filesystem diff. Print filesystem diff.
</para></listitem> </para></listitem>
</varlistentry> </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> </variablelist>
</refsect1> </refsect1>

View File

@ -389,6 +389,7 @@ global:
LIBOSTREE_2017.4 { LIBOSTREE_2017.4 {
global: global:
ostree_check_version; ostree_check_version;
ostree_diff_dirs_with_options;
} LIBOSTREE_2017.3; } LIBOSTREE_2017.3;
/* Stub section for the stable release *after* this development one; don't /* 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, GPtrArray *added,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) 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; gboolean ret = FALSE;
GError *temp_error = NULL; GError *temp_error = NULL;
@ -233,6 +264,10 @@ ostree_diff_dirs (OstreeDiffFlags flags,
g_autoptr(GFile) child_b = NULL; g_autoptr(GFile) child_b = NULL;
g_autoptr(GFileInfo) child_a_info = NULL; g_autoptr(GFileInfo) child_a_info = NULL;
g_autoptr(GFileInfo) child_b_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) if (a == NULL)
{ {
@ -316,6 +351,11 @@ ostree_diff_dirs (OstreeDiffFlags flags,
} }
else 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); child_b_type = g_file_info_get_file_type (child_b_info);
if (child_a_type != child_b_type) 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 (child_a_type == G_FILE_TYPE_DIRECTORY)
{ {
if (!ostree_diff_dirs (flags, child_a, child_b, modified, if (!ostree_diff_dirs_with_options (flags, child_a, child_b, modified,
removed, added, cancellable, error)) removed, added, options,
cancellable, error))
goto out; goto out;
} }
} }

View File

@ -71,6 +71,42 @@ gboolean ostree_diff_dirs (OstreeDiffFlags flags,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); 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 _OSTREE_PUBLIC
void ostree_diff_print (GFile *a, void ostree_diff_print (GFile *a,
GFile *b, GFile *b,

View File

@ -30,11 +30,15 @@
static gboolean opt_stats; static gboolean opt_stats;
static gboolean opt_fs_diff; static gboolean opt_fs_diff;
static gboolean opt_no_xattrs; static gboolean opt_no_xattrs;
static gint opt_owner_uid = -1;
static gint opt_owner_gid = -1;
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL }, { "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 }, { "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 }, { "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 } { 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); 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); removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
added = 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; goto out;
ostree_diff_print (srcf, targetf, modified, removed, added); ostree_diff_print (srcf, targetf, modified, removed, added);

View File

@ -19,7 +19,7 @@
set -euo pipefail set -euo pipefail
echo "1..63" echo "1..65"
$CMD_PREFIX ostree --version > version.yaml $CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("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$' assert_file_has_content diff-test2-2 'A *oh-look-a-file$'
echo "ok diff cwd" 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 cd ${test_tmpdir}/checkout-test2-4
rm four rm four
mkdir four mkdir four