diff: Add --stats option
This a neat way to see how many objects are shared between two commits.
This commit is contained in:
parent
a3b6401788
commit
1b3ef57cf4
|
|
@ -25,7 +25,12 @@
|
||||||
#include "ot-builtins.h"
|
#include "ot-builtins.h"
|
||||||
#include "ostree.h"
|
#include "ostree.h"
|
||||||
|
|
||||||
|
static gboolean opt_stats;
|
||||||
|
static gboolean opt_fs_diff;
|
||||||
|
|
||||||
static GOptionEntry options[] = {
|
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 },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -57,6 +62,61 @@ parse_file_or_commit (OstreeRepo *repo,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GHashTable *
|
||||||
|
reachable_set_intersect (GHashTable *a, GHashTable *b)
|
||||||
|
{
|
||||||
|
GHashTable *ret = ostree_repo_traverse_new_reachable ();
|
||||||
|
GHashTableIter hashiter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&hashiter, a);
|
||||||
|
while (g_hash_table_iter_next (&hashiter, &key, &value))
|
||||||
|
{
|
||||||
|
GVariant *v = key;
|
||||||
|
if (g_hash_table_contains (b, v))
|
||||||
|
g_hash_table_insert (ret, g_variant_ref (v), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
object_set_total_size (OstreeRepo *repo,
|
||||||
|
GHashTable *reachable,
|
||||||
|
guint64 *out_total,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
GHashTableIter hashiter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
*out_total = 0;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&hashiter, reachable);
|
||||||
|
while (g_hash_table_iter_next (&hashiter, &key, &value))
|
||||||
|
{
|
||||||
|
GVariant *v = key;
|
||||||
|
const char *csum;
|
||||||
|
OstreeObjectType objtype;
|
||||||
|
gs_unref_object GFile *objpath = NULL;
|
||||||
|
gs_unref_object GFileInfo *finfo = NULL;
|
||||||
|
|
||||||
|
ostree_object_name_deserialize (v, &csum, &objtype);
|
||||||
|
objpath = ostree_repo_get_object_path (repo, csum, objtype);
|
||||||
|
finfo = g_file_query_info (objpath, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||||
|
cancellable, error);
|
||||||
|
if (!finfo)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*out_total += g_file_info_get_size (finfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *cancellable, GError **error)
|
ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *cancellable, GError **error)
|
||||||
{
|
{
|
||||||
|
|
@ -68,7 +128,6 @@ ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *canc
|
||||||
gs_free char *src_prev = NULL;
|
gs_free char *src_prev = NULL;
|
||||||
gs_unref_object GFile *srcf = NULL;
|
gs_unref_object GFile *srcf = NULL;
|
||||||
gs_unref_object GFile *targetf = NULL;
|
gs_unref_object GFile *targetf = NULL;
|
||||||
gs_unref_object GFile *cwd = NULL;
|
|
||||||
gs_unref_ptrarray GPtrArray *modified = NULL;
|
gs_unref_ptrarray GPtrArray *modified = NULL;
|
||||||
gs_unref_ptrarray GPtrArray *removed = NULL;
|
gs_unref_ptrarray GPtrArray *removed = NULL;
|
||||||
gs_unref_ptrarray GPtrArray *added = NULL;
|
gs_unref_ptrarray GPtrArray *added = NULL;
|
||||||
|
|
@ -105,21 +164,63 @@ ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *canc
|
||||||
target = argv[2];
|
target = argv[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
cwd = g_file_new_for_path (".");
|
if (!opt_stats && !opt_fs_diff)
|
||||||
|
opt_fs_diff = TRUE;
|
||||||
|
|
||||||
if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
|
if (opt_fs_diff)
|
||||||
goto out;
|
{
|
||||||
if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
|
if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
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 (srcf, targetf, modified, removed, added, cancellable, error))
|
if (!ostree_diff_dirs (srcf, targetf, modified, removed, added, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ostree_diff_print (srcf, targetf, modified, removed, added);
|
ostree_diff_print (srcf, targetf, modified, removed, added);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_stats)
|
||||||
|
{
|
||||||
|
gs_unref_hashtable GHashTable *reachable_a = ostree_repo_traverse_new_reachable ();
|
||||||
|
gs_unref_hashtable GHashTable *reachable_b = ostree_repo_traverse_new_reachable ();
|
||||||
|
gs_unref_hashtable GHashTable *reachable_intersection = NULL;
|
||||||
|
gs_free char *rev_a = NULL;
|
||||||
|
gs_free char *rev_b = NULL;
|
||||||
|
gs_free char *size = NULL;
|
||||||
|
guint a_size;
|
||||||
|
guint b_size;
|
||||||
|
guint64 total_common;
|
||||||
|
|
||||||
|
if (!ostree_repo_resolve_rev (repo, src, FALSE, &rev_a, error))
|
||||||
|
goto out;
|
||||||
|
if (!ostree_repo_resolve_rev (repo, target, FALSE, &rev_b, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!ostree_repo_traverse_commit (repo, rev_a, -1, reachable_a, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
if (!ostree_repo_traverse_commit (repo, rev_b, -1, reachable_b, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
a_size = g_hash_table_size (reachable_a);
|
||||||
|
b_size = g_hash_table_size (reachable_b);
|
||||||
|
g_print ("[A] Object Count: %u\n", a_size);
|
||||||
|
g_print ("[B] Object Count: %u\n", b_size);
|
||||||
|
|
||||||
|
reachable_intersection = reachable_set_intersect (reachable_a, reachable_b);
|
||||||
|
|
||||||
|
g_print ("Common Object Count: %u\n", g_hash_table_size (reachable_intersection));
|
||||||
|
|
||||||
|
if (!object_set_total_size (repo, reachable_intersection, &total_common,
|
||||||
|
cancellable, error))
|
||||||
|
goto out;
|
||||||
|
size = g_format_size_full (total_common, 0);
|
||||||
|
g_print ("Common Object Size: %s\n", size);
|
||||||
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue