author | Junio C Hamano <gitster@pobox.com> | |
Sun, 7 Mar 2010 20:47:14 +0000 (12:47 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sun, 7 Mar 2010 20:47:14 +0000 (12:47 -0800) |
* mm/mkstemps-mode-for-packfiles:
Use git_mkstemp_mode instead of plain mkstemp to create object files
git_mkstemps_mode: don't set errno to EINVAL on exit.
Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.
git_mkstemp_mode, xmkstemp_mode: variants of gitmkstemps with mode argument.
Move gitmkstemps to path.c
Add a testcase for ACL with restrictive umask.
Use git_mkstemp_mode instead of plain mkstemp to create object files
git_mkstemps_mode: don't set errno to EINVAL on exit.
Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.
git_mkstemp_mode, xmkstemp_mode: variants of gitmkstemps with mode argument.
Move gitmkstemps to path.c
Add a testcase for ACL with restrictive umask.
1 | 2 | |||
---|---|---|---|---|
Makefile | patch | | diff1 | | diff2 | | blob | history |
builtin-pack-objects.c | patch | | diff1 | | diff2 | | blob | history |
cache.h | patch | | diff1 | | diff2 | | blob | history |
path.c | patch | | diff1 | | diff2 | | blob | history |
sha1_file.c | patch | | diff1 | | diff2 | | blob | history |
diff --combined Makefile
index 52f2cc040ba82696b199537d3155a095939dac68,4387d4207f49d4b80e8e922ccc85bf157447aa0b..f64610a57bfea6176aa9f7d470b92014fe958432
+++ b/Makefile
# DEFAULT_EDITOR='~/bin/vi',
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
+#
+# Define COMPUTE_HEADER_DEPENDENCIES if your compiler supports the -MMD option
+# and you want to avoid rebuilding objects when an unrelated header file
+# changes.
+#
+# Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
+# dependency rules.
GIT-VERSION-FILE: FORCE
@$(SHELL_PATH) ./GIT-VERSION-GEN
COMPAT_OBJS =
LIB_H =
LIB_OBJS =
+PROGRAM_OBJS =
PROGRAMS =
SCRIPT_PERL =
SCRIPT_PYTHON =
SCRIPT_SH =
-TEST_PROGRAMS =
+SCRIPT_LIB =
+TEST_PROGRAMS_NEED_X =
SCRIPT_SH += git-am.sh
SCRIPT_SH += git-bisect.sh
SCRIPT_SH += git-merge-one-file.sh
SCRIPT_SH += git-merge-resolve.sh
SCRIPT_SH += git-mergetool.sh
-SCRIPT_SH += git-mergetool--lib.sh
SCRIPT_SH += git-notes.sh
-SCRIPT_SH += git-parse-remote.sh
SCRIPT_SH += git-pull.sh
SCRIPT_SH += git-quiltimport.sh
SCRIPT_SH += git-rebase--interactive.sh
SCRIPT_SH += git-rebase.sh
SCRIPT_SH += git-repack.sh
SCRIPT_SH += git-request-pull.sh
-SCRIPT_SH += git-sh-setup.sh
SCRIPT_SH += git-stash.sh
SCRIPT_SH += git-submodule.sh
SCRIPT_SH += git-web--browse.sh
+SCRIPT_LIB += git-mergetool--lib
+SCRIPT_LIB += git-parse-remote
+SCRIPT_LIB += git-sh-setup
+
SCRIPT_PERL += git-add--interactive.perl
SCRIPT_PERL += git-difftool.perl
SCRIPT_PERL += git-archimport.perl
# ... and all the rest that could be moved out of bindir to gitexecdir
PROGRAMS += $(EXTRA_PROGRAMS)
-PROGRAMS += git-fast-import$X
-PROGRAMS += git-imap-send$X
-PROGRAMS += git-shell$X
-PROGRAMS += git-show-index$X
-PROGRAMS += git-upload-pack$X
-PROGRAMS += git-http-backend$X
+
+PROGRAM_OBJS += fast-import.o
+PROGRAM_OBJS += imap-send.o
+PROGRAM_OBJS += shell.o
+PROGRAM_OBJS += show-index.o
+PROGRAM_OBJS += upload-pack.o
+PROGRAM_OBJS += http-backend.o
+
+PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
+
+TEST_PROGRAMS_NEED_X += test-chmtime
+TEST_PROGRAMS_NEED_X += test-ctype
+TEST_PROGRAMS_NEED_X += test-date
+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-match-trees
+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-index-version
+
+TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
# List built-in command $C whose implementation cmd_$C() is not in
# builtin-$C.o but is linked in as part of some other command.
LIB_H += builtin.h
LIB_H += cache.h
LIB_H += cache-tree.h
+LIB_H += color.h
LIB_H += commit.h
LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += diffcore.h
LIB_H += diff.h
LIB_H += dir.h
+LIB_H += exec_cmd.h
LIB_H += fsck.h
LIB_H += git-compat-util.h
LIB_H += graph.h
LIB_H += unpack-trees.h
LIB_H += userdiff.h
LIB_H += utf8.h
-LIB_H += wt-status.h
+LIB_H += xdiff-interface.h
+LIB_H += xdiff/xdiff.h
LIB_OBJS += abspath.o
LIB_OBJS += advice.o
-include config.mak.autogen
-include config.mak
+ifdef CHECK_HEADER_DEPENDENCIES
+USE_COMPUTED_HEADER_DEPENDENCIES =
+endif
+
+ifdef COMPUTE_HEADER_DEPENDENCIES
+USE_COMPUTED_HEADER_DEPENDENCIES = YesPlease
+endif
+
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)|'
REMOTE_CURL_PRIMARY = git-remote-http$X
REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X
REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES)
- PROGRAMS += $(REMOTE_CURL_NAMES) git-http-fetch$X
+ PROGRAM_OBJS += http-fetch.o
+ PROGRAMS += $(REMOTE_CURL_NAMES)
curl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p)
ifeq "$(curl_check)" "070908"
ifndef NO_EXPAT
- PROGRAMS += git-http-push$X
+ PROGRAM_OBJS += http-push.o
endif
endif
ifndef NO_EXPAT
EXTLIBS += -lz
ifndef NO_POSIX_ONLY_PROGRAMS
- PROGRAMS += git-daemon$X
+ PROGRAM_OBJS += daemon.o
endif
ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
endif
ifdef NO_MKSTEMPS
COMPAT_CFLAGS += -DNO_MKSTEMPS
- COMPAT_OBJS += compat/mkstemps.o
endif
ifdef NO_UNSETENV
COMPAT_CFLAGS += -DNO_UNSETENV
ifdef BLK_SHA1
SHA1_HEADER = "block-sha1/sha1.h"
LIB_OBJS += block-sha1/sha1.o
+ LIB_H += block-sha1/sha1.h
else
ifdef PPC_SHA1
SHA1_HEADER = "ppc/sha1.h"
LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
+ LIB_H += ppc/sha1.h
else
SHA1_HEADER = <openssl/sha.h>
EXTLIBS += $(LIB_4_CRYPTO)
SHELL = $(SHELL_PATH)
-all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
+all:: shell_compatibility_test $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
ifneq (,$X)
$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
endif
common-cmds.h: $(wildcard Documentation/git-*.txt)
$(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@
+define cmd_munge_script
+$(RM) $@ $@+ && \
+sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
+ -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 >$@+
+endef
+
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
- $(QUIET_GEN)$(RM) $@ $@+ && \
- sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
- -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 >$@+ && \
+ $(QUIET_GEN)$(cmd_munge_script) && \
chmod +x $@+ && \
mv $@+ $@
+$(SCRIPT_LIB) : % : %.sh
+ $(QUIET_GEN)$(cmd_munge_script) && \
+ mv $@+ $@
+
ifndef NO_PERL
$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
: GIT-VERSION-FILE
-%.o: %.c GIT-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
+TEST_OBJS := $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
+GIT_OBJS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
+ git.o http.o http-walker.o remote-curl.o
+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)
+
+dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
+dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
+
+ifdef COMPUTE_HEADER_DEPENDENCIES
+$(dep_dirs):
+ mkdir -p $@
+
+missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
+dep_file = $(dir $@).depend/$(notdir $@).d
+dep_args = -MF $(dep_file) -MMD -MP
+ifdef CHECK_HEADER_DEPENDENCIES
+$(error cannot compute header dependencies outside a normal build. \
+Please unset CHECK_HEADER_DEPENDENCIES and try again)
+endif
+endif
+
+ifndef COMPUTE_HEADER_DEPENDENCIES
+ifndef CHECK_HEADER_DEPENDENCIES
+dep_dirs =
+missing_dep_dirs =
+dep_args =
+endif
+endif
+
+ifdef CHECK_HEADER_DEPENDENCIES
+ifndef PRINT_HEADER_DEPENDENCIES
+missing_deps = $(filter-out $(notdir $^), \
+ $(notdir $(shell $(MAKE) -s $@ \
+ CHECK_HEADER_DEPENDENCIES=YesPlease \
+ USE_COMPUTED_HEADER_DEPENDENCIES=YesPlease \
+ PRINT_HEADER_DEPENDENCIES=YesPlease)))
+endif
+endif
+
+ASM_SRC := $(wildcard $(OBJECTS:o=S))
+ASM_OBJ := $(ASM_SRC:S=o)
+C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
+
+.SUFFIXES:
+
+ifdef PRINT_HEADER_DEPENDENCIES
+$(C_OBJ): %.o: %.c FORCE
+ echo $^
+$(ASM_OBJ): %.o: %.S FORCE
+ echo $^
+
+ifndef CHECK_HEADER_DEPENDENCIES
+$(error cannot print header dependencies during a normal build. \
+Please set CHECK_HEADER_DEPENDENCIES and try again)
+endif
+endif
+
+ifndef PRINT_HEADER_DEPENDENCIES
+ifdef CHECK_HEADER_DEPENDENCIES
+$(C_OBJ): %.o: %.c $(dep_files) FORCE
+ @set -e; echo CHECK $@; \
+ missing_deps="$(missing_deps)"; \
+ if test "$$missing_deps"; \
+ then \
+ echo missing dependencies: $$missing_deps; \
+ false; \
+ fi
+$(ASM_OBJ): %.o: %.S $(dep_files) FORCE
+ @set -e; echo CHECK $@; \
+ missing_deps="$(missing_deps)"; \
+ if test "$$missing_deps"; \
+ then \
+ echo missing dependencies: $$missing_deps; \
+ false; \
+ fi
+endif
+endif
+
+ifndef CHECK_HEADER_DEPENDENCIES
+$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs)
+ $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $<
+$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs)
+ $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $<
+endif
+
%.s: %.c GIT-CFLAGS FORCE
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
-%.o: %.S GIT-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
+
+ifdef USE_COMPUTED_HEADER_DEPENDENCIES
+# Take advantage of gcc's on-the-fly dependency generation
+# See <http://gcc.gnu.org/gcc-3.0/features.html>.
+dep_files_present := $(wildcard $(dep_files))
+ifneq ($(dep_files_present),)
+include $(dep_files_present)
+endif
+else
+# Dependencies on header files, for platforms that do not support
+# the gcc -MMD option.
+#
+# Dependencies on automatically generated headers such as common-cmds.h
+# should _not_ be included here, since they are necessary even when
+# building an object for the first time.
+#
+# XXX. Please check occasionally that these include all dependencies
+# gcc detects!
+
+$(GIT_OBJS): $(LIB_H)
+builtin-branch.o builtin-checkout.o builtin-clone.o builtin-reset.o branch.o transport.o: branch.h
+builtin-bundle.o bundle.o transport.o: bundle.h
+builtin-bisect--helper.o builtin-rev-list.o bisect.o: bisect.h
+builtin-clone.o builtin-fetch-pack.o transport.o: fetch-pack.h
+builtin-grep.o: thread-utils.h
+builtin-send-pack.o transport.o: send-pack.h
+builtin-log.o builtin-shortlog.o: shortlog.h
+builtin-prune.o builtin-reflog.o reachable.o: reachable.h
+builtin-commit.o builtin-revert.o wt-status.o: wt-status.h
+builtin-tar-tree.o archive-tar.o: tar.h
+builtin-pack-objects.o: thread-utils.h
+http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
+http.o http-walker.o http-push.o remote-curl.o: http.h
+
+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
+endif
exec_cmd.s exec_cmd.o: ALL_CFLAGS += \
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
http.s http.o: ALL_CFLAGS += -DGIT_USER_AGENT='"git/$(GIT_VERSION)"'
ifdef NO_EXPAT
-http-walker.o: http.h
http-walker.s http-walker.o: ALL_CFLAGS += -DNO_EXPAT
endif
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL)
-http.o http-walker.o http-push.o: http.h
-
-http.o http-walker.o: $(LIB_H)
-
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,$^) \
$(LIBS) $(CURL_LIBCURL)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
-$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_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)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
-XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
- xdiff/xmerge.o xdiff/xpatience.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
-
$(XDIFF_LIB): $(XDIFF_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS)
fi
endif
-### Testing rules
-
-TEST_PROGRAMS_NEED_X += test-chmtime
-TEST_PROGRAMS_NEED_X += test-ctype
-TEST_PROGRAMS_NEED_X += test-date
-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-match-trees
-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-index-version
-
-TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
-
test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))
all:: $(TEST_PROGRAMS) $(test_bindir_programs)
export NO_SVN_TESTS
+### Testing rules
+
test: all
$(MAKE) -C t/ all
test-parse-options$X: parse-options.o
-test-parse-options.o: parse-options.h
-
-.PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
+.PRECIOUS: $(TEST_OBJS)
test-%$X: test-%.o $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+ $(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
ifndef NO_PERL
clean:
$(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
$(LIB_FILE) $(XDIFF_LIB)
- $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
+ $(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) -r autom4te.cache
$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
### Check documentation
#
check-docs::
- @(for v in $(ALL_PROGRAMS) $(BUILT_INS) git gitk; \
+ @(for v in $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git gitk; \
do \
case "$$v" in \
git-merge-octopus | git-merge-ours | git-merge-recursive | \
documented,gitrepository-layout | \
documented,gittutorial | \
documented,gittutorial-2 | \
+ documented,git-bisect-lk2009 | \
+ documented.git-remote-helpers | \
+ documented,gitworkflows | \
sentinel,not,matching,is,ok ) continue ;; \
esac; \
- case " $(ALL_PROGRAMS) $(BUILT_INS) git gitk " in \
+ case " $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git gitk " in \
*" $$cmd "*) ;; \
*) echo "removed but $$how: $$cmd" ;; \
esac; \
diff --combined builtin-pack-objects.c
index 6b2f65c6db833df59f8b7ab50244f630a828c9a1,539e75d56f7a33fdb1971b51ee0681c43e9662b0..97802585ea3ac69ac6ed2e7995605bdcae84558e
+++ b/builtin-pack-objects.c
return stream.total_out;
}
-/*
- * The per-object header is a pretty dense thing, which is
- * - first byte: low four bits are "size", then three bits of "type",
- * and the high bit is "size continues".
- * - each byte afterwards: low seven bits are size continuation,
- * with the high bit being "size continues"
- */
-static int encode_header(enum object_type type, unsigned long size, unsigned char *hdr)
-{
- int n = 1;
- unsigned char c;
-
- if (type < OBJ_COMMIT || type > OBJ_REF_DELTA)
- die("bad type %d", type);
-
- c = (type << 4) | (size & 15);
- size >>= 4;
- while (size) {
- *hdr++ = c | 0x80;
- c = size & 0x7f;
- size >>= 7;
- n++;
- }
- *hdr = c;
- return n;
-}
-
/*
* we are going to reuse the existing object data as is. make
* sure it is not corrupt.
* The object header is a byte of 'type' followed by zero or
* more bytes of length.
*/
- hdrlen = encode_header(type, size, header);
+ hdrlen = encode_in_pack_object_header(type, size, header);
if (type == OBJ_OFS_DELTA) {
/*
if (entry->delta)
type = (allow_ofs_delta && entry->delta->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
- hdrlen = encode_header(type, entry->size, header);
+ hdrlen = encode_in_pack_object_header(type, entry->size, header);
offset = entry->in_pack_offset;
revidx = find_pack_revindex(p, offset);
return 1;
}
- /* forward declaration for write_pack_file */
- static int adjust_perm(const char *path, mode_t mode);
-
static void write_pack_file(void)
{
uint32_t i = 0, j;
}
if (!pack_to_stdout) {
- mode_t mode = umask(0);
struct stat st;
const char *idx_tmp_name;
char tmpname[PATH_MAX];
- umask(mode);
- mode = 0444 & ~mode;
-
idx_tmp_name = write_idx_file(NULL, written_list,
nr_written, sha1);
snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
base_name, sha1_to_hex(sha1));
free_pack_by_name(tmpname);
- if (adjust_perm(pack_tmp_name, mode))
+ if (adjust_shared_perm(pack_tmp_name))
die_errno("unable to make temporary pack file readable");
if (rename(pack_tmp_name, tmpname))
die_errno("unable to rename temporary pack file");
snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
base_name, sha1_to_hex(sha1));
- if (adjust_perm(idx_tmp_name, mode))
+ if (adjust_shared_perm(idx_tmp_name))
die_errno("unable to make temporary index file readable");
if (rename(idx_tmp_name, tmpname))
die_errno("unable to rename temporary index file");
loosen_unused_packed_objects(&revs);
}
- static int adjust_perm(const char *path, mode_t mode)
- {
- if (chmod(path, mode))
- return -1;
- return adjust_shared_perm(path);
- }
-
int cmd_pack_objects(int argc, const char **argv, const char *prefix)
{
int use_internal_rev_list = 0;
diff --combined cache.h
index d454b7e686d6461162a85ef9c5f752eea401f51a,031963772356d925f3e1e338b72d5c8d38dd615e..4d89aa3da4d32653289c742f37abe8ef604ab11b
+++ b/cache.h
int git_mkstemps(char *path, size_t n, const char *template, int suffix_len);
+ /* set default permissions by passing mode arguments to open(2) */
+ int git_mkstemps_mode(char *pattern, int suffix_len, int mode);
+ int git_mkstemp_mode(char *pattern, int mode);
+
/*
* NOTE NOTE NOTE!!
*
extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);
extern const char *fmt_name(const char *name, const char *email);
extern const char *git_editor(void);
-extern const char *git_pager(void);
+extern const char *git_pager(int stdout_is_tty);
struct checkout {
const char *base_dir;
diff --combined path.c
index d1fccbde7f5ba08ba9876b12e1dbabf87f44b4e9,12ef731acebb96481dcc2360648ce4e1b85de33d..c290e744865af774f8dfb575d66f2755603744fa
+++ b/path.c
return mkstemps(path, suffix_len);
}
+ /* Adapted from libiberty's mkstemp.c. */
+
+ #undef TMP_MAX
+ #define TMP_MAX 16384
+
+ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
+ {
+ static const char letters[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789";
+ static const int num_letters = 62;
+ uint64_t value;
+ struct timeval tv;
+ char *template;
+ size_t len;
+ int fd, count;
+
+ len = strlen(pattern);
+
+ if (len < 6 + suffix_len) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Replace pattern's XXXXXX characters with randomness.
+ * Try TMP_MAX different filenames.
+ */
+ gettimeofday(&tv, NULL);
+ value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
+ template = &pattern[len - 6 - suffix_len];
+ for (count = 0; count < TMP_MAX; ++count) {
+ uint64_t v = value;
+ /* Fill in the random bits. */
+ template[0] = letters[v % num_letters]; v /= num_letters;
+ template[1] = letters[v % num_letters]; v /= num_letters;
+ template[2] = letters[v % num_letters]; v /= num_letters;
+ template[3] = letters[v % num_letters]; v /= num_letters;
+ template[4] = letters[v % num_letters]; v /= num_letters;
+ template[5] = letters[v % num_letters]; v /= num_letters;
+
+ fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
+ if (fd > 0)
+ return fd;
+ /*
+ * Fatal error (EPERM, ENOSPC etc).
+ * It doesn't make sense to loop.
+ */
+ if (errno != EEXIST)
+ break;
+ /*
+ * This is a random value. It is only necessary that
+ * the next TMP_MAX values generated by adding 7777 to
+ * VALUE are different with (module 2^32).
+ */
+ value += 7777;
+ }
+ /* We return the null string if we can't find a unique file name. */
+ pattern[0] = '\0';
+ return -1;
+ }
+
+ int git_mkstemp_mode(char *pattern, int mode)
+ {
+ /* mkstemp is just mkstemps with no suffix */
+ return git_mkstemps_mode(pattern, 0, mode);
+ }
+
+ int gitmkstemps(char *pattern, int suffix_len)
+ {
+ return git_mkstemps_mode(pattern, suffix_len, 0600);
+ }
+
int validate_headref(const char *path)
{
struct stat st;
if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 &&
validate_headref("HEAD") == 0) {
- setenv(GIT_DIR_ENVIRONMENT, ".", 1);
+ set_git_dir(".");
check_repository_format();
return path;
}
/*
* This resurrects the belts and suspenders paranoia check by HPA
* done in <435560F7.4080006@zytor.com> thread, now enter_repo()
- * does not do getcwd() based path canonicalizations.
+ * does not do getcwd() based path canonicalization.
*
* sl becomes true immediately after seeing '/' and continues to
* be true as long as dots continue after that without intervening
diff --combined sha1_file.c
index 006321e009b321db6cf4f7bf35d8385017a7076a,3316f282c6903eb9156835d2d2ebd0d5501ee142..c23cc5e6e19a2d8c9a92161b0a5d62a5ef8e920b
--- 1/sha1_file.c
--- 2/sha1_file.c
+++ b/sha1_file.c
}
out:
- if (set_shared_perm(filename, (S_IFREG|0444)))
+ if (adjust_shared_perm(filename))
return error("unable to set permission to '%s'", filename);
return 0;
}
}
memcpy(buffer, filename, dirlen);
strcpy(buffer + dirlen, "tmp_obj_XXXXXX");
- fd = mkstemp(buffer);
+ fd = git_mkstemp_mode(buffer, 0444);
if (fd < 0 && dirlen && errno == ENOENT) {
/* Make sure the directory exists */
memcpy(buffer, filename, dirlen);
/* Try again */
strcpy(buffer + dirlen - 1, "/tmp_obj_XXXXXX");
- fd = mkstemp(buffer);
+ fd = git_mkstemp_mode(buffer, 0444);
}
return fd;
}
void *buf, unsigned long len, time_t mtime)
{
int fd, ret;
- size_t size;
- unsigned char *compressed;
+ unsigned char compressed[4096];
z_stream stream;
+ git_SHA_CTX c;
+ unsigned char parano_sha1[20];
char *filename;
static char tmpfile[PATH_MAX];
/* Set it up */
memset(&stream, 0, sizeof(stream));
deflateInit(&stream, zlib_compression_level);
- size = 8 + deflateBound(&stream, len+hdrlen);
- compressed = xmalloc(size);
-
- /* Compress it */
stream.next_out = compressed;
- stream.avail_out = size;
+ stream.avail_out = sizeof(compressed);
+ git_SHA1_Init(&c);
/* First header.. */
stream.next_in = (unsigned char *)hdr;
stream.avail_in = hdrlen;
while (deflate(&stream, 0) == Z_OK)
/* nothing */;
+ git_SHA1_Update(&c, hdr, hdrlen);
/* Then the data itself.. */
stream.next_in = buf;
stream.avail_in = len;
- ret = deflate(&stream, Z_FINISH);
+ do {
+ unsigned char *in0 = stream.next_in;
+ ret = deflate(&stream, Z_FINISH);
+ git_SHA1_Update(&c, in0, stream.next_in - in0);
+ if (write_buffer(fd, compressed, stream.next_out - compressed) < 0)
+ die("unable to write sha1 file");
+ stream.next_out = compressed;
+ stream.avail_out = sizeof(compressed);
+ } while (ret == Z_OK);
+
if (ret != Z_STREAM_END)
die("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret);
-
ret = deflateEnd(&stream);
if (ret != Z_OK)
die("deflateEnd on object %s failed (%d)", sha1_to_hex(sha1), ret);
+ git_SHA1_Final(parano_sha1, &c);
+ if (hashcmp(sha1, parano_sha1) != 0)
+ die("confused by unstable object source data for %s", sha1_to_hex(sha1));
- size = stream.total_out;
-
- if (write_buffer(fd, compressed, size) < 0)
- die("unable to write sha1 file");
close_sha1_file(fd);
- free(compressed);
if (mtime) {
struct utimbuf utb;
return ret;
}
+#define SMALL_FILE_SIZE (32*1024)
+
int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
enum object_type type, const char *path)
{
else
ret = -1;
strbuf_release(&sbuf);
+ } else if (size <= SMALL_FILE_SIZE) {
+ char *buf = xmalloc(size);
+ if (size == read_in_full(fd, buf, size))
+ ret = index_mem(sha1, buf, size, write_object, type,
+ path);
+ else
+ ret = error("short read %s", strerror(errno));
+ free(buf);
} else if (size) {
void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
ret = index_mem(sha1, buf, size, write_object, type, path);