Skip to content

Commit c08397e

Browse files
bmwillgitster
authored andcommitted
pathspec: remove PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE flag
Since (ae8d082 pathspec: pass directory indicator to match_pathspec_item()) the path matching logic has been able to cope with submodules without needing to strip off a trailing slash if a path refers to a submodule. Since the stripping the trailing slash is no longer necessary, remove the PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE flag. In addition, factor out the logic which dies if a path decends into a submodule so that it can still be used as a check after a pathspec struct has been initialized. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent bdab972 commit c08397e

6 files changed

Lines changed: 44 additions & 43 deletions

File tree

builtin/add.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
388388
*/
389389
parse_pathspec(&pathspec, 0,
390390
PATHSPEC_PREFER_FULL |
391-
PATHSPEC_SYMLINK_LEADING_PATH |
392-
PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
391+
PATHSPEC_SYMLINK_LEADING_PATH,
393392
prefix, argv);
394393

394+
die_path_inside_submodule(&the_index, &pathspec);
395+
395396
if (add_new_files) {
396397
int baselen;
397398

builtin/check-ignore.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "quote.h"
55
#include "pathspec.h"
66
#include "parse-options.h"
7+
#include "submodule.h"
78

89
static int quiet, verbose, stdin_paths, show_non_matching, no_index;
910
static const char * const check_ignore_usage[] = {
@@ -87,10 +88,11 @@ static int check_ignore(struct dir_struct *dir,
8788
parse_pathspec(&pathspec,
8889
PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
8990
PATHSPEC_SYMLINK_LEADING_PATH |
90-
PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE |
9191
PATHSPEC_KEEP_ORDER,
9292
prefix, argv);
9393

94+
die_path_inside_submodule(&the_index, &pathspec);
95+
9496
/*
9597
* look for pathspecs matching entries in the index, since these
9698
* should not be ignored, in order to be consistent with

pathspec.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -398,32 +398,6 @@ static void strip_submodule_slash_cheap(struct pathspec_item *item)
398398
}
399399
}
400400

401-
static void strip_submodule_slash_expensive(struct pathspec_item *item)
402-
{
403-
int i;
404-
405-
for (i = 0; i < active_nr; i++) {
406-
struct cache_entry *ce = active_cache[i];
407-
int ce_len = ce_namelen(ce);
408-
409-
if (!S_ISGITLINK(ce->ce_mode))
410-
continue;
411-
412-
if (item->len <= ce_len || item->match[ce_len] != '/' ||
413-
memcmp(ce->name, item->match, ce_len))
414-
continue;
415-
416-
if (item->len == ce_len + 1) {
417-
/* strip trailing slash */
418-
item->len--;
419-
item->match[item->len] = '\0';
420-
} else {
421-
die(_("Pathspec '%s' is in submodule '%.*s'"),
422-
item->original, ce_len, ce->name);
423-
}
424-
}
425-
}
426-
427401
/*
428402
* Perform the initialization of a pathspec_item based on a pathspec element.
429403
*/
@@ -499,9 +473,6 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
499473
if (flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP)
500474
strip_submodule_slash_cheap(item);
501475

502-
if (flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE)
503-
strip_submodule_slash_expensive(item);
504-
505476
if (magic & PATHSPEC_LITERAL) {
506477
item->nowildcard_len = item->len;
507478
} else {

pathspec.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,15 @@ struct pathspec {
6262
#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (1<<3)
6363
/* die if a symlink is part of the given path's directory */
6464
#define PATHSPEC_SYMLINK_LEADING_PATH (1<<4)
65-
/*
66-
* This is like a combination of ..LEADING_PATH and .._SLASH_CHEAP
67-
* (but not the same): it strips the trailing slash if the given path
68-
* is a gitlink but also checks and dies if gitlink is part of the
69-
* leading path (i.e. the given path goes beyond a submodule). It's
70-
* safer than _SLASH_CHEAP and also more expensive.
71-
*/
72-
#define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (1<<5)
73-
#define PATHSPEC_PREFIX_ORIGIN (1<<6)
74-
#define PATHSPEC_KEEP_ORDER (1<<7)
65+
#define PATHSPEC_PREFIX_ORIGIN (1<<5)
66+
#define PATHSPEC_KEEP_ORDER (1<<6)
7567
/*
7668
* For the callers that just need pure paths from somewhere else, not
7769
* from command line. Global --*-pathspecs options are ignored. No
7870
* magic is parsed in each pathspec either. If PATHSPEC_LITERAL is
7971
* allowed, then it will automatically set for every pathspec.
8072
*/
81-
#define PATHSPEC_LITERAL_PATH (1<<8)
73+
#define PATHSPEC_LITERAL_PATH (1<<7)
8274

8375
extern void parse_pathspec(struct pathspec *pathspec,
8476
unsigned magic_mask,

submodule.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,39 @@ void die_in_unpopulated_submodule(const struct index_state *istate,
312312
}
313313
}
314314

315+
/*
316+
* Dies if any paths in the provided pathspec descends into a submodule
317+
*/
318+
void die_path_inside_submodule(const struct index_state *istate,
319+
const struct pathspec *ps)
320+
{
321+
int i, j;
322+
323+
for (i = 0; i < istate->cache_nr; i++) {
324+
struct cache_entry *ce = istate->cache[i];
325+
int ce_len = ce_namelen(ce);
326+
327+
if (!S_ISGITLINK(ce->ce_mode))
328+
continue;
329+
330+
for (j = 0; j < ps->nr ; j++) {
331+
const struct pathspec_item *item = &ps->items[j];
332+
333+
if (item->len <= ce_len)
334+
continue;
335+
if (item->match[ce_len] != '/')
336+
continue;
337+
if (strncmp(ce->name, item->match, ce_len))
338+
continue;
339+
if (item->len == ce_len + 1)
340+
continue;
341+
342+
die(_("Pathspec '%s' is in submodule '%.*s'"),
343+
item->original, ce_len, ce->name);
344+
}
345+
}
346+
}
347+
315348
int parse_submodule_update_strategy(const char *value,
316349
struct submodule_update_strategy *dst)
317350
{

submodule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ extern int is_submodule_initialized(const char *path);
5151
extern int is_submodule_populated_gently(const char *path, int *return_error_code);
5252
extern void die_in_unpopulated_submodule(const struct index_state *istate,
5353
const char *prefix);
54+
extern void die_path_inside_submodule(const struct index_state *istate,
55+
const struct pathspec *ps);
5456
extern int parse_submodule_update_strategy(const char *value,
5557
struct submodule_update_strategy *dst);
5658
extern const char *submodule_strategy_to_string(const struct submodule_update_strategy *s);

0 commit comments

Comments
 (0)