Merge branch 'js/c-merge-recursive'
authorJunio C Hamano <junkio@cox.net>
Mon, 28 Aug 2006 03:18:58 +0000 (20:18 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 28 Aug 2006 03:33:46 +0000 (20:33 -0700)
* js/c-merge-recursive: (21 commits)
  discard_cache(): discard index, even if no file was mmap()ed
  merge-recur: do not die unnecessarily
  merge-recur: try to merge older merge bases first
  merge-recur: if there is no common ancestor, fake empty one
  merge-recur: do not setenv("GIT_INDEX_FILE")
  merge-recur: do not call git-write-tree
  merge-recursive: fix rename handling
  .gitignore: git-merge-recur is a built file.
  merge-recur: virtual commits shall never be parsed
  merge-recur: use the unpack_trees() interface instead of exec()ing read-tree
  merge-recur: fix thinko in unique_path()
  Makefile: git-merge-recur depends on xdiff libraries.
  merge-recur: Explain why sha_eq() and struct stage_data cannot go
  merge-recur: Cleanup last mixedCase variables...
  merge-recur: Fix compiler warning with -pedantic
  merge-recur: Remove dead code
  merge-recur: Get rid of debug code
  merge-recur: Convert variable names to lower_case
  Cumulative update of merge-recursive in C
  recur vs recursive: help testing without touching too many stuff.
  ...

This is an evil merge that removes TEST script from the toplevel.

1  2 
.gitignore
Makefile
cache.h
read-cache.c

diff --combined .gitignore
@@@ -62,6 -62,7 +62,7 @@@ git-merge-tre
  git-merge-octopus
  git-merge-one-file
  git-merge-ours
+ git-merge-recur
  git-merge-recursive
  git-merge-resolve
  git-merge-stupid
@@@ -125,7 -126,6 +126,7 @@@ git-verify-ta
  git-whatchanged
  git-write-tree
  git-core-*/?*
 +gitweb/gitweb.cgi
  test-date
  test-delta
  test-dump-cache-tree
@@@ -141,7 -141,7 +142,7 @@@ config.ma
  autom4te.cache
  config.log
  config.status
 -config.mak.in
  config.mak.autogen
 +config.mak.append
  configure
  git-blame
diff --combined Makefile
+++ b/Makefile
@@@ -27,7 -27,7 +27,7 @@@ all
  # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.)
  # do not support the 'size specifiers' introduced by C99, namely ll, hh,
  # j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t).
 -# some c compilers supported these specifiers prior to C99 as an extension.
 +# some C compilers supported these specifiers prior to C99 as an extension.
  #
  # Define NO_STRCASESTR if you don't have strcasestr.
  #
@@@ -121,17 -121,6 +121,17 @@@ template_dir = $(prefix)/share/git-core
  GIT_PYTHON_DIR = $(prefix)/share/git-core/python
  # DESTDIR=
  
 +# default configuration for gitweb
 +GITWEB_CONFIG = gitweb_config.perl
 +GITWEB_HOME_LINK_STR = projects
 +GITWEB_SITENAME =
 +GITWEB_PROJECTROOT = /pub/git
 +GITWEB_BASE_URL =
 +GITWEB_LIST =
 +GITWEB_HOMETEXT = indextext.html
 +GITWEB_CSS = gitweb.css
 +GITWEB_LOGO = git-logo.png
 +
  export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR
  
  CC = gcc
@@@ -184,27 -173,33 +184,28 @@@ SIMPLE_PROGRAMS = 
  
  # ... and all the rest that could be moved out of bindir to gitexecdir
  PROGRAMS = \
 -      git-checkout-index$X \
        git-convert-objects$X git-fetch-pack$X git-fsck-objects$X \
        git-hash-object$X git-index-pack$X git-local-fetch$X \
        git-merge-base$X \
 -      git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
 +      git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \
        git-peek-remote$X git-receive-pack$X \
        git-send-pack$X git-shell$X \
        git-show-index$X git-ssh-fetch$X \
        git-ssh-upload$X git-unpack-file$X \
 -      git-unpack-objects$X git-update-server-info$X \
 +      git-update-server-info$X \
        git-upload-pack$X git-verify-pack$X \
 -      git-symbolic-ref$X \
 -      git-name-rev$X git-pack-redundant$X git-var$X \
 +      git-pack-redundant$X git-var$X \
        git-describe$X git-merge-tree$X git-blame$X git-imap-send$X \
 -      git-merge-recur$X
 -
 -BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \
 -      git-count-objects$X git-diff$X git-push$X git-mailsplit$X \
 -      git-grep$X git-add$X git-rm$X git-rev-list$X git-stripspace$X \
 -      git-check-ref-format$X git-rev-parse$X git-mailinfo$X \
 -      git-init-db$X git-tar-tree$X git-upload-tar$X git-format-patch$X \
 -      git-ls-files$X git-ls-tree$X git-get-tar-commit-id$X \
 -      git-read-tree$X git-commit-tree$X git-write-tree$X \
 -      git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \
 -      git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \
 -      git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \
 -      git-repo-config$X
++      git-merge-recur$X \
 +      $(EXTRA_PROGRAMS)
 +
 +# Empty...
 +EXTRA_PROGRAMS =
 +
 +BUILT_INS = \
 +      git-format-patch$X git-show$X git-whatchanged$X \
 +      git-get-tar-commit-id$X \
 +      $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
  
  # what 'all' will build and 'install' will install, in gitexecdir
  ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@@ -233,7 -228,7 +234,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 dir.h path-list.h unpack-trees.h
 +      tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h
  
  DIFF_OBJS = \
        diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@@ -248,52 -243,20 +249,52 @@@ LIB_OBJS = 
        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 \
 -      alloc.o merge-file.o path-list.o unpack-trees.o $(DIFF_OBJS)
 +      write_or_die.o \
 +      alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS)
  
  BUILTIN_OBJS = \
 -      builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
 -      builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o \
 -      builtin-rm.o builtin-init-db.o builtin-rev-parse.o \
 -      builtin-tar-tree.o builtin-upload-tar.o builtin-update-index.o \
 -      builtin-ls-files.o builtin-ls-tree.o builtin-write-tree.o \
 -      builtin-read-tree.o builtin-commit-tree.o builtin-mailinfo.o \
 -      builtin-apply.o builtin-show-branch.o builtin-diff-files.o \
 -      builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
 -      builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
 -      builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \
 -      builtin-mv.o builtin-prune-packed.o builtin-repo-config.o
 +      builtin-add.o \
 +      builtin-apply.o \
 +      builtin-cat-file.o \
 +      builtin-checkout-index.o \
 +      builtin-check-ref-format.o \
 +      builtin-commit-tree.o \
 +      builtin-count-objects.o \
 +      builtin-diff.o \
 +      builtin-diff-files.o \
 +      builtin-diff-index.o \
 +      builtin-diff-stages.o \
 +      builtin-diff-tree.o \
 +      builtin-fmt-merge-msg.o \
 +      builtin-grep.o \
 +      builtin-init-db.o \
 +      builtin-log.o \
 +      builtin-ls-files.o \
 +      builtin-ls-tree.o \
 +      builtin-mailinfo.o \
 +      builtin-mailsplit.o \
 +      builtin-mv.o \
 +      builtin-name-rev.o \
 +      builtin-pack-objects.o \
 +      builtin-prune.o \
 +      builtin-prune-packed.o \
 +      builtin-push.o \
 +      builtin-read-tree.o \
 +      builtin-repo-config.o \
 +      builtin-rev-list.o \
 +      builtin-rev-parse.o \
 +      builtin-rm.o \
 +      builtin-show-branch.o \
 +      builtin-stripspace.o \
 +      builtin-symbolic-ref.o \
 +      builtin-tar-tree.o \
 +      builtin-unpack-objects.o \
 +      builtin-update-index.o \
 +      builtin-update-ref.o \
 +      builtin-upload-tar.o \
 +      builtin-verify-pack.o \
 +      builtin-write-tree.o \
 +      builtin-zip-tree.o
  
  GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
  LIBS = $(GITLIBS) -lz
@@@ -334,16 -297,15 +335,16 @@@ ifeq ($(uname_S),SunOS
        NEEDS_NSL = YesPlease
        SHELL_PATH = /bin/bash
        NO_STRCASESTR = YesPlease
 -      NO_STRLCPY = YesPlease
        ifeq ($(uname_R),5.8)
                NEEDS_LIBICONV = YesPlease
                NO_UNSETENV = YesPlease
                NO_SETENV = YesPlease
 +              NO_C99_FORMAT = YesPlease
        endif
        ifeq ($(uname_R),5.9)
                NO_UNSETENV = YesPlease
                NO_SETENV = YesPlease
 +              NO_C99_FORMAT = YesPlease
        endif
        INSTALL = ginstall
        TAR = gtar
@@@ -562,7 -524,7 +563,7 @@@ LIB_OBJS += $(COMPAT_OBJS
  export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir
  ### Build rules
  
 -all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk
 +all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk gitweb/gitweb.cgi
  
  all:
        $(MAKE) -C templates
@@@ -575,7 -537,7 +576,7 @@@ git$X: git.c common-cmds.h $(BUILTIN_OB
                $(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
                $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
  
 -builtin-help.o: common-cmds.h
 +help.o: common-cmds.h
  
  $(BUILT_INS): git$X
        rm -f $@ && ln git$X $@
@@@ -620,24 -582,6 +621,24 @@@ git-status: git-commi
        cp $< $@+
        mv $@+ $@
  
 +gitweb/gitweb.cgi: gitweb/gitweb.perl
 +      rm -f $@ $@+
 +      sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
 +          -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
 +          -e 's|++GIT_BINDIR++|$(bindir)|g' \
 +          -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \
 +          -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
 +          -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
 +          -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
 +          -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \
 +          -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \
 +          -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \
 +          -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \
 +          -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
 +          $< >$@+
 +      chmod +x $@+
 +      mv $@+ $@
 +
  git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
        rm -f $@ $@+
        sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
            -e '/@@GITWEB_CGI@@/d' \
            -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \
            -e '/@@GITWEB_CSS@@/d' \
 -          $@.sh | sed "s|/usr/bin/git|$(bindir)/git|" > $@+
 +          $@.sh > $@+
        chmod +x $@+
        mv $@+ $@
  
 +configure: configure.ac
 +      rm -f $@ $<+
 +      sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
 +          $< > $<+
 +      autoconf -o $@ $<+
 +      rm -f $<+
 +
  # These can record GIT_VERSION
  git$X git.spec \
        $(patsubst %.sh,%,$(SCRIPT_SH)) \
@@@ -711,6 -648,11 +712,11 @@@ git-http-push$X: revision.o http.o http
        $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
                $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
  
+ merge-recursive.o path-list.o: path-list.h
+ git-merge-recur$X: merge-recursive.o path-list.o $(GITLIBS)
+       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
+               $(LIBS)
  $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
  $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
  $(DIFF_OBJS): diffcore.h
@@@ -850,11 -792,10 +856,11 @@@ clean
        rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
        rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
        rm -rf autom4te.cache
 -      rm -f config.log config.mak.autogen configure config.status config.cache
 +      rm -f configure config.log config.mak.autogen config.mak.append config.status config.cache
        rm -rf $(GIT_TARNAME) .doc-tmp-dir
        rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
        rm -f $(htmldocs).tar.gz $(manpages).tar.gz
 +      rm -f gitweb/gitweb.cgi
        $(MAKE) -C Documentation/ clean
        $(MAKE) -C templates clean
        $(MAKE) -C t/ clean
@@@ -870,7 -811,7 +876,7 @@@ check-docs:
        do \
                case "$$v" in \
                git-merge-octopus | git-merge-ours | git-merge-recursive | \
-               git-merge-resolve | git-merge-stupid | \
+               git-merge-resolve | git-merge-stupid | git-merge-recur | \
                git-ssh-pull | git-ssh-push ) continue ;; \
                esac ; \
                test -f "Documentation/$$v.txt" || \
diff --combined cache.h
+++ b/cache.h
@@@ -123,7 -123,7 +123,7 @@@ extern int cache_errno
  #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
  #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
  
 -extern char *get_git_dir(void);
 +extern const char *get_git_dir(void);
  extern char *get_object_directory(void);
  extern char *get_refs_directory(void);
  extern char *get_index_file(void);
@@@ -145,6 -145,7 +145,7 @@@ extern void verify_non_filename(const c
  extern int read_cache(void);
  extern int read_cache_from(const char *path);
  extern int write_cache(int newfd, struct cache_entry **cache, int entries);
+ extern int discard_cache(void);
  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 */
@@@ -210,22 -211,6 +211,22 @@@ extern char *sha1_pack_name(const unsig
  extern char *sha1_pack_index_name(const unsigned char *sha1);
  extern const char *find_unique_abbrev(const unsigned char *sha1, int);
  extern const unsigned char null_sha1[20];
 +static inline int is_null_sha1(const unsigned char *sha1)
 +{
 +      return !memcmp(sha1, null_sha1, 20);
 +}
 +static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
 +{
 +      return memcmp(sha1, sha2, 20);
 +}
 +static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
 +{
 +      memcpy(sha_dst, sha_src, 20);
 +}
 +static inline void hashclr(unsigned char *hash)
 +{
 +      memset(hash, 0, 20);
 +}
  
  int git_mkstemp(char *path, size_t n, const char *template);
  
@@@ -260,8 -245,6 +261,8 @@@ extern int move_temp_to_file(const cha
  
  extern int has_sha1_pack(const unsigned char *sha1);
  extern int has_sha1_file(const unsigned char *sha1);
 +extern void *map_sha1_file(const unsigned char *sha1, unsigned long *);
 +extern int legacy_loose_object(unsigned char *);
  
  extern int has_pack_file(const unsigned char *sha1);
  extern int has_pack_index(const unsigned char *sha1);
@@@ -286,7 -269,7 +287,7 @@@ extern void *read_object_with_reference
                                        unsigned long *size,
                                        unsigned char *sha1_ret);
  
 -const char *show_date(unsigned long time, int timezone);
 +const char *show_date(unsigned long time, int timezone, int relative);
  const char *show_rfc2822_date(unsigned long time, int timezone);
  int parse_date(const char *date, char *buf, int bufsize);
  void datestamp(char *buf, int bufsize);
@@@ -396,7 -379,6 +397,7 @@@ extern char git_default_name[MAX_GITNAM
  extern char git_commit_encoding[MAX_ENCODING_LENGTH];
  
  extern int copy_fd(int ifd, int ofd);
 +extern void write_or_die(int fd, const void *buf, size_t count);
  
  /* Finish off pack transfer receiving end */
  extern int receive_unpack_pack(int fd[2], const char *me, int quiet, int);
diff --combined read-cache.c
  #define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) )
  #define CACHE_EXT_TREE 0x54524545     /* "TREE" */
  
 -struct cache_entry **active_cache = NULL;
 +struct cache_entry **active_cache;
  static time_t index_file_timestamp;
 -unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0;
 +unsigned int active_nr, active_alloc, active_cache_changed;
  
 -struct cache_tree *active_cache_tree = NULL;
 +struct cache_tree *active_cache_tree;
  
 -int cache_errno = 0;
 +int cache_errno;
  
 -static void *cache_mmap = NULL;
 -static size_t cache_mmap_size = 0;
 +static void *cache_mmap;
 +static size_t cache_mmap_size;
  
  /*
   * This only updates the "non-critical" parts of the directory
@@@ -60,7 -60,7 +60,7 @@@ static int ce_compare_data(struct cache
        if (fd >= 0) {
                unsigned char sha1[20];
                if (!index_fd(sha1, fd, st, 0, NULL))
 -                      match = memcmp(sha1, ce->sha1, 20);
 +                      match = hashcmp(sha1, ce->sha1);
                /* index_fd() closed the file descriptor already */
        }
        return match;
@@@ -169,11 -169,9 +169,11 @@@ static int ce_match_stat_basic(struct c
        return changed;
  }
  
 -int ce_match_stat(struct cache_entry *ce, struct stat *st, int ignore_valid)
 +int ce_match_stat(struct cache_entry *ce, struct stat *st, int options)
  {
        unsigned int changed;
 +      int ignore_valid = options & 01;
 +      int assume_racy_is_modified = options & 02;
  
        /*
         * If it's marked as always valid in the index, it's
         */
        if (!changed &&
            index_file_timestamp &&
 -          index_file_timestamp <= ntohl(ce->ce_mtime.sec))
 -              changed |= ce_modified_check_fs(ce, st);
 +          index_file_timestamp <= ntohl(ce->ce_mtime.sec)) {
 +              if (assume_racy_is_modified)
 +                      changed |= DATA_CHANGED;
 +              else
 +                      changed |= ce_modified_check_fs(ce, st);
 +      }
  
        return changed;
  }
@@@ -744,7 -738,7 +744,7 @@@ static int verify_hdr(struct cache_head
        SHA1_Init(&c);
        SHA1_Update(&c, hdr, size - 20);
        SHA1_Final(sha1, &c);
 -      if (memcmp(sha1, (char *) hdr + size - 20, 20))
 +      if (hashcmp(sha1, (unsigned char *)hdr + size - 20))
                return error("bad index file sha1 signature");
        return 0;
  }
@@@ -842,22 -836,27 +842,39 @@@ unmap
        die("index file corrupt");
  }
  
+ int discard_cache()
+ {
+       int ret;
+       active_nr = active_cache_changed = 0;
+       index_file_timestamp = 0;
+       cache_tree_free(&active_cache_tree);
+       if (cache_mmap == NULL)
+               return 0;
+       ret = munmap(cache_mmap, cache_mmap_size);
+       cache_mmap = NULL;
+       cache_mmap_size = 0;
+       /* no need to throw away allocated active_cache */
+       return ret;
+ }
  #define WRITE_BUFFER_SIZE 8192
  static unsigned char write_buffer[WRITE_BUFFER_SIZE];
  static unsigned long write_buffer_len;
  
 +static int ce_write_flush(SHA_CTX *context, int fd)
 +{
 +      unsigned int buffered = write_buffer_len;
 +      if (buffered) {
 +              SHA1_Update(context, write_buffer, buffered);
 +              if (write(fd, write_buffer, buffered) != buffered)
 +                      return -1;
 +              write_buffer_len = 0;
 +      }
 +      return 0;
 +}
 +
  static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len)
  {
        while (len) {
                memcpy(write_buffer + buffered, data, partial);
                buffered += partial;
                if (buffered == WRITE_BUFFER_SIZE) {
 -                      SHA1_Update(context, write_buffer, WRITE_BUFFER_SIZE);
 -                      if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE)
 +                      write_buffer_len = buffered;
 +                      if (ce_write_flush(context, fd))
                                return -1;
                        buffered = 0;
                }
@@@ -885,8 -884,10 +902,8 @@@ static int write_index_ext_header(SHA_C
  {
        ext = htonl(ext);
        sz = htonl(sz);
 -      if ((ce_write(context, fd, &ext, 4) < 0) ||
 -          (ce_write(context, fd, &sz, 4) < 0))
 -              return -1;
 -      return 0;
 +      return ((ce_write(context, fd, &ext, 4) < 0) ||
 +              (ce_write(context, fd, &sz, 4) < 0)) ? -1 : 0;
  }
  
  static int ce_flush(SHA_CTX *context, int fd)
        /* Append the SHA1 signature at the end */
        SHA1_Final(write_buffer + left, context);
        left += 20;
 -      if (write(fd, write_buffer, left) != left)
 -              return -1;
 -      return 0;
 +      return (write(fd, write_buffer, left) != left) ? -1 : 0;
  }
  
  static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
                 * $ echo filfre >nitfol
                 * $ git-update-index --add nitfol
                 *
 -               * but it does not.  Whe the second update-index runs,
 +               * but it does not.  When the second update-index runs,
                 * it notices that the entry "frotz" has the same timestamp
                 * as index, and if we were to smudge it by resetting its
                 * size to zero here, then the object name recorded