Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit ae8d082

Browse files
pcloudsgitster
authored andcommitted
pathspec: pass directory indicator to match_pathspec_item()
This patch activates the DO_MATCH_DIRECTORY code in m_p_i(), which makes "git diff HEAD submodule/" and "git diff HEAD submodule" produce the same output. Previously only the version without trailing slash returns the difference (if any). That's the effect of new ce_path_match(). dir_path_match() is not executed by the new tests. And it should not introduce regressions. Previously if path "dir/" is passed in with pathspec "dir/", they obviously match. With new dir_path_match(), the path becomes _directory_ "dir" vs pathspec "dir/", which is not executed by the old code path in m_p_i(). The new code path is executed and produces the same result. The other case is pathspec "dir" and path "dir/" is now turned to "dir" (with DO_MATCH_DIRECTORY). Still the same result before or after the patch. So why change? Because of the next patch about clean.c. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 68690fd commit ae8d082

File tree

6 files changed

+20
-9
lines changed

6 files changed

+20
-9
lines changed

builtin/clean.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
962962

963963
if (pathspec.nr)
964964
matches = match_pathspec(&pathspec, ent->name,
965-
len, 0, NULL);
965+
len, 0, NULL, 0);
966966

967967
if (S_ISDIR(st.st_mode)) {
968968
if (remove_directories || (matches == MATCHED_EXACTLY)) {

builtin/ls-files.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
140140
die("git ls-files: internal error - cache entry not superset of prefix");
141141

142142
if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce),
143-
len, ps_matched))
143+
len, ps_matched,
144+
S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)))
144145
return;
145146

146147
if (tag && *tag && show_valid_bit &&
@@ -197,7 +198,7 @@ static void show_ru_info(void)
197198
if (len < max_prefix_len)
198199
continue; /* outside of the prefix */
199200
if (!match_pathspec(&pathspec, path, len,
200-
max_prefix_len, ps_matched))
201+
max_prefix_len, ps_matched, 0))
201202
continue; /* uninterested */
202203
for (i = 0; i < 3; i++) {
203204
if (!ui->mode[i])

dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,10 @@ static int do_match_pathspec(const struct pathspec *ps,
360360

361361
int match_pathspec(const struct pathspec *ps,
362362
const char *name, int namelen,
363-
int prefix, char *seen)
363+
int prefix, char *seen, int is_dir)
364364
{
365365
int positive, negative;
366-
unsigned flags = 0;
366+
unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;
367367
positive = do_match_pathspec(ps, name, namelen,
368368
prefix, seen, flags);
369369
if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)

dir.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ extern int no_wildcard(const char *string);
134134
extern char *common_prefix(const struct pathspec *pathspec);
135135
extern int match_pathspec(const struct pathspec *pathspec,
136136
const char *name, int namelen,
137-
int prefix, char *seen);
137+
int prefix, char *seen, int is_dir);
138138
extern int within_depth(const char *name, int namelen, int depth, int max_depth);
139139

140140
extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);
@@ -209,14 +209,18 @@ static inline int ce_path_match(const struct cache_entry *ce,
209209
const struct pathspec *pathspec,
210210
char *seen)
211211
{
212-
return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
212+
return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen,
213+
S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode));
213214
}
214215

215216
static inline int dir_path_match(const struct dir_entry *ent,
216217
const struct pathspec *pathspec,
217218
int prefix, char *seen)
218219
{
219-
return match_pathspec(pathspec, ent->name, ent->len, prefix, seen);
220+
int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/';
221+
int len = has_trailing_dir ? ent->len - 1 : ent->len;
222+
return match_pathspec(pathspec, ent->name, len, prefix, seen,
223+
has_trailing_dir);
220224
}
221225

222226
#endif

rerere.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ int rerere_forget(struct pathspec *pathspec)
673673
for (i = 0; i < conflict.nr; i++) {
674674
struct string_list_item *it = &conflict.items[i];
675675
if (!match_pathspec(pathspec, it->string,
676-
strlen(it->string), 0, NULL))
676+
strlen(it->string), 0, NULL, 0))
677677
continue;
678678
rerere_forget_one_path(it->string, &merge_rr);
679679
}

t/t4010-diff-pathspec.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,10 @@ test_expect_success 'diff-tree ignores trailing slash on submodule path' '
127127
test_cmp expect actual
128128
'
129129

130+
test_expect_success 'diff-cache ignores trailing slash on submodule path' '
131+
git diff --name-only HEAD^ submod >expect &&
132+
git diff --name-only HEAD^ submod/ >actual &&
133+
test_cmp expect actual
134+
'
135+
130136
test_done

0 commit comments

Comments
 (0)