Skip to content

Commit 5700772

Browse files
committed
Merge branch 'nd/ls-tree-pathspec'
"git ls-tree" does not support path selection based on negative pathspecs, but did not error out when negative pathspecs are given. * nd/ls-tree-pathspec: t3102: style modernization t3102: document that ls-tree does not yet support negated pathspec ls-tree: disable negative pathspec because it's not supported ls-tree: remove path filtering logic in show_tree tree.c: update read_tree_recursive callback to pass strbuf as base
2 parents 77a801d + f1f6224 commit 5700772

File tree

10 files changed

+74
-69
lines changed

10 files changed

+74
-69
lines changed

archive.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,26 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
157157
return write_entry(args, sha1, path.buf, path.len, mode);
158158
}
159159

160+
static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base,
161+
const char *filename, unsigned mode, int stage,
162+
void *context)
163+
{
164+
return write_archive_entry(sha1, base->buf, base->len,
165+
filename, mode, stage, context);
166+
}
167+
160168
static void queue_directory(const unsigned char *sha1,
161-
const char *base, int baselen, const char *filename,
169+
struct strbuf *base, const char *filename,
162170
unsigned mode, int stage, struct archiver_context *c)
163171
{
164172
struct directory *d;
165-
d = xmallocz(sizeof(*d) + baselen + 1 + strlen(filename));
173+
d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
166174
d->up = c->bottom;
167-
d->baselen = baselen;
175+
d->baselen = base->len;
168176
d->mode = mode;
169177
d->stage = stage;
170178
c->bottom = d;
171-
d->len = sprintf(d->path, "%.*s%s/", baselen, base, filename);
179+
d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
172180
hashcpy(d->sha1, sha1);
173181
}
174182

@@ -191,28 +199,28 @@ static int write_directory(struct archiver_context *c)
191199
}
192200

193201
static int queue_or_write_archive_entry(const unsigned char *sha1,
194-
const char *base, int baselen, const char *filename,
202+
struct strbuf *base, const char *filename,
195203
unsigned mode, int stage, void *context)
196204
{
197205
struct archiver_context *c = context;
198206

199207
while (c->bottom &&
200-
!(baselen >= c->bottom->len &&
201-
!strncmp(base, c->bottom->path, c->bottom->len))) {
208+
!(base->len >= c->bottom->len &&
209+
!strncmp(base->buf, c->bottom->path, c->bottom->len))) {
202210
struct directory *next = c->bottom->up;
203211
free(c->bottom);
204212
c->bottom = next;
205213
}
206214

207215
if (S_ISDIR(mode)) {
208-
queue_directory(sha1, base, baselen, filename,
216+
queue_directory(sha1, base, filename,
209217
mode, stage, c);
210218
return READ_TREE_RECURSIVE;
211219
}
212220

213221
if (write_directory(c))
214222
return -1;
215-
return write_archive_entry(sha1, base, baselen, filename, mode,
223+
return write_archive_entry(sha1, base->buf, base->len, filename, mode,
216224
stage, context);
217225
}
218226

@@ -260,7 +268,7 @@ int write_archive_entries(struct archiver_args *args,
260268
err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
261269
args->pathspec.has_wildcard ?
262270
queue_or_write_archive_entry :
263-
write_archive_entry,
271+
write_archive_entry_buf,
264272
&context);
265273
if (err == READ_TREE_RECURSIVE)
266274
err = 0;
@@ -286,14 +294,14 @@ static const struct archiver *lookup_archiver(const char *name)
286294
return NULL;
287295
}
288296

289-
static int reject_entry(const unsigned char *sha1, const char *base,
290-
int baselen, const char *filename, unsigned mode,
297+
static int reject_entry(const unsigned char *sha1, struct strbuf *base,
298+
const char *filename, unsigned mode,
291299
int stage, void *context)
292300
{
293301
int ret = -1;
294302
if (S_ISDIR(mode)) {
295303
struct strbuf sb = STRBUF_INIT;
296-
strbuf_addstr(&sb, base);
304+
strbuf_addbuf(&sb, base);
297305
strbuf_addstr(&sb, filename);
298306
if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1))
299307
ret = READ_TREE_RECURSIVE;

builtin/checkout.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
6262

6363
}
6464

65-
static int update_some(const unsigned char *sha1, const char *base, int baselen,
65+
static int update_some(const unsigned char *sha1, struct strbuf *base,
6666
const char *pathname, unsigned mode, int stage, void *context)
6767
{
6868
int len;
@@ -72,11 +72,11 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
7272
if (S_ISDIR(mode))
7373
return READ_TREE_RECURSIVE;
7474

75-
len = baselen + strlen(pathname);
75+
len = base->len + strlen(pathname);
7676
ce = xcalloc(1, cache_entry_size(len));
7777
hashcpy(ce->sha1, sha1);
78-
memcpy(ce->name, base, baselen);
79-
memcpy(ce->name + baselen, pathname, len - baselen);
78+
memcpy(ce->name, base->buf, base->len);
79+
memcpy(ce->name + base->len, pathname, len - base->len);
8080
ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
8181
ce->ce_namelen = len;
8282
ce->ce_mode = create_ce_mode(mode);

builtin/log.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
489489
}
490490

491491
static int show_tree_object(const unsigned char *sha1,
492-
const char *base, int baselen,
492+
struct strbuf *base,
493493
const char *pathname, unsigned mode, int stage, void *context)
494494
{
495495
printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");

builtin/ls-tree.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
6161
}
6262
}
6363

64-
static int show_tree(const unsigned char *sha1, const char *base, int baselen,
64+
static int show_tree(const unsigned char *sha1, struct strbuf *base,
6565
const char *pathname, unsigned mode, int stage, void *context)
6666
{
6767
int retval = 0;
68+
int baselen;
6869
const char *type = blob_type;
6970

7071
if (S_ISGITLINK(mode)) {
@@ -79,7 +80,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
7980
*/
8081
type = commit_type;
8182
} else if (S_ISDIR(mode)) {
82-
if (show_recursive(base, baselen, pathname)) {
83+
if (show_recursive(base->buf, base->len, pathname)) {
8384
retval = READ_TREE_RECURSIVE;
8485
if (!(ls_options & LS_SHOW_TREES))
8586
return retval;
@@ -89,10 +90,6 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
8990
else if (ls_options & LS_TREE_ONLY)
9091
return 0;
9192

92-
if (chomp_prefix &&
93-
(baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
94-
return 0;
95-
9693
if (!(ls_options & LS_NAME_ONLY)) {
9794
if (ls_options & LS_SHOW_SIZE) {
9895
char size_text[24];
@@ -112,8 +109,12 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
112109
printf("%06o %s %s\t", mode, type,
113110
find_unique_abbrev(sha1, abbrev));
114111
}
115-
write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix,
116-
pathname, stdout, line_termination);
112+
baselen = base->len;
113+
strbuf_addstr(base, pathname);
114+
write_name_quoted_relative(base->buf,
115+
chomp_prefix ? ls_tree_prefix : NULL,
116+
stdout, line_termination);
117+
strbuf_setlen(base, baselen);
117118
return retval;
118119
}
119120

@@ -173,7 +174,8 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
173174
* cannot be lifted until it is converted to use
174175
* match_pathspec() or tree_entry_interesting()
175176
*/
176-
parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE,
177+
parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE |
178+
PATHSPEC_EXCLUDE,
177179
PATHSPEC_PREFER_CWD,
178180
prefix, argv + 1);
179181
for (i = 0; i < pathspec.nr; i++)

merge-recursive.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -275,23 +275,20 @@ struct tree *write_tree_from_memory(struct merge_options *o)
275275
}
276276

277277
static int save_files_dirs(const unsigned char *sha1,
278-
const char *base, int baselen, const char *path,
278+
struct strbuf *base, const char *path,
279279
unsigned int mode, int stage, void *context)
280280
{
281-
int len = strlen(path);
282-
char *newpath = xmalloc(baselen + len + 1);
281+
int baselen = base->len;
283282
struct merge_options *o = context;
284283

285-
memcpy(newpath, base, baselen);
286-
memcpy(newpath + baselen, path, len);
287-
newpath[baselen + len] = '\0';
284+
strbuf_addstr(base, path);
288285

289286
if (S_ISDIR(mode))
290-
string_list_insert(&o->current_directory_set, newpath);
287+
string_list_insert(&o->current_directory_set, base->buf);
291288
else
292-
string_list_insert(&o->current_file_set, newpath);
293-
free(newpath);
289+
string_list_insert(&o->current_file_set, base->buf);
294290

291+
strbuf_setlen(base, baselen);
295292
return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
296293
}
297294

quote.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -274,27 +274,6 @@ void write_name_quoted(const char *name, FILE *fp, int terminator)
274274
fputc(terminator, fp);
275275
}
276276

277-
void write_name_quotedpfx(const char *pfx, size_t pfxlen,
278-
const char *name, FILE *fp, int terminator)
279-
{
280-
int needquote = 0;
281-
282-
if (terminator) {
283-
needquote = next_quote_pos(pfx, pfxlen) < pfxlen
284-
|| name[next_quote_pos(name, -1)];
285-
}
286-
if (needquote) {
287-
fputc('"', fp);
288-
quote_c_style_counted(pfx, pfxlen, NULL, fp, 1);
289-
quote_c_style(name, NULL, fp, 1);
290-
fputc('"', fp);
291-
} else {
292-
fwrite(pfx, pfxlen, 1, fp);
293-
fputs(name, fp);
294-
}
295-
fputc(terminator, fp);
296-
}
297-
298277
void write_name_quoted_relative(const char *name, const char *prefix,
299278
FILE *fp, int terminator)
300279
{

quote.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq
5656
extern void quote_two_c_style(struct strbuf *, const char *, const char *, int);
5757

5858
extern void write_name_quoted(const char *name, FILE *, int terminator);
59-
extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
60-
const char *name, FILE *, int terminator);
6159
extern void write_name_quoted_relative(const char *name, const char *prefix,
6260
FILE *fp, int terminator);
6361

t/t3102-ls-tree-wildcards.sh

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,25 @@ test_expect_success 'setup' '
1212
'
1313

1414
test_expect_success 'ls-tree a[a] matches literally' '
15-
cat >expected <<EOF &&
16-
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a[a]/three
17-
EOF
15+
cat >expect <<-\EOF &&
16+
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a[a]/three
17+
EOF
1818
git ls-tree -r HEAD "a[a]" >actual &&
19-
test_cmp expected actual
19+
test_cmp expect actual
20+
'
21+
22+
test_expect_success 'ls-tree outside prefix' '
23+
cat >expect <<-\EOF &&
24+
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 ../a[a]/three
25+
EOF
26+
( cd aa && git ls-tree -r HEAD "../a[a]"; ) >actual &&
27+
test_cmp expect actual
28+
'
29+
30+
test_expect_failure 'ls-tree does not yet support negated pathspec' '
31+
git ls-files ":(exclude)a" "a*" >expect &&
32+
git ls-tree --name-only -r HEAD ":(exclude)a" "a*" >actual &&
33+
test_cmp expect actual
2034
'
2135

2236
test_done

tree.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,25 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b
3030
return add_cache_entry(ce, opt);
3131
}
3232

33-
static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
33+
static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
34+
const char *pathname, unsigned mode, int stage,
35+
void *context)
3436
{
35-
return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
37+
return read_one_entry_opt(sha1, base->buf, base->len, pathname,
38+
mode, stage,
3639
ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
3740
}
3841

3942
/*
4043
* This is used when the caller knows there is no existing entries at
4144
* the stage that will conflict with the entry being added.
4245
*/
43-
static int read_one_entry_quick(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
46+
static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base,
47+
const char *pathname, unsigned mode, int stage,
48+
void *context)
4449
{
45-
return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
50+
return read_one_entry_opt(sha1, base->buf, base->len, pathname,
51+
mode, stage,
4652
ADD_CACHE_JUST_APPEND);
4753
}
4854

@@ -70,7 +76,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
7076
continue;
7177
}
7278

73-
switch (fn(entry.sha1, base->buf, base->len,
79+
switch (fn(entry.sha1, base,
7480
entry.path, entry.mode, stage, context)) {
7581
case 0:
7682
continue;

tree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "object.h"
55

66
extern const char *tree_type;
7+
struct strbuf;
78

89
struct tree {
910
struct object object;
@@ -22,7 +23,7 @@ void free_tree_buffer(struct tree *tree);
2223
struct tree *parse_tree_indirect(const unsigned char *sha1);
2324

2425
#define READ_TREE_RECURSIVE 1
25-
typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int, void *);
26+
typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *);
2627

2728
extern int read_tree_recursive(struct tree *tree,
2829
const char *base, int baselen,

0 commit comments

Comments
 (0)