mirror of
https://github.com/ostreedev/ostree.git
synced 2024-10-27 18:55:11 +03:00
Add support for deleting refs
The internal API will be used by admin, and "ostree refs --delete" is handy for interactive management.
This commit is contained in:
parent
5b3fca8426
commit
dc0f3c3dcb
@ -1757,6 +1757,42 @@ create_empty_gvariant_dict (void)
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_ref_to_set (const char *remote,
|
||||
GFile *base,
|
||||
GFile *child,
|
||||
GHashTable *refs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
char *contents;
|
||||
char *relpath;
|
||||
gsize len;
|
||||
GString *refname;
|
||||
|
||||
if (!g_file_load_contents (child, cancellable, &contents, &len, NULL, error))
|
||||
goto out;
|
||||
|
||||
g_strchomp (contents);
|
||||
|
||||
refname = g_string_new ("");
|
||||
if (remote)
|
||||
{
|
||||
g_string_append (refname, remote);
|
||||
g_string_append_c (refname, ':');
|
||||
}
|
||||
relpath = g_file_get_relative_path (base, child);
|
||||
g_string_append (refname, relpath);
|
||||
g_free (relpath);
|
||||
|
||||
g_hash_table_insert (refs, g_string_free (refname, FALSE), contents);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
enumerate_refs_recurse (OstreeRepo *repo,
|
||||
const char *remote,
|
||||
@ -1793,27 +1829,9 @@ enumerate_refs_recurse (OstreeRepo *repo,
|
||||
}
|
||||
else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
char *contents;
|
||||
char *relpath;
|
||||
gsize len;
|
||||
GString *refname;
|
||||
|
||||
if (!g_file_load_contents (child, cancellable, &contents, &len, NULL, error))
|
||||
if (!add_ref_to_set (remote, base, child, refs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_strchomp (contents);
|
||||
|
||||
refname = g_string_new ("");
|
||||
if (remote)
|
||||
{
|
||||
g_string_append (refname, remote);
|
||||
g_string_append_c (refname, ':');
|
||||
}
|
||||
relpath = g_file_get_relative_path (base, child);
|
||||
g_string_append (refname, relpath);
|
||||
g_free (relpath);
|
||||
|
||||
g_hash_table_insert (refs, g_string_free (refname, FALSE), contents);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1840,6 +1858,7 @@ ostree_repo_list_refs (OstreeRepo *repo,
|
||||
{
|
||||
gs_unref_object GFile *dir = NULL;
|
||||
gs_unref_object GFile *child = NULL;
|
||||
gs_unref_object GFileInfo *info = NULL;
|
||||
|
||||
if (!ostree_parse_refspec (refspec_prefix, &remote, &ref_prefix, error))
|
||||
goto out;
|
||||
@ -1850,11 +1869,26 @@ ostree_repo_list_refs (OstreeRepo *repo,
|
||||
dir = g_object_ref (repo->local_heads_dir);
|
||||
|
||||
child = g_file_resolve_relative_path (dir, ref_prefix);
|
||||
|
||||
if (!enumerate_refs_recurse (repo, remote, child, child,
|
||||
ret_all_refs,
|
||||
cancellable, error))
|
||||
if (!ot_gfile_query_info_allow_noent (child, OSTREE_GIO_FAST_QUERYINFO, 0,
|
||||
&info, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (info)
|
||||
{
|
||||
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
|
||||
{
|
||||
if (!enumerate_refs_recurse (repo, remote, child, child,
|
||||
ret_all_refs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!add_ref_to_set (remote, dir, child, ret_all_refs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1954,19 +1988,38 @@ ostree_repo_write_ref (OstreeRepo *self,
|
||||
else
|
||||
{
|
||||
dir = g_file_get_child (self->remote_heads_dir, remote);
|
||||
|
||||
if (!gs_file_ensure_directory (dir, FALSE, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (rev != NULL)
|
||||
{
|
||||
if (!gs_file_ensure_directory (dir, FALSE, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!write_checksum_file (dir, name, rev, error))
|
||||
goto out;
|
||||
|
||||
if (self->mode == OSTREE_REPO_MODE_ARCHIVE
|
||||
|| self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
|
||||
if (rev == NULL)
|
||||
{
|
||||
if (!write_ref_summary (self, NULL, error))
|
||||
gs_unref_object GFile *child = g_file_resolve_relative_path (dir, name);
|
||||
|
||||
if (g_file_query_exists (child, NULL))
|
||||
{
|
||||
if (!gs_file_unlink (child, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!write_checksum_file (dir, name, rev, error))
|
||||
goto out;
|
||||
|
||||
if (rev != NULL)
|
||||
{
|
||||
if (self->mode == OSTREE_REPO_MODE_ARCHIVE
|
||||
|| self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
|
||||
{
|
||||
if (!write_ref_summary (self, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
@ -26,7 +26,10 @@
|
||||
#include "ostree.h"
|
||||
#include "ostree-repo-file.h"
|
||||
|
||||
static gboolean opt_delete;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Delete refs which match PREFIX, rather than listing them", "PREFIX" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -41,9 +44,8 @@ ostree_builtin_refs (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
gs_unref_hashtable GHashTable *refs = NULL;
|
||||
GHashTableIter hashiter;
|
||||
gpointer hashkey, hashvalue;
|
||||
guint i;
|
||||
|
||||
context = g_option_context_new ("[PREFIX...] - List refs");
|
||||
context = g_option_context_new ("[PREFIX] - List refs");
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
|
||||
if (!g_option_context_parse (context, &argc, &argv, error))
|
||||
@ -60,11 +62,24 @@ ostree_builtin_refs (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_hash_table_iter_init (&hashiter, refs);
|
||||
while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
|
||||
if (!opt_delete)
|
||||
{
|
||||
const char *ref = hashkey;
|
||||
g_print ("%s\n", ref);
|
||||
g_hash_table_iter_init (&hashiter, refs);
|
||||
while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
|
||||
{
|
||||
const char *ref = hashkey;
|
||||
g_print ("%s\n", ref);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_iter_init (&hashiter, refs);
|
||||
while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
|
||||
{
|
||||
const char *refspec = hashkey;
|
||||
if (!ostree_repo_write_refspec (repo, refspec, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
@ -44,6 +44,12 @@ assert_not_has_file () {
|
||||
fi
|
||||
}
|
||||
|
||||
assert_not_file_has_content () {
|
||||
if grep -q -e "$2" "$1"; then
|
||||
echo 1>&2 "File '$1' incorrectly matches regexp '$2'"; exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_file_has_content () {
|
||||
if ! grep -q -e "$2" "$1"; then
|
||||
echo 1>&2 "File '$1' doesn't match regexp '$2'"; exit 1
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "1..33"
|
||||
echo "1..34"
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
@ -244,3 +244,13 @@ fi
|
||||
rm repo3 objlist-before-prune objlist-after-prune -rf
|
||||
echo "ok prune"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
$OSTREE commit -b test3 -s "Another commit" --tree=ref=test2
|
||||
ostree --repo=repo refs > reflist
|
||||
assert_file_has_content reflist '^test3$'
|
||||
ostree --repo=repo refs --delete test3
|
||||
ostree --repo=repo refs > reflist
|
||||
assert_not_file_has_content reflist '^test3$'
|
||||
echo "ok reflist --delete"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user