diff options
58 files changed, 540 insertions, 150 deletions
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines new file mode 100644 index 0000000000..3b042db624 --- /dev/null +++ b/Documentation/CodingGuidelines @@ -0,0 +1,112 @@ +Like other projects, we also have some guidelines to keep to the +code. For git in general, three rough rules are: + + - Most importantly, we never say "It's in POSIX; we'll happily + ignore your needs should your system not conform to it." + We live in the real world. + + - However, we often say "Let's stay away from that construct, + it's not even in POSIX". + + - In spite of the above two rules, we sometimes say "Although + this is not in POSIX, it (is so convenient | makes the code + much more readable | has other good characteristics) and + practically all the platforms we care about support it, so + let's use it". + + Again, we live in the real world, and it is sometimes a + judgement call, the decision based more on real world + constraints people face than what the paper standard says. + + +As for more concrete guidelines, just imitate the existing code +(this is a good guideline, no matter which project you are +contributing to). But if you must have a list of rules, +here they are. + +For shell scripts specifically (not exhaustive): + + - We prefer $( ... ) for command substitution; unlike ``, it + properly nests. It should have been the way Bourne spelled + it from day one, but unfortunately isn't. + + - We use ${parameter-word} and its [-=?+] siblings, and their + colon'ed "unset or null" form. + + - We use ${parameter#word} and its [#%] siblings, and their + doubled "longest matching" form. + + - We use Arithmetic Expansion $(( ... )). + + - No "Substring Expansion" ${parameter:offset:length}. + + - No shell arrays. + + - No strlen ${#parameter}. + + - No regexp ${parameter/pattern/string}. + + - We do not use Process Substitution <(list) or >(list). + + - We prefer "test" over "[ ... ]". + + - We do not write the noiseword "function" in front of shell + functions. + +For C programs: + + - We use tabs to indent, and interpret tabs as taking up to + 8 spaces. + + - We try to keep to at most 80 characters per line. + + - When declaring pointers, the star sides with the variable + name, i.e. "char *string", not "char* string" or + "char * string". This makes it easier to understand code + like "char *string, c;". + + - We avoid using braces unnecessarily. I.e. + + if (bla) { + x = 1; + } + + is frowned upon. A gray area is when the statement extends + over a few lines, and/or you have a lengthy comment atop of + it. Also, like in the Linux kernel, if there is a long list + of "else if" statements, it can make sense to add braces to + single line blocks. + + - Try to make your code understandable. You may put comments + in, but comments invariably tend to stale out when the code + they were describing changes. Often splitting a function + into two makes the intention of the code much clearer. + + - Double negation is often harder to understand than no negation + at all. + + - Some clever tricks, like using the !! operator with arithmetic + constructs, can be extremely confusing to others. Avoid them, + unless there is a compelling reason to use them. + + - Use the API. No, really. We have a strbuf (variable length + string), several arrays with the ALLOC_GROW() macro, a + path_list for sorted string lists, a hash map (mapping struct + objects) named "struct decorate", amongst other things. + + - When you come up with an API, document it. + + - The first #include in C files, except in platform specific + compat/ implementations, should be git-compat-util.h or another + header file that includes it, such as cache.h or builtin.h. + + - If you are planning a new command, consider writing it in shell + or perl first, so that changes in semantics can be easily + changed and discussed. Many git commands started out like + that, and a few are still scripts. + + - Avoid introducing a new dependency into git. This means you + usually should stay away from scripting languages not already + used in the git core command set (unless your command is clearly + separate from it, such as an importer to convert random-scm-X + repositories to git). diff --git a/Documentation/Makefile b/Documentation/Makefile index 39ec0ede02..d88664177d 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -37,9 +37,6 @@ man7dir=$(mandir)/man7 ASCIIDOC=asciidoc ASCIIDOC_EXTRA = -ifdef ASCIIDOC8 -ASCIIDOC_EXTRA += -a asciidoc7compatible -endif INSTALL?=install RM ?= rm -f DOC_REF = origin/man @@ -52,6 +49,13 @@ DOCBOOK2X_TEXI=docbook2x-texi -include ../config.mak.autogen -include ../config.mak +ifdef ASCIIDOC8 +ASCIIDOC_EXTRA += -a asciidoc7compatible +endif +ifdef DOCBOOK_XSL_172 +ASCIIDOC_EXTRA += -a docbook-xsl-172 +endif + # # Please note that there is a minor bug in asciidoc. # The version after 6.0.3 _will_ include the patch found here: diff --git a/Documentation/RelNotes-1.5.3.5.txt b/Documentation/RelNotes-1.5.3.5.txt index f99a2cd650..7ff1d5d0d1 100644 --- a/Documentation/RelNotes-1.5.3.5.txt +++ b/Documentation/RelNotes-1.5.3.5.txt @@ -90,5 +90,5 @@ Fixes since v1.5.3.4 * "git-send-pack $remote frotz" segfaulted when there is nothing named 'frotz' on the local end. - * "git-rebase -interactive" did not handle its "--strategy" option + * "git-rebase --interactive" did not handle its "--strategy" option properly. diff --git a/Documentation/RelNotes-1.5.3.6.txt b/Documentation/RelNotes-1.5.3.6.txt new file mode 100644 index 0000000000..069a2b2cf9 --- /dev/null +++ b/Documentation/RelNotes-1.5.3.6.txt @@ -0,0 +1,48 @@ +GIT v1.5.3.6 Release Notes +========================== + +Fixes since v1.5.3.5 +-------------------- + + * git-cvsexportcommit handles root commits better. + + * git-svn dcommit used to clobber when sending a series of + patches. + + * git-svn dcommit failed after attempting to rebase when + started with a dirty index; now it stops upfront. + + * git-grep sometimes refused to work when your index was + unmerged. + + * "git-grep -A1 -B2" acted as if it was told to run "git -A1 -B21". + + * git-hash-object did not honor configuration variables, such as + core.compression. + + * git-index-pack choked on a huge pack on 32-bit machines, even when + large file offsets are supported. + + * atom feeds from git-web said "10" for the month of November. + + * a memory leak in commit walker was plugged. + + * When git-send-email inserted the original author's From: + address in body, it did not mark the message with + Content-type: as needed. + + * git-revert and git-cherry-pick incorrectly refused to start + when the work tree was dirty. + + * git-clean did not honor core.excludesfile configuration. + + * git-add mishandled ".gitignore" files when applying them to + subdirectories. + + * While importing a too branchy history, git-fastimport did not + honor delta depth limit properly. + + * Support for zlib implementations that lack ZLIB_VERNUM and definition + of deflateBound() has been added. + + * Quite a lot of documentation clarifications. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 61635bf04d..83bf54c7ac 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -20,9 +20,6 @@ Checklist (and a short version for the impatient): Patch: - use "git format-patch -M" to create the patch - - send your patch to <git@vger.kernel.org>. If you use - git-send-email(1), please test it first by sending - email to yourself. - do not PGP sign your patch - do not attach your patch, but read in the mail body, unless you cannot teach your mailer to @@ -31,13 +28,15 @@ Checklist (and a short version for the impatient): corrupt whitespaces. - provide additional information (which is unsuitable for the commit message) between the "---" and the diffstat - - send the patch to the list (git@vger.kernel.org) and the - maintainer (gitster@pobox.com). - if you change, add, or remove a command line option or make some other user interface change, the associated documentation should be updated as well. - if your name is not writable in ASCII, make sure that you send off a message in the correct encoding. + - send the patch to the list (git@vger.kernel.org) and the + maintainer (gitster@pobox.com). If you use + git-send-email(1), please test it first by sending + email to yourself. Long version: diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf index af5b1558a6..99d8874aa0 100644 --- a/Documentation/asciidoc.conf +++ b/Documentation/asciidoc.conf @@ -23,7 +23,9 @@ ifdef::backend-docbook[] endif::backend-docbook[] ifdef::backend-docbook[] +ifndef::docbook-xsl-172[] # "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. +# v1.72 breaks with this because it replaces dots not in roff requests. [listingblock] <example><title>{title}</title> <literallayout> @@ -36,6 +38,7 @@ ifdef::doctype-manpage[] endif::doctype-manpage[] </literallayout> {title#}</example> +endif::docbook-xsl-172[] endif::backend-docbook[] ifdef::doctype-manpage[] diff --git a/Documentation/config.txt b/Documentation/config.txt index 7ee97df8a7..83bc33c421 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -226,13 +226,15 @@ core.compression:: An integer -1..9, indicating a default compression level. -1 is the zlib default. 0 means no compression, and 1..9 are various speed/size tradeoffs, 9 being slowest. + If set, this provides a default to other compression variables, + such as 'core.loosecompression' and 'pack.compression'. core.loosecompression:: An integer -1..9, indicating the compression level for objects that are not in a pack file. -1 is the zlib default. 0 means no compression, and 1..9 are various speed/size tradeoffs, 9 being slowest. If not set, defaults to core.compression. If that is - not set, defaults to 0 (best speed). + not set, defaults to 1 (best speed). core.packedGitWindowSize:: Number of bytes of a pack file to map into memory in a @@ -622,7 +624,9 @@ pack.compression:: in a pack file. -1 is the zlib default. 0 means no compression, and 1..9 are various speed/size tradeoffs, 9 being slowest. If not set, defaults to core.compression. If that is - not set, defaults to -1. + not set, defaults to -1, the zlib default, which is "a default + compromise between speed and compression (currently equivalent + to level 6)." pack.deltaCacheSize:: The maximum memory in bytes used for caching deltas in diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt index 67064dd31a..c3f0be535d 100644 --- a/Documentation/core-tutorial.txt +++ b/Documentation/core-tutorial.txt @@ -1082,11 +1082,6 @@ server like git Native transport does. Any stock HTTP server that does not even support directory index would suffice. But you must prepare your repository with `git-update-server-info` to help dumb transport downloaders. -+ -There are (confusingly enough) `git-ssh-fetch` and `git-ssh-upload` -programs, which are 'commit walkers'; they outlived their -usefulness when git Native and SSH transports were introduced, -and not used by `git pull` or `git push` scripts. Once you fetch from the remote repository, you `merge` that with your current branch. @@ -1149,7 +1144,7 @@ back to the earlier repository with "hello" and "example" file, and bring ourselves back to the pre-merge state: ------------ -$ git show-branch --more=3 master mybranch +$ git show-branch --more=2 master mybranch ! [master] Merge work in mybranch * [mybranch] Merge work in mybranch -- @@ -1212,7 +1207,7 @@ $ git-read-tree -m -u $mb HEAD mybranch This is the same `git-read-tree` command we have already seen, but it takes three trees, unlike previous examples. This reads the contents of each tree into different 'stage' in the index -file (the first tree goes to stage 1, the second stage 2, +file (the first tree goes to stage 1, the second to stage 2, etc.). After reading three trees into three stages, the paths that are the same in all three stages are 'collapsed' into stage 0. Also paths that are the same in two of three stages are diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 2fe7355555..fd82fc19b5 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -224,6 +224,7 @@ See Also -------- gitlink:git-status[1] gitlink:git-rm[1] +gitlink:git-reset[1] gitlink:git-mv[1] gitlink:git-commit[1] gitlink:git-update-index[1] diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index b7285bcdbc..37cb8b83b2 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -105,7 +105,7 @@ OPTIONS '--track' were given. --no-track:: - When -b is given and a branch is created off a remote branch, + When a branch is created off a remote branch, set up configuration so that git-pull will not retrieve data from the remote branch, ignoring the branch.autosetupmerge configuration variable. diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index e54fb12103..d4bfd49ce1 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -154,10 +154,13 @@ EXAMPLES -------- When recording your own work, the contents of modified files in your working tree are temporarily stored to a staging area -called the "index" with gitlink:git-add[1]. Removal -of a file is staged with gitlink:git-rm[1]. After building the -state to be committed incrementally with these commands, `git -commit` (without any pathname parameter) is used to record what +called the "index" with gitlink:git-add[1]. A file can be +reverted back, only in the index but not in the working tree, +to that of the last commit with `git-reset HEAD -- <file>`, +which effectively reverts `git-add` and prevents the changes to +this file from participating in the next commit. After building +the state to be committed incrementally with these commands, +`git commit` (without any pathname parameter) is used to record what has been staged so far. This is the most basic form of the command. An example: diff --git a/Documentation/git-get-tar-commit-id.txt b/Documentation/git-get-tar-commit-id.txt index 9b5f86fc30..60d1c52f44 100644 --- a/Documentation/git-get-tar-commit-id.txt +++ b/Documentation/git-get-tar-commit-id.txt @@ -3,7 +3,7 @@ git-get-tar-commit-id(1) NAME ---- -git-get-tar-commit-id - Extract commit ID from an archive created using git-tar-tree +git-get-tar-commit-id - Extract commit ID from an archive created using git-archive SYNOPSIS @@ -14,12 +14,12 @@ SYNOPSIS DESCRIPTION ----------- Acts as a filter, extracting the commit ID stored in archives created by -git-tar-tree. It reads only the first 1024 bytes of input, thus its +gitlink:git-archive[1]. It reads only the first 1024 bytes of input, thus its runtime is not influenced by the size of <tarfile> very much. If no commit ID is found, git-get-tar-commit-id quietly exists with a return code of 1. This can happen if <tarfile> had not been created -using git-tar-tree or if the first parameter of git-tar-tree had been +using git-archive or if the first parameter of git-archive had been a tree ID instead of a commit ID or tag. diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index 5c7316ceb8..25003c3866 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -19,7 +19,7 @@ depending on the subcommand: git reflog expire [--dry-run] [--stale-fix] [--verbose] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>... -git reflog [show] [log-options] +git reflog [show] [log-options] [<ref>] Reflog is a mechanism to record when the tip of branches are updated. This command is to manage the information recorded in it. @@ -32,9 +32,16 @@ directly by the end users -- instead, see gitlink:git-gc[1]. The subcommand "show" (which is also the default, in the absence of any subcommands) will take all the normal log options, and show the log of -`HEAD`, which will cover all recent actions, including branch switches. -It is basically an alias for 'git log -g --abbrev-commit ---pretty=oneline', see gitlink:git-log[1]. +the reference provided in the command-line (or `HEAD`, by default). +The reflog will cover all recent actions (HEAD reflog records branch switching +as well). It is an alias for 'git log -g --abbrev-commit --pretty=oneline'; +see gitlink:git-log[1]. + +The reflog is useful in various git commands, to specify the old value +of a reference. For example, `HEAD@\{2\}` means "where HEAD used to be +two moves ago", `master@\{one.week.ago\}` means "where master used to +point to one week ago", and so on. See gitlink:git-rev-parse[1] for +more details. OPTIONS diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 61a6022ce8..886bc03c4a 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -69,7 +69,7 @@ caution. Fetch updates for a named set of remotes in the repository as defined by remotes.<group>. If a named group is not specified on the command line, the configuration parameter remotes.default will get used; if -remotes.default is not defined, all remotes which do not the +remotes.default is not defined, all remotes which do not have the configuration parameter remote.<name>.skipDefaultUpdate set to true will be updated. (See gitlink:git-config[1]). @@ -91,7 +91,7 @@ $ git remote origin $ git branch -r origin/master -$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git +$ git remote add linux-nfs git://linux-nfs.org/pub/linux/nfs-2.6.git $ git remote linux-nfs origin diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index dd51aa11ea..cf4ee2ebe5 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -148,22 +148,23 @@ with `$Id$` upon check-in. `filter` ^^^^^^^^ -A `filter` attribute can be set to a string value. This names +A `filter` attribute can be set to a string value that names a filter driver specified in the configuration. -A filter driver consists of `clean` command and `smudge` +A filter driver consists of a `clean` command and a `smudge` command, either of which can be left unspecified. Upon -checkout, when `smudge` command is specified, the command is fed -the blob object from its standard input, and its standard output -is used to update the worktree file. Similarly, `clean` command -is used to convert the contents of worktree file upon checkin. +checkout, when the `smudge` command is specified, the command is +fed the blob object from its standard input, and its standard +output is used to update the worktree file. Similarly, the +`clean` command is used to convert the contents of worktree file +upon checkin. -Missing filter driver definition in the config is not an error +A missing filter driver definition in the config is not an error but makes the filter a no-op passthru. The content filtering is done to massage the content into a shape that is more convenient for the platform, filesystem, and -the user to use. The keyword here is "more convenient" and not +the user to use. The key phrase here is "more convenient" and not "turning something unusable into usable". In other words, the intent is that if someone unsets the filter driver definition, or does not have the appropriate filter program, the project diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index c7fdf25e27..c027353337 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -658,16 +658,23 @@ gitlink:git-diff[1]: $ git diff master..test ------------------------------------------------- -Sometimes what you want instead is a set of patches: +That will produce the diff between the tips of the two branches. If +you'd prefer to find the diff from their common ancestor to test, you +can use three dots instead of two: + +------------------------------------------------- +$ git diff master...test +------------------------------------------------- + +Sometimes what you want instead is a set of patches; for this you can +use gitlink:git-format-patch[1]: ------------------------------------------------- $ git format-patch master..test ------------------------------------------------- will generate a file with a patch for each commit reachable from test -but not from master. Note that if master also has commits which are -not reachable from test, then the combined result of these patches -will not be the same as the diff produced by the git-diff example. +but not from master. [[viewing-old-file-versions]] Viewing old file versions @@ -2554,6 +2561,72 @@ branches into their own work. For true distributed development that supports proper merging, published branches should never be rewritten. +[[bisect-merges]] +Why bisecting merge commits can be harder than bisecting linear history +----------------------------------------------------------------------- + +The gitlink:git-bisect[1] command correctly handles history that +includes merge commits. However, when the commit that it finds is a +merge commit, the user may need to work harder than usual to figure out +why that commit introduced a problem. + +Imagine this history: + +................................................ + ---Z---o---X---...---o---A---C---D + \ / + o---o---Y---...---o---B +................................................ + +Suppose that on the upper line of development, the meaning of one +of the functions that exists at Z is changed at commit X. The +commits from Z leading to A change both the function's +implementation and all calling sites that exist at Z, as well +as new calling sites they add, to be consistent. There is no +bug at A. + +Suppose that in the meantime on the lower line of development somebody +adds a new calling site for that function at commit Y. The +commits from Z leading to B all assume the old semantics of that +function and the callers and the callee are consistent with each +other. There is no bug at B, either. + +Suppose further that the two development lines merge cleanly at C, +so no conflict resolution is required. + +Nevertheless, the code at C is broken, because the callers added +on the lower line of development have not been converted to the new +semantics introduced on the upper line of development. So if all +you know is that D is bad, that Z is good, and that +gitlink:git-bisect[1] identifies C as the culprit, how will you +figure out that the problem is due to this change in semantics? + +When the result of a git-bisect is a non-merge commit, you should +normally be able to discover the problem by examining just that commit. +Developers can make this easy by breaking their changes into small +self-contained commits. That won't help in the case above, however, +because the problem isn't obvious from examination of any single +commit; instead, a global view of the development is required. To +make matters worse, the change in semantics in the problematic +function may be just one small part of the changes in the upper +line of development. + +On the other hand, if instead of merging at C you had rebased the +history between Z to B on top of A, you would have gotten this +linear history: + +................................................................ + ---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D* +................................................................ + +Bisecting between Z and D* would hit a single culprit commit Y*, +and understanding why Y* was broken would probably be easier. + +Partly for this reason, many experienced git users, even when +working on an otherwise merge-heavy project, keep the history +linear by rebasing against the latest upstream version before +publishing. + [[advanced-branch-management]] Advanced branch management ========================== diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 88a4acad15..fa38f373ac 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.5.3.5.GIT +DEF_VER=v1.5.3.6.GIT LF=' ' @@ -94,6 +94,8 @@ all:: # Define OLD_ICONV if your library has an old iconv(), where the second # (input buffer pointer) parameter is declared with type (const char **). # +# Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. +# # Define NO_R_TO_GCC_LINKER if your gcc does not like "-R/path/lib" # that tells runtime paths to dynamic libraries; # "-Wl,-rpath=/path/lib" is used instead. @@ -109,6 +111,8 @@ all:: # # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 # +# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72. +# # Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's # MakeMaker (e.g. using ActiveState under Cygwin). # @@ -637,6 +641,10 @@ ifdef OLD_ICONV BASIC_CFLAGS += -DOLD_ICONV endif +ifdef NO_DEFLATE_BOUND + BASIC_CFLAGS += -DNO_DEFLATE_BOUND +endif + ifdef PPC_SHA1 SHA1_HEADER = "ppc/sha1.h" LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o @@ -894,6 +902,7 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS) $(LIB_OBJS) $(BUILTIN_OBJS) fetch.o: $(LIB_H) $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) $(DIFF_OBJS): diffcore.h +builtin-revert.o builtin-runstatus.o wt-status.o: wt-status.h $(LIB_FILE): $(LIB_OBJS) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) @@ -1 +1 @@ -Documentation/RelNotes-1.5.3.5.txt
\ No newline at end of file +Documentation/RelNotes-1.5.3.6.txt
\ No newline at end of file diff --git a/builtin-add.c b/builtin-add.c index 373f87f9f2..850e1c23e5 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -17,7 +17,6 @@ static const char builtin_add_usage[] = "git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <filepattern>..."; static int take_worktree_changes; -static const char *excludes_file; static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix) { @@ -57,12 +56,7 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec, memset(dir, 0, sizeof(*dir)); if (!ignored_too) { dir->collect_ignored = 1; - dir->exclude_per_dir = ".gitignore"; - path = git_path("info/exclude"); - if (!access(path, R_OK)) - add_excludes_from_file(dir, path); - if (excludes_file != NULL && !access(excludes_file, R_OK)) - add_excludes_from_file(dir, excludes_file); + setup_standard_excludes(dir); } /* @@ -144,18 +138,6 @@ static void refresh(int verbose, const char **pathspec) free(seen); } -static int git_add_config(const char *var, const char *value) -{ - if (!strcmp(var, "core.excludesfile")) { - if (!value) - die("core.excludesfile without value"); - excludes_file = xstrdup(value); - return 0; - } - - return git_default_config(var, value); -} - static struct lock_file lock_file; static const char ignore_error[] = @@ -183,7 +165,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) exit(1); } - git_config(git_add_config); + git_config(git_default_config); newfd = hold_locked_index(&lock_file, 1); diff --git a/builtin-bundle.c b/builtin-bundle.c index 1b650069c9..d1840555d6 100644 --- a/builtin-bundle.c +++ b/builtin-bundle.c @@ -6,6 +6,7 @@ #include "revision.h" #include "list-objects.h" #include "run-command.h" +#include "refs.h" /* * Basic handler for bundle files to connect repositories via sneakernet. @@ -253,11 +254,17 @@ static int create_bundle(struct bundle_header *header, const char *path, struct object_array_entry *e = revs.pending.objects + i; unsigned char sha1[20]; char *ref; + const char *display_ref; + int flag; if (e->item->flags & UNINTERESTING) continue; if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1) continue; + if (!resolve_ref(e->name, sha1, 1, &flag)) + flag = 0; + display_ref = (flag & REF_ISSYMREF) ? e->name : ref; + /* * Make sure the refs we wrote out is correct; --max-count and * other limiting options could have prevented all the tips @@ -308,7 +315,7 @@ static int create_bundle(struct bundle_header *header, const char *path, ref_count++; write_or_die(bundle_fd, sha1_to_hex(e->item->sha1), 40); write_or_die(bundle_fd, " ", 1); - write_or_die(bundle_fd, ref, strlen(ref)); + write_or_die(bundle_fd, display_ref, strlen(display_ref)); write_or_die(bundle_fd, "\n", 1); free(ref); } diff --git a/builtin-diff.c b/builtin-diff.c index f77352b40d..f557d21929 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -200,15 +200,11 @@ static void refresh_index_quietly(void) discard_cache(); read_cache(); refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); - if (active_cache_changed) { - if (write_cache(fd, active_cache, active_nr) || - close(fd) || - commit_locked_index(lock_file)) - ; /* - * silently ignore it -- we haven't mucked - * with the real index. - */ - } + + if (active_cache_changed && + !write_cache(fd, active_cache, active_nr) && !close(fd)) + commit_locked_index(lock_file); + rollback_lock_file(lock_file); } diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index 29f70aabc3..0327f40306 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -297,7 +297,7 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un if (!eol) return ""; eol++; - if (eol[1] == '\n') + if (*eol == '\n') return ""; /* end of header */ buf = eol; } diff --git a/builtin-grep.c b/builtin-grep.c index 185876b0a6..bbf747fc7b 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -294,7 +294,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) if (opt->pre_context) { push_arg("-B"); len += snprintf(argptr, sizeof(randarg)-len, - "%u", opt->pre_context); + "%u", opt->pre_context) + 1; if (sizeof(randarg) <= len) die("maximum length of args exceeded"); push_arg(argptr); @@ -303,7 +303,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) if (opt->post_context) { push_arg("-A"); len += snprintf(argptr, sizeof(randarg)-len, - "%u", opt->post_context); + "%u", opt->post_context) + 1; if (sizeof(randarg) <= len) die("maximum length of args exceeded"); push_arg(argptr); @@ -313,7 +313,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) else { push_arg("-C"); len += snprintf(argptr, sizeof(randarg)-len, - "%u", opt->post_context); + "%u", opt->post_context) + 1; if (sizeof(randarg) <= len) die("maximum length of args exceeded"); push_arg(argptr); diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c index 43fc373a15..10fa177340 100644 --- a/builtin-mailsplit.c +++ b/builtin-mailsplit.c @@ -101,20 +101,29 @@ static int populate_maildir_list(struct path_list *list, const char *path) { DIR *dir; struct dirent *dent; + char name[PATH_MAX]; + char *subs[] = { "cur", "new", NULL }; + char **sub; + + for (sub = subs; *sub; ++sub) { + snprintf(name, sizeof(name), "%s/%s", path, *sub); + if ((dir = opendir(name)) == NULL) { + if (errno == ENOENT) + continue; + error("cannot opendir %s (%s)", name, strerror(errno)); + return -1; + } - if ((dir = opendir(path)) == NULL) { - error("cannot opendir %s (%s)", path, strerror(errno)); - return -1; - } + while ((dent = readdir(dir)) != NULL) { + if (dent->d_name[0] == '.') + continue; + snprintf(name, sizeof(name), "%s/%s", *sub, dent->d_name); + path_list_insert(name, list); + } - while ((dent = readdir(dir)) != NULL) { - if (dent->d_name[0] == '.') - continue; - path_list_insert(dent->d_name, list); + closedir(dir); } - closedir(dir); - return 0; } @@ -122,19 +131,17 @@ static int split_maildir(const char *maildir, const char *dir, int nr_prec, int skip) { char file[PATH_MAX]; - char curdir[PATH_MAX]; char name[PATH_MAX]; int ret = -1; int i; struct path_list list = {NULL, 0, 0, 1}; - snprintf(curdir, sizeof(curdir), "%s/cur", maildir); - if (populate_maildir_list(&list, curdir) < 0) + if (populate_maildir_list(&list, maildir) < 0) goto out; for (i = 0; i < list.nr; i++) { FILE *f; - snprintf(file, sizeof(file), "%s/%s", curdir, list.items[i].path); + snprintf(file, sizeof(file), "%s/%s", maildir, list.items[i].path); f = fopen(file, "r"); if (!f) { error("cannot open mail %s (%s)", file, strerror(errno)); @@ -152,10 +159,9 @@ static int split_maildir(const char *maildir, const char *dir, fclose(f); } - path_list_clear(&list, 1); - ret = skip; out: + path_list_clear(&list, 1); return ret; } diff --git a/builtin-revert.c b/builtin-revert.c index eafafbc333..94e77771d2 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -264,7 +264,7 @@ static int revert_or_cherry_pick(int argc, const char **argv) if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); wt_status_prepare(&s); - if (s.commitable || s.workdir_dirty) + if (s.commitable) die ("Dirty index: cannot %s", me); discard_cache(); } @@ -6,7 +6,7 @@ #include SHA1_HEADER #include <zlib.h> -#if ZLIB_VERNUM < 0x1200 +#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200 #define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11) #endif @@ -571,6 +571,7 @@ extern int pager_in_use; extern int pager_use_color; extern char *editor_program; +extern char *excludes_file; /* base85 */ int decode_85(char *dst, const char *line, int linelen); @@ -431,6 +431,13 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.excludesfile")) { + if (!value) + die("core.excludesfile without value"); + excludes_file = xstrdup(value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/config.mak.in b/config.mak.in index a3032e389f..776b805659 100644 --- a/config.mak.in +++ b/config.mak.in @@ -38,3 +38,4 @@ NO_STRCASESTR=@NO_STRCASESTR@ NO_STRLCPY=@NO_STRLCPY@ NO_SETENV=@NO_SETENV@ NO_ICONV=@NO_ICONV@ +NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@ diff --git a/configure.ac b/configure.ac index ed7cc895d2..ab516db379 100644 --- a/configure.ac +++ b/configure.ac @@ -182,6 +182,26 @@ AC_SUBST(NEEDS_LIBICONV) AC_SUBST(NO_ICONV) test -n "$NEEDS_LIBICONV" && LIBS="$LIBS -liconv" # +# Define NO_DEFLATE_BOUND if deflateBound is missing from zlib. +AC_DEFUN([ZLIBTEST_SRC], [ +#include <zlib.h> + +int main(void) +{ + deflateBound(0, 0); + return 0; +} +]) +AC_MSG_CHECKING([for deflateBound in -lz]) +old_LIBS="$LIBS" +LIBS="$LIBS -lz" +AC_LINK_IFELSE(ZLIBTEST_SRC, + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + NO_DEFLATE_BOUND=yes]) +LIBS="$old_LIBS" +AC_SUBST(NO_DEFLATE_BOUND) +# # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, # Patrick Mauritz). AC_CHECK_LIB([c], [socket], @@ -626,6 +626,7 @@ static void free_simplify(struct path_simplify *simplify) int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec) { struct path_simplify *simplify = create_simplify(pathspec); + char *pp = NULL; /* * Make sure to do the per-directory exclude for all the @@ -633,7 +634,8 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i */ if (baselen) { if (dir->exclude_per_dir) { - char *p, *pp = xmalloc(baselen+1); + char *p; + pp = xmalloc(baselen+1); memcpy(pp, base, baselen+1); p = pp; while (1) { @@ -649,12 +651,12 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i else p = pp + baselen; } - free(pp); } } read_directory_recursive(dir, path, base, baselen, 0, simplify); free_simplify(simplify); + free(pp); qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name); qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name); return dir->nr; @@ -709,3 +711,15 @@ int is_inside_dir(const char *dir) char buffer[PATH_MAX]; return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL; } + +void setup_standard_excludes(struct dir_struct *dir) +{ + const char *path; + + dir->exclude_per_dir = ".gitignore"; + path = git_path("info/exclude"); + if (!access(path, R_OK)) + add_excludes_from_file(dir, path); + if (excludes_file && !access(excludes_file, R_OK)) + add_excludes_from_file(dir, excludes_file); +} @@ -64,4 +64,6 @@ extern struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna extern char *get_relative_cwd(char *buffer, int size, const char *dir); extern int is_inside_dir(const char *dir); +extern void setup_standard_excludes(struct dir_struct *dir); + #endif diff --git a/environment.c b/environment.c index b5a6c69f7c..1dab72ec15 100644 --- a/environment.c +++ b/environment.c @@ -34,6 +34,7 @@ char *pager_program; int pager_in_use; int pager_use_color = 1; char *editor_program; +char *excludes_file; int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */ /* This is set by setup_git_dir_gently() and/or git_default_config() */ diff --git a/fast-import.c b/fast-import.c index c07e3d8ef0..5e83296bf4 100644 --- a/fast-import.c +++ b/fast-import.c @@ -154,13 +154,16 @@ Format of STDIN stream: #define PACK_ID_BITS 16 #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1) +#define DEPTH_BITS 13 +#define MAX_DEPTH ((1<<DEPTH_BITS)-1) struct object_entry { struct object_entry *next; uint32_t offset; - unsigned type : TYPE_BITS; - unsigned pack_id : PACK_ID_BITS; + uint32_t type : TYPE_BITS, + pack_id : PACK_ID_BITS, + depth : DEPTH_BITS; unsigned char sha1[20]; }; @@ -1105,7 +1108,7 @@ static int store_object( unsigned pos = sizeof(hdr) - 1; delta_count_by_type[type]++; - last->depth++; + e->depth = last->depth + 1; hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr); write_or_die(pack_data->pack_fd, hdr, hdrlen); @@ -1117,8 +1120,7 @@ static int store_object( write_or_die(pack_data->pack_fd, hdr + pos, sizeof(hdr) - pos); pack_size += sizeof(hdr) - pos; } else { - if (last) - last->depth = 0; + e->depth = 0; hdrlen = encode_header(type, datlen, hdr); write_or_die(pack_data->pack_fd, hdr, hdrlen); pack_size += hdrlen; @@ -1134,6 +1136,7 @@ static int store_object( free(last->data); last->data = dat; last->offset = e->offset; + last->depth = e->depth; last->len = datlen; } return 0; @@ -1181,7 +1184,7 @@ static void load_tree(struct tree_entry *root) if (myoe && myoe->pack_id != MAX_PACK_ID) { if (myoe->type != OBJ_TREE) die("Not a tree: %s", sha1_to_hex(sha1)); - t->delta_depth = 0; + t->delta_depth = myoe->depth; buf = gfi_unpack_entry(myoe, &size); } else { enum object_type type; @@ -2347,8 +2350,11 @@ int main(int argc, const char **argv) } else if (!prefixcmp(a, "--max-pack-size=")) max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024; - else if (!prefixcmp(a, "--depth=")) + else if (!prefixcmp(a, "--depth=")) { max_depth = strtoul(a + 8, NULL, 0); + if (max_depth > MAX_DEPTH) + die("--depth cannot exceed %u", MAX_DEPTH); + } else if (!prefixcmp(a, "--active-branches=")) max_active_branches = strtoul(a + 18, NULL, 0); else if (!prefixcmp(a, "--import-marks=")) diff --git a/git-clean.sh b/git-clean.sh index 4491738186..931d1aa4e4 100755 --- a/git-clean.sh +++ b/git-clean.sh @@ -75,15 +75,22 @@ esac if [ -z "$ignored" ]; then excl="--exclude-per-directory=.gitignore" + excl_info= excludes_file= if [ -f "$GIT_DIR/info/exclude" ]; then excl_info="--exclude-from=$GIT_DIR/info/exclude" fi + if cfg_excl=$(git config core.excludesfile) && test -f "$cfg_excl" + then + excludes_file="--exclude-from=$cfg_excl" + fi if [ "$ignoredonly" ]; then excl="$excl --ignored" fi fi -git ls-files --others --directory $excl ${excl_info:+"$excl_info"} -- "$@" | +git ls-files --others --directory \ + $excl ${excl_info:+"$excl_info"} ${excludes_file:+"$excludes_file"} \ + -- "$@" | while read -r file; do if [ -d "$file" -a ! -L "$file" ]; then if [ -z "$cleandir" ]; then diff --git a/git-instaweb.sh b/git-instaweb.sh index 41ff08f8e4..2ca487d7d5 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -15,7 +15,7 @@ browser="`git config --get instaweb.browser`" port=`git config --get instaweb.port` module_path="`git config --get instaweb.modulepath`" -conf=$GIT_DIR/gitweb/httpd.conf +conf="$GIT_DIR/gitweb/httpd.conf" # Defaults: @@ -32,7 +32,7 @@ start_httpd () { httpd_only="`echo $httpd | cut -f1 -d' '`" if case "$httpd_only" in /*) : ;; *) which $httpd_only >/dev/null;; esac then - $httpd $fqgitdir/gitweb/httpd.conf + $httpd "$fqgitdir/gitweb/httpd.conf" else # many httpds are installed in /usr/sbin or /usr/local/sbin # these days and those are not in most users $PATHs @@ -146,14 +146,14 @@ server.pid-file = "$fqgitdir/pid" cgi.assign = ( ".cgi" => "" ) mimetype.assign = ( ".css" => "text/css" ) EOF - test "$local" = true && echo 'server.bind = "127.0.0.1"' >> "$conf" + test x"$local" = xtrue && echo 'server.bind = "127.0.0.1"' >> "$conf" } apache2_conf () { test -z "$module_path" && module_path=/usr/lib/apache2/modules mkdir -p "$GIT_DIR/gitweb/logs" bind= - test "$local" = true && bind='127.0.0.1:' + test x"$local" = xtrue && bind='127.0.0.1:' echo 'text/css css' > $fqgitdir/mime.types cat > "$conf" <<EOF ServerName "git-instaweb" @@ -206,7 +206,7 @@ EOF } script=' -s#^\(my\|our\) $projectroot =.*#\1 $projectroot = "'`dirname $fqgitdir`'";# +s#^\(my\|our\) $projectroot =.*#\1 $projectroot = "'$(dirname "$fqgitdir")'";# s#\(my\|our\) $gitbin =.*#\1 $gitbin = "'$GIT_EXEC_PATH'";# s#\(my\|our\) $projects_list =.*#\1 $projects_list = $projectroot;# s#\(my\|our\) $git_temp =.*#\1 $git_temp = "'$fqgitdir/gitweb/tmp'";#' @@ -226,8 +226,8 @@ gitweb_css () { EOFGITWEB } -gitweb_cgi $GIT_DIR/gitweb/gitweb.cgi -gitweb_css $GIT_DIR/gitweb/gitweb.css +gitweb_cgi "$GIT_DIR/gitweb/gitweb.cgi" +gitweb_css "$GIT_DIR/gitweb/gitweb.css" case "$httpd" in *lighttpd*) @@ -243,6 +243,5 @@ case "$httpd" in esac start_httpd -test -z "$browser" && browser=echo url=http://127.0.0.1:$port -$browser $url || echo $url +"$browser" $url || echo $url diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index f28c3df204..d65df2cb80 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -361,7 +361,7 @@ do -s|--strategy) case "$#,$1" in *,*=*) - STRATEGY="-s `expr "z$1" : 'z-[^=]*=\(.*\)'`" ;; + STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;; 1,*) usage ;; *) diff --git a/git-request-pull.sh b/git-request-pull.sh index a992430679..95ad66630f 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -24,13 +24,13 @@ headrev=`git rev-parse --verify "$head"^0` || exit merge_base=`git merge-base $baserev $headrev` || die "fatal: No commits in common between $base and $head" -url="`get_remote_url "$url"`" -branch=`git peek-remote "$url" \ +url=$(get_remote_url "$url") +branch=$(git peek-remote "$url" \ | sed -n -e "/^$headrev refs.heads./{ s/^.* refs.heads.// p q - }"` + }") if [ -z "$branch" ]; then echo "warn: No branch of $url is at:" >&2 git log --max-count=1 --pretty='format:warn: %h: %s' $headrev >&2 diff --git a/git-send-email.perl b/git-send-email.perl index 9547cc37a1..b03297c9d7 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -303,7 +303,7 @@ sub expand_aliases { if (!defined $initial_subject && $compose) { do { - $_ = $term->readline("What subject should the emails start with? ", + $_ = $term->readline("What subject should the initial email start with? ", $initial_subject); } while (!defined $_); $initial_subject = $_; @@ -468,11 +468,13 @@ $time = time - scalar $#files; sub unquote_rfc2047 { local ($_) = @_; - if (s/=\?utf-8\?q\?(.*)\?=/$1/g) { + my $encoding; + if (s/=\?([^?]+)\?q\?(.*)\?=/$2/g) { + $encoding = $1; s/_/ /g; s/=([0-9A-F]{2})/chr(hex($1))/eg; } - return "$_"; + return wantarray ? ($_, $encoding) : $_; } # use the simplest quoting being able to handle the recipient @@ -599,6 +601,9 @@ foreach my $t (@files) { open(F,"<",$t) or die "can't open file $t"; my $author = undef; + my $author_encoding; + my $has_content_type; + my $body_encoding; @cc = @initial_cc; @xh = (); my $input_format = undef; @@ -624,12 +629,20 @@ foreach my $t (@files) { next if ($suppress_from); } elsif ($1 eq 'From') { - $author = unquote_rfc2047($2); + ($author, $author_encoding) + = unquote_rfc2047($2); } printf("(mbox) Adding cc: %s from line '%s'\n", $2, $_) unless $quiet; push @cc, $2; } + elsif (/^Content-type:/i) { + $has_content_type = 1; + if (/charset="?[^ "]+/) { + $body_encoding = $1; + } + push @xh, $_; + } elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) { push @xh, $_; } @@ -686,6 +699,22 @@ foreach my $t (@files) { if (defined $author) { $message = "From: $author\n\n$message"; + if (defined $author_encoding) { + if ($has_content_type) { + if ($body_encoding eq $author_encoding) { + # ok, we already have the right encoding + } + else { + # uh oh, we should re-encode + } + } + else { + push @xh, + 'MIME-Version: 1.0', + "Content-Type: text/plain; charset=$author_encoding", + 'Content-Transfer-Encoding: 8bit'; + } + } } send_message(); diff --git a/git-submodule.sh b/git-submodule.sh index 673aa27a45..b91d62632c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -47,7 +47,7 @@ get_repo_base() { module_name() { # Do we have "submodule.<something>.path = $1" defined in .gitmodules file? - re=$(printf '%s' "$1" | sed -e 's/\([^a-zA-Z0-9_]\)/\\\1/g') + re=$(printf '%s' "$1" | sed -e 's/[].[^$\\*]/\\&/g') name=$( GIT_CONFIG=.gitmodules \ git config --get-regexp '^submodule\..*\.path$' | sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' ) diff --git a/git-svn.perl b/git-svn.perl index ec25ea4231..4c779b6c6d 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -374,6 +374,9 @@ sub cmd_set_tree { sub cmd_dcommit { my $head = shift; + git_cmd_try { command_oneline(qw/diff-index --quiet HEAD/) } + 'Cannot dcommit with a dirty index. Commit your changes first' + . "or stash them with `git stash'.\n"; $head ||= 'HEAD'; my @refs; my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs); diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 3064298f28..9deefce0a6 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1713,7 +1713,7 @@ sub parse_date { $date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min; $date{'iso-8601'} = sprintf "%04d-%02d-%02dT%02d:%02d:%02dZ", - 1900+$year, $mon, $mday, $hour ,$min, $sec; + 1900+$year, 1+$mon, $mday, $hour ,$min, $sec; $tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/; my $local = $epoch + ((int $1 + ($2/60)) * 3600); diff --git a/hash-object.c b/hash-object.c index 18f5017f51..0a58f3f126 100644 --- a/hash-object.c +++ b/hash-object.c @@ -42,6 +42,8 @@ int main(int argc, char **argv) int prefix_length = -1; int no_more_flags = 0; + git_config(git_default_config); + for (i = 1 ; i < argc; i++) { if (!no_more_flags && argv[i][0] == '-') { if (!strcmp(argv[i], "-t")) { diff --git a/index-pack.c b/index-pack.c index db58e05041..c232e3fc78 100644 --- a/index-pack.c +++ b/index-pack.c @@ -254,7 +254,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_ static void *get_data_from_pack(struct object_entry *obj) { - unsigned long from = obj[0].idx.offset + obj[0].hdr_size; + off_t from = obj[0].idx.offset + obj[0].hdr_size; unsigned long len = obj[1].idx.offset - from; unsigned long rdy = 0; unsigned char *src, *data; diff --git a/list-objects.c b/list-objects.c index e5c88c278f..4ef58e7ec0 100644 --- a/list-objects.c +++ b/list-objects.c @@ -170,4 +170,11 @@ void traverse_commit_list(struct rev_info *revs, } for (i = 0; i < objects.nr; i++) show_object(&objects.objects[i]); + free(objects.objects); + if (revs->pending.nr) { + free(revs->pending.objects); + revs->pending.nr = 0; + revs->pending.alloc = 0; + revs->pending.objects = NULL; + } } diff --git a/perl/Git.pm b/perl/Git.pm index 3f4080cbf8..dca92c8adb 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -812,7 +812,7 @@ sub _cmd_exec { $self->wc_subdir() and chdir($self->wc_subdir()); } _execv_git_cmd(@args); - die "exec failed: $!"; + die qq[exec "@args" failed: $!]; } # Execute the given Git command ($_[0]) with arguments ($_[1..]) diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index ce045b2a57..a90824ba8a 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -205,7 +205,7 @@ test_expect_success \ echo $h_TEST >.git/MERGE_HEAD && GIT_AUTHOR_DATE="2005-05-26 23:45" \ GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M && - h_MERGED=$(git rev-parse --verify HEAD) + h_MERGED=$(git rev-parse --verify HEAD) && rm -f M' cat >expect <<EOF diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 6c92d61192..984146b5c2 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -149,7 +149,7 @@ test_expect_success 'stop on conflicting pick' ' diff -u expect .git/.dotest-merge/patch && diff -u expect2 file1 && test 4 = $(grep -v "^#" < .git/.dotest-merge/done | wc -l) && - test 0 = $(grep -v "^#" < .git/.dotest-merge/todo | wc -l) + test 0 = $(grep -v "^#" < .git/.dotest-merge/git-rebase-todo | wc -l) ' test_expect_success 'abort' ' diff --git a/t/t3700-add.sh b/t/t3700-add.sh index a328bf57eb..287e058e37 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -104,9 +104,33 @@ test_expect_success 'add ignored ones with -f' ' git ls-files --error-unmatch d.ig/d.if d.ig/d.ig ' +test_expect_success 'add ignored ones with -f' ' + rm -f .git/index && + git add -f d.?? && + git ls-files --error-unmatch d.ig/d.if d.ig/d.ig +' + +test_expect_success '.gitignore with subdirectory' ' + + rm -f .git/index && + mkdir -p sub/dir && + echo "!dir/a.*" >sub/.gitignore && + >sub/a.ig && + >sub/dir/a.ig && + git add sub/dir && + git ls-files --error-unmatch sub/dir/a.ig && + rm -f .git/index && + ( + cd sub/dir && + git add . + ) && + git ls-files --error-unmatch sub/dir/a.ig +' + mkdir 1 1/2 1/3 touch 1/2/a 1/3/b 1/2/c test_expect_success 'check correct prefix detection' ' + rm -f .git/index && git add 1/2/a 1/3/b 1/2/c ' diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index f9db81d3ab..f9db81d3ab 100644..100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 439430f569..7406de35ae 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -153,4 +153,17 @@ test_expect_success 'bundle should be able to create a full history' ' ' +test_expect_success 'bundle should record HEAD correctly' ' + + cd "$D" && + git bundle create bundle5 HEAD master && + git bundle list-heads bundle5 >actual && + for h in HEAD refs/heads/master + do + echo "$(git rev-parse --verify $h) $h" + done >expect && + diff -u expect actual + +' + test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index eb0847afe9..0ed4ae2827 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -177,4 +177,15 @@ test_expect_success 'clean.requireForce and -f' ' ' +test_expect_success 'core.excludesfile' ' + + echo excludes >excludes && + echo included >included && + git config core.excludesfile excludes && + output=$(git clean -n excludes included 2>&1) && + expr "$output" : ".*included" >/dev/null && + ! expr "$output" : ".*excludes" >/dev/null + +' + test_done diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 7f25689bb7..7f25689bb7 100644..100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index 622ea1c0df..02c41697de 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -48,7 +48,7 @@ EOF printf "\r\n" > empty_crlf a_empty_crlf=`git-hash-object -w empty_crlf` - svn import -m 'import for git-svn' . "$svnrepo" >/dev/null + svn import --no-auto-props -m 'import for git-svn' . "$svnrepo" >/dev/null cd .. rm -rf import diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh index 7eff4cdc05..d59acc8d1a 100755 --- a/t/t9106-git-svn-dcommit-clobber-series.sh +++ b/t/t9106-git-svn-dcommit-clobber-series.sh @@ -53,4 +53,10 @@ test_expect_success 'change file but in unrelated area' " test x\"\`sed -n -e 61p < file\`\" = x6611 " +test_expect_failure 'attempt to dcommit with a dirty index' ' + echo foo >>file && + git add file && + git svn dcommit +' + test_done diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit index 18b87309f6..8b057be304 100644 --- a/templates/hooks--pre-commit +++ b/templates/hooks--pre-commit @@ -13,7 +13,7 @@ if git-rev-parse --verify HEAD 2>/dev/null then - git-diff-index -p -M --cached HEAD + git-diff-index -p -M --cached HEAD -- else # NEEDSWORK: we should produce a diff with an empty tree here # if we want to do the same verification for the initial import. @@ -7,9 +7,9 @@ static void report(const char *prefix, const char *err, va_list params) { - fputs(prefix, stderr); - vfprintf(stderr, err, params); - fputs("\n", stderr); + char msg[256]; + vsnprintf(msg, sizeof(msg), err, params); + fprintf(stderr, "%s%s\n", prefix, msg); } static NORETURN void usage_builtin(const char *err) diff --git a/wt-status.c b/wt-status.c index 10ce6eedc7..58dd716a4e 100644 --- a/wt-status.c +++ b/wt-status.c @@ -22,7 +22,6 @@ static const char use_add_rm_msg[] = "use \"git add/rm <file>...\" to update what will be committed"; static const char use_add_to_include_msg[] = "use \"git add <file>...\" to include in what will be committed"; -static const char *excludes_file; static int parse_status_slot(const char *var, int offset) { @@ -247,22 +246,16 @@ static void wt_status_print_changed(struct wt_status *s) static void wt_status_print_untracked(struct wt_status *s) { struct dir_struct dir; - const char *x; int i; int shown_header = 0; memset(&dir, 0, sizeof(dir)); - dir.exclude_per_dir = ".gitignore"; if (!s->untracked) { dir.show_other_directories = 1; dir.hide_empty_directories = 1; } - x = git_path("info/exclude"); - if (file_exists(x)) - add_excludes_from_file(&dir, x); - if (excludes_file && file_exists(excludes_file)) - add_excludes_from_file(&dir, excludes_file); + setup_standard_excludes(&dir); read_directory(&dir, ".", "", 0, NULL); for(i = 0; i < dir.nr; i++) { @@ -360,11 +353,5 @@ int git_status_config(const char *k, const char *v) int slot = parse_status_slot(k, 13); color_parse(v, k, wt_status_colors[slot]); } - if (!strcmp(k, "core.excludesfile")) { - if (!v) - die("core.excludesfile without value"); - excludes_file = xstrdup(v); - return 0; - } return git_default_config(k, v); } |