Merge branch 'lt/dirwalk'
authorJunio C Hamano <junkio@cox.net>
Wed, 24 May 2006 18:04:16 +0000 (11:04 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 24 May 2006 18:04:16 +0000 (11:04 -0700)
This makes 'git add' and 'git rm' built-ins.

* lt/dirwalk:
  Add builtin "git rm" command
  Move pathspec matching from builtin-add.c into dir.c
  Prevent bogus paths from being added to the index.
  builtin-add: fix unmatched pathspec warnings.
  Remove old "git-add.sh" remnants
  builtin-add: warn on unmatched pathspecs
  Do "git add" as a builtin
  Clean up git-ls-file directory walking library interface
  libify git-ls-files directory traversal

1  2 
Makefile
builtin.h
cache.h
git.c
read-cache.c
update-index.c

diff --combined Makefile
+++ b/Makefile
@@@ -113,19 -113,19 +113,19 @@@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__pow
  ### --- END CONFIGURATION SECTION ---
  
  SCRIPT_SH = \
-       git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \
+       git-bisect.sh git-branch.sh git-checkout.sh \
        git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
        git-fetch.sh \
        git-format-patch.sh git-ls-remote.sh \
        git-merge-one-file.sh git-parse-remote.sh \
        git-prune.sh git-pull.sh git-rebase.sh \
        git-repack.sh git-request-pull.sh git-reset.sh \
-       git-resolve.sh git-revert.sh git-rm.sh git-sh-setup.sh \
+       git-resolve.sh git-revert.sh git-sh-setup.sh \
        git-tag.sh git-verify-tag.sh \
        git-applymbox.sh git-applypatch.sh git-am.sh \
        git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
        git-merge-resolve.sh git-merge-ours.sh \
 -      git-lost-found.sh
 +      git-lost-found.sh git-quiltimport.sh
  
  SCRIPT_PERL = \
        git-archimport.perl git-cvsimport.perl git-relink.perl \
@@@ -154,24 -154,24 +154,25 @@@ PROGRAMS = 
        git-convert-objects$X git-diff-files$X \
        git-diff-index$X git-diff-stages$X \
        git-diff-tree$X git-fetch-pack$X git-fsck-objects$X \
 -      git-hash-object$X git-index-pack$X git-init-db$X git-local-fetch$X \
 +      git-hash-object$X git-index-pack$X git-local-fetch$X \
        git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
        git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
        git-peek-remote$X git-prune-packed$X git-read-tree$X \
 -      git-receive-pack$X git-rev-list$X git-rev-parse$X \
 +      git-receive-pack$X git-rev-parse$X \
        git-send-pack$X git-show-branch$X git-shell$X \
        git-show-index$X git-ssh-fetch$X \
        git-ssh-upload$X git-tar-tree$X git-unpack-file$X \
        git-unpack-objects$X git-update-index$X git-update-server-info$X \
        git-upload-pack$X git-verify-pack$X git-write-tree$X \
 -      git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \
 +      git-update-ref$X git-symbolic-ref$X \
        git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
        git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
  
  BUILT_INS = git-log$X git-whatchanged$X git-show$X \
        git-count-objects$X git-diff$X git-push$X \
-       git-grep$X git-rev-list$X git-check-ref-format$X \
+       git-grep$X git-add$X git-rm$X git-rev-list$X \
 -      git-check-ref-format$X
++      git-check-ref-format$X \
 +      git-init-db$X
  
  # what 'all' will build and 'install' will install, in gitexecdir
  ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@@ -200,7 -200,7 +201,7 @@@ LIB_H = 
        blob.h cache.h commit.h csum-file.h delta.h \
        diff.h object.h pack.h pkt-line.h quote.h refs.h \
        run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
-       tree-walk.h log-tree.h
+       tree-walk.h log-tree.h dir.h
  
  DIFF_OBJS = \
        diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@@ -211,7 -211,7 +212,7 @@@ LIB_OBJS = 
        blob.o commit.o connect.o csum-file.o base85.o \
        date.o diff-delta.o entry.o exec_cmd.o ident.o index.o \
        object.o pack-check.o patch-delta.o path.o pkt-line.o \
-       quote.o read-cache.o refs.o run-command.o \
+       quote.o read-cache.o refs.o run-command.o dir.o \
        server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
        tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
        fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
  
  BUILTIN_OBJS = \
        builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-       builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o \
-       builtin-init-db.o
+       builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o \
 -      builtin-rm.o
++      builtin-rm.o builtin-init-db.o
  
  GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
  LIBS = $(GITLIBS) -lz
@@@ -420,9 -420,6 +421,9 @@@ els
        ALL_CFLAGS += -Dsockaddr_storage=sockaddr_in6
  endif
  endif
 +ifdef NO_INET_NTOP
 +      LIB_OBJS += compat/inet_ntop.o
 +endif
  
  ifdef NO_ICONV
        ALL_CFLAGS += -DNO_ICONV
@@@ -464,7 -461,6 +465,7 @@@ PYTHON_PATH_SQ = $(subst ','\'',$(PYTHO
  GIT_PYTHON_DIR_SQ = $(subst ','\'',$(GIT_PYTHON_DIR))
  
  ALL_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' $(COMPAT_CFLAGS)
 +ALL_CFLAGS += -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"'
  LIB_OBJS += $(COMPAT_OBJS)
  export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir
  ### Build rules
@@@ -571,6 -567,10 +572,6 @@@ git-http-push$X: revision.o http.o http
        $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
                $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
  
 -init-db.o: init-db.c
 -      $(CC) -c $(ALL_CFLAGS) \
 -              -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
 -
  $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
  $(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
  $(DIFF_OBJS): diffcore.h
@@@ -627,14 -627,7 +628,14 @@@ install: al
        $(MAKE) -C templates install
        $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
        $(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
 -      $(foreach p,$(BUILT_INS), rm -f '$(DESTDIR_SQ)$(bindir_SQ)/$p' && ln '$(DESTDIR_SQ)$(bindir_SQ)/git$X' '$(DESTDIR_SQ)$(bindir_SQ)/$p' ;)
 +      if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
 +      then \
 +              ln -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
 +                      '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' || \
 +              cp '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
 +                      '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \
 +      fi
 +      $(foreach p,$(BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
  
  install-doc:
        $(MAKE) -C Documentation install
@@@ -661,25 -654,6 +662,25 @@@ dist: git.spec git-tar-tre
  rpm: dist
        $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz
  
 +htmldocs = git-htmldocs-$(GIT_VERSION)
 +manpages = git-manpages-$(GIT_VERSION)
 +dist-doc:
 +      rm -fr .doc-tmp-dir
 +      mkdir .doc-tmp-dir
 +      $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc
 +      cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar .
 +      gzip -n -9 -f $(htmldocs).tar
 +      :
 +      rm -fr .doc-tmp-dir
 +      mkdir .doc-tmp-dir .doc-tmp-dir/man1 .doc-tmp-dir/man7
 +      $(MAKE) -C Documentation DESTDIR=. \
 +              man1=../.doc-tmp-dir/man1 \
 +              man7=../.doc-tmp-dir/man7 \
 +              install
 +      cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
 +      gzip -n -9 -f $(manpages).tar
 +      rm -fr .doc-tmp-dir
 +
  ### Cleaning rules
  
  clean:
                $(LIB_FILE) $(XDIFF_LIB)
        rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
        rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
 -      rm -rf $(GIT_TARNAME)
 +      rm -rf $(GIT_TARNAME) .doc-tmp-dir
        rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
 +      rm -f $(htmldocs).tar $(manpages).tar
        $(MAKE) -C Documentation/ clean
        $(MAKE) -C templates clean
        $(MAKE) -C t/ clean
diff --combined builtin.h
+++ b/builtin.h
@@@ -24,8 -24,7 +24,10 @@@ extern int cmd_count_objects(int argc, 
  
  extern int cmd_push(int argc, const char **argv, char **envp);
  extern int cmd_grep(int argc, const char **argv, char **envp);
+ extern int cmd_rm(int argc, const char **argv, char **envp);
+ extern int cmd_add(int argc, const char **argv, char **envp);
 +extern int cmd_rev_list(int argc, const char **argv, char **envp);
 +extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
 +extern int cmd_init_db(int argc, const char **argv, char **envp);
  
  #endif
diff --combined cache.h
+++ b/cache.h
@@@ -142,6 -142,7 +142,7 @@@ extern void verify_non_filename(const c
  /* Initialize and use the cache information */
  extern int read_cache(void);
  extern int write_cache(int newfd, struct cache_entry **cache, int entries);
+ extern int verify_path(const char *path);
  extern int cache_name_pos(const char *name, int namelen);
  #define ADD_CACHE_OK_TO_ADD 1         /* Ok to add */
  #define ADD_CACHE_OK_TO_REPLACE 2     /* Ok to replace file/directory */
@@@ -158,12 -159,6 +159,12 @@@ extern int index_pipe(unsigned char *sh
  extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
  extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
  
 +#define REFRESH_REALLY                0x0001  /* ignore_valid */
 +#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_cache(unsigned int flags);
 +
  struct cache_file {
        struct cache_file *next;
        char lockfile[PATH_MAX];
diff --combined git.c
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -50,9 -50,8 +50,11 @@@ static void handle_internal_command(in
                { "count-objects", cmd_count_objects },
                { "diff", cmd_diff },
                { "grep", cmd_grep },
+               { "rm", cmd_rm },
+               { "add", cmd_add },
 +              { "rev-list", cmd_rev_list },
 +              { "init-db", cmd_init_db },
 +              { "check-ref-format", cmd_check_ref_format }
        };
        int i;
  
diff --combined read-cache.c
@@@ -332,6 -332,70 +332,70 @@@ int ce_path_match(const struct cache_en
  }
  
  /*
+  * We fundamentally don't like some paths: we don't want
+  * dot or dot-dot anywhere, and for obvious reasons don't
+  * want to recurse into ".git" either.
+  *
+  * Also, we don't want double slashes or slashes at the
+  * end that can make pathnames ambiguous.
+  */
+ static int verify_dotfile(const char *rest)
+ {
+       /*
+        * The first character was '.', but that
+        * has already been discarded, we now test
+        * the rest.
+        */
+       switch (*rest) {
+       /* "." is not allowed */
+       case '\0': case '/':
+               return 0;
+       /*
+        * ".git" followed by  NUL or slash is bad. This
+        * shares the path end test with the ".." case.
+        */
+       case 'g':
+               if (rest[1] != 'i')
+                       break;
+               if (rest[2] != 't')
+                       break;
+               rest += 2;
+       /* fallthrough */
+       case '.':
+               if (rest[1] == '\0' || rest[1] == '/')
+                       return 0;
+       }
+       return 1;
+ }
+ int verify_path(const char *path)
+ {
+       char c;
+       goto inside;
+       for (;;) {
+               if (!c)
+                       return 1;
+               if (c == '/') {
+ inside:
+                       c = *path++;
+                       switch (c) {
+                       default:
+                               continue;
+                       case '/': case '\0':
+                               break;
+                       case '.':
+                               if (verify_dotfile(path))
+                                       continue;
+                       }
+                       return 0;
+               }
+               c = *path++;
+       }
+ }
+ /*
   * Do we have another file that has the beginning components being a
   * proper superset of the name we're trying to add?
   */
@@@ -472,6 -536,8 +536,8 @@@ int add_cache_entry(struct cache_entry 
  
        if (!ok_to_add)
                return -1;
+       if (!verify_path(ce->name))
+               return -1;
  
        if (!skip_df_check &&
            check_file_directory_conflict(ce, pos, ok_to_replace)) {
        return 0;
  }
  
 +/* Three functions to allow overloaded pointer return; see linux/err.h */
 +static inline void *ERR_PTR(long error)
 +{
 +      return (void *) error;
 +}
 +
 +static inline long PTR_ERR(const void *ptr)
 +{
 +      return (long) ptr;
 +}
 +
 +static inline long IS_ERR(const void *ptr)
 +{
 +      return (unsigned long)ptr > (unsigned long)-1000L;
 +}
 +
 +/*
 + * "refresh" does not calculate a new sha1 file or bring the
 + * cache up-to-date for mode/content changes. But what it
 + * _does_ do is to "re-match" the stat information of a file
 + * with the cache, so that you can refresh the cache for a
 + * file that hasn't been changed but where the stat entry is
 + * out of date.
 + *
 + * For example, you'd want to do this after doing a "git-read-tree",
 + * to link up the stat cache details with the proper files.
 + */
 +static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
 +{
 +      struct stat st;
 +      struct cache_entry *updated;
 +      int changed, size;
 +
 +      if (lstat(ce->name, &st) < 0)
 +              return ERR_PTR(-errno);
 +
 +      changed = ce_match_stat(ce, &st, really);
 +      if (!changed) {
 +              if (really && assume_unchanged &&
 +                  !(ce->ce_flags & htons(CE_VALID)))
 +                      ; /* mark this one VALID again */
 +              else
 +                      return NULL;
 +      }
 +
 +      if (ce_modified(ce, &st, really))
 +              return ERR_PTR(-EINVAL);
 +
 +      size = ce_size(ce);
 +      updated = xmalloc(size);
 +      memcpy(updated, ce, size);
 +      fill_stat_cache_info(updated, &st);
 +
 +      /* In this case, if really is not set, we should leave
 +       * CE_VALID bit alone.  Otherwise, paths marked with
 +       * --no-assume-unchanged (i.e. things to be edited) will
 +       * reacquire CE_VALID bit automatically, which is not
 +       * really what we want.
 +       */
 +      if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
 +              updated->ce_flags &= ~htons(CE_VALID);
 +
 +      return updated;
 +}
 +
 +int refresh_cache(unsigned int flags)
 +{
 +      int i;
 +      int has_errors = 0;
 +      int really = (flags & REFRESH_REALLY) != 0;
 +      int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
 +      int quiet = (flags & REFRESH_QUIET) != 0;
 +      int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
 +
 +      for (i = 0; i < active_nr; i++) {
 +              struct cache_entry *ce, *new;
 +              ce = active_cache[i];
 +              if (ce_stage(ce)) {
 +                      while ((i < active_nr) &&
 +                             ! strcmp(active_cache[i]->name, ce->name))
 +                              i++;
 +                      i--;
 +                      if (allow_unmerged)
 +                              continue;
 +                      printf("%s: needs merge\n", ce->name);
 +                      has_errors = 1;
 +                      continue;
 +              }
 +
 +              new = refresh_entry(ce, really);
 +              if (!new)
 +                      continue;
 +              if (IS_ERR(new)) {
 +                      if (not_new && PTR_ERR(new) == -ENOENT)
 +                              continue;
 +                      if (really && PTR_ERR(new) == -EINVAL) {
 +                              /* If we are doing --really-refresh that
 +                               * means the index is not valid anymore.
 +                               */
 +                              ce->ce_flags &= ~htons(CE_VALID);
 +                              active_cache_changed = 1;
 +                      }
 +                      if (quiet)
 +                              continue;
 +                      printf("%s: needs update\n", ce->name);
 +                      has_errors = 1;
 +                      continue;
 +              }
 +              active_cache_changed = 1;
 +              /* You can NOT just free active_cache[i] here, since it
 +               * might not be necessarily malloc()ed but can also come
 +               * from mmap(). */
 +              active_cache[i] = new;
 +      }
 +      return has_errors;
 +}
 +
  static int verify_hdr(struct cache_header *hdr, unsigned long size)
  {
        SHA_CTX c;
diff --combined update-index.c
@@@ -18,6 -18,9 +18,6 @@@
  static int allow_add;
  static int allow_remove;
  static int allow_replace;
 -static int allow_unmerged; /* --refresh needing merge is not error */
 -static int not_new; /* --refresh not having working tree files is not error */
 -static int quiet; /* --refresh needing update is not error */
  static int info_only;
  static int force_remove;
  static int verbose;
@@@ -25,6 -28,23 +25,6 @@@ static int mark_valid_only = 0
  #define MARK_VALID 1
  #define UNMARK_VALID 2
  
 -
 -/* Three functions to allow overloaded pointer return; see linux/err.h */
 -static inline void *ERR_PTR(long error)
 -{
 -      return (void *) error;
 -}
 -
 -static inline long PTR_ERR(const void *ptr)
 -{
 -      return (long) ptr;
 -}
 -
 -static inline long IS_ERR(const void *ptr)
 -{
 -      return (unsigned long)ptr > (unsigned long)-1000L;
 -}
 -
  static void report(const char *fmt, ...)
  {
        va_list vp;
@@@ -120,70 -140,103 +120,6 @@@ static int add_file_to_cache(const cha
        return 0;
  }
  
--/*
-  * We fundamentally don't like some paths: we don't want
-  * dot or dot-dot anywhere, and for obvious reasons don't
-  * want to recurse into ".git" either.
 - * "refresh" does not calculate a new sha1 file or bring the
 - * cache up-to-date for mode/content changes. But what it
 - * _does_ do is to "re-match" the stat information of a file
 - * with the cache, so that you can refresh the cache for a
 - * file that hasn't been changed but where the stat entry is
 - * out of date.
-- *
-  * Also, we don't want double slashes or slashes at the
-  * end that can make pathnames ambiguous.
 - * For example, you'd want to do this after doing a "git-read-tree",
 - * to link up the stat cache details with the proper files.
-- */
- static int verify_dotfile(const char *rest)
 -static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
--{
-       /*
-        * The first character was '.', but that
-        * has already been discarded, we now test
-        * the rest.
-        */
-       switch (*rest) {
-       /* "." is not allowed */
-       case '\0': case '/':
-               return 0;
 -      struct stat st;
 -      struct cache_entry *updated;
 -      int changed, size;
--
-       /*
-        * ".git" followed by  NUL or slash is bad. This
-        * shares the path end test with the ".." case.
-        */
-       case 'g':
-               if (rest[1] != 'i')
-                       break;
-               if (rest[2] != 't')
-                       break;
-               rest += 2;
-       /* fallthrough */
-       case '.':
-               if (rest[1] == '\0' || rest[1] == '/')
-                       return 0;
 -      if (lstat(ce->name, &st) < 0)
 -              return ERR_PTR(-errno);
 -
 -      changed = ce_match_stat(ce, &st, really);
 -      if (!changed) {
 -              if (really && assume_unchanged &&
 -                  !(ce->ce_flags & htons(CE_VALID)))
 -                      ; /* mark this one VALID again */
 -              else
 -                      return NULL;
--      }
-       return 1;
 -
 -      if (ce_modified(ce, &st, really))
 -              return ERR_PTR(-EINVAL);
 -
 -      size = ce_size(ce);
 -      updated = xmalloc(size);
 -      memcpy(updated, ce, size);
 -      fill_stat_cache_info(updated, &st);
 -
 -      /* In this case, if really is not set, we should leave
 -       * CE_VALID bit alone.  Otherwise, paths marked with
 -       * --no-assume-unchanged (i.e. things to be edited) will
 -       * reacquire CE_VALID bit automatically, which is not
 -       * really what we want.
 -       */
 -      if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
 -              updated->ce_flags &= ~htons(CE_VALID);
 -
 -      return updated;
--}
--
- static int verify_path(const char *path)
 -static int refresh_cache(int really)
--{
-       char c;
 -      int i;
 -      int has_errors = 0;
--
-       goto inside;
-       for (;;) {
-               if (!c)
-                       return 1;
-               if (c == '/') {
- inside:
-                       c = *path++;
-                       switch (c) {
-                       default:
 -      for (i = 0; i < active_nr; i++) {
 -              struct cache_entry *ce, *new;
 -              ce = active_cache[i];
 -              if (ce_stage(ce)) {
 -                      while ((i < active_nr) &&
 -                             ! strcmp(active_cache[i]->name, ce->name))
 -                              i++;
 -                      i--;
 -                      if (allow_unmerged)
--                              continue;
-                       case '/': case '\0':
-                               break;
-                       case '.':
-                               if (verify_dotfile(path))
-                                       continue;
 -                      printf("%s: needs merge\n", ce->name);
 -                      has_errors = 1;
 -                      continue;
 -              }
 -
 -              new = refresh_entry(ce, really);
 -              if (!new)
 -                      continue;
 -              if (IS_ERR(new)) {
 -                      if (not_new && PTR_ERR(new) == -ENOENT)
 -                              continue;
 -                      if (really && PTR_ERR(new) == -EINVAL) {
 -                              /* If we are doing --really-refresh that
 -                               * means the index is not valid anymore.
 -                               */
 -                              ce->ce_flags &= ~htons(CE_VALID);
 -                              active_cache_changed = 1;
--                      }
-                       return 0;
 -                      if (quiet)
 -                              continue;
 -                      printf("%s: needs update\n", ce->name);
 -                      has_errors = 1;
 -                      continue;
--              }
-               c = *path++;
 -              active_cache_changed = 1;
 -              /* You can NOT just free active_cache[i] here, since it
 -               * might not be necessarily malloc()ed but can also come
 -               * from mmap(). */
 -              active_cache[i] = new;
--      }
 -      return has_errors;
--}
--
  static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
                         const char *path, int stage)
  {
@@@ -536,7 -589,6 +472,7 @@@ int main(int argc, const char **argv
        const char *prefix = setup_git_directory();
        int prefix_length = prefix ? strlen(prefix) : 0;
        char set_executable_bit = 0;
 +      unsigned int refresh_flags = 0;
  
        git_config(git_default_config);
  
                                continue;
                        }
                        if (!strcmp(path, "-q")) {
 -                              quiet = 1;
 +                              refresh_flags |= REFRESH_QUIET;
                                continue;
                        }
                        if (!strcmp(path, "--add")) {
                                continue;
                        }
                        if (!strcmp(path, "--unmerged")) {
 -                              allow_unmerged = 1;
 +                              refresh_flags |= REFRESH_UNMERGED;
                                continue;
                        }
                        if (!strcmp(path, "--refresh")) {
 -                              has_errors |= refresh_cache(0);
 +                              has_errors |= refresh_cache(refresh_flags);
                                continue;
                        }
                        if (!strcmp(path, "--really-refresh")) {
 -                              has_errors |= refresh_cache(1);
 +                              has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags);
                                continue;
                        }
                        if (!strcmp(path, "--cacheinfo")) {
                                goto finish;
                        }
                        if (!strcmp(path, "--ignore-missing")) {
 -                              not_new = 1;
 +                              refresh_flags |= REFRESH_IGNORE_MISSING;
                                continue;
                        }
                        if (!strcmp(path, "--verbose")) {