ls-tree: support --object-only option for "git-ls-tree"
'--object-only' is an alias for '--format=%(objectname)'. It cannot
be used together other format-altering options like '--name-only',
'--long' or '--format', they are mutually exclusive.
The "--name-only" option outputs <filepath> only. Likewise, <objectName>
is another high frequency used field, so implement '--object-only' option
will bring intuitive and clear semantics for this scenario. Using
'--format=%(objectname)' we can achieve a similar effect, but the former
is with a lower learning cost(without knowing the format requirement
of '--format' option).
Even so, if a user is prefer to use "--format=%(objectname)", this is entirely
welcome because they are not only equivalent in function, but also have almost
identical performance. The reason is this commit also add the specific of
"--format=%(objectname)" to the current fast-pathes (builtin formats) to
avoid running unnecessary parsing mechanisms.
The following performance benchmarks are based on torvalds/linux.git:
When hit the fast-path:
Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --object-only HEAD
Time (mean ± σ): 83.6 ms ± 2.0 ms [User: 59.4 ms, System: 24.1 ms]
Range (min … max): 80.4 ms … 87.2 ms 35 runs
Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(objectname)' HEAD
Time (mean ± σ): 84.1 ms ± 1.8 ms [User: 61.7 ms, System: 22.3 ms]
Range (min … max): 80.9 ms … 87.5 ms 35 runs
But for a customized format, it will be slower:
Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='oid: %(objectname)' HEAD
Time (mean ± σ): 96.5 ms ± 2.5 ms [User: 72.9 ms, System: 23.5 ms]
Range (min … max): 93.1 ms … 104.1 ms 31 runs
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Teng Long <dyroneteng@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
455923e0a1
commit
cab851c2f8
@ -24,7 +24,6 @@ static struct pathspec pathspec;
|
||||
static int chomp_prefix;
|
||||
static const char *ls_tree_prefix;
|
||||
static const char *format;
|
||||
|
||||
struct show_tree_data {
|
||||
unsigned mode;
|
||||
enum object_type type;
|
||||
@ -42,6 +41,7 @@ static enum ls_tree_cmdmode {
|
||||
MODE_DEFAULT = 0,
|
||||
MODE_LONG,
|
||||
MODE_NAME_ONLY,
|
||||
MODE_OBJECT_ONLY,
|
||||
} cmdmode;
|
||||
|
||||
static void expand_objectsize(struct strbuf *line, const struct object_id *oid,
|
||||
@ -227,6 +227,11 @@ static int show_tree(const struct object_id *oid, struct strbuf *base,
|
||||
return recurse;
|
||||
}
|
||||
|
||||
if (cmdmode == MODE_OBJECT_ONLY) {
|
||||
printf("%s%c", find_unique_abbrev(oid, abbrev), line_termination);
|
||||
return recurse;
|
||||
}
|
||||
|
||||
if (cmdmode == MODE_NAME_ONLY) {
|
||||
baselen = base->len;
|
||||
strbuf_addstr(base, pathname);
|
||||
@ -264,6 +269,10 @@ static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = {
|
||||
.mode = MODE_NAME_ONLY, /* And MODE_NAME_STATUS */
|
||||
.fmt = "%(path)",
|
||||
},
|
||||
{
|
||||
.mode = MODE_OBJECT_ONLY,
|
||||
.fmt = "%(objectname)",
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
@ -288,6 +297,8 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
|
||||
MODE_NAME_ONLY),
|
||||
OPT_CMDMODE(0, "name-status", &cmdmode, N_("list only filenames"),
|
||||
MODE_NAME_ONLY),
|
||||
OPT_CMDMODE(0, "object-only", &cmdmode, N_("list only objects"),
|
||||
MODE_OBJECT_ONLY),
|
||||
OPT_SET_INT(0, "full-name", &chomp_prefix,
|
||||
N_("use full path names"), 0),
|
||||
OPT_BOOL(0, "full-tree", &full_tree,
|
||||
|
||||
Reference in New Issue
Block a user