Merge branch 'np/pack'
authorJunio C Hamano <junkio@cox.net>
Sat, 2 Jun 2007 19:18:56 +0000 (12:18 -0700)
committerJunio C Hamano <junkio@cox.net>
Sat, 2 Jun 2007 19:18:56 +0000 (12:18 -0700)
* np/pack:
fix repack with --max-pack-size
builtin-pack-object: cache small deltas
git-pack-objects: cache small deltas between big objects
builtin-pack-objects: don't fail, if delta is not possible

27 files changed:
.mailmap
Documentation/Makefile
Documentation/asciidoc.conf
Documentation/config.txt
Documentation/git-am.txt
Documentation/git-config.txt
Documentation/git-gc.txt
Documentation/git-ls-files.txt
Documentation/git-read-tree.txt
Documentation/git-status.txt
Documentation/gitignore.txt [new file with mode: 0644]
Documentation/repository-layout.txt
Documentation/user-manual.txt
Makefile
base85.c
builtin-count-objects.c
builtin-fsck.c
cache.h
commit.c
diff-delta.c
git-rebase.sh
pack-check.c
pack-redundant.c
sha1_file.c
sha1_name.c
t/t3901-i18n-patch.sh
t/t6101-rev-parse-parents.sh
index 4e0615e9beb06928e9440e3dd60014cc265f9ee5..aa8ee6b3f1671bbc3a07af7be544c4f83d0d7b1b 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -7,6 +7,8 @@
 
 Aneesh Kumar K.V <aneesh.kumar@gmail.com>
 Chris Shoemaker <c.shoemaker@cox.net>
+Dana L. How <danahow@gmail.com>
+Dana L. How <how@deathvalley.cswitch.com>
 Daniel Barkalow <barkalow@iabervon.org>
 David Kågedal <davidk@lysator.liu.se>
 Fredrik Kuivinen <freku045@student.liu.se>
@@ -19,8 +21,8 @@ Jon Loeliger <jdl@freescale.com>
 Jon Seymour <jon@blackcubes.dyndns.org>
 Karl Hasselström <kha@treskal.com>
 Kent Engstrom <kent@lysator.liu.se>
-Lars Doelle <lars.doelle@on-line.de>
 Lars Doelle <lars.doelle@on-line ! de>
+Lars Doelle <lars.doelle@on-line.de>
 Lukas Sandström <lukass@etek.chalmers.se>
 Martin Langhoff <martin@catalyst.net.nz>
 Michele Ballabio <barra_cuda@katamail.com>
@@ -34,12 +36,11 @@ Sean Estabrooks <seanlkml@sympatico.ca>
 Shawn O. Pearce <spearce@spearce.org>
 Theodore Ts'o <tytso@mit.edu>
 Tony Luck <tony.luck@intel.com>
-Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
 Uwe Kleine-König <Uwe_Zeisberger@digi.com>
-Uwe Kleine-König <uzeisberger@io.fsforth.de>
 Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
+Uwe Kleine-König <uzeisberger@io.fsforth.de>
+Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
 Ville Skyttä <scop@xemacs.org>
 YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
 anonymous <linux@horizon.com>
 anonymous <linux@horizon.net>
-Dana L. How <how@deathvalley.cswitch.com>
index 3f92783d55b401a5c919f7c9176a12953d0c4904..9cef4806d1a51bac670ebe192a4482fde95c9013 100644 (file)
@@ -2,7 +2,7 @@ MAN1_TXT= \
        $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
                $(wildcard git-*.txt)) \
        gitk.txt
-MAN5_TXT=gitattributes.txt
+MAN5_TXT=gitattributes.txt gitignore.txt
 MAN7_TXT=git.txt
 
 DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT))
@@ -112,8 +112,7 @@ clean:
 %.html : %.txt
        rm -f $@+ $@
        $(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \
-               $(ASCIIDOC_EXTRA) -o - $< | \
-               sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' >$@+
+               $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $<
        mv $@+ $@
 
 %.1 %.5 %.7 : %.xml
@@ -122,8 +121,7 @@ clean:
 %.xml : %.txt
        rm -f $@+ $@
        $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
-               $(ASCIIDOC_EXTRA) -o - $< | \
-               sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' >$@+
+               $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $<
        mv $@+ $@
 
 user-manual.xml: user-manual.txt user-manual.conf
index fa7dc94845be148dd85dfc2265dade2093a6c11f..60e15ba3494b93f2c956356d3d5fd905385d0c1f 100644 (file)
@@ -40,7 +40,7 @@ template::[header-declarations]
 <refentrytitle>{mantitle}</refentrytitle>
 <manvolnum>{manvolnum}</manvolnum>
 <refmiscinfo class="source">Git</refmiscinfo>
-<refmiscinfo class="version">@@GIT_VERSION@@</refmiscinfo>
+<refmiscinfo class="version">{git_version}</refmiscinfo>
 <refmiscinfo class="manual">Git Manual</refmiscinfo>
 </refmeta>
 <refnamediv>
index 6ea4f10150ee4034e4c24752a444ef324506ea69..5868d587a905e0aaa55194c7716f9e258a030474 100644 (file)
@@ -259,7 +259,8 @@ Common unit suffixes of 'k', 'm', or 'g' are supported.
 core.excludeFile::
        In addition to '.gitignore' (per-directory) and
        '.git/info/exclude', git looks into this file for patterns
-       of files which are not meant to be tracked.
+       of files which are not meant to be tracked.  See
+       gitlink:gitignore[5].
 
 alias.*::
        Command aliases for the gitlink:git[1] command wrapper - e.g.
index 25cf84a0c724c262fada98cdad27fb3cf705841a..f78e5dc28d7a641a2c6db93ba74d95e45d175dd0 100644 (file)
@@ -13,7 +13,6 @@ SYNOPSIS
          [--3way] [--interactive] [--binary]
          [--whitespace=<option>] [-C<n>] [-p<n>]
          <mbox>|<Maildir>...
-
 'git-am' [--skip | --resolved]
 
 DESCRIPTION
index 827a49970d77cc1af431e673323510bb94e0a391..056b14724c4058ce7443264303713bbdc899f04c 100644 (file)
@@ -31,7 +31,7 @@ If you want to update or unset an option which can occur on multiple
 lines, a POSIX regexp `value_regex` needs to be given.  Only the
 existing values that match the regexp are updated or unset.  If
 you want to handle the lines that do *not* match the regex, just
-prepend a single exclamation mark in front (see EXAMPLES).
+prepend a single exclamation mark in front (see also <<EXAMPLES>>).
 
 The type specifier can be either '--int' or '--bool', which will make
 'git-config' ensure that the variable(s) are of the given type and
@@ -48,7 +48,7 @@ This command will fail if:
 . the section or key is invalid,
 . you try to unset an option which does not exist,
 . you try to unset/set an option for which multiple lines match, or
-. you use --global option without $HOME being properly set.
+. you use '--global' option without $HOME being properly set.
 
 
 OPTIONS
@@ -75,11 +75,22 @@ OPTIONS
        Like --get-all, but interprets the name as a regular expression.
 
 --global::
-       Use global ~/.gitconfig file rather than the repository .git/config.
+       For writing options: write to global ~/.gitconfig file rather than
+       the repository .git/config.
++
+For reading options: read only from global ~/.gitconfig rather than
+from all available files.
++
+See also <<FILES>>.
 
 --system::
-       Use system-wide $(prefix)/etc/gitconfig rather than the repository
-       .git/config.
+       For writing options: write to system-wide $(prefix)/etc/gitconfig
+       rather than the repository .git/config.
++
+For reading options: read only from system-wide $(prefix)/etc/gitconfig
+rather than from all available files.
++
+See also <<FILES>>.
 
 --remove-section::
        Remove the given section from the configuration file.
@@ -106,21 +117,64 @@ OPTIONS
        by 1024, 1048576, or 1073741824 prior to output.
 
 
+[[FILES]]
+FILES
+-----
+
+There are three files where git-config will search for configuration
+options:
+
+.git/config::
+       Repository specific configuration file. (The filename is
+       of course relative to the repository root, not the working
+       directory.)
+
+~/.gitconfig::
+       User-specific configuration file. Also called "global"
+       configuration file.
+
+$(prefix)/etc/gitconfig::
+       System-wide configuration file.
+
+If no further options are given, all reading options will read all of these
+files that are available. If the global or the system-wide configuration
+file are not available they will be ignored. If the repository configuration
+file is not available or readable, git-config will exit with a non-zero
+error code. However, in neither case will an error message be issued.
+
+All writing options will per default write to the repository specific
+configuration file. Note that this also affects options like '--replace-all'
+and '--unset'. *git-config will only ever change one file at a time*.
+
+You can override these rules either by command line options or by environment
+variables. The '--global' and the '--system' options will limit the file used
+to the global or system-wide file respectively. The GIT_CONFIG environment
+variable has a similar effect, but you can specify any filename you want.
+
+The GIT_CONFIG_LOCAL environment variable on the other hand only changes
+the name used instead of the repository configuration file. The global and
+the system-wide configuration files will still be read. (For writing options
+this will obviously result in the same behavior as using GIT_CONFIG.)
+
+
 ENVIRONMENT
 -----------
 
 GIT_CONFIG::
        Take the configuration from the given file instead of .git/config.
-       Using the "--global" option forces this to ~/.gitconfig.
+       Using the "--global" option forces this to ~/.gitconfig. Using the
+       "--system" option forces this to $(prefix)/etc/gitconfig.
 
 GIT_CONFIG_LOCAL::
-       Currently the same as $GIT_CONFIG; when Git will support global
-       configuration files, this will cause it to take the configuration
-       from the global configuration file in addition to the given file.
+       Take the configuration from the given file instead if .git/config.
+       Still read the global and the system-wide configuration files, though.
 
+See also <<FILES>>.
 
-EXAMPLE
--------
+
+[[EXAMPLES]]
+EXAMPLES
+--------
 
 Given a .git/config like this:
 
index 4ac839f938f9c2617c211dd829ba910577534558..c7742ca9630b13d1eeef16d175f8ca840ddff4b0 100644 (file)
@@ -37,10 +37,10 @@ OPTIONS
 
 --aggressive::
        Usually 'git-gc' runs very quickly while providing good disk
-       space utilization and performance.   This option will cause
-       git-gc to more aggressive optimize the repository at the expense
+       space utilization and performance.  This option will cause
+       git-gc to more aggressively optimize the repository at the expense
        of taking much more time.  The effects of this optimization are
-       persistent, so this option only needs to be sporadically; every
+       persistent, so this option only needs to be used occasionally; every
        few hundred changesets or so.
 
 Configuration
index 43e0d2266c04e6039095dbee709d736275b02838..a78a9ff1b85d1c8cf003ddab63b8412cf3083657 100644 (file)
@@ -139,46 +139,24 @@ Exclude Patterns
 
 'git-ls-files' can use a list of "exclude patterns" when
 traversing the directory tree and finding files to show when the
-flags --others or --ignored are specified.
+flags --others or --ignored are specified.  gitlink:gitignore[5]
+specifies the format of exclude patterns.
 
-These exclude patterns come from these places:
+These exclude patterns come from these places, in order:
 
-  1. command line flag --exclude=<pattern> specifies a single
-     pattern.
+  1. The command line flag --exclude=<pattern> specifies a
+     single pattern.  Patterns are ordered in the same order
+     they appear in the command line.
 
-  2. command line flag --exclude-from=<file> specifies a list of
-     patterns stored in a file.
+  2. The command line flag --exclude-from=<file> specifies a
+     file containing a list of patterns.  Patterns are ordered
+     in the same order they appear in the file.
 
   3. command line flag --exclude-per-directory=<name> specifies
      a name of the file in each directory 'git-ls-files'
-     examines, and if exists, its contents are used as an
-     additional list of patterns.
-
-An exclude pattern file used by (2) and (3) contains one pattern
-per line.  A line that starts with a '#' can be used as comment
-for readability.
-
-There are three lists of patterns that are in effect at a given
-time.  They are built and ordered in the following way:
-
- * --exclude=<pattern> from the command line; patterns are
-   ordered in the same order as they appear on the command line.
-
- * lines read from --exclude-from=<file>; patterns are ordered
-   in the same order as they appear in the file.
-
- * When --exclude-per-directory=<name> is specified, upon
-   entering a directory that has such a file, its contents are
-   appended at the end of the current "list of patterns".  They
-   are popped off when leaving the directory.
-
-Each pattern in the pattern list specifies "a match pattern" and
-optionally the fate; either a file that matches the pattern is
-considered excluded or included.  A filename is matched against
-the patterns in the three lists; the --exclude-from list is
-checked first, then the --exclude-per-directory list, and then
-finally the --exclude list. The last match determines its fate.
-If there is no match in the three lists, the fate is "included".
+     examines, normally `.gitignore`.  Files in deeper
+     directories take precedence.  Patterns are ordered in the
+     same order they appear in the files.
 
 A pattern specified on the command line with --exclude or read
 from the file specified with --exclude-from is relative to the
@@ -186,58 +164,9 @@ top of the directory tree.  A pattern read from a file specified
 by --exclude-per-directory is relative to the directory that the
 pattern file appears in.
 
-An exclude pattern is of the following format:
-
- - an optional prefix '!' which means that the fate this pattern
-   specifies is "include", not the usual "exclude"; the
-   remainder of the pattern string is interpreted according to
-   the following rules.
-
- - if it does not contain a slash '/', it is a shell glob
-   pattern and used to match against the filename without
-   leading directories.
-
- - otherwise, it is a shell glob pattern, suitable for
-   consumption by fnmatch(3) with FNM_PATHNAME flag.  I.e. a
-   slash in the pattern must match a slash in the pathname.
-   "Documentation/\*.html" matches "Documentation/git.html" but
-   not "ppc/ppc.html".  As a natural exception, "/*.c" matches
-   "cat-file.c" but not "mozilla-sha1/sha1.c".
-
-An example:
-
---------------------------------------------------------------
-    $ cat .git/info/exclude
-    # ignore objects and archives, anywhere in the tree.
-    *.[oa]
-    $ cat Documentation/.gitignore
-    # ignore generated html files,
-    *.html
-    # except foo.html which is maintained by hand
-    !foo.html
-    $ git-ls-files --ignored \
-        --exclude='Documentation/*.[0-9]' \
-        --exclude-from=.git/info/exclude \
-        --exclude-per-directory=.gitignore
---------------------------------------------------------------
-
-Another example:
-
---------------------------------------------------------------
-    $ cat .gitignore
-    vmlinux*
-    $ ls arch/foo/kernel/vm*
-    arch/foo/kernel/vmlinux.lds.S
-    $ echo '!/vmlinux*' >arch/foo/kernel/.gitignore
---------------------------------------------------------------
-
-The second .gitignore keeps `arch/foo/kernel/vmlinux.lds.S` file
-from getting ignored.
-
-
 See Also
 --------
-gitlink:git-read-tree[1]
+gitlink:git-read-tree[1], gitlink:gitignore[5]
 
 
 Author
@@ -246,7 +175,7 @@ Written by Linus Torvalds <torvalds@osdl.org>
 
 Documentation
 --------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
+Documentation by David Greaves, Junio C Hamano, Josh Triplett, and the git-list <git@vger.kernel.org>.
 
 GIT
 ---
index 019c8bef7af2868af150b4a13472b8ce26744ea3..acb57447a864a54b3b531b7ef7403563fd20f886 100644 (file)
@@ -341,7 +341,8 @@ have finished your work-in-progress), attempt the merge again.
 
 See Also
 --------
-gitlink:git-write-tree[1]; gitlink:git-ls-files[1]
+gitlink:git-write-tree[1]; gitlink:git-ls-files[1];
+gitlink:gitignore[5]
 
 
 Author
index d7015387b51d88f6bd6e3918b2bd40c4e9529f15..1fd1af102ae948ca008bbd35675d859340e46dbd 100644 (file)
@@ -42,11 +42,9 @@ mean the same thing and the latter is kept for backward
 compatibility) and `color.status.<slot>` configuration variables
 to colorize its output.
 
-As for gitlink:git-add[1], the configuration variable
-'core.excludesfile' can indicate a path to a file containing patterns
-of file names to exclude, in addition to patterns given in
-'info/exclude' and '.gitignore'.
-
+See Also
+--------
+gitlink:gitignore[5]
 
 Author
 ------
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
new file mode 100644 (file)
index 0000000..ea79d74
--- /dev/null
@@ -0,0 +1,116 @@
+gitignore(5)
+============
+
+NAME
+----
+gitignore - Specifies intentionally untracked files to ignore
+
+SYNOPSIS
+--------
+$GIT_DIR/info/exclude, .gitignore
+
+DESCRIPTION
+-----------
+
+A `gitignore` file specifies intentionally untracked files that
+git should ignore.  Each line in a `gitignore` file specifies a
+pattern.
+
+When deciding whether to ignore a path, git normally checks
+`gitignore` patterns from multiple sources, with the following
+order of precedence:
+
+ * Patterns read from the file specified by the configuration
+   variable 'core.excludesfile'.
+
+ * Patterns read from `$GIT_DIR/info/exclude`.
+
+ * Patterns read from a `.gitignore` file in the same directory
+   as the path, or in any parent directory, ordered from the
+   deepest such file to a file in the root of the repository.
+   These patterns match relative to the location of the
+   `.gitignore` file.  A project normally includes such
+   `.gitignore` files in its repository, containing patterns for
+   files generated as part of the project build.
+
+The underlying git plumbing tools, such as
+gitlink:git-ls-files[1] and gitlink:git-read-tree[1], read
+`gitignore` patterns specified by command-line options, or from
+files specified by command-line options.  Higher-level git
+tools, such as gitlink:git-status[1] and gitlink:git-add[1],
+use patterns from the sources specified above.
+
+Patterns have the following format:
+
+ - A blank line matches no files, so it can serve as a separator
+   for readability.
+
+ - A line starting with # serves as a comment.
+
+ - An optional prefix '!' which negates the pattern; any
+   matching file excluded by a previous pattern will become
+   included again.
+
+ - If the pattern does not contain a slash '/', git treats it as
+   a shell glob pattern and checks for a match against the
+   pathname without leading directories.
+
+ - Otherwise, git treats the pattern as a shell glob suitable
+   for consumption by fnmatch(3) with the FNM_PATHNAME flag:
+   wildcards in the pattern will not match a / in the pathname.
+   For example, "Documentation/\*.html" matches
+   "Documentation/git.html" but not
+   "Documentation/ppc/ppc.html".  A leading slash matches the
+   beginning of the pathname; for example, "/*.c" matches
+   "cat-file.c" but not "mozilla-sha1/sha1.c".
+
+An example:
+
+--------------------------------------------------------------
+    $ git-status
+    [...]
+    # Untracked files:
+    [...]
+    #       Documentation/foo.html
+    #       Documentation/gitignore.html
+    #       file.o
+    #       lib.a
+    #       src/internal.o
+    [...]
+    $ cat .git/info/exclude
+    # ignore objects and archives, anywhere in the tree.
+    *.[oa]
+    $ cat Documentation/.gitignore
+    # ignore generated html files,
+    *.html
+    # except foo.html which is maintained by hand
+    !foo.html
+    $ git-status
+    [...]
+    # Untracked files:
+    [...]
+    #       Documentation/foo.html
+    [...]
+--------------------------------------------------------------
+
+Another example:
+
+--------------------------------------------------------------
+    $ cat .gitignore
+    vmlinux*
+    $ ls arch/foo/kernel/vm*
+    arch/foo/kernel/vmlinux.lds.S
+    $ echo '!/vmlinux*' >arch/foo/kernel/.gitignore
+--------------------------------------------------------------
+
+The second .gitignore prevents git from ignoring
+`arch/foo/kernel/vmlinux.lds.S`.
+
+Documentation
+-------------
+Documentation by David Greaves, Junio C Hamano, Josh Triplett,
+Frank Lichtenheld, and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
index 0459bd9ca1732beec1150e4354f1a03eafd53fe4..15221b53206eb65072f147ac72f556d0a1ee55e4 100644 (file)
@@ -155,8 +155,7 @@ info/exclude::
        exclude pattern list. `.gitignore` is the per-directory
        ignore file.  `git status`, `git add`, `git rm` and `git
        clean` look at it but the core git commands do not look
-       at it.  See also: gitlink:git-ls-files[1] `--exclude-from`
-       and `--exclude-per-directory`.
+       at it.  See also: gitlink:gitignore[5].
 
 remotes::
        Stores shorthands to be used to give URL and default
index 4fabb8e2a9e601c82b55ac25b1b9d8cfb9a06d3a..7eaafa80e9dde9d90c1eca1f760c7ade599f8250 100644 (file)
@@ -1103,12 +1103,12 @@ showing up in the output of "`git status`", etc.
 
 Git therefore provides "exclude patterns" for telling git which files to
 actively ignore. Exclude patterns are thoroughly explained in the
-"Exclude Patterns" section of the gitlink:git-ls-files[1] manual page,
-but the heart of the concept is simply a list of files which git should
-ignore. Entries in the list may contain globs to specify multiple files,
-or may be prefixed by "`!`" to explicitly include (un-ignore) a previously
-excluded (ignored) file (i.e. later exclude patterns override earlier ones).
-The following example should illustrate such patterns:
+gitlink:gitignore[5] manual page, but the heart of the concept is simply
+a list of files which git should ignore. Entries in the list may contain
+globs to specify multiple files, or may be prefixed by "`!`" to
+explicitly include (un-ignore) a previously excluded (ignored) file
+(i.e. later exclude patterns override earlier ones).  The following
+example should illustrate such patterns:
 
 -------------------------------------------------
 # Lines starting with '#' are considered comments.
index 75277343f6f69931bfa008d69032734e2e2d0c8d..cac0a4a2edc074d45d69665a68f23b9260847743 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -942,7 +942,7 @@ endif
 
 ### Testing rules
 
-TEST_PROGRAMS = test-chmtime$X test-genrandom$X
+TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X
 
 all:: $(TEST_PROGRAMS)
 
@@ -955,26 +955,12 @@ export NO_SVN_TESTS
 test: all
        $(MAKE) -C t/ all
 
-test-date$X: test-date.c date.o ctype.o
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) test-date.c date.o ctype.o
+test-date$X: date.o ctype.o
 
-test-delta$X: test-delta.o diff-delta.o patch-delta.o $(GITLIBS)
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
+test-delta$X: diff-delta.o patch-delta.o
 
-test-dump-cache-tree$X: dump-cache-tree.o $(GITLIBS)
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-test-sha1$X: test-sha1.o $(GITLIBS)
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-test-match-trees$X: test-match-trees.o $(GITLIBS)
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-test-chmtime$X: test-chmtime.c
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $<
-
-test-genrandom$X: test-genrandom.c
-       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $<
+test-%$X: test-%.o $(GITLIBS)
+       $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
 
 check-sha1:: test-sha1$X
        ./test-sha1.sh
index a6c41d597ab8eccb5eb2ccf2b3b543398c360b44..b88270f90844095b3d352cc4213cbebd95a7f420 100644 (file)
--- a/base85.c
+++ b/base85.c
@@ -66,7 +66,7 @@ int decode_85(char *dst, const char *buffer, int len)
                 */
                if (0x03030303 < acc ||
                    0xffffffff - de < (acc *= 85))
-                       error("invalid base85 sequence %.5s", buffer-5);
+                       return error("invalid base85 sequence %.5s", buffer-5);
                acc += de;
                say1(" %08x", acc);
 
index ff90ebd465002882781507ecfcfc33cab2f759fc..4274ec19500953bd7b6775e6d66271e9e116fa86 100644 (file)
@@ -111,6 +111,8 @@ int cmd_count_objects(int ac, const char **av, const char *prefix)
                for (p = packed_git; p; p = p->next) {
                        if (!p->pack_local)
                                continue;
+                       if (open_pack_index(p))
+                               continue;
                        packed += p->num_objects;
                        num_pack++;
                }
index cbbcaf011a09d1dd9b3f2a01d18e1ab93e26fd3b..9959818ceddf52ec24d9b24b0cade558f4d43070 100644 (file)
@@ -668,7 +668,10 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
                        verify_pack(p, 0);
 
                for (p = packed_git; p; p = p->next) {
-                       uint32_t i, num = p->num_objects;
+                       uint32_t i, num;
+                       if (open_pack_index(p))
+                               continue;
+                       num = p->num_objects;
                        for (i = 0; i < num; i++)
                                fsck_sha1(nth_packed_object_sha1(p, i));
                }
diff --git a/cache.h b/cache.h
index ec85d93e0d39a3c55c9579c734401b80331aa19a..8a9d1f3883150fd40ac1b6c0a44fa896c3133b04 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -359,8 +359,8 @@ extern void *map_sha1_file(const unsigned char *sha1, unsigned long *);
 extern int has_pack_file(const unsigned char *sha1);
 extern int has_pack_index(const unsigned char *sha1);
 
-extern signed char hexval_table[256];
-static inline unsigned int hexval(unsigned int c)
+extern const signed char hexval_table[256];
+static inline unsigned int hexval(unsigned char c)
 {
        return hexval_table[c];
 }
@@ -483,10 +483,11 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
                                         struct packed_git *packs);
 
 extern void pack_report(void);
+extern int open_pack_index(struct packed_git *);
 extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
 extern void unuse_pack(struct pack_window **);
 extern struct packed_git *add_packed_git(const char *, int, int);
-extern const unsigned char *nth_packed_object_sha1(const struct packed_git *, uint32_t);
+extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
 extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
 extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
 extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
index bee066fa3227c876022424bd0e6238c1053e1231..5632e32685478dcce34e479e8e916b0ccd3a3b13 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -511,12 +511,16 @@ static int add_rfc2047(char *buf, const char *line, int len,
        bp += i;
        for (i = 0; i < len; i++) {
                unsigned ch = line[i] & 0xFF;
-               if (is_rfc2047_special(ch)) {
+               /*
+                * We encode ' ' using '=20' even though rfc2047
+                * allows using '_' for readability.  Unfortunately,
+                * many programs do not understand this and just
+                * leave the underscore in place.
+                */
+               if (is_rfc2047_special(ch) || ch == ' ') {
                        sprintf(bp, "=%02X", ch);
                        bp += 3;
                }
-               else if (ch == ' ')
-                       *bp++ = '_';
                else
                        *bp++ = ch;
        }
index 17757d2af9576f4a340c5dbd62d30b597140ddba..faf96e47130e3a2af26f55fc1173874f078617fc 100644 (file)
@@ -388,7 +388,7 @@ create_delta(const struct delta_index *index,
                                outsize = max_size + MAX_OP_SIZE + 1;
                        if (max_size && outpos > max_size)
                                break;
-                       out = xrealloc(out, outsize);
+                       out = realloc(out, outsize);
                        if (!out) {
                                free(tmp);
                                return NULL;
index 61770b5a2837b9d69ffb1db455f39ffdb3c8ea00..2aa3a011dbe31e5167534a8bf443ff27dd96b38f 100755 (executable)
@@ -55,7 +55,7 @@ continue_merge () {
        if test -n "$unmerged"
        then
                echo "You still have unmerged paths in your index"
-               echo "did you forget update-index?"
+               echo "did you forget to use git add?"
                die "$RESOLVEMSG"
        fi
 
@@ -126,7 +126,7 @@ do
        --continue)
                git-diff-files --quiet || {
                        echo "You must edit all merge conflicts and then"
-                       echo "mark them as resolved using git update-index"
+                       echo "mark them as resolved using git add"
                        exit 1
                }
                if test -d "$dotest"
index c168642c0c0d9479b1ccc8564ce6c80c9055ab00..3623c716e3e3b7d4a28800e34afd0e5f0e13a43d 100644 (file)
@@ -128,12 +128,17 @@ static void show_pack_info(struct packed_git *p)
 
 int verify_pack(struct packed_git *p, int verbose)
 {
-       off_t index_size = p->index_size;
-       const unsigned char *index_base = p->index_data;
+       off_t index_size;
+       const unsigned char *index_base;
        SHA_CTX ctx;
        unsigned char sha1[20];
        int ret;
 
+       if (open_pack_index(p))
+               return error("packfile %s index not opened", p->pack_name);
+       index_size = p->index_size;
+       index_base = p->index_data;
+
        ret = 0;
        /* Verify SHA1 sum of the index file */
        SHA1_Init(&ctx);
index 87077e150c1b53a26464089a2cabafafb32e6636..6bc3bdf3f4c33f369c63acf9284ce9af18286184 100644 (file)
@@ -550,6 +550,9 @@ static struct pack_list * add_pack(struct packed_git *p)
        l.pack = p;
        llist_init(&l.all_objects);
 
+       if (open_pack_index(p))
+               return NULL;
+
        base = p->index_data;
        base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
        step = (p->index_version < 2) ? 24 : 20;
index 12d2ef201197d93885d0adacd43d9621950a8615..30bcd46ceb761b0f0b17295d532a6ddb5f33387a 100644 (file)
@@ -33,7 +33,7 @@ const unsigned char null_sha1[20];
 
 static unsigned int sha1_file_open_flag = O_NOATIME;
 
-signed char hexval_table[256] = {
+const signed char hexval_table[256] = {
         -1, -1, -1, -1, -1, -1, -1, -1,                /* 00-07 */
         -1, -1, -1, -1, -1, -1, -1, -1,                /* 08-0f */
         -1, -1, -1, -1, -1, -1, -1, -1,                /* 10-17 */
@@ -376,11 +376,12 @@ void prepare_alt_odb(void)
 {
        const char *alt;
 
+       if (alt_odb_tail)
+               return;
+
        alt = getenv(ALTERNATE_DB_ENVIRONMENT);
        if (!alt) alt = "";
 
-       if (alt_odb_tail)
-               return;
        alt_odb_tail = &alt_odb_list;
        link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);
 
@@ -530,6 +531,21 @@ static int check_packed_git_idx(const char *path,  struct packed_git *p)
        return 0;
 }
 
+int open_pack_index(struct packed_git *p)
+{
+       char *idx_name;
+       int ret;
+
+       if (p->index_data)
+               return 0;
+
+       idx_name = xstrdup(p->pack_name);
+       strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
+       ret = check_packed_git_idx(idx_name, p);
+       free(idx_name);
+       return ret;
+}
+
 static void scan_windows(struct packed_git *p,
        struct packed_git **lru_p,
        struct pack_window **lru_w,
@@ -605,6 +621,9 @@ static int open_packed_git_1(struct packed_git *p)
        unsigned char *idx_sha1;
        long fd_flag;
 
+       if (!p->index_data && open_pack_index(p))
+               return error("packfile %s index unavailable", p->pack_name);
+
        p->pack_fd = open(p->pack_name, O_RDONLY);
        if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
                return -1;
@@ -757,8 +776,7 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
                return NULL;
        memcpy(p->pack_name, path, path_len);
        strcpy(p->pack_name + path_len, ".pack");
-       if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode) ||
-           check_packed_git_idx(path, p)) {
+       if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
                free(p);
                return NULL;
        }
@@ -766,6 +784,10 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
        /* ok, it looks sane as far as we can check without
         * actually mapping the pack file.
         */
+       p->index_version = 0;
+       p->index_data = NULL;
+       p->index_size = 0;
+       p->num_objects = 0;
        p->pack_size = st.st_size;
        p->next = NULL;
        p->windows = NULL;
@@ -1572,10 +1594,15 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
        return data;
 }
 
-const unsigned char *nth_packed_object_sha1(const struct packed_git *p,
+const unsigned char *nth_packed_object_sha1(struct packed_git *p,
                                            uint32_t n)
 {
        const unsigned char *index = p->index_data;
+       if (!index) {
+               if (open_pack_index(p))
+                       return NULL;
+               index = p->index_data;
+       }
        if (n >= p->num_objects)
                return NULL;
        index += 4 * 256;
@@ -1612,6 +1639,12 @@ off_t find_pack_entry_one(const unsigned char *sha1,
        const unsigned char *index = p->index_data;
        unsigned hi, lo;
 
+       if (!index) {
+               if (open_pack_index(p))
+                       return 0;
+               level1_ofs = p->index_data;
+               index = p->index_data;
+       }
        if (p->index_version > 1) {
                level1_ofs += 2;
                index += 8;
@@ -1654,20 +1687,25 @@ static int matches_pack_name(struct packed_git *p, const char *ig)
 
 static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
 {
+       static struct packed_git *last_found = (void *)1;
        struct packed_git *p;
        off_t offset;
 
        prepare_packed_git();
+       if (!packed_git)
+               return 0;
+       p = (last_found == (void *)1) ? packed_git : last_found;
 
-       for (p = packed_git; p; p = p->next) {
+       do {
                if (ignore_packed) {
                        const char **ig;
                        for (ig = ignore_packed; *ig; ig++)
                                if (!matches_pack_name(p, *ig))
                                        break;
                        if (*ig)
-                               continue;
+                               goto next;
                }
+
                offset = find_pack_entry_one(sha1, p);
                if (offset) {
                        /*
@@ -1680,14 +1718,23 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, cons
                         */
                        if (p->pack_fd == -1 && open_packed_git(p)) {
                                error("packfile %s cannot be accessed", p->pack_name);
-                               continue;
+                               goto next;
                        }
                        e->offset = offset;
                        e->p = p;
                        hashcpy(e->sha1, sha1);
+                       last_found = p;
                        return 1;
                }
-       }
+
+               next:
+               if (p == last_found)
+                       p = packed_git;
+               else
+                       p = p->next;
+               if (p == last_found)
+                       p = p->next;
+       } while (p);
        return 0;
 }
 
index 55f25a2d3b49b1d565a9840b7dcfb2e22687cdd3..7df01af78805686572e32d5ade1460fc925a9a71 100644 (file)
@@ -76,8 +76,11 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
 
        prepare_packed_git();
        for (p = packed_git; p && found < 2; p = p->next) {
-               uint32_t num = p->num_objects;
-               uint32_t first = 0, last = num;
+               uint32_t num, last;
+               uint32_t first = 0;
+               open_pack_index(p);
+               num = p->num_objects;
+               last = num;
                while (first < last) {
                        uint32_t mid = (first + last) / 2;
                        const unsigned char *now;
@@ -133,6 +136,7 @@ static int find_unique_short_object(int len, char *canonical,
        int has_unpacked, has_packed;
        unsigned char unpacked_sha1[20], packed_sha1[20];
 
+       prepare_alt_odb();
        has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
        has_packed = find_short_packed_object(len, res, packed_sha1);
        if (!has_unpacked && !has_packed)
@@ -654,7 +658,6 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
        const char *cp;
 
        *mode = S_IFINVALID;
-       prepare_alt_odb();
        ret = get_sha1_1(name, namelen, sha1);
        if (!ret)
                return ret;
index a881797bc7b6679f2328405adc450a7840061896..24bf0ee0184bab6f3703f17f280e413041d2a686 100755 (executable)
@@ -13,7 +13,7 @@ check_encoding () {
        while test "$i" -le $cnt
        do
                git format-patch --encoding=UTF-8 --stdout HEAD~$i..HEAD~$j |
-               grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" &&
+               grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" &&
                git-cat-file commit HEAD~$j |
                case "$header" in
                8859)
@@ -73,9 +73,9 @@ test_expect_success 'format-patch output (ISO-8859-1)' '
        git format-patch --stdout master..HEAD^ >out-l1 &&
        git format-patch --stdout HEAD^ >out-l2 &&
        grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l1 &&
-       grep "^From: =?ISO-8859-1?q?=C1=E9=ED_=F3=FA?=" out-l1 &&
+       grep "^From: =?ISO-8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l1 &&
        grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l2 &&
-       grep "^From: =?ISO-8859-1?q?=C1=E9=ED_=F3=FA?=" out-l2
+       grep "^From: =?ISO-8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l2
 '
 
 test_expect_success 'format-patch output (UTF-8)' '
@@ -84,9 +84,9 @@ test_expect_success 'format-patch output (UTF-8)' '
        git format-patch --stdout master..HEAD^ >out-u1 &&
        git format-patch --stdout HEAD^ >out-u2 &&
        grep "^Content-Type: text/plain; charset=UTF-8" out-u1 &&
-       grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-u1 &&
+       grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" out-u1 &&
        grep "^Content-Type: text/plain; charset=UTF-8" out-u2 &&
-       grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-u2
+       grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" out-u2
 '
 
 test_expect_success 'rebase (U/U)' '
index 7d354a1fae774ca0e77e554dad827f1a9b781818..b0252b9413e5274d87f5437882be1fd625bc8bef 100755 (executable)
@@ -29,5 +29,15 @@ test_expect_success 'final^1^3 not valid' "if git-rev-parse --verify final^1^3;
 test_expect_failure '--verify start2^1' 'git-rev-parse --verify start2^1'
 test_expect_success '--verify start2^0' 'git-rev-parse --verify start2^0'
 
+test_expect_success 'repack for next test' 'git repack -a -d'
+test_expect_success 'short SHA-1 works' '
+       start=`git rev-parse --verify start` &&
+       echo $start &&
+       abbrv=`echo $start | sed s/.\$//` &&
+       echo $abbrv &&
+       abbrv=`git rev-parse --verify $abbrv` &&
+       echo $abbrv &&
+       test $start = $abbrv'
+
 test_done