use syntax similar to `git-checkout` to make <tree-ish> optional for
`ls-tree`. if <tree-ish> is omitted, default to HEAD. infer arguments as
follows:
1. if args start with --
assume <tree-ish> to be HEAD
2. if exactly one arg precedes --, treat the argument as <tree-ish>
3. if more than one arg precedes --, exit with an error
4. if -- is not in args
a) if args[0] is a valid <tree-ish> object, treat is as such
b) else, assume <tree-ish> to be HEAD
in all cases, every argument besides <tree-ish> is treated as a <path>
---
builtin/ls-tree.c | 39 ++++++++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 5 deletions(-)
diff --git builtin/ls-tree.c builtin/ls-tree.c
index 409da4e83..14102b052 100644
--- builtin/ls-tree.c
+++ builtin/ls-tree.c
@@ -153,7 +153,7 @@ int cmd_ls_tree(int argc, const char **argv, const char
*prefix)
chomp_prefix = strlen(prefix);
argc = parse_options(argc, argv, prefix, ls_tree_options,
- ls_tree_usage, 0);
+ ls_tree_usage, PARSE_OPT_KEEP_DASHDASH);
if (full_tree) {
ls_tree_prefix = prefix = NULL;
chomp_prefix = 0;
@@ -163,10 +163,39 @@ int cmd_ls_tree(int argc, const char **argv, const char
*prefix)
((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
ls_options |= LS_SHOW_TREES;
+ const char *object;
+ short initialized = 0;
if (argc < 1)
- usage_with_options(ls_tree_usage, ls_tree_options);
- if (get_oid(argv[0], &oid))
- die("Not a valid object name %s", argv[0]);
+ object = "HEAD";
+ else {
+ /* taken from checkout.c;
+ * we have a simpler case because we never create a branch */
+ short dash_dash_pos = -1, i = 0;
+ for (; i < argc; i++) {
+ if (!strcmp(argv[i], "--")) {
+ dash_dash_pos = i;
+ break;
+ }
+ }
+ if (dash_dash_pos == 0) {
+ object = "HEAD";
+ argv++, argc++;
+ } else if (dash_dash_pos == 1) {
+ object = argv[0];
+ argv += 2, argc += 2;
+ } else if (dash_dash_pos >= 2)
+ die(_("only one reference expected, %d given."),
dash_dash_pos);
+ else if (get_oid(argv[0], &oid)) // not a valid object
+ object = "HEAD";
+ else {
+ argv++, argc++;
+ initialized = 1;
+ }
+ }
+
+ if (!initialized) // if we've already run get_oid, don't run it again
+ if (get_oid(object, &oid))
+ die("Not a valid object name %s", object);
/*
* show_recursive() rolls its own matching code and is
@@ -177,7 +206,7 @@ int cmd_ls_tree(int argc, const char **argv, const char
*prefix)
parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC &
~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
PATHSPEC_PREFER_CWD,
- prefix, argv + 1);
+ prefix, argv);
for (i = 0; i < pathspec.nr; i++)
pathspec.items[i].nowildcard_len = pathspec.items[i].len;
pathspec.has_wildcard = 0;
--
2.18.GIT