From: Junio C Hamano Date: Sat, 22 Aug 2009 01:47:53 +0000 (-0700) Subject: Merge branch 'cc/replace' X-Git-Tag: v1.6.5-rc0~52 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/f00ecbe42b82f3c8e6a170074f2299487026e400?ds=inline;hp=-c Merge branch 'cc/replace' * cc/replace: t6050: check pushing something based on a replaced commit Documentation: add documentation for "git replace" Add git-replace to .gitignore builtin-replace: use "usage_msg_opt" to give better error messages parse-options: add new function "usage_msg_opt" builtin-replace: teach "git replace" to actually replace Add new "git replace" command environment: add global variable to disable replacement mktag: call "check_sha1_signature" with the replacement sha1 replace_object: add a test case object: call "check_sha1_signature" with the replacement sha1 sha1_file: add a "read_sha1_file_repl" function replace_object: add mechanism to replace objects found in "refs/replace/" refs: add a "for_each_replace_ref" function --- f00ecbe42b82f3c8e6a170074f2299487026e400 diff --combined Makefile index e6df8ecde6,6c46629b8c..66eedeff42 --- a/Makefile +++ b/Makefile @@@ -3,11 -3,6 +3,11 @@@ all: # Define V=1 to have a more verbose compile. # +# Define SHELL_PATH to a POSIX shell if your /bin/sh is broken. +# +# Define SANE_TOOL_PATH to a colon-separated list of paths to prepend +# to PATH if your tools in /usr/bin are broken. +# # Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf() # or vsnprintf() return -1 instead of number of characters which would # have been written to the final string if enough space had been available. @@@ -57,12 -52,6 +57,12 @@@ # # Define NO_MKDTEMP if you don't have mkdtemp in the C library. # +# Define NO_MKSTEMPS if you don't have mkstemps in the C library. +# +# Define NO_LIBGEN_H if you don't have libgen.h. +# +# Define NEEDS_LIBGEN if your libgen needs -lgen when linking +# # Define NO_SYS_SELECT_H if you don't have sys/select.h. # # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. @@@ -84,10 -73,6 +84,10 @@@ # specify your own (or DarwinPort's) include directories and # library directories by defining CFLAGS and LDFLAGS appropriately. # +# Define BLK_SHA1 environment variable if you want the C version +# of the SHA1 that assumes you can do unaligned 32-bit loads and +# have a fast htonl() function. +# # Define PPC_SHA1 environment variable when running make to make use of # a bundled SHA1 routine optimized for PowerPC. # @@@ -106,10 -91,6 +106,10 @@@ # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, # Patrick Mauritz). # +# Define NEEDS_RESOLV if linking with -lnsl and/or -lsocket is not enough. +# Notably on Solaris hstrerror resides in libresolv and on Solaris 7 +# inet_ntop and inet_pton additionally reside there. +# # Define NO_MMAP if you want to avoid mmap. # # Define NO_PTHREADS if you do not have or do not want to use Pthreads. @@@ -197,11 -178,6 +197,11 @@@ # # Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed # programs as a tar, where bin/ and libexec/ might be on different file systems. +# +# Define USE_NED_ALLOCATOR if you want to replace the platforms default +# memory allocators with the nedmalloc allocator written by Niall Douglas. +# +# Define NO_REGEX if you have no or inferior regex support in your C library. GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE @$(SHELL_PATH) ./GIT-VERSION-GEN @@@ -536,6 -512,7 +536,7 @@@ LIB_OBJS += read-cache. LIB_OBJS += reflog-walk.o LIB_OBJS += refs.o LIB_OBJS += remote.o + LIB_OBJS += replace_object.o LIB_OBJS += rerere.o LIB_OBJS += revision.o LIB_OBJS += run-command.o @@@ -625,6 -602,7 +626,7 @@@ BUILTIN_OBJS += builtin-read-tree. BUILTIN_OBJS += builtin-receive-pack.o BUILTIN_OBJS += builtin-reflog.o BUILTIN_OBJS += builtin-remote.o + BUILTIN_OBJS += builtin-replace.o BUILTIN_OBJS += builtin-rerere.o BUILTIN_OBJS += builtin-reset.o BUILTIN_OBJS += builtin-rev-list.o @@@ -660,12 -638,10 +662,12 @@@ EXTLIBS ifeq ($(uname_S),Linux) NO_STRLCPY = YesPlease + NO_MKSTEMPS = YesPlease THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),GNU/kFreeBSD) NO_STRLCPY = YesPlease + NO_MKSTEMPS = YesPlease THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),UnixWare) @@@ -677,7 -653,6 +679,7 @@@ SHELL_PATH = /usr/local/bin/bash NO_IPV6 = YesPlease NO_HSTRERROR = YesPlease + NO_MKSTEMPS = YesPlease BASIC_CFLAGS += -Kthread BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib @@@ -701,7 -676,6 +703,7 @@@ ifeq ($(uname_S),SCO_SV SHELL_PATH = /usr/bin/bash NO_IPV6 = YesPlease NO_HSTRERROR = YesPlease + NO_MKSTEMPS = YesPlease BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib NO_STRCASESTR = YesPlease @@@ -726,22 -700,12 +728,22 @@@ ifeq ($(uname_S),SunOS NEEDS_SOCKET = YesPlease NEEDS_NSL = YesPlease SHELL_PATH = /bin/bash + SANE_TOOL_PATH = /usr/xpg6/bin:/usr/xpg4/bin NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease - NO_HSTRERROR = YesPlease NO_MKDTEMP = YesPlease - ifneq ($(uname_R),5.11) - OLD_ICONV = UnfortunatelyYes + NO_MKSTEMPS = YesPlease + NO_REGEX = YesPlease + NO_EXTERNAL_GREP = YesPlease + ifeq ($(uname_R),5.7) + NEEDS_RESOLV = YesPlease + NO_IPV6 = YesPlease + NO_SOCKADDR_STORAGE = YesPlease + NO_UNSETENV = YesPlease + NO_SETENV = YesPlease + NO_STRLCPY = YesPlease + NO_C99_FORMAT = YesPlease + NO_STRTOUMAX = YesPlease endif ifeq ($(uname_R),5.8) NO_UNSETENV = YesPlease @@@ -755,19 -719,15 +757,19 @@@ NO_C99_FORMAT = YesPlease NO_STRTOUMAX = YesPlease endif - INSTALL = ginstall + ifdef NO_IPV6 + NEEDS_RESOLV = YesPlease + endif + INSTALL = /usr/ucb/install TAR = gtar - BASIC_CFLAGS += -D__EXTENSIONS__ + BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H endif ifeq ($(uname_O),Cygwin) NO_D_TYPE_IN_DIRENT = YesPlease NO_D_INO_IN_DIRENT = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease + NO_MKSTEMPS = YesPlease NO_SYMLINK_HEAD = YesPlease NEEDS_LIBICONV = YesPlease NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes @@@ -811,13 -771,11 +813,13 @@@ ifeq ($(uname_S),NetBSD BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib THREADED_DELTA_SEARCH = YesPlease USE_ST_TIMESPEC = YesPlease + NO_MKSTEMPS = YesPlease endif ifeq ($(uname_S),AIX) NO_STRCASESTR=YesPlease NO_MEMMEM = YesPlease NO_MKDTEMP = YesPlease + NO_MKSTEMPS = YesPlease NO_STRLCPY = YesPlease NO_NSEC = YesPlease FREAD_READS_DIRECTORIES = UnfortunatelyYes @@@ -833,40 -791,24 +835,40 @@@ endi ifeq ($(uname_S),GNU) # GNU/Hurd NO_STRLCPY=YesPlease + NO_MKSTEMPS = YesPlease +endif +ifeq ($(uname_S),IRIX) + NO_SETENV = YesPlease + NO_UNSETENV = YesPlease + NO_STRCASESTR = YesPlease + NO_MEMMEM = YesPlease + NO_MKSTEMPS = YesPlease + NO_MKDTEMP = YesPlease + NO_MMAP = YesPlease + NO_EXTERNAL_GREP = UnfortunatelyYes + SNPRINTF_RETURNS_BOGUS = YesPlease + SHELL_PATH = /usr/gnu/bin/bash + NEEDS_LIBGEN = YesPlease endif ifeq ($(uname_S),IRIX64) - NO_IPV6=YesPlease NO_SETENV=YesPlease + NO_UNSETENV = YesPlease NO_STRCASESTR=YesPlease NO_MEMMEM = YesPlease - NO_STRLCPY = YesPlease - NO_SOCKADDR_STORAGE=YesPlease + NO_MKSTEMPS = YesPlease + NO_MKDTEMP = YesPlease + NO_MMAP = YesPlease + NO_EXTERNAL_GREP = UnfortunatelyYes + SNPRINTF_RETURNS_BOGUS = YesPlease SHELL_PATH=/usr/gnu/bin/bash - BASIC_CFLAGS += -DPATH_MAX=1024 - # for now, build 32-bit version - BASIC_LDFLAGS += -L/usr/lib32 + NEEDS_LIBGEN = YesPlease endif ifeq ($(uname_S),HP-UX) NO_IPV6=YesPlease NO_SETENV=YesPlease NO_STRCASESTR=YesPlease NO_MEMMEM = YesPlease + NO_MKSTEMPS = YesPlease NO_STRLCPY = YesPlease NO_MKDTEMP = YesPlease NO_UNSETENV = YesPlease @@@ -882,7 -824,7 +884,7 @@@ ifneq (,$(findstring MINGW,$(uname_S)) pathsep = ; NO_PREAD = YesPlease NO_OPENSSL = YesPlease - NO_CURL = YesPlease + NO_LIBGEN_H = YesPlease NO_SYMLINK_HEAD = YesPlease NO_IPV6 = YesPlease NO_SETENV = YesPlease @@@ -890,12 -832,12 +892,12 @@@ NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease NO_MEMMEM = YesPlease - NO_PTHREADS = YesPlease NEEDS_LIBICONV = YesPlease OLD_ICONV = YesPlease NO_C99_FORMAT = YesPlease NO_STRTOUMAX = YesPlease NO_MKDTEMP = YesPlease + NO_MKSTEMPS = YesPlease SNPRINTF_RETURNS_BOGUS = YesPlease NO_SVN_TESTS = YesPlease NO_PERL_MAKEMAKER = YesPlease @@@ -904,44 -846,22 +906,44 @@@ NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease NO_NSEC = YesPlease USE_WIN32_MMAP = YesPlease + USE_NED_ALLOCATOR = YesPlease UNRELIABLE_FSTAT = UnfortunatelyYes OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch - COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 + NO_REGEX = YesPlease + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" - COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o + COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o EXTLIBS += -lws2_32 X = .exe +ifneq (,$(wildcard ../THIS_IS_MSYSGIT)) + htmldir=doc/git/html/ + prefix = + INSTALL = /bin/install + EXTLIBS += /mingw/lib/libz.a + NO_R_TO_GCC_LINKER = YesPlease + INTERNAL_QSORT = YesPlease + THREADED_DELTA_SEARCH = YesPlease +else + NO_CURL = YesPlease + NO_PTHREADS = YesPlease +endif endif ifneq (,$(findstring arm,$(uname_M))) ARM_SHA1 = YesPlease + NO_MKSTEMPS = YesPlease endif -include config.mak.autogen -include config.mak +ifdef SANE_TOOL_PATH +SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH)) +BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix $(SANE_TOOL_PATH_SQ)|' +PATH := $(SANE_TOOL_PATH):${PATH} +else +BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d' +endif + ifeq ($(uname_S),Darwin) ifndef NO_FINK ifeq ($(shell test -d /sw/lib && echo y),y) @@@ -968,11 -888,6 +970,11 @@@ ifndef CC_LD_DYNPAT endif endif +ifdef NO_LIBGEN_H + COMPAT_CFLAGS += -DNO_LIBGEN_H + COMPAT_OBJS += compat/basename.o +endif + ifdef NO_CURL BASIC_CFLAGS += -DNO_CURL else @@@ -1039,18 -954,12 +1041,18 @@@ ifdef NEEDS_LIBICON endif EXTLIBS += $(ICONV_LINK) -liconv endif +ifdef NEEDS_LIBGEN + EXTLIBS += -lgen +endif ifdef NEEDS_SOCKET EXTLIBS += -lsocket endif ifdef NEEDS_NSL EXTLIBS += -lnsl endif +ifdef NEEDS_RESOLV + EXTLIBS += -lresolv +endif ifdef NO_D_TYPE_IN_DIRENT BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT endif @@@ -1106,10 -1015,6 +1108,10 @@@ ifdef NO_MKDTEM COMPAT_CFLAGS += -DNO_MKDTEMP COMPAT_OBJS += compat/mkdtemp.o endif +ifdef NO_MKSTEMPS + COMPAT_CFLAGS += -DNO_MKSTEMPS + COMPAT_OBJS += compat/mkstemps.o +endif ifdef NO_UNSETENV COMPAT_CFLAGS += -DNO_UNSETENV COMPAT_OBJS += compat/unsetenv.o @@@ -1171,10 -1076,6 +1173,10 @@@ ifdef NO_DEFLATE_BOUN BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef BLK_SHA1 + SHA1_HEADER = "block-sha1/sha1.h" + LIB_OBJS += block-sha1/sha1.o +else ifdef PPC_SHA1 SHA1_HEADER = "ppc/sha1.h" LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o @@@ -1192,7 -1093,6 +1194,7 @@@ els endif endif endif +endif ifdef NO_PERL_MAKEMAKER export NO_PERL_MAKEMAKER endif @@@ -1232,15 -1132,6 +1234,15 @@@ endi ifdef UNRELIABLE_FSTAT BASIC_CFLAGS += -DUNRELIABLE_FSTAT endif +ifdef NO_REGEX + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o +endif + +ifdef USE_NED_ALLOCATOR + COMPAT_CFLAGS += -DUSE_NED_ALLOCATOR -DOVERRIDE_STRDUP -DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR -Icompat/nedmalloc + COMPAT_OBJS += compat/nedmalloc/nedmalloc.o +endif ifeq ($(TCLTK_PATH),) NO_TCLTK=NoThanks @@@ -1316,7 -1207,7 +1318,7 @@@ SHELL = $(SHELL_PATH all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS ifneq (,$X) - $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';) + $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';) endif all:: @@@ -1369,7 -1260,6 +1371,7 @@@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : % -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ + -e $(BROKEN_PATH_FIX) \ $@.sh >$@+ && \ chmod +x $@+ && \ mv $@+ $@ @@@ -1500,7 -1390,7 +1502,7 @@@ git-http-push$X: revision.o http.o http $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) -$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) +$(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h) builtin-revert.o wt-status.o: wt-status.h $(LIB_FILE): $(LIB_OBJS) @@@ -1609,8 -1499,6 +1611,8 @@@ test-delta$X: diff-delta.o patch-delta. test-parse-options$X: parse-options.o +test-parse-options.o: parse-options.h + .PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS)) test-%$X: test-%.o $(GITLIBS) @@@ -1669,16 -1557,15 +1671,16 @@@ ifneq (,$X endif bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \ execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \ - { $(RM) "$$execdir/git-add$X" && \ + { test "$$bindir/" = "$$execdir/" || \ + { $(RM) "$$execdir/git$X" && \ test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \ - ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \ - cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \ - { for p in $(filter-out git-add$X,$(BUILT_INS)); do \ + ln "$$bindir/git$X" "$$execdir/git$X" 2>/dev/null || \ + cp "$$bindir/git$X" "$$execdir/git$X"; } ; } && \ + { for p in $(BUILT_INS); do \ $(RM) "$$execdir/$$p" && \ - ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \ - ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \ - cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \ + ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git$X" "$$execdir/$$p" || exit; \ done; } && \ ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X" @@@ -1759,7 -1646,7 +1761,7 @@@ distclean: clea $(RM) configure clean: - $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \ + $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \ $(LIB_FILE) $(XDIFF_LIB) $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) diff --combined builtin-fsck.c index b3d38fa277,bc05de6800..c58b0e337e --- a/builtin-fsck.c +++ b/builtin-fsck.c @@@ -104,7 -104,7 +104,7 @@@ static int mark_object(struct object *o static void mark_object_reachable(struct object *obj) { - mark_object(obj, OBJ_ANY, 0); + mark_object(obj, OBJ_ANY, NULL); } static int traverse_one_object(struct object *obj, struct object *parent) @@@ -217,7 -217,7 +217,7 @@@ static void check_unreachable_object(st return; } if (!(f = fopen(filename, "w"))) - die("Could not open %s", filename); + die_errno("Could not open '%s'", filename); if (obj->type == OBJ_BLOB) { enum object_type type; unsigned long size; @@@ -225,15 -225,15 +225,15 @@@ &type, &size); if (buf) { if (fwrite(buf, size, 1, f) != 1) - die("Could not write %s: %s", - filename, strerror(errno)); + die_errno("Could not write '%s'", + filename); free(buf); } } else fprintf(f, "%s\n", sha1_to_hex(obj->sha1)); if (fclose(f)) - die("Could not finish %s: %s", - filename, strerror(errno)); + die_errno("Could not finish '%s'", + filename); } return; } @@@ -292,7 -292,7 +292,7 @@@ static int fsck_sha1(const unsigned cha fprintf(stderr, "Checking %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1)); - if (fsck_walk(obj, mark_used, 0)) + if (fsck_walk(obj, mark_used, NULL)) objerror(obj, "broken links"); if (fsck_object(obj, check_strict, fsck_error_func)) return -1; @@@ -589,6 -589,7 +589,7 @@@ int cmd_fsck(int argc, const char **arg struct alternate_object_database *alt; errors_found = 0; + read_replace_refs = 0; argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0); if (write_lost_and_found) { diff --combined builtin-pack-objects.c index 9cc8a8451d,b2c93d3d21..c4337480fd --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@@ -86,7 -86,7 +86,7 @@@ static int pack_compression_level = Z_D static int pack_compression_seen; static unsigned long delta_cache_size = 0; -static unsigned long max_delta_cache_size = 0; +static unsigned long max_delta_cache_size = 256 * 1024 * 1024; static unsigned long cache_max_small_delta_size = 1000; static unsigned long window_memory_limit = 0; @@@ -536,9 -536,11 +536,9 @@@ static void write_pack_file(void base_name, sha1_to_hex(sha1)); free_pack_by_name(tmpname); if (adjust_perm(pack_tmp_name, mode)) - die("unable to make temporary pack file readable: %s", - strerror(errno)); + die_errno("unable to make temporary pack file readable"); if (rename(pack_tmp_name, tmpname)) - die("unable to rename temporary pack file: %s", - strerror(errno)); + die_errno("unable to rename temporary pack file"); /* * Packs are runtime accessed in their mtime @@@ -564,9 -566,11 +564,9 @@@ snprintf(tmpname, sizeof(tmpname), "%s-%s.idx", base_name, sha1_to_hex(sha1)); if (adjust_perm(idx_tmp_name, mode)) - die("unable to make temporary index file readable: %s", - strerror(errno)); + die_errno("unable to make temporary index file readable"); if (rename(idx_tmp_name, tmpname)) - die("unable to rename temporary index file: %s", - strerror(errno)); + die_errno("unable to rename temporary index file"); free(idx_tmp_name); free(pack_tmp_name); @@@ -649,7 -653,8 +649,7 @@@ static void rehash_objects(void static unsigned name_hash(const char *name) { - unsigned char c; - unsigned hash = 0; + unsigned c, hash = 0; if (!name) return 0; @@@ -1875,7 -1880,7 +1875,7 @@@ static void read_object_list_from_stdin if (!ferror(stdin)) die("fgets returned NULL, not EOF, not error!"); if (errno != EINTR) - die("fgets: %s", strerror(errno)); + die_errno("fgets"); clearerr(stdin); continue; } @@@ -2098,6 -2103,8 +2098,8 @@@ int cmd_pack_objects(int argc, const ch int rp_ac_alloc = 64; int rp_ac; + read_replace_refs = 0; + rp_av = xcalloc(rp_ac_alloc, sizeof(*rp_av)); rp_av[0] = "pack-objects"; @@@ -2255,10 -2262,6 +2257,10 @@@ die("bad %s", arg); continue; } + if (!strcmp(arg, "--keep-true-parents")) { + grafts_replace_parents = 0; + continue; + } usage(pack_usage); } diff --combined builtin-unpack-objects.c index 557148a693,c9f5ac0c34..968fda7219 --- a/builtin-unpack-objects.c +++ b/builtin-unpack-objects.c @@@ -68,7 -68,7 +68,7 @@@ static void *fill(int min if (ret <= 0) { if (!ret) die("early EOF"); - die("read error on input: %s", strerror(errno)); + die_errno("read error on input"); } len += ret; } while (len < min); @@@ -158,7 -158,7 +158,7 @@@ struct obj_info #define FLAG_WRITTEN (1u<<21) static struct obj_info *obj_list; -unsigned nr_objects; +static unsigned nr_objects; /* * Called only from check_object() after it verified this object @@@ -200,7 -200,7 +200,7 @@@ static int check_object(struct object * if (fsck_object(obj, 1, fsck_error_function)) die("Error in object"); - if (!fsck_walk(obj, check_object, 0)) + if (!fsck_walk(obj, check_object, NULL)) die("Error on reachable objects of %s", sha1_to_hex(obj->sha1)); write_cached_object(obj); return 1; @@@ -210,7 -210,7 +210,7 @@@ static void write_rest(void { unsigned i; for (i = 0; i < nr_objects; i++) - check_object(obj_list[i].obj, OBJ_ANY, 0); + check_object(obj_list[i].obj, OBJ_ANY, NULL); } static void added_object(unsigned nr, enum object_type type, @@@ -422,8 -422,8 +422,8 @@@ static void unpack_delta_entry(enum obj static void unpack_one(unsigned nr) { unsigned shift; - unsigned char *pack, c; - unsigned long size; + unsigned char *pack; + unsigned long size, c; enum object_type type; obj_list[nr].offset = consumed_bytes; @@@ -495,6 -495,8 +495,8 @@@ int cmd_unpack_objects(int argc, const int i; unsigned char sha1[20]; + read_replace_refs = 0; + git_config(git_default_config, NULL); quiet = !isatty(2); diff --combined builtin.h index 9993dfcf99,38ceddc53d..51e4ba7f36 --- a/builtin.h +++ b/builtin.h @@@ -13,6 -13,7 +13,6 @@@ extern const char git_more_info_string[ extern void list_common_cmds_help(void); extern const char *help_unknown_cmd(const char *cmd); extern void prune_packed_objects(int); -extern int read_line_with_nul(char *buf, int size, FILE *file); extern int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out); extern int commit_tree(const char *msg, unsigned char *tree, @@@ -111,5 -112,6 +111,6 @@@ extern int cmd_write_tree(int argc, con extern int cmd_verify_pack(int argc, const char **argv, const char *prefix); extern int cmd_show_ref(int argc, const char **argv, const char *prefix); extern int cmd_pack_refs(int argc, const char **argv, const char *prefix); + extern int cmd_replace(int argc, const char **argv, const char *prefix); #endif diff --combined cache.h index eee717c81b,91ef34071e..f793789377 --- a/cache.h +++ b/cache.h @@@ -468,9 -468,6 +468,9 @@@ extern int index_fd(unsigned char *sha1 extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object); extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); +/* "careful lstat()" */ +extern int check_path(const char *path, int len, struct stat *st); + #define REFRESH_REALLY 0x0001 /* ignore_valid */ #define REFRESH_UNMERGED 0x0002 /* allow unmerged */ #define REFRESH_QUIET 0x0004 /* be quiet about it */ @@@ -512,7 -509,6 +512,7 @@@ extern int log_all_ref_updates extern int warn_ambiguous_refs; extern int shared_repository; extern const char *apply_default_whitespace; +extern const char *apply_default_ignorewhitespace; extern int zlib_compression_level; extern int core_compression_level; extern int core_compression_seen; @@@ -520,6 -516,7 +520,7 @@@ extern size_t packed_git_window_size extern size_t packed_git_limit; extern size_t delta_base_cache_limit; extern int auto_crlf; + extern int read_replace_refs; extern int fsync_object_files; extern int core_preload_index; @@@ -547,6 -544,7 +548,6 @@@ enum rebase_setup_type }; enum push_default_type { - PUSH_DEFAULT_UNSPECIFIED = -1, PUSH_DEFAULT_NOTHING = 0, PUSH_DEFAULT_MATCHING, PUSH_DEFAULT_TRACKING, @@@ -564,8 -562,6 +565,8 @@@ enum object_creation_mode extern enum object_creation_mode object_creation_mode; +extern int grafts_replace_parents; + #define GIT_REPO_VERSION 0 extern int repository_format_version; extern int check_repository_format(void); @@@ -619,8 -615,6 +620,8 @@@ extern int is_empty_blob_sha1(const uns int git_mkstemp(char *path, size_t n, const char *template); +int git_mkstemps(char *path, size_t n, const char *template, int suffix_len); + /* * NOTE NOTE NOTE!! * @@@ -656,7 -650,11 +657,11 @@@ char *strip_path_suffix(const char *pat /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ extern int sha1_object_info(const unsigned char *, unsigned long *); - extern void * read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size); + extern void *read_sha1_file_repl(const unsigned char *sha1, enum object_type *type, unsigned long *size, const unsigned char **replacement); + static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size) + { + return read_sha1_file_repl(sha1, type, size, NULL); + } extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1); extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1); extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *); @@@ -749,17 -747,7 +754,17 @@@ struct checkout }; extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); + +struct cache_def { + char path[PATH_MAX + 1]; + int len; + int flags; + int track_flags; + int prefix_len_stat_func; +}; + extern int has_symlink_leading_path(const char *name, int len); +extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int); extern int has_symlink_or_noent_leading_path(const char *name, int len); extern int has_dirs_only_path(const char *name, int len, int prefix_len); extern void invalidate_lstat_cache(const char *name, int len); diff --combined commit.h index 4886544b63,a8bdd09096..d1674d7f16 --- a/commit.h +++ b/commit.h @@@ -40,6 -40,8 +40,6 @@@ int parse_commit_buffer(struct commit * int parse_commit(struct commit *item); -void unparse_commit(struct commit *item); - struct commit_list * commit_list_insert(struct commit *item, struct commit_list **list_p); unsigned commit_list_count(const struct commit_list *l); struct commit_list * insert_by_date(struct commit *item, struct commit_list **list); @@@ -64,7 -66,6 +64,7 @@@ enum cmit_fmt }; extern int non_ascii(int); +extern int has_non_ascii(const char *text); struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */ extern char *reencode_commit_message(const struct commit *commit, const char **encoding_p); @@@ -123,6 -124,8 +123,8 @@@ struct commit_graft *read_graft_line(ch int register_commit_graft(struct commit_graft *, int); struct commit_graft *lookup_commit_graft(const unsigned char *sha1); + const unsigned char *lookup_replace_object(const unsigned char *sha1); + extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup); extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup); extern struct commit_list *get_octopus_merge_bases(struct commit_list *in); diff --combined environment.c index 3cf88f58c4,6d90074648..5de6837840 --- a/environment.c +++ b/environment.c @@@ -26,7 -26,6 +26,7 @@@ const char *git_commit_encoding const char *git_log_output_encoding; int shared_repository = PERM_UMASK; const char *apply_default_whitespace; +const char *apply_default_ignorewhitespace; int zlib_compression_level = Z_BEST_SPEED; int core_compression_level; int core_compression_seen; @@@ -39,16 -38,16 +39,17 @@@ int pager_use_color = 1 const char *editor_program; const char *excludes_file; int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */ + int read_replace_refs = 1; enum safe_crlf safe_crlf = SAFE_CRLF_WARN; unsigned whitespace_rule_cfg = WS_DEFAULT_RULE; enum branch_track git_branch_track = BRANCH_TRACK_REMOTE; enum rebase_setup_type autorebase = AUTOREBASE_NEVER; -enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; +enum push_default_type push_default = PUSH_DEFAULT_MATCHING; #ifndef OBJECT_CREATION_MODE #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS #endif enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; +int grafts_replace_parents = 1; /* Parallel index stat data preload? */ int core_preload_index = 0; diff --combined git.c index 4588a8bac2,8695d67f2a..5da6c65697 --- a/git.c +++ b/git.c @@@ -188,9 -188,10 +188,9 @@@ static int handle_alias(int *argcp, con alias_command); new_argv = xrealloc(new_argv, sizeof(char *) * - (count + *argcp + 1)); + (count + *argcp)); /* insert after command name */ memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp); - new_argv[count+*argcp] = NULL; *argv = new_argv; *argcp += count - 1; @@@ -199,7 -200,7 +199,7 @@@ } if (subdir && chdir(subdir)) - die("Cannot change to %s: %s", subdir, strerror(errno)); + die_errno("Cannot change to '%s'", subdir); errno = saved_errno; @@@ -245,7 -246,7 +245,7 @@@ static int run_builtin(struct cmd_struc status = p->fn(argc, argv, prefix); if (status) - return status & 0xff; + return status; /* Somebody closed stdout? */ if (fstat(fileno(stdout), &st)) @@@ -256,11 -257,11 +256,11 @@@ /* Check for ENOSPC and EIO errors.. */ if (fflush(stdout)) - die("write failure on standard output: %s", strerror(errno)); + die_errno("write failure on standard output"); if (ferror(stdout)) die("unknown write failure on standard output"); if (fclose(stdout)) - die("close failed on standard output: %s", strerror(errno)); + die_errno("close failed on standard output"); return 0; } @@@ -339,6 -340,7 +339,7 @@@ static void handle_internal_command(in { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, + { "replace", cmd_replace, RUN_SETUP }, { "repo-config", cmd_config }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, @@@ -416,9 -418,13 +417,9 @@@ static void execv_dashed_external(cons * if we fail because the command is not found, it is * OK to return. Otherwise, we just pass along the status code. */ - status = run_command_v_opt(argv, 0); - if (status != -ERR_RUN_COMMAND_EXEC) { - if (IS_RUN_COMMAND_ERR(status)) - die("unable to run '%s'", argv[0]); - exit(-status); - } - errno = ENOENT; /* as if we called execvp */ + status = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE); + if (status >= 0 || errno != ENOENT) + exit(status); argv[0] = tmp; diff --combined mktag.c index a609e3ebd1,6e0b5feaee..a3b4270c18 --- a/mktag.c +++ b/mktag.c @@@ -19,16 -19,17 +19,17 @@@ /* * We refuse to tag something we can't verify. Just because. */ - static int verify_object(unsigned char *sha1, const char *expected_type) + static int verify_object(const unsigned char *sha1, const char *expected_type) { int ret = -1; enum object_type type; unsigned long size; - void *buffer = read_sha1_file(sha1, &type, &size); + const unsigned char *repl; + void *buffer = read_sha1_file_repl(sha1, &type, &size, &repl); if (buffer) { if (type == type_from_string(expected_type)) - ret = check_sha1_signature(sha1, buffer, size, expected_type); + ret = check_sha1_signature(repl, buffer, size, expected_type); free(buffer); } return ret; @@@ -165,7 -166,7 +166,7 @@@ int main(int argc, char **argv setup_git_directory(); if (strbuf_read(&buf, 0, 4096) < 0) { - die("could not read from stdin"); + die_errno("could not read from stdin"); } /* Verify it for some basic sanity: it needs to start with diff --combined parse-options.c index 3b71fbb541,743f5bae4e..a64a4d6ee2 --- a/parse-options.c +++ b/parse-options.c @@@ -306,28 -306,6 +306,28 @@@ static void check_typos(const char *arg } } +static void parse_options_check(const struct option *opts) +{ + int err = 0; + + for (; opts->type != OPTION_END; opts++) { + if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) && + (opts->flags & PARSE_OPT_OPTARG)) { + if (opts->long_name) { + error("`--%s` uses incompatible flags " + "LASTARG_DEFAULT and OPTARG", opts->long_name); + } else { + error("`-%c` uses incompatible flags " + "LASTARG_DEFAULT and OPTARG", opts->short_name); + } + err |= 1; + } + } + + if (err) + exit(129); +} + void parse_options_start(struct parse_opt_ctx_t *ctx, int argc, const char **argv, const char *prefix, int flags) @@@ -353,8 -331,6 +353,8 @@@ int parse_options_step(struct parse_opt { int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); + parse_options_check(options); + /* we must reset ->opt, unknown short option leave it dangling */ ctx->opt = NULL; @@@ -464,7 -440,7 +464,7 @@@ int parse_options(int argc, const char static int usage_argh(const struct option *opts) { const char *s; - int literal = opts->flags & PARSE_OPT_LITERAL_ARGHELP; + int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !opts->argh; if (opts->flags & PARSE_OPT_OPTARG) if (opts->long_name) s = literal ? "[=%s]" : "[=<%s>]"; @@@ -472,13 -448,13 +472,13 @@@ s = literal ? "[%s]" : "[<%s>]"; else s = literal ? " %s" : " <%s>"; - return fprintf(stderr, s, opts->argh); + return fprintf(stderr, s, opts->argh ? opts->argh : "..."); } #define USAGE_OPTS_WIDTH 24 #define USAGE_GAP 2 -int usage_with_options_internal(const char * const *usagestr, +static int usage_with_options_internal(const char * const *usagestr, const struct option *opts, int full) { if (!usagestr) @@@ -511,7 -487,7 +511,7 @@@ continue; pos = fprintf(stderr, " "); - if (opts->short_name) { + if (opts->short_name && !(opts->flags & PARSE_OPT_NEGHELP)) { if (opts->flags & PARSE_OPT_NODASH) pos += fprintf(stderr, "%c", opts->short_name); else @@@ -520,14 -496,44 +520,14 @@@ if (opts->long_name && opts->short_name) pos += fprintf(stderr, ", "); if (opts->long_name) - pos += fprintf(stderr, "--%s", opts->long_name); + pos += fprintf(stderr, "--%s%s", + (opts->flags & PARSE_OPT_NEGHELP) ? "no-" : "", + opts->long_name); if (opts->type == OPTION_NUMBER) pos += fprintf(stderr, "-NUM"); - switch (opts->type) { - case OPTION_ARGUMENT: - break; - case OPTION_INTEGER: - if (opts->flags & PARSE_OPT_OPTARG) - if (opts->long_name) - pos += fprintf(stderr, "[=]"); - else - pos += fprintf(stderr, "[]"); - else - pos += fprintf(stderr, " "); - break; - case OPTION_CALLBACK: - if (opts->flags & PARSE_OPT_NOARG) - break; - /* FALLTHROUGH */ - case OPTION_FILENAME: - /* FALLTHROUGH */ - case OPTION_STRING: - if (opts->argh) - pos += usage_argh(opts); - else { - if (opts->flags & PARSE_OPT_OPTARG) - if (opts->long_name) - pos += fprintf(stderr, "[=...]"); - else - pos += fprintf(stderr, "[...]"); - else - pos += fprintf(stderr, " ..."); - } - break; - default: /* OPTION_{BIT,BOOLEAN,NUMBER,SET_INT,SET_PTR} */ - break; - } + if (!(opts->flags & PARSE_OPT_NOARG)) + pos += usage_argh(opts); if (pos <= USAGE_OPTS_WIDTH) pad = USAGE_OPTS_WIDTH - pos; @@@ -549,6 -555,14 +549,14 @@@ void usage_with_options(const char * co exit(129); } + void usage_msg_opt(const char *msg, + const char * const *usagestr, + const struct option *options) + { + fprintf(stderr, "%s\n\n", msg); + usage_with_options(usagestr, options); + } + int parse_options_usage(const char * const *usagestr, const struct option *opts) { diff --combined parse-options.h index b32587ad7c,f0f885c67d..f295a2cf85 --- a/parse-options.h +++ b/parse-options.h @@@ -36,7 -36,6 +36,7 @@@ enum parse_opt_option_flags PARSE_OPT_LASTARG_DEFAULT = 16, PARSE_OPT_NODASH = 32, PARSE_OPT_LITERAL_ARGHELP = 64, + PARSE_OPT_NEGHELP = 128, }; struct option; @@@ -68,22 -67,16 +68,22 @@@ typedef int parse_opt_cb(const struct o * `flags`:: * mask of parse_opt_option_flags. * PARSE_OPT_OPTARG: says that the argument is optional (not for BOOLEANs) - * PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs + * PARSE_OPT_NOARG: says that this option takes no argument * PARSE_OPT_NONEG: says that this option cannot be negated * PARSE_OPT_HIDDEN: this option is skipped in the default usage, and * shown only in the full usage. - * PARSE_OPT_LASTARG_DEFAULT: if no argument is given, the default value - * is used. + * PARSE_OPT_LASTARG_DEFAULT: says that this option will take the default + * value if no argument is given when the option + * is last on the command line. If the option is + * not last it will require an argument. + * Should not be used with PARSE_OPT_OPTARG. * PARSE_OPT_NODASH: this option doesn't start with a dash. * PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets * (i.e. '') in the help message. * Useful for options with multiple parameters. + * PARSE_OPT_NEGHELP: says that the long option should always be shown with + * the --no prefix in the usage message. Sometimes + * useful for users of OPTION_NEGBIT. * * `callback`:: * pointer to the callback to use for OPTION_CALLBACK. @@@ -108,20 -101,14 +108,20 @@@ struct option }; #define OPT_END() { OPTION_END } -#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) } +#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, \ + (h), PARSE_OPT_NOARG} #define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } -#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) } -#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, (h), 0, NULL, (b) } -#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) } -#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) } -#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) } -#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) } +#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), \ + PARSE_OPT_NOARG, NULL, (b) } +#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG, NULL, (b) } +#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG } +#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG, NULL, (i) } +#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG, NULL, (p) } +#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) } #define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) } #define OPT_DATE(s, l, v, h) \ { OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \ @@@ -145,6 -132,10 +145,10 @@@ extern int parse_options(int argc, cons extern NORETURN void usage_with_options(const char * const *usagestr, const struct option *options); + extern NORETURN void usage_msg_opt(const char *msg, + const char * const *usagestr, + const struct option *options); + /*----- incremental advanced APIs -----*/ enum { diff --combined refs.c index dd9c9ba3f6,6a136512c7..24865cf5a6 --- a/refs.c +++ b/refs.c @@@ -531,10 -531,9 +531,10 @@@ static int do_one_ref(const char *base { if (strncmp(base, entry->name, trim)) return 0; + /* Is this a "negative ref" that represents a deleted ref? */ + if (is_null_sha1(entry->sha1)) + return 0; if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) { - if (is_null_sha1(entry->sha1)) - return 0; if (!has_sha1_file(entry->sha1)) { error("%s does not point to a valid object!", entry->name); return 0; @@@ -668,6 -667,11 +668,11 @@@ int for_each_remote_ref(each_ref_fn fn return for_each_ref_in("refs/remotes/", fn, cb_data); } + int for_each_replace_ref(each_ref_fn fn, void *cb_data) + { + return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data); + } + int for_each_rawref(each_ref_fn fn, void *cb_data) { return do_for_each_ref("refs/", fn, 0, @@@ -821,7 -825,7 +826,7 @@@ static int remove_empty_directories(con strbuf_init(&path, 20); strbuf_addstr(&path, file); - result = remove_dir_recursively(&path, 1); + result = remove_dir_recursively(&path, REMOVE_DIR_EMPTY_ONLY); strbuf_release(&path); @@@ -1419,7 -1423,7 +1424,7 @@@ int read_ref_at(const char *ref, unsign logfile = git_path("logs/%s", ref); logfd = open(logfile, O_RDONLY, 0); if (logfd < 0) - die("Unable to read log %s: %s", logfile, strerror(errno)); + die_errno("Unable to read log '%s'", logfile); fstat(logfd, &st); if (!st.st_size) die("Log %s is empty.", logfile); @@@ -1526,10 -1530,8 +1531,10 @@@ int for_each_recent_reflog_ent(const ch if (fstat(fileno(logfp), &statbuf) || statbuf.st_size < ofs || fseek(logfp, -ofs, SEEK_END) || - fgets(buf, sizeof(buf), logfp)) + fgets(buf, sizeof(buf), logfp)) { + fclose(logfp); return -1; + } } while (fgets(buf, sizeof(buf), logfp)) { diff --combined sha1_file.c index 1d996a1990,9119b795bd..4ea0b18d0a --- a/sha1_file.c +++ b/sha1_file.c @@@ -1162,7 -1162,8 +1162,7 @@@ unsigned long unpack_object_header_buff unsigned long len, enum object_type *type, unsigned long *sizep) { unsigned shift; - unsigned char c; - unsigned long size; + unsigned long size, c; unsigned long used = 0; c = buf[used++]; @@@ -1170,7 -1171,7 +1170,7 @@@ size = c & 15; shift = 4; while (c & 0x80) { - if (len <= used || sizeof(long) * 8 <= shift) { + if (len <= used || bitsizeof(long) <= shift) { error("bad object header"); return 0; } @@@ -2144,13 -2145,26 +2144,26 @@@ static void *read_object(const unsigne return read_packed_sha1(sha1, type, size); } - void *read_sha1_file(const unsigned char *sha1, enum object_type *type, - unsigned long *size) + void *read_sha1_file_repl(const unsigned char *sha1, + enum object_type *type, + unsigned long *size, + const unsigned char **replacement) { - void *data = read_object(sha1, type, size); + const unsigned char *repl = lookup_replace_object(sha1); + void *data = read_object(repl, type, size); + + /* die if we replaced an object with one that does not exist */ + if (!data && repl != sha1) + die("replacement %s not found for %s", + sha1_to_hex(repl), sha1_to_hex(sha1)); + /* legacy behavior is to die on corrupted objects */ - if (!data && (has_loose_object(sha1) || has_packed_and_bad(sha1))) - die("object %s is corrupted", sha1_to_hex(sha1)); + if (!data && (has_loose_object(repl) || has_packed_and_bad(repl))) + die("object %s is corrupted", sha1_to_hex(repl)); + + if (replacement) + *replacement = repl; + return data; } @@@ -2286,7 -2300,7 +2299,7 @@@ static void close_sha1_file(int fd if (fsync_object_files) fsync_or_die(fd, "sha1 file"); if (close(fd) != 0) - die("error when closing sha1 file (%s)", strerror(errno)); + die_errno("error when closing sha1 file"); } /* Size of directory component, including the ending '/' */ diff --combined upload-pack.c index f7d308a411,e6c4f347eb..4d8be834ff --- a/upload-pack.c +++ b/upload-pack.c @@@ -28,8 -28,7 +28,8 @@@ static unsigned long oldest_have static int multi_ack, nr_our_refs; static int use_thin_pack, use_ofs_delta, use_include_tag; -static int no_progress; +static int no_progress, daemon_mode; +static int shallow_nr; static struct object_array have_obj; static struct object_array want_obj; static unsigned int timeout; @@@ -108,6 -107,8 +108,6 @@@ static int do_rev_list(int fd, void *cr struct rev_info revs; pack_pipe = fdopen(fd, "w"); - if (create_full_pack) - use_thin_pack = 0; /* no point doing it */ init_revisions(&revs, NULL); revs.tag_objects = 1; revs.tree_objects = 1; @@@ -154,21 -155,13 +154,21 @@@ static void create_pack_file(void const char *argv[10]; int arg = 0; - rev_list.proc = do_rev_list; - /* .data is just a boolean: any non-NULL value will do */ - rev_list.data = create_full_pack ? &rev_list : NULL; - if (start_async(&rev_list)) - die("git upload-pack: unable to fork git-rev-list"); + if (shallow_nr) { + rev_list.proc = do_rev_list; + rev_list.data = 0; + if (start_async(&rev_list)) + die("git upload-pack: unable to fork git-rev-list"); + argv[arg++] = "pack-objects"; + } else { + argv[arg++] = "pack-objects"; + argv[arg++] = "--revs"; + if (create_full_pack) + argv[arg++] = "--all"; + else if (use_thin_pack) + argv[arg++] = "--thin"; + } - argv[arg++] = "pack-objects"; argv[arg++] = "--stdout"; if (!no_progress) argv[arg++] = "--progress"; @@@ -179,7 -172,7 +179,7 @@@ argv[arg++] = NULL; memset(&pack_objects, 0, sizeof(pack_objects)); - pack_objects.in = rev_list.out; /* start_command closes it */ + pack_objects.in = shallow_nr ? rev_list.out : -1; pack_objects.out = -1; pack_objects.err = -1; pack_objects.git_cmd = 1; @@@ -188,24 -181,6 +188,24 @@@ if (start_command(&pack_objects)) die("git upload-pack: unable to fork git-pack-objects"); + /* pass on revisions we (don't) want */ + if (!shallow_nr) { + FILE *pipe_fd = fdopen(pack_objects.in, "w"); + if (!create_full_pack) { + int i; + for (i = 0; i < want_obj.nr; i++) + fprintf(pipe_fd, "%s\n", sha1_to_hex(want_obj.objects[i].item->sha1)); + fprintf(pipe_fd, "--not\n"); + for (i = 0; i < have_obj.nr; i++) + fprintf(pipe_fd, "%s\n", sha1_to_hex(have_obj.objects[i].item->sha1)); + } + + fprintf(pipe_fd, "\n"); + fflush(pipe_fd); + fclose(pipe_fd); + } + + /* We read from pack_objects.err to capture stderr output for * progress bar, and pack_objects.out to capture the pack data. */ @@@ -301,7 -276,7 +301,7 @@@ error("git upload-pack: git-pack-objects died with error."); goto fail; } - if (finish_async(&rev_list)) + if (shallow_nr && finish_async(&rev_list)) goto fail; /* error was already reported */ /* flush the data */ @@@ -476,7 -451,6 +476,7 @@@ static void receive_needs(void static char line[1000]; int len, depth = 0; + shallow_nr = 0; if (debug_fd) write_in_full(debug_fd, "#S\n", 3); for (;;) { @@@ -547,10 -521,6 +547,10 @@@ } if (debug_fd) write_in_full(debug_fd, "#E\n", 3); + + if (!use_sideband && daemon_mode) + no_progress = 1; + if (depth == 0 && shallows.nr == 0) return; if (depth > 0) { @@@ -564,7 -534,6 +564,7 @@@ packet_write(1, "shallow %s", sha1_to_hex(object->sha1)); register_shallow(object->sha1); + shallow_nr++; } result = result->next; } @@@ -598,8 -567,6 +598,8 @@@ for (i = 0; i < shallows.nr; i++) register_shallow(shallows.objects[i].item->sha1); } + + shallow_nr += shallows.nr; free(shallows.objects); } @@@ -651,6 -618,7 +651,7 @@@ int main(int argc, char **argv int strict = 0; git_extract_argv0_path(argv[0]); + read_replace_refs = 0; for (i = 1; i < argc; i++) { char *arg = argv[i]; @@@ -663,7 -631,6 +664,7 @@@ } if (!prefixcmp(arg, "--timeout=")) { timeout = atoi(arg+10); + daemon_mode = 1; continue; } if (!strcmp(arg, "--")) {