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