Merge branch 'jl/add-n-ignore-missing'
authorJunio C Hamano <gitster@pobox.com>
Mon, 19 Jul 2010 18:09:38 +0000 (11:09 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 Jul 2010 18:09:38 +0000 (11:09 -0700)
* jl/add-n-ignore-missing:
git add: Add the "--ignore-missing" option for the dry run

Documentation/git-add.txt
builtin/add.c
dir.c
dir.h
t/t3700-add.sh
index 74741a42f409a7af5c60584a0d3b7a0be851811c..bfea2c2d62ca7112fca8d8e78f2bc71503d2a889 100644 (file)
@@ -57,7 +57,8 @@ OPTIONS
 
 -n::
 --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::
 --verbose::
@@ -131,6 +132,12 @@ subdirectories.
        them, do not abort the operation, but continue adding the
        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
        the list of files, (useful when filenames might be mistaken
index 17149cfeedcc39956dc55f8b72acc1227fed5213..56a4e0af6b35ea9f6d86accad27a1c87bc5ad0d9 100644 (file)
@@ -310,7 +310,7 @@ static const char ignore_error[] =
 "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 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[] = {
        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( 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-missing", &ignore_missing, "check if - even missing - files are ignored in dry run"),
        OPT_END(),
 };
 
@@ -385,6 +386,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
        if (addremove && take_worktree_changes)
                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) {
                static const char *here[2] = { ".", NULL };
                argc = 1;
@@ -441,9 +444,14 @@ int cmd_add(int argc, const char **argv, const char *prefix)
                        seen = find_used_pathspec(pathspec);
                for (i = 0; pathspec[i]; i++) {
                        if (!seen[i] && pathspec[i][0]
-                           && !file_exists(pathspec[i]))
-                               die("pathspec '%s' did not match any files",
-                                   pathspec[i]);
+                           && !file_exists(pathspec[i])) {
+                               if (ignore_missing) {
+                                       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);
        }
diff --git a/dir.c b/dir.c
index 151ea670d961d39394990f122469557b6f217de3..133f472a1e73786e781c1021eea17e543858937f 100644 (file)
--- a/dir.c
+++ b/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);
 }
 
-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))
                return NULL;
diff --git a/dir.h b/dir.h
index 3bead5f0e25a864c34f515b7bff4c89b55ce84fe..278d84cdf7df01c33a45e6dc9c20592cecff9d85 100644 (file)
--- a/dir.h
+++ b/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,
                              int *dtype, struct exclude_list *el);
 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,
                                          char **buf_p, struct exclude_list *which, int check_index);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
index 6f031af9f35e4d6350e8e6dd4619d55c66214aa6..47fbf5362f38c1618661562d31b63821304c63a7 100755 (executable)
@@ -260,4 +260,29 @@ test_expect_success '"add non-existent" should fail' '
        ! (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