Skip to content

Commit 3fa95ce

Browse files
committed
Merge branch 'sb/ls-tree-parseopt'
* sb/ls-tree-parseopt: ls-tree: migrate to parse-options t3101: test more ls-tree options
2 parents ef6a243 + 61fdbcf commit 3fa95ce

File tree

2 files changed

+127
-62
lines changed

2 files changed

+127
-62
lines changed

builtin-ls-tree.c

Lines changed: 40 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "commit.h"
1010
#include "quote.h"
1111
#include "builtin.h"
12+
#include "parse-options.h"
1213

1314
static int line_termination = '\n';
1415
#define LS_RECURSIVE 1
@@ -22,8 +23,10 @@ static const char **pathspec;
2223
static int chomp_prefix;
2324
static const char *ls_tree_prefix;
2425

25-
static const char ls_tree_usage[] =
26-
"git ls-tree [-d] [-r] [-t] [-l] [-z] [--name-only] [--name-status] [--full-name] [--full-tree] [--abbrev[=<n>]] <tree-ish> [path...]";
26+
static const char * const ls_tree_usage[] = {
27+
"git ls-tree [<options>] <tree-ish> [path...]",
28+
NULL
29+
};
2730

2831
static int show_recursive(const char *base, int baselen, const char *pathname)
2932
{
@@ -117,76 +120,53 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
117120
{
118121
unsigned char sha1[20];
119122
struct tree *tree;
123+
int full_tree = 0;
124+
const struct option ls_tree_options[] = {
125+
OPT_BIT('d', NULL, &ls_options, "only show trees",
126+
LS_TREE_ONLY),
127+
OPT_BIT('r', NULL, &ls_options, "recurse into subtrees",
128+
LS_RECURSIVE),
129+
OPT_BIT('t', NULL, &ls_options, "show trees when recursing",
130+
LS_SHOW_TREES),
131+
OPT_SET_INT('z', NULL, &line_termination,
132+
"terminate entries with NUL byte", 0),
133+
OPT_BIT('l', "long", &ls_options, "include object size",
134+
LS_SHOW_SIZE),
135+
OPT_BIT(0, "name-only", &ls_options, "list only filenames",
136+
LS_NAME_ONLY),
137+
OPT_BIT(0, "name-status", &ls_options, "list only filenames",
138+
LS_NAME_ONLY),
139+
OPT_SET_INT(0, "full-name", &chomp_prefix,
140+
"use full path names", 0),
141+
OPT_BOOLEAN(0, "full-tree", &full_tree,
142+
"list entire tree; not just current directory "
143+
"(implies --full-name)"),
144+
OPT__ABBREV(&abbrev),
145+
OPT_END()
146+
};
120147

121148
git_config(git_default_config, NULL);
122149
ls_tree_prefix = prefix;
123150
if (prefix && *prefix)
124151
chomp_prefix = strlen(prefix);
125-
while (1 < argc && argv[1][0] == '-') {
126-
switch (argv[1][1]) {
127-
case 'z':
128-
line_termination = 0;
129-
break;
130-
case 'r':
131-
ls_options |= LS_RECURSIVE;
132-
break;
133-
case 'd':
134-
ls_options |= LS_TREE_ONLY;
135-
break;
136-
case 't':
137-
ls_options |= LS_SHOW_TREES;
138-
break;
139-
case 'l':
140-
ls_options |= LS_SHOW_SIZE;
141-
break;
142-
case '-':
143-
if (!strcmp(argv[1]+2, "name-only") ||
144-
!strcmp(argv[1]+2, "name-status")) {
145-
ls_options |= LS_NAME_ONLY;
146-
break;
147-
}
148-
if (!strcmp(argv[1]+2, "long")) {
149-
ls_options |= LS_SHOW_SIZE;
150-
break;
151-
}
152-
if (!strcmp(argv[1]+2, "full-name")) {
153-
chomp_prefix = 0;
154-
break;
155-
}
156-
if (!strcmp(argv[1]+2, "full-tree")) {
157-
ls_tree_prefix = prefix = NULL;
158-
chomp_prefix = 0;
159-
break;
160-
}
161-
if (!prefixcmp(argv[1]+2, "abbrev=")) {
162-
abbrev = strtoul(argv[1]+9, NULL, 10);
163-
if (abbrev && abbrev < MINIMUM_ABBREV)
164-
abbrev = MINIMUM_ABBREV;
165-
else if (abbrev > 40)
166-
abbrev = 40;
167-
break;
168-
}
169-
if (!strcmp(argv[1]+2, "abbrev")) {
170-
abbrev = DEFAULT_ABBREV;
171-
break;
172-
}
173-
/* otherwise fallthru */
174-
default:
175-
usage(ls_tree_usage);
176-
}
177-
argc--; argv++;
152+
153+
argc = parse_options(argc, argv, prefix, ls_tree_options,
154+
ls_tree_usage, 0);
155+
if (full_tree) {
156+
ls_tree_prefix = prefix = NULL;
157+
chomp_prefix = 0;
178158
}
179159
/* -d -r should imply -t, but -d by itself should not have to. */
180160
if ( (LS_TREE_ONLY|LS_RECURSIVE) ==
181161
((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
182162
ls_options |= LS_SHOW_TREES;
183163

184-
if (argc < 2)
185-
usage(ls_tree_usage);
186-
if (get_sha1(argv[1], sha1))
187-
die("Not a valid object name %s", argv[1]);
164+
if (argc < 1)
165+
usage_with_options(ls_tree_usage, ls_tree_options);
166+
if (get_sha1(argv[0], sha1))
167+
die("Not a valid object name %s", argv[0]);
188168

189-
pathspec = get_pathspec(prefix, argv + 2);
169+
pathspec = get_pathspec(prefix, argv + 1);
190170
tree = parse_tree_indirect(sha1);
191171
if (!tree)
192172
die("not a tree object");

t/t3101-ls-tree-dirname.sh

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ test_expect_success \
3939
tree=`git write-tree` &&
4040
echo $tree'
4141

42-
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
43-
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
42+
_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
43+
_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
4444
test_output () {
4545
sed -e "s/ $_x40 / X /" <current >check
4646
test_cmp expected check
@@ -141,4 +141,89 @@ test_expect_success 'ls-tree filter is leading path match' '
141141
test_output
142142
'
143143

144+
test_expect_success 'ls-tree --full-name' '
145+
(
146+
cd path0 &&
147+
git ls-tree --full-name $tree a
148+
) >current &&
149+
cat >expected <<\EOF &&
150+
040000 tree X path0/a
151+
EOF
152+
test_output
153+
'
154+
155+
test_expect_success 'ls-tree --full-tree' '
156+
(
157+
cd path1/b/c &&
158+
git ls-tree --full-tree $tree
159+
) >current &&
160+
cat >expected <<\EOF &&
161+
100644 blob X 1.txt
162+
100644 blob X 2.txt
163+
040000 tree X path0
164+
040000 tree X path1
165+
040000 tree X path2
166+
040000 tree X path3
167+
EOF
168+
test_output
169+
'
170+
171+
test_expect_success 'ls-tree --full-tree -r' '
172+
(
173+
cd path3/ &&
174+
git ls-tree --full-tree -r $tree
175+
) >current &&
176+
cat >expected <<\EOF &&
177+
100644 blob X 1.txt
178+
100644 blob X 2.txt
179+
100644 blob X path0/a/b/c/1.txt
180+
100644 blob X path1/b/c/1.txt
181+
100644 blob X path2/1.txt
182+
100644 blob X path3/1.txt
183+
100644 blob X path3/2.txt
184+
EOF
185+
test_output
186+
'
187+
188+
test_expect_success 'ls-tree --abbrev=5' '
189+
git ls-tree --abbrev=5 $tree >current &&
190+
sed -e "s/ $_x05[0-9a-f]* / X /" <current >check &&
191+
cat >expected <<\EOF &&
192+
100644 blob X 1.txt
193+
100644 blob X 2.txt
194+
040000 tree X path0
195+
040000 tree X path1
196+
040000 tree X path2
197+
040000 tree X path3
198+
EOF
199+
test_cmp expected check
200+
'
201+
202+
test_expect_success 'ls-tree --name-only' '
203+
git ls-tree --name-only $tree >current
204+
cat >expected <<\EOF &&
205+
1.txt
206+
2.txt
207+
path0
208+
path1
209+
path2
210+
path3
211+
EOF
212+
test_output
213+
'
214+
215+
test_expect_success 'ls-tree --name-only -r' '
216+
git ls-tree --name-only -r $tree >current
217+
cat >expected <<\EOF &&
218+
1.txt
219+
2.txt
220+
path0/a/b/c/1.txt
221+
path1/b/c/1.txt
222+
path2/1.txt
223+
path3/1.txt
224+
path3/2.txt
225+
EOF
226+
test_output
227+
'
228+
144229
test_done

0 commit comments

Comments
 (0)