Skip to content

Commit f0096c0

Browse files
pcloudsgitster
authored andcommitted
Convert read_tree{,_recursive} to support struct pathspec
This patch changes behavior of the two functions. Previously it does prefix matching only. Now it can also do wildcard matching. All callers are updated. Some gain wildcard matching (archive, checkout), others reset pathspec_item.has_wildcard to retain old behavior (ls-files, ls-tree as they are plumbing). Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ffd31f6 commit f0096c0

File tree

9 files changed

+62
-29
lines changed

9 files changed

+62
-29
lines changed

archive.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ int write_archive_entries(struct archiver_args *args,
157157
struct archiver_context context;
158158
struct unpack_trees_options opts;
159159
struct tree_desc t;
160+
struct pathspec pathspec;
160161
int err;
161162

162163
if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -191,8 +192,10 @@ int write_archive_entries(struct archiver_args *args,
191192
git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
192193
}
193194

194-
err = read_tree_recursive(args->tree, "", 0, 0, args->pathspec,
195+
init_pathspec(&pathspec, args->pathspec);
196+
err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
195197
write_archive_entry, &context);
198+
free_pathspec(&pathspec);
196199
if (err == READ_TREE_RECURSIVE)
197200
err = 0;
198201
return err;
@@ -221,11 +224,14 @@ static int reject_entry(const unsigned char *sha1, const char *base,
221224

222225
static int path_exists(struct tree *tree, const char *path)
223226
{
224-
const char *pathspec[] = { path, NULL };
225-
226-
if (read_tree_recursive(tree, "", 0, 0, pathspec, reject_entry, NULL))
227-
return 1;
228-
return 0;
227+
const char *paths[] = { path, NULL };
228+
struct pathspec pathspec;
229+
int ret;
230+
231+
init_pathspec(&pathspec, paths);
232+
ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL);
233+
free_pathspec(&pathspec);
234+
return ret != 0;
229235
}
230236

231237
static void parse_pathspec_arg(const char **pathspec,

builtin/checkout.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
7878

7979
static int read_tree_some(struct tree *tree, const char **pathspec)
8080
{
81-
read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
81+
struct pathspec ps;
82+
init_pathspec(&ps, pathspec);
83+
read_tree_recursive(tree, "", 0, 0, &ps, update_some, NULL);
84+
free_pathspec(&ps);
8285

8386
/* update the index with the given tree's info
8487
* for all args, expanding wildcards, and exit

builtin/log.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,13 +390,15 @@ int cmd_show(int argc, const char **argv, const char *prefix)
390390
struct rev_info rev;
391391
struct object_array_entry *objects;
392392
struct setup_revision_opt opt;
393+
struct pathspec match_all;
393394
int i, count, ret = 0;
394395

395396
git_config(git_log_config, NULL);
396397

397398
if (diff_use_color_default == -1)
398399
diff_use_color_default = git_use_color_default;
399400

401+
init_pathspec(&match_all, NULL);
400402
init_revisions(&rev, prefix);
401403
rev.diff = 1;
402404
rev.always_show_header = 1;
@@ -443,7 +445,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
443445
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
444446
name,
445447
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
446-
read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
448+
read_tree_recursive((struct tree *)o, "", 0, 0, &match_all,
447449
show_tree_object, NULL);
448450
rev.shown_one = 1;
449451
break;

builtin/ls-files.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
338338
{
339339
struct tree *tree;
340340
unsigned char sha1[20];
341-
const char **match;
341+
struct pathspec pathspec;
342342
struct cache_entry *last_stage0 = NULL;
343343
int i;
344344

@@ -360,10 +360,11 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
360360
static const char *(matchbuf[2]);
361361
matchbuf[0] = prefix;
362362
matchbuf[1] = NULL;
363-
match = matchbuf;
363+
init_pathspec(&pathspec, matchbuf);
364+
pathspec.items[0].has_wildcard = 0;
364365
} else
365-
match = NULL;
366-
if (read_tree(tree, 1, match))
366+
init_pathspec(&pathspec, NULL);
367+
if (read_tree(tree, 1, &pathspec))
367368
die("unable to read tree entries %s", tree_name);
368369

369370
for (i = 0; i < active_nr; i++) {

builtin/ls-tree.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static int line_termination = '\n';
1919
#define LS_SHOW_SIZE 16
2020
static int abbrev;
2121
static int ls_options;
22-
static const char **pathspec;
22+
static struct pathspec pathspec;
2323
static int chomp_prefix;
2424
static const char *ls_tree_prefix;
2525

@@ -35,7 +35,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
3535
if (ls_options & LS_RECURSIVE)
3636
return 1;
3737

38-
s = pathspec;
38+
s = pathspec.raw;
3939
if (!s)
4040
return 0;
4141

@@ -120,7 +120,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
120120
{
121121
unsigned char sha1[20];
122122
struct tree *tree;
123-
int full_tree = 0;
123+
int i, full_tree = 0;
124124
const struct option ls_tree_options[] = {
125125
OPT_BIT('d', NULL, &ls_options, "only show trees",
126126
LS_TREE_ONLY),
@@ -166,11 +166,13 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
166166
if (get_sha1(argv[0], sha1))
167167
die("Not a valid object name %s", argv[0]);
168168

169-
pathspec = get_pathspec(prefix, argv + 1);
169+
init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
170+
for (i = 0; i < pathspec.nr; i++)
171+
pathspec.items[i].has_wildcard = 0;
170172
tree = parse_tree_indirect(sha1);
171173
if (!tree)
172174
die("not a tree object");
173-
read_tree_recursive(tree, "", 0, 0, pathspec, show_tree, NULL);
175+
read_tree_recursive(tree, "", 0, 0, &pathspec, show_tree, NULL);
174176

175177
return 0;
176178
}

merge-recursive.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,9 @@ static int save_files_dirs(const unsigned char *sha1,
288288
static int get_files_dirs(struct merge_options *o, struct tree *tree)
289289
{
290290
int n;
291-
if (read_tree_recursive(tree, "", 0, 0, NULL, save_files_dirs, o))
291+
struct pathspec match_all;
292+
init_pathspec(&match_all, NULL);
293+
if (read_tree_recursive(tree, "", 0, 0, &match_all, save_files_dirs, o))
292294
return 0;
293295
n = o->current_file_set.nr + o->current_directory_set.nr;
294296
return n;

t/t3102-ls-tree-wildcards.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
3+
test_description='ls-tree with(out) wildcards'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
mkdir a aa "a*" &&
9+
touch a/one aa/two "a*/three" &&
10+
git add a/one aa/two "a*/three" &&
11+
git commit -m test
12+
'
13+
14+
test_expect_success 'ls-tree a* matches literally' '
15+
cat >expected <<EOF &&
16+
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a*/three
17+
EOF
18+
git ls-tree -r HEAD "a*" >actual &&
19+
test_cmp expected actual
20+
'
21+
22+
test_done

tree.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,15 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
114114

115115
int read_tree_recursive(struct tree *tree,
116116
const char *base, int baselen,
117-
int stage, const char **match,
117+
int stage, struct pathspec *pathspec,
118118
read_tree_fn_t fn, void *context)
119119
{
120120
struct strbuf sb = STRBUF_INIT;
121-
struct pathspec pathspec;
122-
int i, ret;
121+
int ret;
123122

124-
init_pathspec(&pathspec, match);
125-
for (i = 0; i < pathspec.nr; i++)
126-
pathspec.items[i].has_wildcard = 0;
127123
strbuf_add(&sb, base, baselen);
128-
ret = read_tree_1(tree, &sb, stage, &pathspec, fn, context);
124+
ret = read_tree_1(tree, &sb, stage, pathspec, fn, context);
129125
strbuf_release(&sb);
130-
free_pathspec(&pathspec);
131126
return ret;
132127
}
133128

@@ -141,7 +136,7 @@ static int cmp_cache_name_compare(const void *a_, const void *b_)
141136
ce2->name, ce2->ce_flags);
142137
}
143138

144-
int read_tree(struct tree *tree, int stage, const char **match)
139+
int read_tree(struct tree *tree, int stage, struct pathspec *match)
145140
{
146141
read_tree_fn_t fn = NULL;
147142
int i, err;

tree.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const ch
2525

2626
extern int read_tree_recursive(struct tree *tree,
2727
const char *base, int baselen,
28-
int stage, const char **match,
28+
int stage, struct pathspec *pathspec,
2929
read_tree_fn_t fn, void *context);
3030

31-
extern int read_tree(struct tree *tree, int stage, const char **paths);
31+
extern int read_tree(struct tree *tree, int stage, struct pathspec *pathspec);
3232

3333
#endif /* TREE_H */

0 commit comments

Comments
 (0)