diff options
28 files changed, 328 insertions, 101 deletions
diff --git a/Documentation/RelNotes-1.7.0.txt b/Documentation/RelNotes-1.7.0.txt index 997b026a73..323ae54007 100644 --- a/Documentation/RelNotes-1.7.0.txt +++ b/Documentation/RelNotes-1.7.0.txt @@ -25,7 +25,7 @@ Notes on behaviour change configured that variable. * "git status" is not "git commit --dry-run" anymore. This change does - not affect you if you run the command without pathspec. + not affect you if you run the command without argument. * "git diff" traditionally treated various "ignore whitespace" options only as a way to filter the patch output. "git diff --exit-code -b" @@ -38,6 +38,13 @@ Notes on behaviour change whitespaces is reported with zero exit status when run with --exit-code, and there is no "diff --git" header for such a change. + * external diff and textconv helpers are now executed using the shell. + This makes them consistent with other programs executed by git, and + allows you to pass command-line parameters to the helpers. Any helper + paths containing spaces or other metacharacters now need to be + shell-quoted. The affected helpers are GIT_EXTERNAL_DIFF in the + environment, and diff.*.command and diff.*.textconv in the config + file. Updates since v1.6.6 -------------------- @@ -175,6 +182,9 @@ Updates since v1.6.6 * Many more commands are now built-in. + * THREADED_DELTA_SEARCH is no more. If you build with threads, delta + compression will always take advantage of it. + Fixes since v1.6.6 ------------------ @@ -190,15 +200,16 @@ release, unless otherwise noted. from non-root dir, 2010-01-26) may be merged to older maintenance branches. - * When "git diff" is asked to compare the work tree with something, - it used to consider that a checked-out submodule with uncommitted - changes is not modified; this could cause people to forget committing - these changes in the submodule before committing in the superproject. - It now considers such a change as a modification. + * When using "git status" or asking "git diff" to compare the work tree + with something, they used to consider that a checked-out submodule with + uncommitted changes is not modified; this could cause people to forget + committing these changes in the submodule before committing in the + superproject. They now consider such a change as a modification and + "git diff" will append a "-dirty" to the work tree side when generating + patch output or when used with the --submodule option. -- exec >/var/tmp/1 -O=v1.7.0-rc0-48-gdace5dd -O=v1.7.0-rc0-67-gb10b918 +O=v1.7.0-rc1-6-g2ee8c5b echo O=$(git describe master) git shortlog --no-merges $O..master ^maint diff --git a/Documentation/config.txt b/Documentation/config.txt index 17901e244a..36ad992a56 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -417,6 +417,20 @@ You probably do not need to adjust this value. + Common unit suffixes of 'k', 'm', or 'g' are supported. +core.bigFileThreshold:: + Files larger than this size are stored deflated, without + attempting delta compression. Storing large files without + delta compression avoids excessive memory usage, at the + slight expense of increased disk usage. ++ +Default is 512 MiB on all platforms. This should be reasonable +for most projects as source code and other text files can still +be delta compressed, but larger binary media files won't be. ++ +Common unit suffixes of 'k', 'm', or 'g' are supported. ++ +Currently only linkgit:git-fast-import[1] honors this setting. + core.excludesfile:: In addition to '.gitignore' (per-directory) and '.git/info/exclude', git looks into this file for patterns diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index b71712473e..15c7e794f4 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -19,7 +19,7 @@ git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]:: git-diff-files [<pattern>...]:: compares the index and the files on the filesystem. -The "git-diff-tree" command begins its ouput by printing the hash of +The "git-diff-tree" command begins its output by printing the hash of what is being compared. After that, all the commands print one output line per changed file. diff --git a/Documentation/git-bisect-lk2009.txt b/Documentation/git-bisect-lk2009.txt index 6b7b2e5497..86b3015c13 100644 --- a/Documentation/git-bisect-lk2009.txt +++ b/Documentation/git-bisect-lk2009.txt @@ -799,7 +799,7 @@ fixed in the "main" branch by commit "F"? The result of such a bisection would be that we would find that H is the first bad commit, when in fact it's B. So that would be wrong! -And yes it's can happen in practice that people working on one branch +And yes it can happen in practice that people working on one branch are not aware that people working on another branch fixed a bug! It could also happen that F fixed more than one bug or that it is a revert of some big development effort that was not ready to be diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index c24e14b870..98ec6b5871 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -37,7 +37,7 @@ unsigned, with 'verbatim', they will be silently exported and with 'warn', they will be exported, but you will see a warning. --tag-of-filtered-object=(abort|drop|rewrite):: - Specify how to handle tags whose tagged objectis filtered out. + Specify how to handle tags whose tagged object is filtered out. Since revisions and files to export can be limited by path, tagged objects may be filtered completely. + diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index ff4022c15f..2691114440 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -50,6 +50,12 @@ OPTIONS importers may wish to lower this, such as to ensure the resulting packfiles fit on CDs. +--big-file-threshold=<n>:: + Maximum size of a blob that fast-import will attempt to + create a delta for, expressed in bytes. The default is 512m + (512 MiB). Some importers may wish to lower this on systems + with constrained memory. + --depth=<n>:: Maximum delta depth, for blob and tree deltification. Default is 10. @@ -152,7 +158,7 @@ fast-forward update, fast-import will skip updating that ref and instead prints a warning message. fast-import will always attempt to update all branch refs, and does not stop on the first failure. -Branch updates can be forced with \--force, but its recommended that +Branch updates can be forced with \--force, but it's recommended that this only be used on an otherwise quiet repository. Using \--force is not necessary for an initial import into an empty repository. @@ -267,7 +273,7 @@ is always copied into the identity string at the time it is being created by fast-import. There is no way to specify a different time or timezone. + -This particular format is supplied as its short to implement and +This particular format is supplied as it's short to implement and may be useful to a process that wants to create a new commit right now, without needing to use a working directory or 'git update-index'. @@ -420,7 +426,7 @@ quoting or escaping syntax is supported within `<committish>`. Here `<committish>` is any of the following: * The name of an existing branch already in fast-import's internal branch - table. If fast-import doesn't know the name, its treated as a SHA-1 + table. If fast-import doesn't know the name, it's treated as a SHA-1 expression. * A mark reference, `:<idnum>`, where `<idnum>` is the mark number. @@ -759,7 +765,7 @@ assigned mark. The mark command is optional here as some frontends have chosen to generate the Git SHA-1 for the blob on their own, and feed that -directly to `commit`. This is typically more work than its worth +directly to `commit`. This is typically more work than it's worth however, as marks are inexpensive to store and easy to use. `data` diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt index 07931c6874..5238820657 100644 --- a/Documentation/git-http-backend.txt +++ b/Documentation/git-http-backend.txt @@ -14,7 +14,7 @@ DESCRIPTION ----------- A simple CGI program to serve the contents of a Git repository to Git clients accessing the repository over http:// and https:// protocols. -The program supports clients fetching using both the smart HTTP protcol +The program supports clients fetching using both the smart HTTP protocol and the backwards-compatible dumb HTTP protocol, as well as clients pushing using the smart HTTP protocol. diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt index 4685a898f1..1b5f61aa0b 100644 --- a/Documentation/git-remote-helpers.txt +++ b/Documentation/git-remote-helpers.txt @@ -25,7 +25,7 @@ Commands are given by the caller on the helper's standard input, one per line. 'capabilities':: Lists the capabilities of the helper, one per line, ending - with a blank line. Each capability may be preceeded with '*'. + with a blank line. Each capability may be preceded with '*'. This marks them mandatory for git version using the remote helper to understand (unknown mandatory capability is fatal error). diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index e7845d4055..fc731525da 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -33,7 +33,7 @@ OPTIONS --stop-at-non-option:: Only meaningful in `--parseopt` mode. Lets the option parser stop at the first non-option argument. This can be used to parse sub-commands - that take options themself. + that take options themselves. --sq-quote:: Use 'git rev-parse' in shell quoting mode (see SQ-QUOTE diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 63aa694968..2502531a3d 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -218,7 +218,7 @@ OPTIONS This option is only valid for the update command. Rebase the current branch onto the commit recorded in the superproject. If this option is given, the submodule's HEAD will not - be detached. If a a merge failure prevents this process, you will have + be detached. If a merge failure prevents this process, you will have to resolve these failures with linkgit:git-rebase[1]. If the key `submodule.$name.update` is set to `rebase`, this option is implicit. diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 3ef71179d9..6e9baf8b38 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -233,27 +233,27 @@ endif::git-rev-list[] Pretend as if all the refs in `$GIT_DIR/refs/heads` are listed on the command line as '<commit>'. If `pattern` is given, limit branches to ones matching given shell glob. If pattern lacks '?', - '*', or '[', '/*' at the end is impiled. + '*', or '[', '/*' at the end is implied. --tags[=pattern]:: Pretend as if all the refs in `$GIT_DIR/refs/tags` are listed on the command line as '<commit>'. If `pattern` is given, limit tags to ones matching given shell glob. If pattern lacks '?', '*', - or '[', '/*' at the end is impiled. + or '[', '/*' at the end is implied. --remotes[=pattern]:: Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed on the command line as '<commit>'. If `pattern`is given, limit remote tracking branches to ones matching given shell glob. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. + If pattern lacks '?', '*', or '[', '/*' at the end is implied. --glob=glob-pattern:: Pretend as if all the refs matching shell glob `glob-pattern` are listed on the command line as '<commit>'. Leading 'refs/', is automatically prepended if missing. If pattern lacks '?', '*', - or '[', '/*' at the end is impiled. + or '[', '/*' at the end is implied. ifndef::git-rev-list[] diff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt index b26c28133c..68bf4cad8b 100644 --- a/Documentation/technical/api-run-command.txt +++ b/Documentation/technical/api-run-command.txt @@ -51,7 +51,7 @@ The functions above do the following: ENOENT; a diagnostic is printed only if .silent_exec_failure is 0. . Otherwise, the program is run. If it terminates regularly, its exit - code is returned. No diagnistic is printed, even if the exit code is + code is returned. No diagnostic is printed, even if the exit code is non-zero. . If the program terminated due to a signal, then the return value is the diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index 7950eeeda4..9a5cdafa9c 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -149,7 +149,7 @@ advertisement list at all, but other refs may still appear. The stream MUST include capability declarations behind a NUL on the first ref. The peeled value of a ref (that is "ref^{}") MUST be immediately after the ref itself, if presented. A conforming server -MUST peel the ref if its an annotated tag. +MUST peel the ref if it's an annotated tag. ---- advertised-refs = (no-refs / list-of-refs) @@ -261,7 +261,7 @@ Without either multi_ack or multi_ack_detailed: * upload-pack sends "NAK" on a flush-pkt if no common object has been found yet. If one has been found, and thus an ACK - was already sent, its silent on the flush-pkt. + was already sent, it's silent on the flush-pkt. After the client has gotten enough ACK responses that it can determine that the server has enough information to send an efficient packfile @@ -271,9 +271,9 @@ as common with the server, or the --date-order queue is empty), or the client determines that it wants to give up (in the canonical implementation, this is determined when the client sends 256 'have' lines without getting any of them ACKed by the server - meaning there is nothing in common and -the server should just send all it's objects), then the client will send +the server should just send all of its objects), then the client will send a 'done' command. The 'done' command signals to the server that the client -is ready to receive it's packfile data. +is ready to receive its packfile data. However, the 256 limit *only* turns on in the canonical client implementation if we have received at least one "ACK %s continue" @@ -286,7 +286,7 @@ ACK after 'done' if there is at least one common base and multi_ack or multi_ack_detailed is enabled. The server always sends NAK after 'done' if there is no common base found. -Then the server will start sending it's packfile data. +Then the server will start sending its packfile data. ---- server-response = *ack_multi ack / nak diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt index 1892d3eeac..fd1a593149 100644 --- a/Documentation/technical/protocol-capabilities.txt +++ b/Documentation/technical/protocol-capabilities.txt @@ -60,7 +60,7 @@ doesn't, as in the following diagram: If the client wants x,y and starts out by saying have F,S, the server doesn't know what F,S is. Eventually the client says "have d" and the server sends "ACK d continue" to let the client know to stop -walking down that line (so don't send c-b-a), but its not done yet, +walking down that line (so don't send c-b-a), but it's not done yet, it needs a base for x. The client keeps going with S-R-Q, until a gets reached, at which point the server has a clear base and it all ends. @@ -181,7 +181,7 @@ delete-refs ----------- If the server sends back the 'delete-refs' capability, it means that -it is capable of accepting an zero-id value as the target +it is capable of accepting a zero-id value as the target value of a reference update. It is not sent back by the client, it simply informs the client that it can be sent zero-id values to delete references. diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index b169836684..fe6fb722da 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1196,7 +1196,7 @@ the time, you will want to commit your changes before you can merge, and if you don't, then linkgit:git-stash[1] can take these changes away while you're doing the merge, and reapply them afterwards. -If the changes are independant enough, Git will automatically complete +If the changes are independent enough, Git will automatically complete the merge and commit the result (or reuse an existing commit in case of <<fast-forwards,fast-forward>>, see below). On the other hand, if there are conflicts--for example, if the same file is @@ -3640,6 +3640,26 @@ Did you forget to 'git add'? Unable to checkout '261dfac35cb99d380eb966e102c1197139f7fa24' in submodule path 'a' ------------------------------------------------- +In older git versions it could be easily forgotten to commit new or modified +files in a submodule, which silently leads to similar problems as not pushing +the submodule changes. Starting with git 1.7.0 both "git status" and "git diff" +in the superproject show submodules as modified when they contain new or +modified files to protect against accidentally committing such a state. "git +diff" will also add a "-dirty" to the work tree side when generating patch +output or used with the --submodule option: + +------------------------------------------------- +$ git diff +diff --git a/sub b/sub +--- a/sub ++++ b/sub +@@ -1 +1 @@ +-Subproject commit 3f356705649b5d566d97ff843cf193359229a453 ++Subproject commit 3f356705649b5d566d97ff843cf193359229a453-dirty +$ git diff --submodule +Submodule sub 3f35670..3f35670-dirty: +------------------------------------------------- + You also should not rewind branches in a submodule beyond commits that were ever recorded in any superproject. @@ -180,9 +180,6 @@ all:: # If not set it defaults to the bare 'wish'. If it is set to the empty # string then NO_TCLTK will be forced (this is used by configure script). # -# Define THREADED_DELTA_SEARCH if you have pthreads and wish to exploit -# parallel delta searching when packing objects. -# # Define INTERNAL_QSORT to use Git's implementation of qsort(), which # is a simplified version of the merge sort used in glibc. This is # recommended if Git triggers O(n^2) behavior in your platform's qsort(). @@ -699,12 +696,10 @@ 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) CC = cc @@ -758,7 +753,6 @@ ifeq ($(uname_S),Darwin) NO_STRLCPY = YesPlease endif NO_MEMMEM = YesPlease - THREADED_DELTA_SEARCH = YesPlease USE_ST_TIMESPEC = YesPlease endif ifeq ($(uname_S),SunOS) @@ -771,7 +765,6 @@ ifeq ($(uname_S),SunOS) NO_MKDTEMP = YesPlease NO_MKSTEMPS = YesPlease NO_REGEX = YesPlease - THREADED_DELTA_SEARCH = YesPlease ifeq ($(uname_R),5.7) NEEDS_RESOLV = YesPlease NO_IPV6 = YesPlease @@ -827,7 +820,6 @@ ifeq ($(uname_S),FreeBSD) BASIC_LDFLAGS += -L/usr/local/lib DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease USE_ST_TIMESPEC = YesPlease - THREADED_DELTA_SEARCH = YesPlease ifeq ($(shell expr "$(uname_R)" : '4\.'),2) PTHREAD_LIBS = -pthread NO_UINTMAX_T = YesPlease @@ -841,7 +833,6 @@ ifeq ($(uname_S),OpenBSD) NEEDS_LIBICONV = YesPlease BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib - THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),NetBSD) ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2) @@ -849,7 +840,6 @@ ifeq ($(uname_S),NetBSD) endif BASIC_CFLAGS += -I/usr/pkg/include BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib - THREADED_DELTA_SEARCH = YesPlease USE_ST_TIMESPEC = YesPlease NO_MKSTEMPS = YesPlease endif @@ -864,9 +854,7 @@ ifeq ($(uname_S),AIX) INTERNAL_QSORT = UnfortunatelyYes NEEDS_LIBICONV=YesPlease BASIC_CFLAGS += -D_LARGE_FILES - ifneq ($(shell expr "$(uname_V)" : '[1234]'),1) - THREADED_DELTA_SEARCH = YesPlease - else + ifeq ($(shell expr "$(uname_V)" : '[1234]'),1) NO_PTHREADS = YesPlease endif endif @@ -892,7 +880,6 @@ ifeq ($(uname_S),IRIX) SNPRINTF_RETURNS_BOGUS = YesPlease SHELL_PATH = /usr/gnu/bin/bash NEEDS_LIBGEN = YesPlease - THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),IRIX64) NO_SETENV=YesPlease @@ -911,7 +898,6 @@ ifeq ($(uname_S),IRIX64) SNPRINTF_RETURNS_BOGUS = YesPlease SHELL_PATH=/usr/gnu/bin/bash NEEDS_LIBGEN = YesPlease - THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),HP-UX) NO_IPV6=YesPlease @@ -961,7 +947,6 @@ ifeq ($(uname_S),Windows) NO_CURL = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease - THREADED_DELTA_SEARCH = YesPlease CC = compat/vcbuild/scripts/clink.pl AR = compat/vcbuild/scripts/lib.pl @@ -1013,7 +998,6 @@ ifneq (,$(findstring MINGW,$(uname_S))) NO_REGEX = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease - THREADED_DELTA_SEARCH = YesPlease COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \ @@ -1311,16 +1295,12 @@ ifdef RUNTIME_PREFIX endif ifdef NO_PTHREADS - THREADED_DELTA_SEARCH = BASIC_CFLAGS += -DNO_PTHREADS else EXTLIBS += $(PTHREAD_LIBS) -endif - -ifdef THREADED_DELTA_SEARCH - BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH LIB_OBJS += thread-utils.o endif + ifdef DIR_HAS_BSD_GROUP_SEMANTICS COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS endif diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index b0887d759d..4a41547a27 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -17,7 +17,7 @@ #include "progress.h" #include "refs.h" -#ifdef THREADED_DELTA_SEARCH +#ifndef NO_PTHREADS #include "thread-utils.h" #include <pthread.h> #endif @@ -1255,7 +1255,7 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size, return 0; } -#ifdef THREADED_DELTA_SEARCH +#ifndef NO_PTHREADS static pthread_mutex_t read_mutex; #define read_lock() pthread_mutex_lock(&read_mutex) @@ -1380,7 +1380,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* * Handle memory allocation outside of the cache * accounting lock. Compiler will optimize the strangeness - * away when THREADED_DELTA_SEARCH is not defined. + * away when NO_PTHREADS is defined. */ free(trg_entry->delta_data); cache_lock(); @@ -1567,7 +1567,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size, free(array); } -#ifdef THREADED_DELTA_SEARCH +#ifndef NO_PTHREADS /* * The main thread waits on the condition that (at least) one of the workers @@ -1899,7 +1899,7 @@ static int git_pack_config(const char *k, const char *v, void *cb) if (delta_search_threads < 0) die("invalid number of threads specified (%d)", delta_search_threads); -#ifndef THREADED_DELTA_SEARCH +#ifdef NO_PTHREADS if (delta_search_threads != 1) warning("no threads support, ignoring %s", k); #endif @@ -2227,7 +2227,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) delta_search_threads = strtoul(arg+10, &end, 0); if (!arg[10] || *end || delta_search_threads < 0) usage(pack_usage); -#ifndef THREADED_DELTA_SEARCH +#ifdef NO_PTHREADS if (delta_search_threads != 1) warning("no threads support, " "ignoring %s", arg); diff --git a/config.mak.in b/config.mak.in index 67b12f73a1..6008ac9f1b 100644 --- a/config.mak.in +++ b/config.mak.in @@ -56,5 +56,4 @@ NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@ FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@ SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@ NO_PTHREADS=@NO_PTHREADS@ -THREADED_DELTA_SEARCH=@THREADED_DELTA_SEARCH@ PTHREAD_LIBS=@PTHREAD_LIBS@ diff --git a/configure.ac b/configure.ac index 78345ebb60..914ae5759f 100644 --- a/configure.ac +++ b/configure.ac @@ -23,21 +23,32 @@ AC_DEFUN([GIT_CONF_APPEND_LINE], # GIT_ARG_SET_PATH(PROGRAM) # ------------------------- # Provide --with-PROGRAM=PATH option to set PATH to PROGRAM +# Optional second argument allows setting NO_PROGRAM=YesPlease if +# --without-PROGRAM version used. AC_DEFUN([GIT_ARG_SET_PATH], [AC_ARG_WITH([$1], [AS_HELP_STRING([--with-$1=PATH], [provide PATH to $1])], - [GIT_CONF_APPEND_PATH($1)],[]) + [GIT_CONF_APPEND_PATH($1,$2)],[]) ])# GIT_ARG_SET_PATH # # GIT_CONF_APPEND_PATH(PROGRAM) # ------------------------------ # Parse --with-PROGRAM=PATH option to set PROGRAM_PATH=PATH # Used by GIT_ARG_SET_PATH(PROGRAM) +# Optional second argument allows setting NO_PROGRAM=YesPlease if +# --without-PROGRAM is used. AC_DEFUN([GIT_CONF_APPEND_PATH], [PROGRAM=m4_toupper($1); \ if test "$withval" = "no"; then \ - AC_MSG_ERROR([You cannot use git without $1]); \ + if test -n "$2"; then \ + m4_toupper($1)_PATH=$withval; \ + AC_MSG_NOTICE([Disabling use of ${PROGRAM}]); \ + GIT_CONF_APPEND_LINE(NO_${PROGRAM}=YesPlease); \ + GIT_CONF_APPEND_LINE(${PROGRAM}_PATH=); \ + else \ + AC_MSG_ERROR([You cannot use git without $1]); \ + fi; \ else \ if test "$withval" = "yes"; then \ AC_MSG_WARN([You should provide path for --with-$1=PATH]); \ @@ -277,7 +288,7 @@ GIT_ARG_SET_PATH(shell) GIT_ARG_SET_PATH(perl) # # Define PYTHON_PATH to provide path to Python. -GIT_ARG_SET_PATH(python) +GIT_ARG_SET_PATH(python, allow-without) # # Define ZLIB_PATH to provide path to zlib. GIT_ARG_SET_PATH(zlib) @@ -762,10 +773,9 @@ AC_SUBST(NO_MKSTEMPS) # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. # Enable it on Windows. By default, symrefs are still used. # -# Define NO_PTHREADS if we do not have pthreads +# Define NO_PTHREADS if we do not have pthreads. # -# Define PTHREAD_LIBS to the linker flag used for Pthread support and define -# THREADED_DELTA_SEARCH if Pthreads are available. +# Define PTHREAD_LIBS to the linker flag used for Pthread support. AC_DEFUN([PTHREADTEST_SRC], [ #include <pthread.h> @@ -782,7 +792,6 @@ dnl [[pthread_mutex_t test_mutex;]] dnl )]) NO_PTHREADS=UnfortunatelyYes -THREADED_DELTA_SEARCH= PTHREAD_LIBS= if test -n "$USER_NOPTHREAD"; then @@ -798,7 +807,6 @@ elif test -z "$PTHREAD_CFLAGS"; then [AC_MSG_RESULT([yes]) NO_PTHREADS= PTHREAD_LIBS="$opt" - THREADED_DELTA_SEARCH=YesPlease break ], [AC_MSG_RESULT([no])]) @@ -812,7 +820,6 @@ else [AC_MSG_RESULT([yes]) NO_PTHREADS= PTHREAD_LIBS="$PTHREAD_CFLAGS" - THREADED_DELTA_SEARCH=YesPlease ], [AC_MSG_RESULT([no])]) @@ -823,7 +830,6 @@ CFLAGS="$old_CFLAGS" AC_SUBST(PTHREAD_LIBS) AC_SUBST(NO_PTHREADS) -AC_SUBST(THREADED_DELTA_SEARCH) ## Output files AC_CONFIG_FILES(["${config_file}":"${config_in}":"${config_append}"]) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index d1512e0acf..e7c48144e6 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1037,7 +1037,7 @@ class P4Sync(Command): if includeFile: filesForCommit.append(f) - if f['action'] not in ('delete', 'purge'): + if f['action'] not in ('delete', 'move/delete', 'purge'): filesToRead.append(f) else: filesToDelete.append(f) diff --git a/fast-import.c b/fast-import.c index 901784fe91..ca210822db 100644 --- a/fast-import.c +++ b/fast-import.c @@ -281,6 +281,7 @@ struct recent_command /* Configured limits on output */ static unsigned long max_depth = 10; static off_t max_packsize = (1LL << 32) - 1; +static uintmax_t big_file_threshold = 512 * 1024 * 1024; static int force_update; static int pack_compression_level = Z_DEFAULT_COMPRESSION; static int pack_compression_seen; @@ -1014,7 +1015,7 @@ static void cycle_packfile(void) static size_t encode_header( enum object_type type, - size_t size, + uintmax_t size, unsigned char *hdr) { int n = 1; @@ -1170,6 +1171,118 @@ static int store_object( return 0; } +static void truncate_pack(off_t to) +{ + if (ftruncate(pack_data->pack_fd, to) + || lseek(pack_data->pack_fd, to, SEEK_SET) != to) + die_errno("cannot truncate pack to skip duplicate"); + pack_size = to; +} + +static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark) +{ + size_t in_sz = 64 * 1024, out_sz = 64 * 1024; + unsigned char *in_buf = xmalloc(in_sz); + unsigned char *out_buf = xmalloc(out_sz); + struct object_entry *e; + unsigned char sha1[20]; + unsigned long hdrlen; + off_t offset; + git_SHA_CTX c; + z_stream s; + int status = Z_OK; + + /* Determine if we should auto-checkpoint. */ + if ((pack_size + 60 + len) > max_packsize + || (pack_size + 60 + len) < pack_size) + cycle_packfile(); + + offset = pack_size; + + hdrlen = snprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1; + if (out_sz <= hdrlen) + die("impossibly large object header"); + + git_SHA1_Init(&c); + git_SHA1_Update(&c, out_buf, hdrlen); + + memset(&s, 0, sizeof(s)); + deflateInit(&s, pack_compression_level); + + hdrlen = encode_header(OBJ_BLOB, len, out_buf); + if (out_sz <= hdrlen) + die("impossibly large object header"); + + s.next_out = out_buf + hdrlen; + s.avail_out = out_sz - hdrlen; + + while (status != Z_STREAM_END) { + if (0 < len && !s.avail_in) { + size_t cnt = in_sz < len ? in_sz : (size_t)len; + size_t n = fread(in_buf, 1, cnt, stdin); + if (!n && feof(stdin)) + die("EOF in data (%" PRIuMAX " bytes remaining)", len); + + git_SHA1_Update(&c, in_buf, n); + s.next_in = in_buf; + s.avail_in = n; + len -= n; + } + + status = deflate(&s, len ? 0 : Z_FINISH); + + if (!s.avail_out || status == Z_STREAM_END) { + size_t n = s.next_out - out_buf; + write_or_die(pack_data->pack_fd, out_buf, n); + pack_size += n; + s.next_out = out_buf; + s.avail_out = out_sz; + } + + switch (status) { + case Z_OK: + case Z_BUF_ERROR: + case Z_STREAM_END: + continue; + default: + die("unexpected deflate failure: %d", status); + } + } + deflateEnd(&s); + git_SHA1_Final(sha1, &c); + + if (sha1out) + hashcpy(sha1out, sha1); + + e = insert_object(sha1); + + if (mark) + insert_mark(mark, e); + + if (e->offset) { + duplicate_count_by_type[OBJ_BLOB]++; + truncate_pack(offset); + + } else if (find_sha1_pack(sha1, packed_git)) { + e->type = OBJ_BLOB; + e->pack_id = MAX_PACK_ID; + e->offset = 1; /* just not zero! */ + duplicate_count_by_type[OBJ_BLOB]++; + truncate_pack(offset); + + } else { + e->depth = 0; + e->type = OBJ_BLOB; + e->pack_id = pack_id; + e->offset = offset; + object_count++; + object_count_by_type[OBJ_BLOB]++; + } + + free(in_buf); + free(out_buf); +} + /* All calls must be guarded by find_object() or find_mark() to * ensure the 'struct object_entry' passed was written by this * process instance. We unpack the entry by the offset, avoiding @@ -1757,7 +1870,7 @@ static void parse_mark(void) next_mark = 0; } -static void parse_data(struct strbuf *sb) +static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res) { strbuf_reset(sb); @@ -1781,9 +1894,15 @@ static void parse_data(struct strbuf *sb) free(term); } else { - size_t n = 0, length; + uintmax_t len = strtoumax(command_buf.buf + 5, NULL, 10); + size_t n = 0, length = (size_t)len; - length = strtoul(command_buf.buf + 5, NULL, 10); + if (limit && limit < len) { + *len_res = len; + return 0; + } + if (length < len) + die("data is too large to use in this context"); while (n < length) { size_t s = strbuf_fread(sb, length - n, stdin); @@ -1795,6 +1914,7 @@ static void parse_data(struct strbuf *sb) } skip_optional_lf(); + return 1; } static int validate_raw_date(const char *src, char *result, int maxlen) @@ -1859,14 +1979,32 @@ static char *parse_ident(const char *buf) return ident; } -static void parse_new_blob(void) +static void parse_and_store_blob( + struct last_object *last, + unsigned char *sha1out, + uintmax_t mark) { static struct strbuf buf = STRBUF_INIT; + uintmax_t len; + if (parse_data(&buf, big_file_threshold, &len)) + store_object(OBJ_BLOB, &buf, last, sha1out, mark); + else { + if (last) { + strbuf_release(&last->data); + last->offset = 0; + last->depth = 0; + } + stream_blob(len, sha1out, mark); + skip_optional_lf(); + } +} + +static void parse_new_blob(void) +{ read_next_command(); parse_mark(); - parse_data(&buf); - store_object(OBJ_BLOB, &buf, &last_blob, NULL, next_mark); + parse_and_store_blob(&last_blob, NULL, next_mark); } static void unload_one_branch(void) @@ -2080,15 +2218,12 @@ static void file_change_m(struct branch *b) * another repository. */ } else if (inline_data) { - static struct strbuf buf = STRBUF_INIT; - if (p != uq.buf) { strbuf_addstr(&uq, p); p = uq.buf; } read_next_command(); - parse_data(&buf); - store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0); + parse_and_store_blob(&last_blob, sha1, 0); } else if (oe) { if (oe->type != OBJ_BLOB) die("Not a blob (actually a %s): %s", @@ -2216,15 +2351,12 @@ static void note_change_n(struct branch *b, unsigned char old_fanout) die("Invalid ref name or SHA1 expression: %s", p); if (inline_data) { - static struct strbuf buf = STRBUF_INIT; - if (p != uq.buf) { strbuf_addstr(&uq, p); p = uq.buf; } read_next_command(); - parse_data(&buf); - store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0); + parse_and_store_blob(&last_blob, sha1, 0); } else if (oe) { if (oe->type != OBJ_BLOB) die("Not a blob (actually a %s): %s", @@ -2401,7 +2533,7 @@ static void parse_new_commit(void) } if (!committer) die("Expected committer but didn't get one"); - parse_data(&msg); + parse_data(&msg, 0, NULL); read_next_command(); parse_from(b); merge_list = parse_merge(&merge_count); @@ -2528,7 +2660,7 @@ static void parse_new_tag(void) tagger = NULL; /* tag payload/message */ - parse_data(&msg); + parse_data(&msg, 0, NULL); /* build the tag object */ strbuf_reset(&new_data); @@ -2667,6 +2799,8 @@ static int parse_one_option(const char *option) { if (!prefixcmp(option, "max-pack-size=")) { option_max_pack_size(option + 14); + } else if (!prefixcmp(option, "big-file-threshold=")) { + big_file_threshold = strtoumax(option + 19, NULL, 0) * 1024 * 1024; } else if (!prefixcmp(option, "depth=")) { option_depth(option + 6); } else if (!prefixcmp(option, "active-branches=")) { @@ -2749,11 +2883,15 @@ static int git_pack_config(const char *k, const char *v, void *cb) pack_compression_seen = 1; return 0; } + if (!strcmp(k, "core.bigfilethreshold")) { + long n = git_config_int(k, v); + big_file_threshold = 0 < n ? n : 0; + } return git_default_config(k, v, cb); } static const char fast_import_usage[] = -"git fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]"; +"git fast-import [--date-format=f] [--max-pack-size=n] [--big-file-threshold=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]"; static void parse_argv(void) { diff --git a/git.spec.in b/git.spec.in index 0a031088da..ee74a5eed7 100644 --- a/git.spec.in +++ b/git.spec.in @@ -98,7 +98,7 @@ BuildRequires: perl(Error) Perl interface to Git %define path_settings ETC_GITCONFIG=/etc/gitconfig prefix=%{_prefix} mandir=%{_mandir} htmldir=%{_docdir}/%{name}-%{version} -%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} +%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %prep %setup -q @@ -192,6 +192,9 @@ rm -rf $RPM_BUILD_ROOT # No files for you! %changelog +* Sun Jan 31 2010 Junio C Hamano <gitster@pobox.com> +- Do not use %define inside %{!?...} construct. + * Sat Jan 30 2010 Junio C Hamano <gitster@pobox.com> - We don't ship Python bits until a real foreign scm interface comes. diff --git a/read-cache.c b/read-cache.c index 309b77a6c9..f1f789b7b8 100644 --- a/read-cache.c +++ b/read-cache.c @@ -26,7 +26,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int reall #define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) ) #define CACHE_EXT_TREE 0x54524545 /* "TREE" */ -#define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUN" */ +#define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */ struct index_state the_index; diff --git a/resolve-undo.c b/resolve-undo.c index 37d73cd949..0f50ee0484 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -53,7 +53,7 @@ void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo) for_each_string_list(write_one, resolve_undo, sb); } -struct string_list *resolve_undo_read(void *data, unsigned long size) +struct string_list *resolve_undo_read(const char *data, unsigned long size) { struct string_list *resolve_undo; size_t len; @@ -93,7 +93,7 @@ struct string_list *resolve_undo_read(void *data, unsigned long size) continue; if (size < 20) goto error; - hashcpy(ui->sha1[i], data); + hashcpy(ui->sha1[i], (const unsigned char *)data); size -= 20; data += 20; } diff --git a/resolve-undo.h b/resolve-undo.h index e4e5c1b1ad..845876911d 100644 --- a/resolve-undo.h +++ b/resolve-undo.h @@ -8,7 +8,7 @@ struct resolve_undo_info { extern void record_resolve_undo(struct index_state *, struct cache_entry *); extern void resolve_undo_write(struct strbuf *, struct string_list *); -extern struct string_list *resolve_undo_read(void *, unsigned long); +extern struct string_list *resolve_undo_read(const char *, unsigned long); extern void resolve_undo_clear_index(struct index_state *); extern int unmerge_index_entry_at(struct index_state *, int); extern void unmerge_index(struct index_state *, const char **); diff --git a/submodule.c b/submodule.c index 6f7c21090b..7d70c4f7bf 100644 --- a/submodule.c +++ b/submodule.c @@ -10,17 +10,19 @@ static int add_submodule_odb(const char *path) { struct strbuf objects_directory = STRBUF_INIT; struct alternate_object_database *alt_odb; + int ret = 0; strbuf_addf(&objects_directory, "%s/.git/objects/", path); - if (!is_directory(objects_directory.buf)) - return -1; - + if (!is_directory(objects_directory.buf)) { + ret = -1; + goto done; + } /* avoid adding it twice */ for (alt_odb = alt_odb_list; alt_odb; alt_odb = alt_odb->next) if (alt_odb->name - alt_odb->base == objects_directory.len && !strncmp(alt_odb->base, objects_directory.buf, objects_directory.len)) - return 0; + goto done; alt_odb = xmalloc(objects_directory.len + 42 + sizeof(*alt_odb)); alt_odb->next = alt_odb_list; @@ -31,7 +33,9 @@ static int add_submodule_odb(const char *path) alt_odb->name[41] = '\0'; alt_odb_list = alt_odb; prepare_alt_odb(); - return 0; +done: + strbuf_release(&objects_directory); + return ret; } void show_submodule_summary(FILE *f, const char *path, diff --git a/t/t5705-clone-2gb.sh b/t/t5705-clone-2gb.sh index 9f52154cac..adfaae8c5b 100755 --- a/t/t5705-clone-2gb.sh +++ b/t/t5705-clone-2gb.sh @@ -31,7 +31,7 @@ test_expect_success 'setup' ' echo "data 5" && echo ">2gb" && cat commit) | - git fast-import && + git fast-import --big-file-threshold=2 && test ! -f exit-status ' diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 60d6f5d1ba..131f032988 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -1536,4 +1536,50 @@ test_expect_success 'R: ignore non-git options' ' git fast-import <input ' +## +## R: very large blobs +## +blobsize=$((2*1024*1024 + 53)) +test-genrandom bar $blobsize >expect +cat >input <<INPUT_END +commit refs/heads/big-file +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +R - big file +COMMIT + +M 644 inline big1 +data $blobsize +INPUT_END +cat expect >>input +cat >>input <<INPUT_END +M 644 inline big2 +data $blobsize +INPUT_END +cat expect >>input +echo >>input + +test_expect_success \ + 'R: blob bigger than threshold' \ + 'test_create_repo R && + git --git-dir=R/.git fast-import --big-file-threshold=1 <input' +test_expect_success \ + 'R: verify created pack' \ + ': >verify && + for p in R/.git/objects/pack/*.pack; + do + git verify-pack -v $p >>verify || exit; + done' +test_expect_success \ + 'R: verify written objects' \ + 'git --git-dir=R/.git cat-file blob big-file:big1 >actual && + test_cmp expect actual && + a=$(git --git-dir=R/.git rev-parse big-file:big1) && + b=$(git --git-dir=R/.git rev-parse big-file:big2) && + test $a = $b' +test_expect_success \ + 'R: blob appears only once' \ + 'n=$(grep $a verify | wc -l) && + test 1 = $n' + test_done |