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