mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-12-28 22:32:58 +03:00
530 lines
18 KiB
Diff
530 lines
18 KiB
Diff
|
diff --git a/builtin-add.c b/builtin-add.c
|
||
|
index bf13aa3..02c6751 100644
|
||
|
--- a/builtin-add.c
|
||
|
+++ b/builtin-add.c
|
||
|
@@ -123,6 +123,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
|
||
|
init_revisions(&rev, prefix);
|
||
|
setup_revisions(0, NULL, &rev, NULL);
|
||
|
rev.prune_data = pathspec;
|
||
|
+ rev.glob_paths = 0; /* git-add has its own filename matching machinery */
|
||
|
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
|
||
|
rev.diffopt.format_callback = update_callback;
|
||
|
data.flags = flags;
|
||
|
diff --git a/builtin-blame.c b/builtin-blame.c
|
||
|
index 9bced3b..237d1fe 100644
|
||
|
--- a/builtin-blame.c
|
||
|
+++ b/builtin-blame.c
|
||
|
@@ -343,7 +343,7 @@ static struct origin *find_origin(struct scoreboard *sb,
|
||
|
paths[0] = origin->path;
|
||
|
paths[1] = NULL;
|
||
|
|
||
|
- diff_tree_setup_paths(paths, &diff_opts);
|
||
|
+ diff_tree_setup_paths(paths, &diff_opts, 0);
|
||
|
if (diff_setup_done(&diff_opts) < 0)
|
||
|
die("diff-setup");
|
||
|
|
||
|
@@ -417,7 +417,7 @@ static struct origin *find_rename(struct scoreboard *sb,
|
||
|
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
|
||
|
diff_opts.single_follow = origin->path;
|
||
|
paths[0] = NULL;
|
||
|
- diff_tree_setup_paths(paths, &diff_opts);
|
||
|
+ diff_tree_setup_paths(paths, &diff_opts, 0);
|
||
|
if (diff_setup_done(&diff_opts) < 0)
|
||
|
die("diff-setup");
|
||
|
|
||
|
@@ -1099,7 +1099,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
|
||
|
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
|
||
|
|
||
|
paths[0] = NULL;
|
||
|
- diff_tree_setup_paths(paths, &diff_opts);
|
||
|
+ diff_tree_setup_paths(paths, &diff_opts, 0);
|
||
|
if (diff_setup_done(&diff_opts) < 0)
|
||
|
die("diff-setup");
|
||
|
|
||
|
@@ -2346,6 +2346,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
||
|
parse_done:
|
||
|
argc = parse_options_end(&ctx);
|
||
|
|
||
|
+ if (revs.glob_paths) {
|
||
|
+ error("git blame does not support `--glob-paths'");
|
||
|
+ usage_with_options(blame_opt_usage, options);
|
||
|
+ }
|
||
|
+
|
||
|
if (!blame_move_score)
|
||
|
blame_move_score = BLAME_DEFAULT_MOVE_SCORE;
|
||
|
if (!blame_copy_score)
|
||
|
diff --git a/builtin-reset.c b/builtin-reset.c
|
||
|
index 2e5a886..6026b34 100644
|
||
|
--- a/builtin-reset.c
|
||
|
+++ b/builtin-reset.c
|
||
|
@@ -128,14 +128,15 @@ static void update_index_from_diff(struct diff_queue_struct *q,
|
||
|
}
|
||
|
|
||
|
static int read_from_tree(const char *prefix, const char **argv,
|
||
|
- unsigned char *tree_sha1)
|
||
|
+ unsigned char *tree_sha1, int glob_paths)
|
||
|
{
|
||
|
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
|
||
|
int index_fd, index_was_discarded = 0;
|
||
|
struct diff_options opt;
|
||
|
|
||
|
memset(&opt, 0, sizeof(opt));
|
||
|
- diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv), &opt);
|
||
|
+ diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv),
|
||
|
+ &opt, glob_paths);
|
||
|
opt.output_format = DIFF_FORMAT_CALLBACK;
|
||
|
opt.format_callback = update_index_from_diff;
|
||
|
opt.format_callback_data = &index_was_discarded;
|
||
|
@@ -171,6 +172,7 @@ static const char *reset_type_names[] = { "mixed", "soft", "hard", NULL };
|
||
|
int cmd_reset(int argc, const char **argv, const char *prefix)
|
||
|
{
|
||
|
int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
|
||
|
+ int glob_paths = 0;
|
||
|
const char *rev = "HEAD";
|
||
|
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
|
||
|
*old_orig = NULL, sha1_old_orig[20];
|
||
|
@@ -182,6 +184,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||
|
OPT_SET_INT(0, "soft", &reset_type, "reset only HEAD", SOFT),
|
||
|
OPT_SET_INT(0, "hard", &reset_type,
|
||
|
"reset HEAD, index and working tree", HARD),
|
||
|
+ OPT_BOOLEAN(0, "glob-paths", &glob_paths,
|
||
|
+ "match paths with fnmatch"),
|
||
|
OPT_BOOLEAN('q', NULL, &quiet,
|
||
|
"disable showing new HEAD in hard reset and progress message"),
|
||
|
OPT_END()
|
||
|
@@ -246,7 +250,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||
|
else if (reset_type != NONE)
|
||
|
die("Cannot do %s reset with paths.",
|
||
|
reset_type_names[reset_type]);
|
||
|
- return read_from_tree(prefix, argv + i, sha1);
|
||
|
+ return read_from_tree(prefix, argv + i, sha1, glob_paths);
|
||
|
}
|
||
|
if (reset_type == NONE)
|
||
|
reset_type = MIXED; /* by default */
|
||
|
diff --git a/builtin-update-index.c b/builtin-update-index.c
|
||
|
index 38eb53c..28b09a3 100644
|
||
|
--- a/builtin-update-index.c
|
||
|
+++ b/builtin-update-index.c
|
||
|
@@ -23,6 +23,7 @@ static int allow_replace;
|
||
|
static int info_only;
|
||
|
static int force_remove;
|
||
|
static int verbose;
|
||
|
+static int glob_paths;
|
||
|
static int mark_valid_only;
|
||
|
#define MARK_VALID 1
|
||
|
#define UNMARK_VALID 2
|
||
|
@@ -534,7 +535,7 @@ static int do_reupdate(int ac, const char **av,
|
||
|
struct cache_entry *old = NULL;
|
||
|
int save_nr;
|
||
|
|
||
|
- if (ce_stage(ce) || !ce_path_match(ce, pathspec))
|
||
|
+ if (ce_stage(ce) || !ce_path_match(ce, pathspec, glob_paths))
|
||
|
continue;
|
||
|
if (has_head)
|
||
|
old = read_one_ent(NULL, head_sha1,
|
||
|
@@ -659,6 +660,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
||
|
force_remove = 1;
|
||
|
continue;
|
||
|
}
|
||
|
+ if (!strcmp(path, "--glob-paths")) {
|
||
|
+ glob_paths = 1;
|
||
|
+ continue;
|
||
|
+ }
|
||
|
if (!strcmp(path, "-z")) {
|
||
|
line_termination = 0;
|
||
|
continue;
|
||
|
@@ -702,6 +707,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
||
|
usage(update_index_usage);
|
||
|
die("unknown option %s", path);
|
||
|
}
|
||
|
+ if (glob_paths)
|
||
|
+ die("--glob-paths without -g");
|
||
|
p = prefix_path(prefix, prefix_length, path);
|
||
|
update_one(p, NULL, 0);
|
||
|
if (set_executable_bit)
|
||
|
@@ -712,6 +719,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
||
|
if (read_from_stdin) {
|
||
|
struct strbuf buf, nbuf;
|
||
|
|
||
|
+ if (glob_paths)
|
||
|
+ die("--glob-paths without -g");
|
||
|
strbuf_init(&buf, 0);
|
||
|
strbuf_init(&nbuf, 0);
|
||
|
while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
|
||
|
diff --git a/cache.h b/cache.h
|
||
|
index a779d92..5560195 100644
|
||
|
--- a/cache.h
|
||
|
+++ b/cache.h
|
||
|
@@ -387,7 +387,8 @@ extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
|
||
|
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
|
||
|
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
|
||
|
|
||
|
-extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
|
||
|
+extern int ce_path_match(const struct cache_entry *ce, const char **pathspec,
|
||
|
+ int glob_paths);
|
||
|
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
|
||
|
extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
|
||
|
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
|
||
|
diff --git a/diff-lib.c b/diff-lib.c
|
||
|
index e7eaff9..87925a2 100644
|
||
|
--- a/diff-lib.c
|
||
|
+++ b/diff-lib.c
|
||
|
@@ -77,7 +77,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
|
||
|
DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
|
||
|
break;
|
||
|
|
||
|
- if (!ce_path_match(ce, revs->prune_data))
|
||
|
+ if (!ce_path_match(ce, revs->prune_data, revs->glob_paths))
|
||
|
continue;
|
||
|
|
||
|
if (ce_stage(ce)) {
|
||
|
@@ -431,7 +431,7 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
|
||
|
if (tree == o->df_conflict_entry)
|
||
|
tree = NULL;
|
||
|
|
||
|
- if (ce_path_match(idx ? idx : tree, revs->prune_data))
|
||
|
+ if (ce_path_match(idx ? idx : tree, revs->prune_data, revs->glob_paths))
|
||
|
do_oneway_diff(o, idx, tree);
|
||
|
|
||
|
return 0;
|
||
|
@@ -508,6 +508,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
|
||
|
|
||
|
init_revisions(&revs, NULL);
|
||
|
revs.prune_data = opt->paths;
|
||
|
+ revs.glob_paths = opt->glob_paths;
|
||
|
tree = parse_tree_indirect(tree_sha1);
|
||
|
if (!tree)
|
||
|
die("bad tree object %s", sha1_to_hex(tree_sha1));
|
||
|
diff --git a/diff-no-index.c b/diff-no-index.c
|
||
|
index f6994cf..ec549a7 100644
|
||
|
--- a/diff-no-index.c
|
||
|
+++ b/diff-no-index.c
|
||
|
@@ -240,6 +240,7 @@ void diff_no_index(struct rev_info *revs,
|
||
|
}
|
||
|
else
|
||
|
revs->diffopt.paths = argv + argc - 2;
|
||
|
+ revs->diffopt.glob_paths = 0;
|
||
|
revs->diffopt.nr_paths = 2;
|
||
|
|
||
|
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
|
||
|
diff --git a/diff.h b/diff.h
|
||
|
index 50fb5dd..56f0857 100644
|
||
|
--- a/diff.h
|
||
|
+++ b/diff.h
|
||
|
@@ -102,6 +102,7 @@ struct diff_options {
|
||
|
FILE *file;
|
||
|
int close_file;
|
||
|
|
||
|
+ int glob_paths;
|
||
|
int nr_paths;
|
||
|
const char **paths;
|
||
|
int *pathlens;
|
||
|
@@ -128,7 +129,8 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix);
|
||
|
|
||
|
extern const char mime_boundary_leader[];
|
||
|
|
||
|
-extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
|
||
|
+extern void diff_tree_setup_paths(const char **paths, struct diff_options *opt,
|
||
|
+ int glob_paths);
|
||
|
extern void diff_tree_release_paths(struct diff_options *);
|
||
|
extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
|
||
|
const char *base, struct diff_options *opt);
|
||
|
diff --git a/gitk-git/gitk b/gitk-git/gitk
|
||
|
index fddcb45..18c5cbc 100644
|
||
|
--- a/gitk-git/gitk
|
||
|
+++ b/gitk-git/gitk
|
||
|
@@ -1866,6 +1866,7 @@ proc makewindow {} {
|
||
|
set gm [tk_optionMenu .tf.lbar.gdttype gdttype \
|
||
|
[mc "containing:"] \
|
||
|
[mc "touching paths:"] \
|
||
|
+ [mc "touching paths (glob):"] \
|
||
|
[mc "adding/removing string:"]]
|
||
|
trace add variable gdttype write gdttype_change
|
||
|
pack .tf.lbar.gdttype -side left -fill y
|
||
|
@@ -3588,6 +3589,11 @@ proc do_file_hl {serial} {
|
||
|
set highlight_paths [makepatterns $paths]
|
||
|
highlight_filelist
|
||
|
set gdtargs [concat -- $paths]
|
||
|
+ } elseif {$gdttype eq [mc "touching paths (glob):"]} {
|
||
|
+ if {[catch {set paths [shellsplit $highlight_files]}]} return
|
||
|
+ set highlight_paths $paths
|
||
|
+ highlight_filelist
|
||
|
+ set gdtargs [concat --glob-paths -- $paths]
|
||
|
} elseif {$gdttype eq [mc "adding/removing string:"]} {
|
||
|
set gdtargs [list "-S$highlight_files"]
|
||
|
} else {
|
||
|
diff --git a/read-cache.c b/read-cache.c
|
||
|
index 1648428..c11ded9 100644
|
||
|
--- a/read-cache.c
|
||
|
+++ b/read-cache.c
|
||
|
@@ -582,7 +582,8 @@ int ce_same_name(struct cache_entry *a, struct cache_entry *b)
|
||
|
return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
|
||
|
}
|
||
|
|
||
|
-int ce_path_match(const struct cache_entry *ce, const char **pathspec)
|
||
|
+static int ce_path_match_standard(const struct cache_entry *ce,
|
||
|
+ const char **pathspec)
|
||
|
{
|
||
|
const char *match, *name;
|
||
|
int len;
|
||
|
@@ -608,6 +609,31 @@ int ce_path_match(const struct cache_entry *ce, const char **pathspec)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int ce_path_match_globbed(const struct cache_entry *ce,
|
||
|
+ const char **pathspec)
|
||
|
+{
|
||
|
+ const char *match, *name;
|
||
|
+
|
||
|
+ if (!pathspec)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ name = ce->name;
|
||
|
+ while ((match = *pathspec++) != NULL) {
|
||
|
+ if (!fnmatch(match, name, 0))
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int ce_path_match(const struct cache_entry *ce,
|
||
|
+ const char **pathspec, int glob_paths)
|
||
|
+{
|
||
|
+ if (glob_paths)
|
||
|
+ return ce_path_match_globbed(ce, pathspec);
|
||
|
+ else
|
||
|
+ return ce_path_match_standard(ce, pathspec);
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* We fundamentally don't like some paths: we don't want
|
||
|
* dot or dot-dot anywhere, and for obvious reasons don't
|
||
|
diff --git a/revision.c b/revision.c
|
||
|
index 3897fec..0dd1091 100644
|
||
|
--- a/revision.c
|
||
|
+++ b/revision.c
|
||
|
@@ -519,6 +519,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
|
||
|
if (revs->diffopt.nr_paths) {
|
||
|
ids.diffopts.nr_paths = revs->diffopt.nr_paths;
|
||
|
ids.diffopts.paths = revs->diffopt.paths;
|
||
|
+ ids.diffopts.glob_paths = revs->diffopt.glob_paths; /* CHECKME */
|
||
|
ids.diffopts.pathlens = revs->diffopt.pathlens;
|
||
|
}
|
||
|
|
||
|
@@ -826,7 +827,7 @@ static void prepare_show_merge(struct rev_info *revs)
|
||
|
struct cache_entry *ce = active_cache[i];
|
||
|
if (!ce_stage(ce))
|
||
|
continue;
|
||
|
- if (ce_path_match(ce, revs->prune_data)) {
|
||
|
+ if (ce_path_match(ce, revs->prune_data, revs->glob_paths)) {
|
||
|
prune_num++;
|
||
|
prune = xrealloc(prune, sizeof(*prune) * prune_num);
|
||
|
prune[prune_num-2] = ce->name;
|
||
|
@@ -837,6 +838,7 @@ static void prepare_show_merge(struct rev_info *revs)
|
||
|
i++;
|
||
|
}
|
||
|
revs->prune_data = prune;
|
||
|
+ revs->glob_paths = 0;
|
||
|
revs->limited = 1;
|
||
|
}
|
||
|
|
||
|
@@ -1033,6 +1035,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
||
|
revs->min_age = approxidate(arg + 8);
|
||
|
} else if (!strcmp(arg, "--first-parent")) {
|
||
|
revs->first_parent_only = 1;
|
||
|
+ } else if (!strcmp(arg, "--glob-paths")) {
|
||
|
+ revs->glob_paths = 1;
|
||
|
} else if (!strcmp(arg, "-g") || !strcmp(arg, "--walk-reflogs")) {
|
||
|
init_reflog_walk(&revs->reflog_info);
|
||
|
} else if (!strcmp(arg, "--default")) {
|
||
|
@@ -1220,6 +1224,7 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
|
||
|
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
|
||
|
{
|
||
|
int i, flags, left, seen_dashdash;
|
||
|
+ const char **paths = NULL;
|
||
|
|
||
|
/* First, search for "--" */
|
||
|
seen_dashdash = 0;
|
||
|
@@ -1230,7 +1235,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||
|
argv[i] = NULL;
|
||
|
argc = i;
|
||
|
if (argv[i + 1])
|
||
|
- revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
|
||
|
+ paths = argv + i + 1;
|
||
|
seen_dashdash = 1;
|
||
|
break;
|
||
|
}
|
||
|
@@ -1290,6 +1295,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||
|
if (seen_dashdash || *arg == '^')
|
||
|
die("bad revision '%s'", arg);
|
||
|
|
||
|
+ if (revs->glob_paths)
|
||
|
+ die("--glob-paths without --");
|
||
|
+
|
||
|
/* If we didn't have a "--":
|
||
|
* (1) all filenames must exist;
|
||
|
* (2) all rev-args must not be interpretable
|
||
|
@@ -1301,10 +1309,19 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||
|
|
||
|
revs->prune_data = get_pathspec(revs->prefix,
|
||
|
argv + i);
|
||
|
+ revs->glob_paths = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ /* Third, handle paths listed after -- */
|
||
|
+ if (paths != NULL) {
|
||
|
+ if (revs->glob_paths)
|
||
|
+ revs->prune_data = paths;
|
||
|
+ else
|
||
|
+ revs->prune_data = get_pathspec(revs->prefix, paths);
|
||
|
+ }
|
||
|
+
|
||
|
if (revs->def == NULL)
|
||
|
revs->def = def;
|
||
|
if (revs->show_merge)
|
||
|
@@ -1333,12 +1350,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||
|
revs->limited = 1;
|
||
|
|
||
|
if (revs->prune_data) {
|
||
|
- diff_tree_setup_paths(revs->prune_data, &revs->pruning);
|
||
|
+ diff_tree_setup_paths(revs->prune_data, &revs->pruning,
|
||
|
+ revs->glob_paths);
|
||
|
/* Can't prune commits with rename following: the paths change.. */
|
||
|
if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
|
||
|
revs->prune = 1;
|
||
|
if (!revs->full_diff)
|
||
|
- diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
|
||
|
+ diff_tree_setup_paths(revs->prune_data, &revs->diffopt,
|
||
|
+ revs->glob_paths);
|
||
|
}
|
||
|
if (revs->combine_merges) {
|
||
|
revs->ignore_merges = 0;
|
||
|
diff --git a/revision.h b/revision.h
|
||
|
index fa68c65..a68cdb8 100644
|
||
|
--- a/revision.h
|
||
|
+++ b/revision.h
|
||
|
@@ -32,6 +32,9 @@ struct rev_info {
|
||
|
void *prune_data;
|
||
|
unsigned int early_output;
|
||
|
|
||
|
+ /* whether prune_data contains fnmatch() patterns */
|
||
|
+ unsigned int glob_paths:1;
|
||
|
+
|
||
|
/* Traversal flags */
|
||
|
unsigned int dense:1,
|
||
|
prune:1,
|
||
|
diff --git a/tree-diff.c b/tree-diff.c
|
||
|
index bbb126f..0aa1e9b 100644
|
||
|
--- a/tree-diff.c
|
||
|
+++ b/tree-diff.c
|
||
|
@@ -82,6 +82,11 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int tree_entry_interesting_globbed(struct tree_desc *, const char *,
|
||
|
+ int, struct diff_options *);
|
||
|
+static int tree_entry_interesting_standard(struct tree_desc *, const char *,
|
||
|
+ int, struct diff_options *);
|
||
|
+
|
||
|
/*
|
||
|
* Is a tree entry interesting given the pathspec we have?
|
||
|
*
|
||
|
@@ -91,7 +96,19 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
|
||
|
* - zero for no
|
||
|
* - negative for "no, and no subsequent entries will be either"
|
||
|
*/
|
||
|
-static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)
|
||
|
+static int tree_entry_interesting(struct tree_desc *desc,
|
||
|
+ const char *base, int baselen, struct diff_options *opt)
|
||
|
+{
|
||
|
+ if (opt->glob_paths)
|
||
|
+ return tree_entry_interesting_globbed(desc, base,
|
||
|
+ baselen, opt);
|
||
|
+ else
|
||
|
+ return tree_entry_interesting_standard(desc, base,
|
||
|
+ baselen, opt);
|
||
|
+}
|
||
|
+
|
||
|
+static int tree_entry_interesting_standard(struct tree_desc *desc,
|
||
|
+ const char *base, int baselen, struct diff_options *opt)
|
||
|
{
|
||
|
const char *path;
|
||
|
const unsigned char *sha1;
|
||
|
@@ -190,6 +207,41 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
|
||
|
return never_interesting; /* No matches */
|
||
|
}
|
||
|
|
||
|
+static int tree_entry_interesting_globbed(struct tree_desc *desc,
|
||
|
+ const char *base, int baselen, struct diff_options *opt)
|
||
|
+{
|
||
|
+ const char *path;
|
||
|
+ char *fullpath;
|
||
|
+ const unsigned char *sha1;
|
||
|
+ unsigned mode;
|
||
|
+ int i;
|
||
|
+ int pathlen;
|
||
|
+ int result;
|
||
|
+
|
||
|
+ if (!opt->nr_paths)
|
||
|
+ return 1;
|
||
|
+ sha1 = tree_entry_extract(desc, &path, &mode);
|
||
|
+ if (S_ISDIR(mode))
|
||
|
+ return 1;
|
||
|
+ pathlen = tree_entry_len(path, sha1);
|
||
|
+
|
||
|
+ fullpath = xmalloc(pathlen + baselen + 1);
|
||
|
+ memcpy(fullpath, base, baselen);
|
||
|
+ memcpy(fullpath + baselen, path, pathlen + 1);
|
||
|
+
|
||
|
+ result = 0;
|
||
|
+ for (i = 0; i < opt->nr_paths; i++) {
|
||
|
+ const char *match = opt->paths[i];
|
||
|
+ if (!fnmatch(match, fullpath, 0)) {
|
||
|
+ result = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ free(fullpath);
|
||
|
+ return result;
|
||
|
+}
|
||
|
+
|
||
|
/* A whole sub-tree went away or appeared */
|
||
|
static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen)
|
||
|
{
|
||
|
@@ -338,7 +390,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
|
||
|
diff_opts.single_follow = opt->paths[0];
|
||
|
diff_opts.break_opt = opt->break_opt;
|
||
|
paths[0] = NULL;
|
||
|
- diff_tree_setup_paths(paths, &diff_opts);
|
||
|
+ diff_tree_setup_paths(paths, &diff_opts, 0);
|
||
|
if (diff_setup_done(&diff_opts) < 0)
|
||
|
die("unable to set up diff options to follow renames");
|
||
|
diff_tree(t1, t2, base, &diff_opts);
|
||
|
@@ -362,7 +414,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
|
||
|
/* Update the path we use from now on.. */
|
||
|
diff_tree_release_paths(opt);
|
||
|
opt->paths[0] = xstrdup(p->one->path);
|
||
|
- diff_tree_setup_paths(opt->paths, opt);
|
||
|
+ diff_tree_setup_paths(opt->paths, opt, 0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
@@ -440,11 +492,13 @@ void diff_tree_release_paths(struct diff_options *opt)
|
||
|
free(opt->pathlens);
|
||
|
}
|
||
|
|
||
|
-void diff_tree_setup_paths(const char **p, struct diff_options *opt)
|
||
|
+void diff_tree_setup_paths(const char **p, struct diff_options *opt,
|
||
|
+ int glob_paths)
|
||
|
{
|
||
|
opt->nr_paths = 0;
|
||
|
opt->pathlens = NULL;
|
||
|
opt->paths = NULL;
|
||
|
+ opt->glob_paths = glob_paths;
|
||
|
|
||
|
if (p) {
|
||
|
int i;
|