Browse Source

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
maint
Junio C Hamano 10 years ago
parent
commit
570077231f
  1. 34
      archive.c
  2. 8
      builtin/checkout.c
  3. 2
      builtin/log.c
  4. 20
      builtin/ls-tree.c
  5. 15
      merge-recursive.c
  6. 21
      quote.c
  7. 2
      quote.h
  8. 22
      t/t3102-ls-tree-wildcards.sh
  9. 16
      tree.c
  10. 3
      tree.h

34
archive.c

@ -157,18 +157,26 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, @@ -157,18 +157,26 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
return write_entry(args, sha1, path.buf, path.len, mode);
}

static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base,
const char *filename, unsigned mode, int stage,
void *context)
{
return write_archive_entry(sha1, base->buf, base->len,
filename, mode, stage, context);
}

static void queue_directory(const unsigned char *sha1,
const char *base, int baselen, const char *filename,
struct strbuf *base, const char *filename,
unsigned mode, int stage, struct archiver_context *c)
{
struct directory *d;
d = xmallocz(sizeof(*d) + baselen + 1 + strlen(filename));
d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
d->up = c->bottom;
d->baselen = baselen;
d->baselen = base->len;
d->mode = mode;
d->stage = stage;
c->bottom = d;
d->len = sprintf(d->path, "%.*s%s/", baselen, base, filename);
d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
hashcpy(d->sha1, sha1);
}

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

static int queue_or_write_archive_entry(const unsigned char *sha1,
const char *base, int baselen, const char *filename,
struct strbuf *base, const char *filename,
unsigned mode, int stage, void *context)
{
struct archiver_context *c = context;

while (c->bottom &&
!(baselen >= c->bottom->len &&
!strncmp(base, c->bottom->path, c->bottom->len))) {
!(base->len >= c->bottom->len &&
!strncmp(base->buf, c->bottom->path, c->bottom->len))) {
struct directory *next = c->bottom->up;
free(c->bottom);
c->bottom = next;
}

if (S_ISDIR(mode)) {
queue_directory(sha1, base, baselen, filename,
queue_directory(sha1, base, filename,
mode, stage, c);
return READ_TREE_RECURSIVE;
}

if (write_directory(c))
return -1;
return write_archive_entry(sha1, base, baselen, filename, mode,
return write_archive_entry(sha1, base->buf, base->len, filename, mode,
stage, context);
}

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

static int reject_entry(const unsigned char *sha1, const char *base,
int baselen, const char *filename, unsigned mode,
static int reject_entry(const unsigned char *sha1, struct strbuf *base,
const char *filename, unsigned mode,
int stage, void *context)
{
int ret = -1;
if (S_ISDIR(mode)) {
struct strbuf sb = STRBUF_INIT;
strbuf_addstr(&sb, base);
strbuf_addbuf(&sb, base);
strbuf_addstr(&sb, filename);
if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1))
ret = READ_TREE_RECURSIVE;

8
builtin/checkout.c

@ -62,7 +62,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new, @@ -62,7 +62,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,

}

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

len = baselen + strlen(pathname);
len = base->len + strlen(pathname);
ce = xcalloc(1, cache_entry_size(len));
hashcpy(ce->sha1, sha1);
memcpy(ce->name, base, baselen);
memcpy(ce->name + baselen, pathname, len - baselen);
memcpy(ce->name, base->buf, base->len);
memcpy(ce->name + base->len, pathname, len - base->len);
ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
ce->ce_namelen = len;
ce->ce_mode = create_ce_mode(mode);

2
builtin/log.c

@ -489,7 +489,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev) @@ -489,7 +489,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
}

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

20
builtin/ls-tree.c

@ -61,10 +61,11 @@ static int show_recursive(const char *base, int baselen, const char *pathname) @@ -61,10 +61,11 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
}
}

static int show_tree(const unsigned char *sha1, const char *base, int baselen,
static int show_tree(const unsigned char *sha1, struct strbuf *base,
const char *pathname, unsigned mode, int stage, void *context)
{
int retval = 0;
int baselen;
const char *type = blob_type;

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

if (chomp_prefix &&
(baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
return 0;

if (!(ls_options & LS_NAME_ONLY)) {
if (ls_options & LS_SHOW_SIZE) {
char size_text[24];
@ -112,8 +109,12 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen, @@ -112,8 +109,12 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
printf("%06o %s %s\t", mode, type,
find_unique_abbrev(sha1, abbrev));
}
write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix,
pathname, stdout, line_termination);
baselen = base->len;
strbuf_addstr(base, pathname);
write_name_quoted_relative(base->buf,
chomp_prefix ? ls_tree_prefix : NULL,
stdout, line_termination);
strbuf_setlen(base, baselen);
return retval;
}

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

15
merge-recursive.c

@ -275,23 +275,20 @@ struct tree *write_tree_from_memory(struct merge_options *o) @@ -275,23 +275,20 @@ struct tree *write_tree_from_memory(struct merge_options *o)
}

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

memcpy(newpath, base, baselen);
memcpy(newpath + baselen, path, len);
newpath[baselen + len] = '\0';
strbuf_addstr(base, path);

if (S_ISDIR(mode))
string_list_insert(&o->current_directory_set, newpath);
string_list_insert(&o->current_directory_set, base->buf);
else
string_list_insert(&o->current_file_set, newpath);
free(newpath);
string_list_insert(&o->current_file_set, base->buf);

strbuf_setlen(base, baselen);
return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
}


21
quote.c

@ -274,27 +274,6 @@ void write_name_quoted(const char *name, FILE *fp, int terminator) @@ -274,27 +274,6 @@ void write_name_quoted(const char *name, FILE *fp, int terminator)
fputc(terminator, fp);
}

void write_name_quotedpfx(const char *pfx, size_t pfxlen,
const char *name, FILE *fp, int terminator)
{
int needquote = 0;

if (terminator) {
needquote = next_quote_pos(pfx, pfxlen) < pfxlen
|| name[next_quote_pos(name, -1)];
}
if (needquote) {
fputc('"', fp);
quote_c_style_counted(pfx, pfxlen, NULL, fp, 1);
quote_c_style(name, NULL, fp, 1);
fputc('"', fp);
} else {
fwrite(pfx, pfxlen, 1, fp);
fputs(name, fp);
}
fputc(terminator, fp);
}

void write_name_quoted_relative(const char *name, const char *prefix,
FILE *fp, int terminator)
{

2
quote.h

@ -56,8 +56,6 @@ extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq @@ -56,8 +56,6 @@ extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq
extern void quote_two_c_style(struct strbuf *, const char *, const char *, int);

extern void write_name_quoted(const char *name, FILE *, int terminator);
extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
const char *name, FILE *, int terminator);
extern void write_name_quoted_relative(const char *name, const char *prefix,
FILE *fp, int terminator);


22
t/t3102-ls-tree-wildcards.sh

@ -12,11 +12,25 @@ test_expect_success 'setup' ' @@ -12,11 +12,25 @@ test_expect_success 'setup' '
'

test_expect_success 'ls-tree a[a] matches literally' '
cat >expected <<EOF &&
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a[a]/three
EOF
cat >expect <<-\EOF &&
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a[a]/three
EOF
git ls-tree -r HEAD "a[a]" >actual &&
test_cmp expected actual
test_cmp expect actual
'

test_expect_success 'ls-tree outside prefix' '
cat >expect <<-\EOF &&
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 ../a[a]/three
EOF
( cd aa && git ls-tree -r HEAD "../a[a]"; ) >actual &&
test_cmp expect actual
'

test_expect_failure 'ls-tree does not yet support negated pathspec' '
git ls-files ":(exclude)a" "a*" >expect &&
git ls-tree --name-only -r HEAD ":(exclude)a" "a*" >actual &&
test_cmp expect actual
'

test_done

16
tree.c

@ -30,9 +30,12 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b @@ -30,9 +30,12 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b
return add_cache_entry(ce, opt);
}

static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
const char *pathname, unsigned mode, int stage,
void *context)
{
return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
return read_one_entry_opt(sha1, base->buf, base->len, pathname,
mode, stage,
ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
}

@ -40,9 +43,12 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel @@ -40,9 +43,12 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel
* This is used when the caller knows there is no existing entries at
* the stage that will conflict with the entry being added.
*/
static int read_one_entry_quick(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base,
const char *pathname, unsigned mode, int stage,
void *context)
{
return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
return read_one_entry_opt(sha1, base->buf, base->len, pathname,
mode, stage,
ADD_CACHE_JUST_APPEND);
}

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

switch (fn(entry.sha1, base->buf, base->len,
switch (fn(entry.sha1, base,
entry.path, entry.mode, stage, context)) {
case 0:
continue;

3
tree.h

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
#include "object.h"

extern const char *tree_type;
struct strbuf;

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

#define READ_TREE_RECURSIVE 1
typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int, void *);
typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *);

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

Loading…
Cancel
Save