diff --git a/man/ostree-rev-parse.xml b/man/ostree-rev-parse.xml index 74c585fd..f39868a6 100644 --- a/man/ostree-rev-parse.xml +++ b/man/ostree-rev-parse.xml @@ -54,6 +54,19 @@ License along with this library. If not, see . + + Options + + + , + + + If the repository has exactly one commit, then print it; any other case will result in an error. + + + + + Description diff --git a/src/ostree/ot-builtin-rev-parse.c b/src/ostree/ot-builtin-rev-parse.c index 521d2159..95cb45ab 100644 --- a/src/ostree/ot-builtin-rev-parse.c +++ b/src/ostree/ot-builtin-rev-parse.c @@ -25,13 +25,17 @@ #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" +#include /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-rev-parse.xml) when changing the option list. */ +static gboolean opt_single; + static GOptionEntry options[] = { + { "single", 'S', 0, G_OPTION_ARG_NONE, &opt_single, "If the repository has exactly one commit, then print it; any other case will result in an error", NULL }, { NULL } }; @@ -43,11 +47,43 @@ ostree_builtin_rev_parse (int argc, char **argv, OstreeCommandInvocation *invoca if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) return FALSE; + if (opt_single) + { + if (argc >= 2) + { + ot_util_usage_error (context, "Cannot specify arguments with --single", error); + return FALSE; + } + + g_autoptr(GHashTable) objects = NULL; + if (!ostree_repo_list_commit_objects_starting_with (repo, "", &objects, cancellable, error)) + return FALSE; + + GVariant *found = NULL; + GLNX_HASH_TABLE_FOREACH (objects, GVariant*, key) + { + if (found) + return glnx_throw (error, "Multiple commit objects found"); + found = key; + } + if (!found) + return glnx_throw (error, "No commit objects found"); + const char *checksum; + OstreeObjectType objtype; + ostree_object_name_deserialize (found, &checksum, &objtype); + g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT); + + g_print ("%s\n", checksum); + + return TRUE; /* Note early return */ + } + if (argc < 2) { ot_util_usage_error (context, "REV must be specified", error); return FALSE; } + for (gint i = 1; i < argc; i++) { const char *rev = argv[i]; diff --git a/tests/basic-test.sh b/tests/basic-test.sh index 04506c3d..67d57dda 100644 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..$((87 + ${extra_basic_tests:-0}))" +echo "1..$((88 + ${extra_basic_tests:-0}))" CHECKOUT_U_ARG="" CHECKOUT_H_ARGS="-H" @@ -97,6 +97,22 @@ $OSTREE rev-parse 'test2^' $OSTREE rev-parse 'test2^^' 2>/dev/null && fatal "rev-parse test2^^ unexpectedly succeeded!" echo "ok rev-parse" +if $OSTREE rev-parse -S 2>err.txt; then + fatal "rev parse multiple" +fi +assert_file_has_content_literal err.txt 'Multiple commit objects found' +$CMD_PREFIX ostree --repo=repo-copy init --mode=archive +if $CMD_PREFIX ostree --repo=repo-copy rev-parse -S 2>err.txt; then + fatal "rev parse none" +fi +assert_file_has_content_literal err.txt 'No commit objects found' +rev=$($OSTREE rev-parse test2) +$CMD_PREFIX ostree --repo=repo-copy pull-local repo test2 +rev2=$($CMD_PREFIX ostree --repo=repo-copy rev-parse -S) +assert_streq "${rev}" "${rev2}" +echo "ok rev-parse -S" + + checksum=$($OSTREE rev-parse test2) partial=${checksum:0:6} echo "partial:" $partial