]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'jj/icase-directory'
authorJunio C Hamano <gitster@pobox.com>
Sat, 4 Dec 2010 00:10:34 +0000 (16:10 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 4 Dec 2010 00:10:34 +0000 (16:10 -0800)
* jj/icase-directory:
  Support case folding in git fast-import when core.ignorecase=true
  Support case folding for git add when core.ignorecase=true
  Add case insensitivity support when using git ls-files
  Add case insensitivity support for directories when using git status
  Case insensitivity support for .gitignore via core.ignorecase
  Add string comparison functions that respect the ignore_case variable.
  Makefile & configure: add a NO_FNMATCH_CASEFOLD flag
  Makefile & configure: add a NO_FNMATCH flag

Conflicts:
Makefile
config.mak.in
configure.ac
fast-import.c

1  2 
Makefile
config.mak.in
configure.ac
dir.c
fast-import.c
read-cache.c

diff --combined Makefile
index 1d4241346594e5e0df7df7f766899d4ac76d84ff,8407c38407640d2c4768bbbaa9d79275b4ba9526..29ebe70599aa9c01ddb84e5611ac08d441adef4c
+++ b/Makefile
@@@ -68,8 -68,11 +68,13 @@@ all:
  #
  # Define NO_MKSTEMPS if you don't have mkstemps in the C library.
  #
 +# Define NO_STRTOK_R if you don't have strtok_r in the C library.
 +#
+ # Define NO_FNMATCH if you don't have fnmatch in the C library.
+ #
+ # Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
+ # FNM_CASEFOLD GNU extension.
+ #
  # Define NO_LIBGEN_H if you don't have libgen.h.
  #
  # Define NEEDS_LIBGEN if your libgen needs -lgen when linking
@@@ -270,7 -273,6 +275,7 @@@ STRIP ?= stri
  #   infodir
  #   htmldir
  #   ETC_GITCONFIG (but not sysconfdir)
 +#   ETC_GITATTRIBUTES
  # can be specified as a relative path some/where/else;
  # this is interpreted as relative to $(prefix) and "git" at
  # runtime figures out where they are based on the path to the executable.
@@@ -289,11 -291,9 +294,11 @@@ htmldir = share/doc/git-do
  ifeq ($(prefix),/usr)
  sysconfdir = /etc
  ETC_GITCONFIG = $(sysconfdir)/gitconfig
 +ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes
  else
  sysconfdir = $(prefix)/etc
  ETC_GITCONFIG = etc/gitconfig
 +ETC_GITATTRIBUTES = etc/gitattributes
  endif
  lib = lib
  # DESTDIR=
@@@ -313,7 -313,6 +318,7 @@@ TCL_PATH = tcls
  TCLTK_PATH = wish
  PTHREAD_LIBS = -lpthread
  PTHREAD_CFLAGS =
 +GCOV = gcov
  
  export TCL_PATH TCLTK_PATH
  
@@@ -393,15 -392,12 +398,15 @@@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH
          $(patsubst %.py,%,$(SCRIPT_PYTHON)) \
          git-instaweb
  
 +ETAGS_TARGET = TAGS
 +
  # Empty...
  EXTRA_PROGRAMS =
  
  # ... and all the rest that could be moved out of bindir to gitexecdir
  PROGRAMS += $(EXTRA_PROGRAMS)
  
 +PROGRAM_OBJS += daemon.o
  PROGRAM_OBJS += fast-import.o
  PROGRAM_OBJS += imap-send.o
  PROGRAM_OBJS += shell.o
@@@ -417,17 -413,12 +422,17 @@@ TEST_PROGRAMS_NEED_X += test-dat
  TEST_PROGRAMS_NEED_X += test-delta
  TEST_PROGRAMS_NEED_X += test-dump-cache-tree
  TEST_PROGRAMS_NEED_X += test-genrandom
 +TEST_PROGRAMS_NEED_X += test-line-buffer
  TEST_PROGRAMS_NEED_X += test-match-trees
 +TEST_PROGRAMS_NEED_X += test-obj-pool
  TEST_PROGRAMS_NEED_X += test-parse-options
  TEST_PROGRAMS_NEED_X += test-path-utils
  TEST_PROGRAMS_NEED_X += test-run-command
  TEST_PROGRAMS_NEED_X += test-sha1
  TEST_PROGRAMS_NEED_X += test-sigchain
 +TEST_PROGRAMS_NEED_X += test-string-pool
 +TEST_PROGRAMS_NEED_X += test-svn-fe
 +TEST_PROGRAMS_NEED_X += test-treap
  TEST_PROGRAMS_NEED_X += test-index-version
  
  TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
@@@ -482,7 -473,6 +487,7 @@@ export PYTHON_PAT
  
  LIB_FILE=libgit.a
  XDIFF_LIB=xdiff/lib.a
 +VCSSVN_LIB=vcs-svn/lib.a
  
  LIB_H += advice.h
  LIB_H += archive.h
@@@ -497,8 -487,6 +502,8 @@@ LIB_H += compat/bswap.
  LIB_H += compat/cygwin.h
  LIB_H += compat/mingw.h
  LIB_H += compat/win32/pthread.h
 +LIB_H += compat/win32/syslog.h
 +LIB_H += compat/win32/sys/poll.h
  LIB_H += csum-file.h
  LIB_H += decorate.h
  LIB_H += delta.h
@@@ -849,6 -837,7 +854,7 @@@ ifeq ($(uname_S),SunOS
        NO_MKDTEMP = YesPlease
        NO_MKSTEMPS = YesPlease
        NO_REGEX = YesPlease
+       NO_FNMATCH_CASEFOLD = YesPlease
        ifeq ($(uname_R),5.6)
                SOCKLEN_T = int
                NO_HSTRERROR = YesPlease
@@@ -990,7 -979,6 +996,7 @@@ ifeq ($(uname_S),IRIX
        # NO_MMAP.  If you suspect that your compiler is not affected by this
        # issue, comment out the NO_MMAP statement.
        NO_MMAP = YesPlease
 +      NO_REGEX = YesPlease
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH = /usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
@@@ -1009,7 -997,6 +1015,7 @@@ ifeq ($(uname_S),IRIX64
        # NO_MMAP.  If you suspect that your compiler is not affected by this
        # issue, comment out the NO_MMAP statement.
        NO_MMAP = YesPlease
 +      NO_REGEX = YesPlease
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH=/usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
@@@ -1054,7 -1041,7 +1060,8 @@@ ifeq ($(uname_S),Windows
        NO_UNSETENV = YesPlease
        NO_STRCASESTR = YesPlease
        NO_STRLCPY = YesPlease
 +      NO_STRTOK_R = YesPlease
+       NO_FNMATCH = YesPlease
        NO_MEMMEM = YesPlease
        # NEEDS_LIBICONV = YesPlease
        NO_ICONV = YesPlease
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        RUNTIME_PREFIX = YesPlease
 -      NO_POSIX_ONLY_PROGRAMS = YesPlease
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
        NO_CURL = YesPlease
        NO_PYTHON = YesPlease
        BLK_SHA1 = YesPlease
 +      NO_POSIX_GOODIES = UnfortunatelyYes
        NATIVE_CRLF = YesPlease
  
        CC = compat/vcbuild/scripts/clink.pl
        AR = compat/vcbuild/scripts/lib.pl
        CFLAGS =
        BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
-       COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o compat/win32/sys/poll.o
-       COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
 -      COMPAT_OBJS = compat/msvc.o compat/winansi.o compat/win32/pthread.o
++      COMPAT_OBJS = compat/msvc.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o compat/win32/sys/poll.o
+       COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
        BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
        EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib
        PTHREAD_LIBS =
  endif
        X = .exe
  endif
 +ifeq ($(uname_S),Interix)
 +      NO_SYS_POLL_H = YesPlease
 +      NO_INTTYPES_H = YesPlease
 +      NO_INITGROUPS = YesPlease
 +      NO_IPV6 = YesPlease
 +      NO_MEMMEM = YesPlease
 +      NO_MKDTEMP = YesPlease
 +      NO_STRTOUMAX = YesPlease
 +      NO_NSEC = YesPlease
 +      NO_MKSTEMPS = YesPlease
 +      ifeq ($(uname_R),3.5)
 +              NO_INET_NTOP = YesPlease
 +              NO_INET_PTON = YesPlease
 +      endif
 +      ifeq ($(uname_R),5.2)
 +              NO_INET_NTOP = YesPlease
 +              NO_INET_PTON = YesPlease
 +      endif
 +endif
  ifneq (,$(findstring MINGW,$(uname_S)))
        pathsep = ;
        NO_PREAD = YesPlease
        NO_UNSETENV = YesPlease
        NO_STRCASESTR = YesPlease
        NO_STRLCPY = YesPlease
 +      NO_STRTOK_R = YesPlease
+       NO_FNMATCH = YesPlease
        NO_MEMMEM = YesPlease
        NEEDS_LIBICONV = YesPlease
        OLD_ICONV = YesPlease
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        RUNTIME_PREFIX = YesPlease
 -      NO_POSIX_ONLY_PROGRAMS = YesPlease
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
        NO_REGEX = YesPlease
        NO_PYTHON = YesPlease
        BLK_SHA1 = YesPlease
-       COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
 +      ETAGS_TARGET = ETAGS
 +      NO_INET_PTON = YesPlease
 +      NO_INET_NTOP = YesPlease
 +      NO_POSIX_GOODIES = UnfortunatelyYes
+       COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/win32
        COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
-       COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
 -      COMPAT_OBJS += compat/mingw.o compat/winansi.o compat/win32/pthread.o
++      COMPAT_OBJS += compat/mingw.o compat/winansi.o \
 +              compat/win32/pthread.o compat/win32/syslog.o \
 +              compat/win32/sys/poll.o
        EXTLIBS += -lws2_32
        PTHREAD_LIBS =
        X = .exe
@@@ -1271,6 -1234,9 +1279,6 @@@ ifdef ZLIB_PAT
  endif
  EXTLIBS += -lz
  
 -ifndef NO_POSIX_ONLY_PROGRAMS
 -      PROGRAM_OBJS += daemon.o
 -endif
  ifndef NO_OPENSSL
        OPENSSL_LIBSSL = -lssl
        ifdef OPENSSLDIR
@@@ -1360,10 -1326,17 +1368,21 @@@ endi
  ifdef NO_STRTOULL
        COMPAT_CFLAGS += -DNO_STRTOULL
  endif
 +ifdef NO_STRTOK_R
 +      COMPAT_CFLAGS += -DNO_STRTOK_R
 +      COMPAT_OBJS += compat/strtok_r.o
 +endif
+ ifdef NO_FNMATCH
+       COMPAT_CFLAGS += -Icompat/fnmatch
+       COMPAT_CFLAGS += -DNO_FNMATCH
+       COMPAT_OBJS += compat/fnmatch/fnmatch.o
+ else
+ ifdef NO_FNMATCH_CASEFOLD
+       COMPAT_CFLAGS += -Icompat/fnmatch
+       COMPAT_CFLAGS += -DNO_FNMATCH_CASEFOLD
+       COMPAT_OBJS += compat/fnmatch/fnmatch.o
+ endif
+ endif
  ifdef NO_SETENV
        COMPAT_CFLAGS += -DNO_SETENV
        COMPAT_OBJS += compat/setenv.o
@@@ -1382,15 -1355,6 +1401,15 @@@ endi
  ifdef NO_SYS_SELECT_H
        BASIC_CFLAGS += -DNO_SYS_SELECT_H
  endif
 +ifdef NO_SYS_POLL_H
 +      BASIC_CFLAGS += -DNO_SYS_POLL_H
 +endif
 +ifdef NO_INTTYPES_H
 +      BASIC_CFLAGS += -DNO_INTTYPES_H
 +endif
 +ifdef NO_INITGROUPS
 +      BASIC_CFLAGS += -DNO_INITGROUPS
 +endif
  ifdef NO_MMAP
        COMPAT_CFLAGS += -DNO_MMAP
        COMPAT_OBJS += compat/mmap.o
@@@ -1428,11 -1392,9 +1447,11 @@@ endi
  endif
  ifdef NO_INET_NTOP
        LIB_OBJS += compat/inet_ntop.o
 +      BASIC_CFLAGS += -DNO_INET_NTOP
  endif
  ifdef NO_INET_PTON
        LIB_OBJS += compat/inet_pton.o
 +      BASIC_CFLAGS += -DNO_INET_PTON
  endif
  
  ifdef NO_ICONV
@@@ -1447,10 -1409,6 +1466,10 @@@ ifdef NO_DEFLATE_BOUN
        BASIC_CFLAGS += -DNO_DEFLATE_BOUND
  endif
  
 +ifdef NO_POSIX_GOODIES
 +      BASIC_CFLAGS += -DNO_POSIX_GOODIES
 +endif
 +
  ifdef BLK_SHA1
        SHA1_HEADER = "block-sha1/sha1.h"
        LIB_OBJS += block-sha1/sha1.o
@@@ -1508,7 -1466,7 +1527,7 @@@ ifdef NO_REGE
  endif
  
  ifdef USE_NED_ALLOCATOR
 -       COMPAT_CFLAGS += -DUSE_NED_ALLOCATOR -DOVERRIDE_STRDUP -DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR -Icompat/nedmalloc
 +       COMPAT_CFLAGS += -Icompat/nedmalloc
         COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
  endif
  
@@@ -1545,7 -1503,6 +1564,7 @@@ ifndef 
        QUIET_BUILT_IN = @echo '   ' BUILTIN $@;
        QUIET_GEN      = @echo '   ' GEN $@;
        QUIET_LNCP     = @echo '   ' LN/CP $@;
 +      QUIET_GCOV     = @echo '   ' GCOV $@;
        QUIET_SUBDIR0  = +@subdir=
        QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
                         $(MAKE) $(PRINT_DIR) -C $$subdir
@@@ -1563,7 -1520,6 +1582,7 @@@ endi
  
  SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
  ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG))
 +ETC_GITATTRIBUTES_SQ = $(subst ','\'',$(ETC_GITATTRIBUTES))
  
  DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
  bindir_SQ = $(subst ','\'',$(bindir))
@@@ -1801,9 -1757,7 +1820,9 @@@ ifndef NO_CUR
  endif
  XDIFF_OBJS = xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
        xdiff/xmerge.o xdiff/xpatience.o
 -OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS)
 +VCSSVN_OBJS = vcs-svn/string_pool.o vcs-svn/line_buffer.o \
 +      vcs-svn/repo_tree.o vcs-svn/fast_export.o vcs-svn/svndump.o
 +OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
  
  dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
  dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
@@@ -1925,11 -1879,6 +1944,11 @@@ http.o http-walker.o http-push.o http-f
  xdiff-interface.o $(XDIFF_OBJS): \
        xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \
        xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h
 +
 +$(VCSSVN_OBJS): \
 +      vcs-svn/obj_pool.h vcs-svn/trp.h vcs-svn/string_pool.h \
 +      vcs-svn/line_buffer.h vcs-svn/repo_tree.h vcs-svn/fast_export.h \
 +      vcs-svn/svndump.h
  endif
  
  exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \
@@@ -1942,29 -1891,18 +1961,29 @@@ builtin/init-db.s builtin/init-db.o: EX
  
  config.s config.o: EXTRA_CPPFLAGS = -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"'
  
 -http.s http.o: EXTRA_CPPFLAGS = -DGIT_USER_AGENT='"git/$(GIT_VERSION)"'
 +attr.s attr.o: EXTRA_CPPFLAGS = -DETC_GITATTRIBUTES='"$(ETC_GITATTRIBUTES_SQ)"'
 +
 +http.s http.o: EXTRA_CPPFLAGS = -DGIT_HTTP_USER_AGENT='"git/$(GIT_VERSION)"'
  
  ifdef NO_EXPAT
  http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT
  endif
  
 +ifdef NO_REGEX
 +compat/regex/regex.o: EXTRA_CPPFLAGS = -DGAWK -DNO_MBSUPPORT
 +endif
 +
 +ifdef USE_NED_ALLOCATOR
 +compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
 +      -DNDEBUG -DOVERRIDE_STRDUP -DREPLACE_SYSTEM_ALLOCATOR
 +endif
 +
  git-%$X: %.o $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
  
  git-imap-send$X: imap-send.o $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 -              $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL)
 +              $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO)
  
  git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
@@@ -1989,8 -1927,6 +2008,8 @@@ $(LIB_FILE): $(LIB_OBJS
  $(XDIFF_LIB): $(XDIFF_OBJS)
        $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS)
  
 +$(VCSSVN_LIB): $(VCSSVN_OBJS)
 +      $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(VCSSVN_OBJS)
  
  doc:
        $(MAKE) -C Documentation all
@@@ -2007,11 -1943,11 +2026,11 @@@ info
  pdf:
        $(MAKE) -C Documentation pdf
  
 -TAGS:
 -      $(RM) TAGS
 -      $(FIND) . -name '*.[hcS]' -print | xargs etags -a
 +$(ETAGS_TARGET): FORCE
 +      $(RM) $(ETAGS_TARGET)
 +      $(FIND) . -name '*.[hcS]' -print | xargs etags -a -o $(ETAGS_TARGET)
  
 -tags:
 +tags: FORCE
        $(RM) tags
        $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
  
@@@ -2020,7 -1956,7 +2039,7 @@@ cscope
        $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
  
  ### Detect prefix changes
 -TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
 +TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):\
               $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
  
  GIT-CFLAGS: FORCE
@@@ -2089,18 -2025,12 +2108,18 @@@ test-date$X: date.o ctype.
  
  test-delta$X: diff-delta.o patch-delta.o
  
 +test-line-buffer$X: vcs-svn/lib.a
 +
  test-parse-options$X: parse-options.o
  
 +test-string-pool$X: vcs-svn/lib.a
 +
 +test-svn-fe$X: vcs-svn/lib.a
 +
  .PRECIOUS: $(TEST_OBJS)
  
  test-%$X: test-%.o $(GITLIBS)
 -      $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
 +      $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)
  
  check-sha1:: test-sha1$X
        ./test-sha1.sh
@@@ -2275,13 -2205,13 +2294,13 @@@ distclean: clea
        $(RM) configure
  
  clean:
 -      $(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
 -              builtin/*.o $(LIB_FILE) $(XDIFF_LIB)
 +      $(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o vcs-svn/*.o \
 +              builtin/*.o $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
        $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
        $(RM) $(TEST_PROGRAMS)
        $(RM) -r bin-wrappers
        $(RM) -r $(dep_dirs)
 -      $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
 +      $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope*
        $(RM) -r autom4te.cache
        $(RM) config.log config.mak.autogen config.mak.append config.status config.cache
        $(RM) -r $(GIT_TARNAME) .doc-tmp-dir
@@@ -2305,7 -2235,7 +2324,7 @@@ endi
  
  .PHONY: all install clean strip
  .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
 -.PHONY: FORCE TAGS tags cscope
 +.PHONY: FORCE cscope
  
  ### Check documentation
  #
@@@ -2379,18 -2309,11 +2398,18 @@@ coverage
        $(MAKE) coverage-build
        $(MAKE) coverage-report
  
 +object_dirs := $(sort $(dir $(OBJECTS)))
  coverage-clean:
 -      rm -f *.gcda *.gcno
 +      $(RM) $(addsuffix *.gcov,$(object_dirs))
 +      $(RM) $(addsuffix *.gcda,$(object_dirs))
 +      $(RM) $(addsuffix *.gcno,$(object_dirs))
 +      $(RM) coverage-untested-functions
 +      $(RM) -r cover_db/
 +      $(RM) -r cover_db_html/
  
  COVERAGE_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs
  COVERAGE_LDFLAGS = $(CFLAGS)  -O0 -lgcov
 +GCOVFLAGS = --preserve-paths --branch-probabilities --all-blocks
  
  coverage-build: coverage-clean
        $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all
                -j1 test
  
  coverage-report:
 -      gcov -b *.c
 +      $(QUIET_GCOV)for dir in $(object_dirs); do \
 +              $(GCOV) $(GCOVFLAGS) --object-directory=$$dir $$dir*.c || exit; \
 +      done
 +
 +coverage-untested-functions: coverage-report
        grep '^function.*called 0 ' *.c.gcov \
                | sed -e 's/\([^:]*\)\.gcov: *function \([^ ]*\) called.*/\1: \2/' \
 -              | tee coverage-untested-functions
 +              > coverage-untested-functions
 +
 +cover_db: coverage-report
 +      gcov2perl -db cover_db *.gcov
 +
 +cover_db_html: cover_db
 +      cover -report html -outputdir cover_db_html cover_db
diff --combined config.mak.in
index a0c34eec15773f0f3e4d2b4e12f0c76e722ede95,e4c3f569a30b6addb097d6d412e0744bcf886e64..56343bab505b59289d0a5334a2a6ac840d3f10d1
@@@ -46,7 -46,8 +46,9 @@@ NO_IPV6=@NO_IPV6
  NO_C99_FORMAT=@NO_C99_FORMAT@
  NO_HSTRERROR=@NO_HSTRERROR@
  NO_STRCASESTR=@NO_STRCASESTR@
 +NO_STRTOK_R=@NO_STRTOK_R@
+ NO_FNMATCH=@NO_FNMATCH@
+ NO_FNMATCH_CASEFOLD=@NO_FNMATCH_CASEFOLD@
  NO_MEMMEM=@NO_MEMMEM@
  NO_STRLCPY=@NO_STRLCPY@
  NO_UINTMAX_T=@NO_UINTMAX_T@
@@@ -59,7 -60,6 +61,7 @@@ NO_INET_NTOP=@NO_INET_NTOP
  NO_INET_PTON=@NO_INET_PTON@
  NO_ICONV=@NO_ICONV@
  OLD_ICONV=@OLD_ICONV@
 +NO_REGEX=@NO_REGEX@
  NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
  INLINE=@INLINE@
  SOCKLEN_T=@SOCKLEN_T@
diff --combined configure.ac
index c5bc9a05f3730dc42f6a0dbf35551107886d7b0c,cbca4c763a9b005266f8818a5eafb9bb6f7903f6..33dd46262bfb7e6d9db80446fa06ff0ba819f5df
@@@ -282,15 -282,7 +282,15 @@@ GIT_PARSE_WITH(iconv)
  GIT_PARSE_WITH_SET_MAKE_VAR(gitconfig, ETC_GITCONFIG,
                        Use VALUE instead of /etc/gitconfig as the
                        global git configuration file.
 -                      If VALUE is not fully qualified it will be interpretted
 +                      If VALUE is not fully qualified it will be interpreted
 +                      as a path relative to the computed prefix at runtime.)
 +
 +#
 +# Allow user to set ETC_GITATTRIBUTES variable
 +GIT_PARSE_WITH_SET_MAKE_VAR(gitattributes, ETC_GITATTRIBUTES,
 +                      Use VALUE instead of /etc/gitattributes as the
 +                      global git attributes file.
 +                      If VALUE is not fully qualified it will be interpreted
                        as a path relative to the computed prefix at runtime.)
  
  #
@@@ -617,18 -609,6 +617,18 @@@ AC_CHECK_HEADER([sys/select.h]
  [NO_SYS_SELECT_H=UnfortunatelyYes])
  AC_SUBST(NO_SYS_SELECT_H)
  #
 +# Define NO_SYS_POLL_H if you don't have sys/poll.h
 +AC_CHECK_HEADER([sys/poll.h],
 +[NO_SYS_POLL_H=],
 +[NO_SYS_POLL_H=UnfortunatelyYes])
 +AC_SUBST(NO_SYS_POLL_H)
 +#
 +# Define NO_INTTYPES_H if you don't have inttypes.h
 +AC_CHECK_HEADER([inttypes.h],
 +[NO_INTTYPES_H=],
 +[NO_INTTYPES_H=UnfortunatelyYes])
 +AC_SUBST(NO_INTTYPES_H)
 +#
  # Define OLD_ICONV if your library has an old iconv(), where the second
  # (input buffer pointer) parameter is declared with type (const char **).
  AC_DEFUN([OLDICONVTEST_SRC], [[
@@@ -726,27 -706,6 +726,27 @@@ els
  fi
  AC_SUBST(NO_C99_FORMAT)
  #
 +# Define NO_REGEX if you have no or inferior regex support in your C library.
 +AC_CACHE_CHECK([whether the platform regex can handle null bytes],
 + [ac_cv_c_excellent_regex], [
 +AC_EGREP_CPP(yippeeyeswehaveit,
 +      AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
 +#include <regex.h>
 +],
 +[#ifdef REG_STARTEND
 +yippeeyeswehaveit
 +#endif
 +]),
 +      [ac_cv_c_excellent_regex=yes],
 +      [ac_cv_c_excellent_regex=no])
 +])
 +if test $ac_cv_c_excellent_regex = yes; then
 +      NO_REGEX=
 +else
 +      NO_REGEX=YesPlease
 +fi
 +AC_SUBST(NO_REGEX)
 +#
  # Define FREAD_READS_DIRECTORIES if your are on a system which succeeds
  # when attempting to read from an fopen'ed directory.
  AC_CACHE_CHECK([whether system succeeds to read fopen'ed directory],
@@@ -824,12 -783,34 +824,40 @@@ GIT_CHECK_FUNC(strcasestr
  [NO_STRCASESTR=YesPlease])
  AC_SUBST(NO_STRCASESTR)
  #
 +# Define NO_STRTOK_R if you don't have strtok_r
 +GIT_CHECK_FUNC(strtok_r,
 +[NO_STRTOK_R=],
 +[NO_STRTOK_R=YesPlease])
 +AC_SUBST(NO_STRTOK_R)
 +#
+ # Define NO_FNMATCH if you don't have fnmatch
+ GIT_CHECK_FUNC(fnmatch,
+ [NO_FNMATCH=],
+ [NO_FNMATCH=YesPlease])
+ AC_SUBST(NO_FNMATCH)
+ #
+ # Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
+ # FNM_CASEFOLD GNU extension.
+ AC_CACHE_CHECK([whether the fnmatch function supports the FNMATCH_CASEFOLD GNU extension],
+  [ac_cv_c_excellent_fnmatch], [
+ AC_EGREP_CPP(yippeeyeswehaveit,
+       AC_LANG_PROGRAM([
+ #include <fnmatch.h>
+ ],
+ [#ifdef FNM_CASEFOLD
+ yippeeyeswehaveit
+ #endif
+ ]),
+       [ac_cv_c_excellent_fnmatch=yes],
+       [ac_cv_c_excellent_fnmatch=no])
+ ])
+ if test $ac_cv_c_excellent_fnmatch = yes; then
+       NO_FNMATCH_CASEFOLD=
+ else
+       NO_FNMATCH_CASEFOLD=YesPlease
+ fi
+ AC_SUBST(NO_FNMATCH_CASEFOLD)
+ #
  # Define NO_MEMMEM if you don't have memmem.
  GIT_CHECK_FUNC(memmem,
  [NO_MEMMEM=],
@@@ -880,12 -861,6 +908,12 @@@ GIT_CHECK_FUNC(mkstemps
  [NO_MKSTEMPS=YesPlease])
  AC_SUBST(NO_MKSTEMPS)
  #
 +# Define NO_INITGROUPS if you don't have initgroups in the C library.
 +GIT_CHECK_FUNC(initgroups,
 +[NO_INITGROUPS=],
 +[NO_INITGROUPS=YesPlease])
 +AC_SUBST(NO_INITGROUPS)
 +#
  #
  # Define NO_MMAP if you want to avoid mmap.
  #
diff --combined dir.c
index b2dfb69eb5606a7538cc5e1876a91f703ec4969c,58ec1a11d9807598bd5004d63cc87e7ecd0f1776..852e60f2a8d4784bf73d044f89fe822538121286
--- 1/dir.c
--- 2/dir.c
+++ b/dir.c
@@@ -18,6 -18,22 +18,22 @@@ static int read_directory_recursive(str
        int check_only, const struct path_simplify *simplify);
  static int get_dtype(struct dirent *de, const char *path, int len);
  
+ /* helper string functions with support for the ignore_case flag */
+ int strcmp_icase(const char *a, const char *b)
+ {
+       return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
+ }
+ int strncmp_icase(const char *a, const char *b, size_t count)
+ {
+       return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
+ }
+ int fnmatch_icase(const char *pattern, const char *string, int flags)
+ {
+       return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
+ }
  static int common_prefix(const char **pathspec)
  {
        const char *path, *slash, *next;
@@@ -91,16 -107,30 +107,30 @@@ static int match_one(const char *match
        if (!*match)
                return MATCHED_RECURSIVELY;
  
-       for (;;) {
-               unsigned char c1 = *match;
-               unsigned char c2 = *name;
-               if (c1 == '\0' || is_glob_special(c1))
-                       break;
-               if (c1 != c2)
-                       return 0;
-               match++;
-               name++;
-               namelen--;
+       if (ignore_case) {
+               for (;;) {
+                       unsigned char c1 = tolower(*match);
+                       unsigned char c2 = tolower(*name);
+                       if (c1 == '\0' || is_glob_special(c1))
+                               break;
+                       if (c1 != c2)
+                               return 0;
+                       match++;
+                       name++;
+                       namelen--;
+               }
+       } else {
+               for (;;) {
+                       unsigned char c1 = *match;
+                       unsigned char c2 = *name;
+                       if (c1 == '\0' || is_glob_special(c1))
+                               break;
+                       if (c1 != c2)
+                               return 0;
+                       match++;
+                       name++;
+                       namelen--;
+               }
        }
  
  
         * we need to match by fnmatch
         */
        matchlen = strlen(match);
-       if (strncmp(match, name, matchlen))
-               return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
+       if (strncmp_icase(match, name, matchlen))
+               return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0;
  
        if (namelen == matchlen)
                return MATCHED_EXACTLY;
@@@ -232,7 -262,7 +262,7 @@@ int add_excludes_from_file_to_list(cons
  {
        struct stat st;
        int fd, i;
 -      size_t size;
 +      size_t size = 0;
        char *buf, *entry;
  
        fd = open(fname, O_RDONLY);
@@@ -360,8 -390,7 +390,8 @@@ int excluded_from_list(const char *path
  
                        if (x->flags & EXC_FLAG_MUSTBEDIR) {
                                if (!dtype) {
 -                                      if (!prefixcmp(pathname, exclude))
 +                                      if (!prefixcmp(pathname, exclude) &&
 +                                          pathname[x->patternlen] == '/')
                                                return to_exclude;
                                        else
                                                continue;
                        if (x->flags & EXC_FLAG_NODIR) {
                                /* match basename */
                                if (x->flags & EXC_FLAG_NOWILDCARD) {
-                                       if (!strcmp(exclude, basename))
+                                       if (!strcmp_icase(exclude, basename))
                                                return to_exclude;
                                } else if (x->flags & EXC_FLAG_ENDSWITH) {
                                        if (x->patternlen - 1 <= pathlen &&
-                                           !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))
+                                           !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))
                                                return to_exclude;
                                } else {
-                                       if (fnmatch(exclude, basename, 0) == 0)
+                                       if (fnmatch_icase(exclude, basename, 0) == 0)
                                                return to_exclude;
                                }
                        }
  
                                if (pathlen < baselen ||
                                    (baselen && pathname[baselen-1] != '/') ||
-                                   strncmp(pathname, x->base, baselen))
+                                   strncmp_icase(pathname, x->base, baselen))
                                    continue;
  
                                if (x->flags & EXC_FLAG_NOWILDCARD) {
-                                       if (!strcmp(exclude, pathname + baselen))
+                                       if (!strcmp_icase(exclude, pathname + baselen))
                                                return to_exclude;
                                } else {
-                                       if (fnmatch(exclude, pathname+baselen,
+                                       if (fnmatch_icase(exclude, pathname+baselen,
                                                    FNM_PATHNAME) == 0)
                                            return to_exclude;
                                }
@@@ -469,6 -498,39 +499,39 @@@ enum exist_status 
        index_gitdir
  };
  
+ /*
+  * Do not use the alphabetically stored index to look up
+  * the directory name; instead, use the case insensitive
+  * name hash.
+  */
+ static enum exist_status directory_exists_in_index_icase(const char *dirname, int len)
+ {
+       struct cache_entry *ce = index_name_exists(&the_index, dirname, len + 1, ignore_case);
+       unsigned char endchar;
+       if (!ce)
+               return index_nonexistent;
+       endchar = ce->name[len];
+       /*
+        * The cache_entry structure returned will contain this dirname
+        * and possibly additional path components.
+        */
+       if (endchar == '/')
+               return index_directory;
+       /*
+        * If there are no additional path components, then this cache_entry
+        * represents a submodule.  Submodules, despite being directories,
+        * are stored in the cache without a closing slash.
+        */
+       if (!endchar && S_ISGITLINK(ce->ce_mode))
+               return index_gitdir;
+       /* This should never be hit, but it exists just in case. */
+       return index_nonexistent;
+ }
  /*
   * The index sorts alphabetically by entry name, which
   * means that a gitlink sorts as '\0' at the end, while
   */
  static enum exist_status directory_exists_in_index(const char *dirname, int len)
  {
-       int pos = cache_name_pos(dirname, len);
+       int pos;
+       if (ignore_case)
+               return directory_exists_in_index_icase(dirname, len);
+       pos = cache_name_pos(dirname, len);
        if (pos < 0)
                pos = -pos-1;
        while (pos < active_nr) {
diff --combined fast-import.c
index 8263dbe841a6ac738c3a5a31006f3fdffcbc7e77,c3abe554cbd302f6fe982a4c655b3530a6a10563..534c68db6fe4d0c34c38e632bd2c442966cf8663
@@@ -156,6 -156,7 +156,7 @@@ Format of STDIN stream
  #include "csum-file.h"
  #include "quote.h"
  #include "exec_cmd.h"
+ #include "dir.h"
  
  #define PACK_ID_BITS 16
  #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
@@@ -1437,20 -1438,6 +1438,20 @@@ static void store_tree(struct tree_entr
        t->entry_count -= del;
  }
  
 +static void tree_content_replace(
 +      struct tree_entry *root,
 +      const unsigned char *sha1,
 +      const uint16_t mode,
 +      struct tree_content *newtree)
 +{
 +      if (!S_ISDIR(mode))
 +              die("Root cannot be a non-directory");
 +      hashcpy(root->versions[1].sha1, sha1);
 +      if (root->tree)
 +              release_tree_content_recursive(root->tree);
 +      root->tree = newtree;
 +}
 +
  static int tree_content_set(
        struct tree_entry *root,
        const char *p,
        const uint16_t mode,
        struct tree_content *subtree)
  {
 -      struct tree_content *t = root->tree;
 +      struct tree_content *t;
        const char *slash1;
        unsigned int i, n;
        struct tree_entry *e;
        if (!slash1 && !S_ISDIR(mode) && subtree)
                die("Non-directories cannot have subtrees");
  
 +      if (!root->tree)
 +              load_tree(root);
 +      t = root->tree;
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
-               if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+               if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
                        if (!slash1) {
                                if (!S_ISDIR(mode)
                                                && e->versions[1].mode == mode
@@@ -1531,7 -1515,7 +1532,7 @@@ static int tree_content_remove
        const char *p,
        struct tree_entry *backup_leaf)
  {
 -      struct tree_content *t = root->tree;
 +      struct tree_content *t;
        const char *slash1;
        unsigned int i, n;
        struct tree_entry *e;
        else
                n = strlen(p);
  
 +      if (!root->tree)
 +              load_tree(root);
 +      t = root->tree;
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
-               if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+               if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
 +                      if (slash1 && !S_ISDIR(e->versions[1].mode))
 +                              /*
 +                               * If p names a file in some subdirectory, and a
 +                               * file or symlink matching the name of the
 +                               * parent directory of p exists, then p cannot
 +                               * exist and need not be deleted.
 +                               */
 +                              return 1;
                        if (!slash1 || !S_ISDIR(e->versions[1].mode))
                                goto del_entry;
                        if (!e->tree)
@@@ -1592,7 -1565,7 +1593,7 @@@ static int tree_content_get
        const char *p,
        struct tree_entry *leaf)
  {
 -      struct tree_content *t = root->tree;
 +      struct tree_content *t;
        const char *slash1;
        unsigned int i, n;
        struct tree_entry *e;
        else
                n = strlen(p);
  
 +      if (!root->tree)
 +              load_tree(root);
 +      t = root->tree;
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
-               if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+               if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
                        if (!slash1) {
                                memcpy(leaf, e, sizeof(*leaf));
                                if (e->tree && is_null_sha1(e->versions[1].sha1))
@@@ -2162,7 -2132,6 +2163,7 @@@ static void file_change_m(struct branc
        case S_IFREG | 0644:
        case S_IFREG | 0755:
        case S_IFLNK:
 +      case S_IFDIR:
        case S_IFGITLINK:
                /* ok */
                break;
                 * another repository.
                 */
        } else if (inline_data) {
 +              if (S_ISDIR(mode))
 +                      die("Directories cannot be specified 'inline': %s",
 +                              command_buf.buf);
                if (p != uq.buf) {
                        strbuf_addstr(&uq, p);
                        p = uq.buf;
                }
                read_next_command();
                parse_and_store_blob(&last_blob, sha1, 0);
 -      } else if (oe) {
 -              if (oe->type != OBJ_BLOB)
 -                      die("Not a blob (actually a %s): %s",
 -                              typename(oe->type), command_buf.buf);
        } else {
 -              enum object_type type = sha1_object_info(sha1, NULL);
 +              enum object_type expected = S_ISDIR(mode) ?
 +                                              OBJ_TREE: OBJ_BLOB;
 +              enum object_type type = oe ? oe->type :
 +                                      sha1_object_info(sha1, NULL);
                if (type < 0)
 -                      die("Blob not found: %s", command_buf.buf);
 -              if (type != OBJ_BLOB)
 -                      die("Not a blob (actually a %s): %s",
 -                          typename(type), command_buf.buf);
 +                      die("%s not found: %s",
 +                                      S_ISDIR(mode) ?  "Tree" : "Blob",
 +                                      command_buf.buf);
 +              if (type != expected)
 +                      die("Not a %s (actually a %s): %s",
 +                              typename(expected), typename(type),
 +                              command_buf.buf);
        }
  
 +      if (!*p) {
 +              tree_content_replace(&b->branch_tree, sha1, mode, NULL);
 +              return;
 +      }
        tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
  }
  
@@@ -2294,13 -2254,6 +2295,13 @@@ static void file_change_cr(struct branc
                tree_content_get(&b->branch_tree, s, &leaf);
        if (!leaf.versions[1].mode)
                die("Path %s not in branch", s);
 +      if (!*d) {      /* C "path/to/subdir" "" */
 +              tree_content_replace(&b->branch_tree,
 +                      leaf.versions[1].sha1,
 +                      leaf.versions[1].mode,
 +                      leaf.tree);
 +              return;
 +      }
        tree_content_set(&b->branch_tree, d,
                leaf.versions[1].sha1,
                leaf.versions[1].mode,
@@@ -2918,7 -2871,7 +2919,7 @@@ static int git_pack_config(const char *
  }
  
  static const char fast_import_usage[] =
 -"git fast-import [--date-format=f] [--max-pack-size=n] [--big-file-threshold=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
 +"git fast-import [--date-format=<f>] [--max-pack-size=<n>] [--big-file-threshold=<n>] [--depth=<n>] [--active-branches=<n>] [--export-marks=<marks.file>]";
  
  static void parse_argv(void)
  {
diff --combined read-cache.c
index 1f42473e8070a05ada8c56b0d60537227a5223ec,ac0fc80e77caeec13e61336b77c2a3798d0ab5c1..4f2e890b01b0c27ef2e49080e1fd34bf67e969c7
@@@ -608,6 -608,29 +608,29 @@@ int add_to_index(struct index_state *is
                ce->ce_mode = ce_mode_from_stat(ent, st_mode);
        }
  
+       /* When core.ignorecase=true, determine if a directory of the same name but differing
+        * case already exists within the Git repository.  If it does, ensure the directory
+        * case of the file being added to the repository matches (is folded into) the existing
+        * entry's directory case.
+        */
+       if (ignore_case) {
+               const char *startPtr = ce->name;
+               const char *ptr = startPtr;
+               while (*ptr) {
+                       while (*ptr && *ptr != '/')
+                               ++ptr;
+                       if (*ptr == '/') {
+                               struct cache_entry *foundce;
+                               ++ptr;
+                               foundce = index_name_exists(&the_index, ce->name, ptr - ce->name, ignore_case);
+                               if (foundce) {
+                                       memcpy((void *)startPtr, foundce->name + (startPtr - ce->name), ptr - startPtr);
+                                       startPtr = ptr;
+                               }
+                       }
+               }
+       }
        alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
        if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
                /* Nothing changed, really */
@@@ -1516,7 -1539,6 +1539,7 @@@ static int ce_write_entry(git_SHA_CTX *
        int size = ondisk_ce_size(ce);
        struct ondisk_cache_entry *ondisk = xcalloc(1, size);
        char *name;
 +      int result;
  
        ondisk->ctime.sec = htonl(ce->ce_ctime.sec);
        ondisk->mtime.sec = htonl(ce->ce_mtime.sec);
                name = ondisk->name;
        memcpy(name, ce->name, ce_namelen(ce));
  
 -      return ce_write(c, fd, ondisk, size);
 +      result = ce_write(c, fd, ondisk, size);
 +      free(ondisk);
 +      return result;
  }
  
  int write_index(struct index_state *istate, int newfd)