Skip to content

Commit 1a15fed

Browse files
committed
Merge branch 'jk/add-empty' into ei/oneline+add-empty
* jk/add-empty: builtin-add: simplify (and increase accuracy of) exclude handling dir_struct: add collect_ignored option
2 parents c927e6c + e96980e commit 1a15fed

File tree

3 files changed

+51
-53
lines changed

3 files changed

+51
-53
lines changed

builtin-add.c

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -40,42 +40,29 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
4040
dir->nr = dst - dir->entries;
4141

4242
for (i = 0; i < specs; i++) {
43-
struct stat st;
44-
const char *match;
45-
if (seen[i])
46-
continue;
47-
48-
match = pathspec[i];
49-
if (!match[0])
50-
continue;
51-
52-
/* Existing file? We must have ignored it */
53-
if (!lstat(match, &st)) {
54-
struct dir_entry *ent;
55-
56-
ent = dir_add_name(dir, match, strlen(match));
57-
ent->ignored = 1;
58-
if (S_ISDIR(st.st_mode))
59-
ent->ignored_dir = 1;
60-
continue;
61-
}
62-
die("pathspec '%s' did not match any files", match);
43+
if (!seen[i] && !file_exists(pathspec[i]))
44+
die("pathspec '%s' did not match any files",
45+
pathspec[i]);
6346
}
6447
}
6548

66-
static void fill_directory(struct dir_struct *dir, const char **pathspec)
49+
static void fill_directory(struct dir_struct *dir, const char **pathspec,
50+
int ignored_too)
6751
{
6852
const char *path, *base;
6953
int baselen;
7054

7155
/* Set up the default git porcelain excludes */
7256
memset(dir, 0, sizeof(*dir));
73-
dir->exclude_per_dir = ".gitignore";
74-
path = git_path("info/exclude");
75-
if (!access(path, R_OK))
76-
add_excludes_from_file(dir, path);
77-
if (!access(excludes_file, R_OK))
78-
add_excludes_from_file(dir, excludes_file);
57+
if (!ignored_too) {
58+
dir->collect_ignored = 1;
59+
dir->exclude_per_dir = ".gitignore";
60+
path = git_path("info/exclude");
61+
if (!access(path, R_OK))
62+
add_excludes_from_file(dir, path);
63+
if (!access(excludes_file, R_OK))
64+
add_excludes_from_file(dir, excludes_file);
65+
}
7966

8067
/*
8168
* Calculate common prefix for the pathspec, and
@@ -219,13 +206,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
219206
}
220207
pathspec = get_pathspec(prefix, argv + i);
221208

222-
fill_directory(&dir, pathspec);
209+
fill_directory(&dir, pathspec, ignored_too);
223210

224211
if (show_only) {
225212
const char *sep = "", *eof = "";
226213
for (i = 0; i < dir.nr; i++) {
227-
if (!ignored_too && dir.entries[i]->ignored)
228-
continue;
229214
printf("%s%s", sep, dir.entries[i]->name);
230215
sep = " ";
231216
eof = "\n";
@@ -237,25 +222,13 @@ int cmd_add(int argc, const char **argv, const char *prefix)
237222
if (read_cache() < 0)
238223
die("index file corrupt");
239224

240-
if (!ignored_too) {
241-
int has_ignored = 0;
242-
for (i = 0; i < dir.nr; i++)
243-
if (dir.entries[i]->ignored)
244-
has_ignored = 1;
245-
if (has_ignored) {
246-
fprintf(stderr, ignore_warning);
247-
for (i = 0; i < dir.nr; i++) {
248-
if (!dir.entries[i]->ignored)
249-
continue;
250-
fprintf(stderr, "%s", dir.entries[i]->name);
251-
if (dir.entries[i]->ignored_dir)
252-
fprintf(stderr, " (directory)");
253-
fputc('\n', stderr);
254-
}
255-
fprintf(stderr,
256-
"Use -f if you really want to add them.\n");
257-
exit(1);
225+
if (dir.ignored_nr) {
226+
fprintf(stderr, ignore_warning);
227+
for (i = 0; i < dir.ignored_nr; i++) {
228+
fprintf(stderr, "%s\n", dir.ignored[i]->name);
258229
}
230+
fprintf(stderr, "Use -f if you really want to add them.\n");
231+
exit(1);
259232
}
260233

261234
for (i = 0; i < dir.nr; i++)

dir.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len) {
275275
struct dir_entry *ent;
276276

277277
ent = xmalloc(sizeof(*ent) + len + 1);
278-
ent->ignored = ent->ignored_dir = 0;
279278
ent->len = len;
280279
memcpy(ent->name, pathname, len);
281280
ent->name[len] = 0;
@@ -291,6 +290,15 @@ struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int
291290
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
292291
}
293292

293+
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
294+
{
295+
if (cache_name_pos(pathname, len) >= 0)
296+
return NULL;
297+
298+
ALLOC_GROW(dir->ignored, dir->ignored_nr, dir->ignored_alloc);
299+
return dir->ignored[dir->ignored_nr++] = dir_entry_new(pathname, len);
300+
}
301+
294302
enum exist_status {
295303
index_nonexistent = 0,
296304
index_directory,
@@ -423,6 +431,18 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
423431
return 0;
424432
}
425433

434+
static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
435+
{
436+
if (simplify) {
437+
for (; simplify->path; simplify++) {
438+
if (len == simplify->len
439+
&& !memcmp(path, simplify->path, len))
440+
return 1;
441+
}
442+
}
443+
return 0;
444+
}
445+
426446
/*
427447
* Read a directory tree. We currently ignore anything but
428448
* directories, regular files and symlinks. That's because git
@@ -463,6 +483,9 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
463483
continue;
464484

465485
exclude = excluded(dir, fullname);
486+
if (exclude && dir->collect_ignored
487+
&& in_pathspec(fullname, baselen + len, simplify))
488+
dir_add_ignored(dir, fullname, baselen + len);
466489
if (exclude != dir->show_ignored) {
467490
if (!dir->show_ignored || DTYPE(de) != DT_DIR) {
468491
continue;
@@ -609,6 +632,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
609632
read_directory_recursive(dir, path, base, baselen, 0, simplify);
610633
free_simplify(simplify);
611634
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
635+
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
612636
return dir->nr;
613637
}
614638

dir.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313

1414

1515
struct dir_entry {
16-
unsigned int ignored : 1;
17-
unsigned int ignored_dir : 1;
18-
unsigned int len : 30;
16+
unsigned int len;
1917
char name[FLEX_ARRAY]; /* more */
2018
};
2119

@@ -31,11 +29,14 @@ struct exclude_list {
3129

3230
struct dir_struct {
3331
int nr, alloc;
32+
int ignored_nr, ignored_alloc;
3433
unsigned int show_ignored:1,
3534
show_other_directories:1,
3635
hide_empty_directories:1,
37-
no_gitlinks:1;
36+
no_gitlinks:1,
37+
collect_ignored:1;
3838
struct dir_entry **entries;
39+
struct dir_entry **ignored;
3940

4041
/* Exclude info */
4142
const char *exclude_per_dir;

0 commit comments

Comments
 (0)