Skip to content

Commit 8fbe9b3

Browse files
committed
Merge branch 'jl/add-n-ignore-missing'
* jl/add-n-ignore-missing: git add: Add the "--ignore-missing" option for the dry run
2 parents 8ac3a66 + 108da0d commit 8fbe9b3

5 files changed

Lines changed: 47 additions & 6 deletions

File tree

Documentation/git-add.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ OPTIONS
5757

5858
-n::
5959
--dry-run::
60-
Don't actually add the file(s), just show if they exist.
60+
Don't actually add the file(s), just show if they exist and/or will
61+
be ignored.
6162

6263
-v::
6364
--verbose::
@@ -131,6 +132,12 @@ subdirectories.
131132
them, do not abort the operation, but continue adding the
132133
others. The command shall still exit with non-zero status.
133134

135+
--ignore-missing::
136+
This option can only be used together with --dry-run. By using
137+
this option the user can check if any of the given files would
138+
be ignored, no matter if they are already present in the work
139+
tree or not.
140+
134141
\--::
135142
This option can be used to separate command-line options from
136143
the list of files, (useful when filenames might be mistaken

builtin/add.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ static const char ignore_error[] =
310310
"The following paths are ignored by one of your .gitignore files:\n";
311311

312312
static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
313-
static int ignore_add_errors, addremove, intent_to_add;
313+
static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
314314

315315
static struct option builtin_add_options[] = {
316316
OPT__DRY_RUN(&show_only),
@@ -325,6 +325,7 @@ static struct option builtin_add_options[] = {
325325
OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
326326
OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
327327
OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
328+
OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, "check if - even missing - files are ignored in dry run"),
328329
OPT_END(),
329330
};
330331

@@ -385,6 +386,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
385386

386387
if (addremove && take_worktree_changes)
387388
die("-A and -u are mutually incompatible");
389+
if (!show_only && ignore_missing)
390+
die("Option --ignore-missing can only be used together with --dry-run");
388391
if ((addremove || take_worktree_changes) && !argc) {
389392
static const char *here[2] = { ".", NULL };
390393
argc = 1;
@@ -441,9 +444,14 @@ int cmd_add(int argc, const char **argv, const char *prefix)
441444
seen = find_used_pathspec(pathspec);
442445
for (i = 0; pathspec[i]; i++) {
443446
if (!seen[i] && pathspec[i][0]
444-
&& !file_exists(pathspec[i]))
445-
die("pathspec '%s' did not match any files",
446-
pathspec[i]);
447+
&& !file_exists(pathspec[i])) {
448+
if (ignore_missing) {
449+
if (excluded(&dir, pathspec[i], DT_UNKNOWN))
450+
dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
451+
} else
452+
die("pathspec '%s' did not match any files",
453+
pathspec[i]);
454+
}
447455
}
448456
free(seen);
449457
}

dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna
453453
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
454454
}
455455

456-
static struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
456+
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
457457
{
458458
if (!cache_name_is_other(pathname, len))
459459
return NULL;

dir.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const
7272
extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,
7373
int *dtype, struct exclude_list *el);
7474
extern int excluded(struct dir_struct *, const char *, int *);
75+
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len);
7576
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
7677
char **buf_p, struct exclude_list *which, int check_index);
7778
extern void add_excludes_from_file(struct dir_struct *, const char *fname);

t/t3700-add.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,29 @@ test_expect_success '"add non-existent" should fail' '
260260
! (git ls-files | grep "non-existent")
261261
'
262262

263+
test_expect_success 'git add --dry-run of existing changed file' "
264+
echo new >>track-this &&
265+
git add --dry-run track-this >actual 2>&1 &&
266+
echo \"add 'track-this'\" | test_cmp - actual
267+
"
268+
269+
test_expect_success 'git add --dry-run of non-existing file' "
270+
echo ignored-file >>.gitignore &&
271+
! (git add --dry-run track-this ignored-file >actual 2>&1) &&
272+
echo \"fatal: pathspec 'ignored-file' did not match any files\" | test_cmp - actual
273+
"
274+
275+
cat >expect <<EOF
276+
The following paths are ignored by one of your .gitignore files:
277+
ignored-file
278+
Use -f if you really want to add them.
279+
fatal: no files added
280+
add 'track-this'
281+
EOF
282+
283+
test_expect_success 'git add --dry-run --ignore-missing of non-existing file' '
284+
!(git add --dry-run --ignore-missing track-this ignored-file >actual 2>&1) &&
285+
test_cmp expect actual
286+
'
287+
263288
test_done

0 commit comments

Comments
 (0)