git add: Add the "--ignore-missing" option for the dry run
Sometimes it is useful to know if a file or directory will be ignored before it is added to the work tree. An example is "git submodule add", where it would be really nice to be able to fail with an appropriate error message before the submodule is cloned and checked out. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
637ab29b86
commit
108da0db12
@ -57,7 +57,8 @@ OPTIONS
|
|||||||
|
|
||||||
-n::
|
-n::
|
||||||
--dry-run::
|
--dry-run::
|
||||||
Don't actually add the file(s), just show if they exist.
|
Don't actually add the file(s), just show if they exist and/or will
|
||||||
|
be ignored.
|
||||||
|
|
||||||
-v::
|
-v::
|
||||||
--verbose::
|
--verbose::
|
||||||
@ -131,6 +132,12 @@ subdirectories.
|
|||||||
them, do not abort the operation, but continue adding the
|
them, do not abort the operation, but continue adding the
|
||||||
others. The command shall still exit with non-zero status.
|
others. The command shall still exit with non-zero status.
|
||||||
|
|
||||||
|
--ignore-missing::
|
||||||
|
This option can only be used together with --dry-run. By using
|
||||||
|
this option the user can check if any of the given files would
|
||||||
|
be ignored, no matter if they are already present in the work
|
||||||
|
tree or not.
|
||||||
|
|
||||||
\--::
|
\--::
|
||||||
This option can be used to separate command-line options from
|
This option can be used to separate command-line options from
|
||||||
the list of files, (useful when filenames might be mistaken
|
the list of files, (useful when filenames might be mistaken
|
||||||
|
@ -310,7 +310,7 @@ static const char ignore_error[] =
|
|||||||
"The following paths are ignored by one of your .gitignore files:\n";
|
"The following paths are ignored by one of your .gitignore files:\n";
|
||||||
|
|
||||||
static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
|
static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
|
||||||
static int ignore_add_errors, addremove, intent_to_add;
|
static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
|
||||||
|
|
||||||
static struct option builtin_add_options[] = {
|
static struct option builtin_add_options[] = {
|
||||||
OPT__DRY_RUN(&show_only),
|
OPT__DRY_RUN(&show_only),
|
||||||
@ -325,6 +325,7 @@ static struct option builtin_add_options[] = {
|
|||||||
OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
|
OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
|
||||||
OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
|
OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
|
||||||
OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
|
OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
|
||||||
|
OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, "check if - even missing - files are ignored in dry run"),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -385,6 +386,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
if (addremove && take_worktree_changes)
|
if (addremove && take_worktree_changes)
|
||||||
die("-A and -u are mutually incompatible");
|
die("-A and -u are mutually incompatible");
|
||||||
|
if (!show_only && ignore_missing)
|
||||||
|
die("Option --ignore-missing can only be used together with --dry-run");
|
||||||
if ((addremove || take_worktree_changes) && !argc) {
|
if ((addremove || take_worktree_changes) && !argc) {
|
||||||
static const char *here[2] = { ".", NULL };
|
static const char *here[2] = { ".", NULL };
|
||||||
argc = 1;
|
argc = 1;
|
||||||
@ -441,9 +444,14 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||||||
seen = find_used_pathspec(pathspec);
|
seen = find_used_pathspec(pathspec);
|
||||||
for (i = 0; pathspec[i]; i++) {
|
for (i = 0; pathspec[i]; i++) {
|
||||||
if (!seen[i] && pathspec[i][0]
|
if (!seen[i] && pathspec[i][0]
|
||||||
&& !file_exists(pathspec[i]))
|
&& !file_exists(pathspec[i])) {
|
||||||
die("pathspec '%s' did not match any files",
|
if (ignore_missing) {
|
||||||
pathspec[i]);
|
if (excluded(&dir, pathspec[i], DT_UNKNOWN))
|
||||||
|
dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
|
||||||
|
} else
|
||||||
|
die("pathspec '%s' did not match any files",
|
||||||
|
pathspec[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(seen);
|
free(seen);
|
||||||
}
|
}
|
||||||
|
2
dir.c
2
dir.c
@ -453,7 +453,7 @@ static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna
|
|||||||
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
|
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
|
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
|
||||||
{
|
{
|
||||||
if (!cache_name_is_other(pathname, len))
|
if (!cache_name_is_other(pathname, len))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
1
dir.h
1
dir.h
@ -72,6 +72,7 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const
|
|||||||
extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,
|
extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,
|
||||||
int *dtype, struct exclude_list *el);
|
int *dtype, struct exclude_list *el);
|
||||||
extern int excluded(struct dir_struct *, const char *, int *);
|
extern int excluded(struct dir_struct *, const char *, int *);
|
||||||
|
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len);
|
||||||
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
|
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
|
||||||
char **buf_p, struct exclude_list *which, int check_index);
|
char **buf_p, struct exclude_list *which, int check_index);
|
||||||
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
|
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
|
||||||
|
@ -260,4 +260,29 @@ test_expect_success '"add non-existent" should fail' '
|
|||||||
! (git ls-files | grep "non-existent")
|
! (git ls-files | grep "non-existent")
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git add --dry-run of existing changed file' "
|
||||||
|
echo new >>track-this &&
|
||||||
|
git add --dry-run track-this >actual 2>&1 &&
|
||||||
|
echo \"add 'track-this'\" | test_cmp - actual
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success 'git add --dry-run of non-existing file' "
|
||||||
|
echo ignored-file >>.gitignore &&
|
||||||
|
! (git add --dry-run track-this ignored-file >actual 2>&1) &&
|
||||||
|
echo \"fatal: pathspec 'ignored-file' did not match any files\" | test_cmp - actual
|
||||||
|
"
|
||||||
|
|
||||||
|
cat >expect <<EOF
|
||||||
|
The following paths are ignored by one of your .gitignore files:
|
||||||
|
ignored-file
|
||||||
|
Use -f if you really want to add them.
|
||||||
|
fatal: no files added
|
||||||
|
add 'track-this'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'git add --dry-run --ignore-missing of non-existing file' '
|
||||||
|
!(git add --dry-run --ignore-missing track-this ignored-file >actual 2>&1) &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user