prune: Add option to traverse refs only
The previous code (unintentionally) only traversed from refs; so data only reachable from previous commits would be deleted. That shouldn't be the default, but we do want to offer it as an option. So add a --refs-only option.
This commit is contained in:
parent
51b1dd7cbd
commit
7861b98673
|
|
@ -29,27 +29,31 @@
|
||||||
#include <glib/gprintf.h>
|
#include <glib/gprintf.h>
|
||||||
|
|
||||||
static gboolean opt_no_prune;
|
static gboolean opt_no_prune;
|
||||||
static int opt_depth = -1;
|
static gint opt_depth = -1;
|
||||||
|
static gboolean opt_refs_only;
|
||||||
|
|
||||||
static GOptionEntry options[] = {
|
static GOptionEntry options[] = {
|
||||||
{ "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Only traverse commit objects by this count", NULL },
|
|
||||||
{ "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Only display unreachable objects; don't delete", NULL },
|
{ "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Only display unreachable objects; don't delete", NULL },
|
||||||
|
{ "refs-only", 0, 0, G_OPTION_ARG_NONE, &opt_refs_only, "Only compute reachability via refs", NULL },
|
||||||
|
{ "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Only traverse DEPTH parents for each commit (default: -1=infinite)", "DEPTH" },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
OstreeRepo *repo;
|
OstreeRepo *repo;
|
||||||
GHashTable *reachable;
|
GHashTable *reachable;
|
||||||
guint n_reachable;
|
guint n_reachable_meta;
|
||||||
guint n_unreachable;
|
guint n_reachable_content;
|
||||||
|
guint n_unreachable_meta;
|
||||||
|
guint n_unreachable_content;
|
||||||
} OtPruneData;
|
} OtPruneData;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
prune_loose_object (OtPruneData *data,
|
maybe_prune_loose_object (OtPruneData *data,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
ot_lvariant GVariant *key = NULL;
|
ot_lvariant GVariant *key = NULL;
|
||||||
|
|
@ -66,10 +70,18 @@ prune_loose_object (OtPruneData *data,
|
||||||
if (!ot_gfile_unlink (objf, cancellable, error))
|
if (!ot_gfile_unlink (objf, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
data->n_unreachable++;
|
if (OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||||
|
data->n_unreachable_meta++;
|
||||||
|
else
|
||||||
|
data->n_unreachable_content++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
data->n_reachable++;
|
{
|
||||||
|
if (OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||||
|
data->n_reachable_meta++;
|
||||||
|
else
|
||||||
|
data->n_reachable_content++;
|
||||||
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
|
@ -103,28 +115,47 @@ ostree_builtin_prune (int argc, char **argv, GFile *repo_path, GError **error)
|
||||||
|
|
||||||
data.repo = repo;
|
data.repo = repo;
|
||||||
data.reachable = ostree_traverse_new_reachable ();
|
data.reachable = ostree_traverse_new_reachable ();
|
||||||
data.n_reachable = 0;
|
|
||||||
data.n_unreachable = 0;
|
|
||||||
|
|
||||||
if (!ostree_repo_list_all_refs (repo, &all_refs, cancellable, error))
|
if (opt_refs_only)
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&hash_iter, all_refs);
|
|
||||||
|
|
||||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
|
||||||
{
|
{
|
||||||
const char *checksum = value;
|
if (!ostree_repo_list_all_refs (repo, &all_refs, cancellable, error))
|
||||||
|
|
||||||
// g_print ("Computing reachable, currently %u total, from %s: %s\n", g_hash_table_size (data.reachable), name, checksum);
|
|
||||||
if (!ostree_traverse_commit (repo, checksum, opt_depth, data.reachable, cancellable, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&hash_iter, all_refs);
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||||
|
{
|
||||||
|
const char *checksum = value;
|
||||||
|
|
||||||
|
// g_print ("Computing reachable, currently %u total, from %s: %s\n", g_hash_table_size (data.reachable), name, checksum);
|
||||||
|
if (!ostree_traverse_commit (repo, checksum, opt_depth, data.reachable, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects, cancellable, error))
|
if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
g_hash_table_iter_init (&hash_iter, objects);
|
if (!opt_refs_only)
|
||||||
|
{
|
||||||
|
g_hash_table_iter_init (&hash_iter, objects);
|
||||||
|
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||||
|
{
|
||||||
|
GVariant *serialized_key = key;
|
||||||
|
const char *checksum;
|
||||||
|
OstreeObjectType objtype;
|
||||||
|
|
||||||
|
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
||||||
|
|
||||||
|
if (objtype != OSTREE_OBJECT_TYPE_COMMIT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ostree_traverse_commit (repo, checksum, opt_depth, data.reachable, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&hash_iter, objects);
|
||||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||||
{
|
{
|
||||||
GVariant *serialized_key = key;
|
GVariant *serialized_key = key;
|
||||||
|
|
@ -132,20 +163,21 @@ ostree_builtin_prune (int argc, char **argv, GFile *repo_path, GError **error)
|
||||||
const char *checksum;
|
const char *checksum;
|
||||||
OstreeObjectType objtype;
|
OstreeObjectType objtype;
|
||||||
gboolean is_loose;
|
gboolean is_loose;
|
||||||
|
|
||||||
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
||||||
|
|
||||||
g_variant_get_child (objdata, 0, "b", &is_loose);
|
g_variant_get_child (objdata, 0, "b", &is_loose);
|
||||||
|
|
||||||
if (is_loose)
|
if (!is_loose)
|
||||||
{
|
continue;
|
||||||
if (!prune_loose_object (&data, checksum, objtype, cancellable, error))
|
|
||||||
goto out;
|
if (!maybe_prune_loose_object (&data, checksum, objtype, cancellable, error))
|
||||||
}
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("Total reachable: %u\n", data.n_reachable);
|
g_print ("Total reachable: %u meta, %u content\n",
|
||||||
g_print ("Total unreachable: %u\n", data.n_unreachable);
|
data.n_reachable_meta, data.n_reachable_content);
|
||||||
|
g_print ("Total unreachable: %u meta, %u content\n",
|
||||||
|
data.n_unreachable_meta, data.n_unreachable_content);
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue