Code

git-add: Add support for --refresh option.
authorAlexandre Julliard <julliard@winehq.org>
Sat, 11 Aug 2007 21:59:01 +0000 (23:59 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 Aug 2007 19:58:38 +0000 (12:58 -0700)
This allows to refresh only a subset of the project files, based on
the specified pathspecs.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-add.txt
builtin-add.c
cache.h
read-cache.c
t/t3700-add.sh

index 4af3a9b0d78d70d101196326d4c6fbadd743b924..dee38f8250f2a2757155853b246b75029dd303bc 100644 (file)
@@ -7,7 +7,7 @@ git-add - Add file contents to the index
 
 SYNOPSIS
 --------
-'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--] <file>...
+'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <file>...
 
 DESCRIPTION
 -----------
@@ -66,6 +66,10 @@ OPTIONS
        command line. If no paths are specified, all tracked files are
        updated.
 
+\--refresh::
+       Don't add the file(s), but only refresh their stat()
+       information in the index.
+
 \--::
        This option can be used to separate command-line options from
        the list of files, (useful when filenames might be mistaken
index de5c108f8f5765e78c8ca15dcad58f3796015acc..82c806acf003e04f2435477eb4624eb72fe4fb32 100644 (file)
@@ -123,6 +123,23 @@ static void update(int verbose, const char **files)
        run_diff_files(&rev, 0);
 }
 
+static void refresh(int verbose, const char **pathspec)
+{
+       char *seen;
+       int i, specs;
+
+       for (specs = 0; pathspec[specs];  specs++)
+               /* nothing */;
+       seen = xcalloc(specs, 1);
+       if (read_cache() < 0)
+               die("index file corrupt");
+       refresh_index(&the_index, verbose ? 0 : REFRESH_QUIET, pathspec, seen);
+       for (i = 0; i < specs; i++) {
+               if (!seen[i])
+                       die("pathspec '%s' did not match any files", pathspec[i]);
+       }
+}
+
 static int git_add_config(const char *var, const char *value)
 {
        if (!strcmp(var, "core.excludesfile")) {
@@ -143,7 +160,7 @@ static const char ignore_warning[] =
 int cmd_add(int argc, const char **argv, const char *prefix)
 {
        int i, newfd;
-       int verbose = 0, show_only = 0, ignored_too = 0;
+       int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
        const char **pathspec;
        struct dir_struct dir;
        int add_interactive = 0;
@@ -191,6 +208,10 @@ int cmd_add(int argc, const char **argv, const char *prefix)
                        take_worktree_changes = 1;
                        continue;
                }
+               if (!strcmp(arg, "--refresh")) {
+                       refresh_only = 1;
+                       continue;
+               }
                usage(builtin_add_usage);
        }
 
@@ -206,6 +227,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        }
        pathspec = get_pathspec(prefix, argv + i);
 
+       if (refresh_only) {
+               refresh(verbose, pathspec);
+               goto finish;
+       }
+
        fill_directory(&dir, pathspec, ignored_too);
 
        if (show_only) {
diff --git a/cache.h b/cache.h
index 4507404240e404cac040a9435a29eb85a879a03d..c7e00e7b0528d640af9e70a2d84455e7cf727993 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -173,7 +173,7 @@ extern struct index_state the_index;
 #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))
 #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
 #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose))
-#define refresh_cache(flags) refresh_index(&the_index, flags)
+#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
 #define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really))
 #define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really))
 #endif
@@ -278,7 +278,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 #define REFRESH_UNMERGED       0x0002  /* allow unmerged */
 #define REFRESH_QUIET          0x0004  /* be quiet about it */
 #define REFRESH_IGNORE_MISSING 0x0008  /* ignore non-existent */
-extern int refresh_index(struct index_state *, unsigned int flags);
+extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
 
 struct lock_file {
        struct lock_file *next;
index 865369df0e7210446853c6704f68f12a8872124b..8b1c94e0e3f539cd0b507fd130b60aa443b9680b 100644 (file)
@@ -7,6 +7,7 @@
 #include "cache.h"
 #include "cache-tree.h"
 #include "refs.h"
+#include "dir.h"
 
 /* Index extensions.
  *
@@ -798,7 +799,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
        return updated;
 }
 
-int refresh_index(struct index_state *istate, unsigned int flags)
+int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec, char *seen)
 {
        int i;
        int has_errors = 0;
@@ -824,6 +825,9 @@ int refresh_index(struct index_state *istate, unsigned int flags)
                        continue;
                }
 
+               if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+                       continue;
+
                new = refresh_cache_ent(istate, ce, really, &cache_errno);
                if (new == ce)
                        continue;
index 213e9249daa5be824f8b6e1efbc754e39f67bde7..a328bf57eb67fd96a88020f02948d380ec699496 100755 (executable)
@@ -143,4 +143,16 @@ test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over st
        git ls-files --stage | grep "^120000 .* 0       symlink$"
 '
 
+test_expect_success 'git add --refresh' '
+       >foo && git add foo && git commit -a -m "commit all" &&
+       test -z "`git diff-index HEAD -- foo`" &&
+       git read-tree HEAD &&
+       case "`git diff-index HEAD -- foo`" in
+       :100644" "*"M   foo") echo ok;;
+       *) echo fail; (exit 1);;
+       esac &&
+       git add --refresh -- foo &&
+       test -z "`git diff-index HEAD -- foo`"
+'
+
 test_done