From: Junio C Hamano Date: Sat, 4 Dec 2010 00:10:34 +0000 (-0800) Subject: Merge branch 'jj/icase-directory' X-Git-Tag: v1.7.4-rc0~94 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/5e738ae820ec53c45895b029baa3a1f63e654b1b?ds=sidebyside;hp=-c Merge branch 'jj/icase-directory' * 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 --- 5e738ae820ec53c45895b029baa3a1f63e654b1b diff --combined Makefile index 1d42413465,8407c38407..29ebe70599 --- a/Makefile +++ 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 @@@ -1067,6 -1054,7 +1074,6 @@@ 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 @@@ -1077,15 -1065,14 +1084,15 @@@ 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 = @@@ -1099,25 -1086,6 +1106,25 @@@ els 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 @@@ -1128,7 -1096,7 +1135,8 @@@ 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 @@@ -1139,6 -1107,7 +1147,6 @@@ 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 @@@ -1148,15 -1117,9 +1156,15 @@@ NO_REGEX = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease + ETAGS_TARGET = ETAGS + NO_INET_PTON = YesPlease + NO_INET_NTOP = YesPlease + NO_POSIX_GOODIES = UnfortunatelyYes - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32 + 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 @@@ -2398,17 -2321,7 +2417,17 @@@ -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 a0c34eec15,e4c3f569a3..56343bab50 --- a/config.mak.in +++ b/config.mak.in @@@ -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 c5bc9a05f3,cbca4c763a..33dd46262b --- a/configure.ac +++ b/configure.ac @@@ -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 +], +[#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 + ], + [#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 b2dfb69eb5,58ec1a11d9..852e60f2a8 --- a/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--; + } } @@@ -109,8 -139,8 +139,8 @@@ * 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; @@@ -375,14 -404,14 +405,14 @@@ 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; } } @@@ -397,14 -426,14 +427,14 @@@ 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 @@@ -478,7 -540,12 +541,12 @@@ */ 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 8263dbe841,c3abe554cb..534c68db6f --- a/fast-import.c +++ b/fast-import.c @@@ -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<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, @@@ -1458,7 -1445,7 +1459,7 @@@ 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; @@@ -1473,12 -1460,9 +1474,12 @@@ 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; @@@ -1542,20 -1526,9 +1543,20 @@@ 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; @@@ -1603,12 -1576,9 +1604,12 @@@ 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; @@@ -2208,34 -2177,25 +2209,34 @@@ * 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=] [--max-pack-size=] [--big-file-threshold=] [--depth=] [--active-branches=] [--export-marks=]"; static void parse_argv(void) { diff --combined read-cache.c index 1f42473e80,ac0fc80e77..4f2e890b01 --- a/read-cache.c +++ b/read-cache.c @@@ -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); @@@ -1540,9 -1562,7 +1563,9 @@@ 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)