Merge branch 'jk/no-more-self-assignment' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 12 Apr 2013 20:41:46 +0000 (13:41 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 12 Apr 2013 20:41:46 +0000 (13:41 -0700)
* jk/no-more-self-assignment:
match-trees: simplify score_trees() using tree_entry()
submodule: clarify logic in show_submodule_summary

177 files changed:
.mailmap
Documentation/CodingGuidelines
Documentation/RelNotes/1.8.1.6.txt [new file with mode: 0644]
Documentation/RelNotes/1.8.2.1.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/diff-options.txt
Documentation/git-archive.txt
Documentation/git-commit.txt
Documentation/git-credential.txt
Documentation/git-describe.txt
Documentation/git-filter-branch.txt
Documentation/git-merge.txt
Documentation/git-pull.txt
Documentation/git-push.txt
Documentation/git-remote-ext.txt
Documentation/git-status.txt
Documentation/git-svn.txt
Documentation/git-tag.txt
Documentation/git-tools.txt
Documentation/git-update-index.txt
Documentation/git.txt
Documentation/gitcli.txt
Documentation/githooks.txt
Documentation/merge-options.txt
Documentation/pretty-formats.txt
Documentation/revisions.txt
Documentation/technical/api-argv-array.txt
Documentation/technical/api-credentials.txt
Documentation/technical/api-ref-iteration.txt
Documentation/technical/index-format.txt
Documentation/technical/pack-format.txt
Documentation/user-manual.txt
GIT-VERSION-GEN
INSTALL
RelNotes
advice.c
advice.h
archive-zip.c
archive.c
attr.c
builtin/apply.c
builtin/branch.c
builtin/cat-file.c
builtin/commit.c
builtin/describe.c
builtin/fast-export.c
builtin/fmt-merge-msg.c
builtin/grep.c
builtin/index-pack.c
builtin/mailsplit.c
builtin/merge-tree.c
builtin/prune.c
builtin/reflog.c
builtin/tag.c
builtin/update-index.c
builtin/verify-tag.c
bundle.c
cache.h
commit.c
commit.h
compat/nedmalloc/malloc.c.h
compat/obstack.h
compat/precompose_utf8.c
compat/regex/regcomp.c
compat/regex/regex.c
compat/regex/regex_internal.c
contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
contrib/credential/osxkeychain/git-credential-osxkeychain.c
contrib/credential/wincred/git-credential-wincred.c
contrib/examples/git-remote.perl
contrib/examples/git-svnimport.perl
contrib/fast-import/git-import.perl
contrib/fast-import/git-import.sh
contrib/fast-import/import-zips.py
contrib/hooks/setgitperms.perl
contrib/mw-to-git/git-remote-mediawiki.perl
contrib/mw-to-git/git-remote-mediawiki.txt
contrib/mw-to-git/t/README
contrib/mw-to-git/t/install-wiki.sh
contrib/mw-to-git/t/install-wiki/LocalSettings.php
contrib/mw-to-git/t/t9362-mw-to-git-utf8.sh
contrib/remote-helpers/test-hg.sh
contrib/subtree/t/t7900-subtree.sh
daemon.c
diff.c
dir.c
entry.c
environment.c
fast-import.c
git-add--interactive.perl
git-archimport.perl
git-compat-util.h
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-merge-one-file.sh
git-quiltimport.sh
git-relink.perl
git-send-email.perl
git-sh-setup.sh
git-submodule.sh
git-svn.perl
git.c
gitweb/INSTALL
gitweb/gitweb.perl
gpg-interface.c
gpg-interface.h
graph.c
graph.h
imap-send.c
kwset.c
log-tree.c
name-hash.c
object.c
object.h
pack-refs.c
perl/Git.pm
perl/Git/I18N.pm
perl/private-Error.pm
po/README
pretty.c
reachable.c
read-cache.c
refs.c
revision.c
sequencer.c
setup.c
t/README
t/lib-git-svn.sh
t/t0024-crlf-archive.sh
t/t1006-cat-file.sh
t/t1509/prepare-chroot.sh
t/t1510-repo-setup.sh
t/t2003-checkout-cache-mkdir.sh
t/t3200-branch.sh
t/t3211-peel-ref.sh [new file with mode: 0755]
t/t3701-add-interactive.sh
t/t4001-diff-rename.sh
t/t4014-format-patch.sh
t/t4018-diff-funcname.sh
t/t4124-apply-ws-rule.sh
t/t5002-archive-attr-pattern.sh
t/t5003-archive-zip.sh
t/t5004-archive-corner-cases.sh [new file with mode: 0755]
t/t5004/empty.zip [new file with mode: 0644]
t/t5500-fetch-pack.sh
t/t5516-fetch-push.sh
t/t6009-rev-list-parent.sh
t/t6030-bisect-porcelain.sh
t/t7004-tag.sh
t/t7060-wtstatus.sh
t/t7062-wtstatus-ignorecase.sh [new file with mode: 0755]
t/t7406-submodule-update.sh
t/t7502-commit.sh
t/t7508-status.sh
t/t7512-status-help.sh
t/t7601-merge-pull-config.sh
t/t7610-mergetool.sh
t/t7811-grep-open.sh
t/t9001-send-email.sh
t/t9010-svn-fe.sh
t/t9300-fast-import.sh
t/test-lib.sh
templates/hooks--update.sample
test-chmtime.c
test-delta.c
test-genrandom.c
transport-helper.c
transport.c
transport.h
upload-pack.c
utf8.c
utf8.h
wt-status.c
wt-status.h
xdiff/xdiffi.c
xdiff/xhistogram.c
index c7e86183001a00ad2105765708b5b59852ef6640..48d7acf013c611d4885cddffdf516bb5d0ea5a86 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -73,6 +73,7 @@ Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
 <nico@fluxnic.net> <nico@cam.org>
 Peter Krefting <peter@softwolves.pp.se> <peter@svarten.intern.softwolves.pp.se>
 Peter Krefting <peter@softwolves.pp.se> <peter@softwolves.pp.se>
+Petr Baudis <pasky@ucw.cz> <pasky@suse.cz>
 Philippe Bruhat <book@cpan.org>
 Ralf Thielow <ralf.thielow@gmail.com> <ralf.thielow@googlemail.com>
 Ramsay Allan Jones <ramsay@ramsay1.demon.co.uk>
index b1bfff630fc0ec22d68757ebab84e76ee5abbc2c..7e4d5716a62bf59e8f072163ebac3064dad323ae 100644 (file)
@@ -237,6 +237,9 @@ For Python scripts:
 
 Writing Documentation:
 
+ Most (if not all) of the documentation pages are written in AsciiDoc
+ and processed into HTML output and manpages.
+
  Every user-visible change should be reflected in the documentation.
  The same general rule as for code applies -- imitate the existing
  conventions.  A few commented examples follow to provide reference
diff --git a/Documentation/RelNotes/1.8.1.6.txt b/Documentation/RelNotes/1.8.1.6.txt
new file mode 100644 (file)
index 0000000..c15cf2e
--- /dev/null
@@ -0,0 +1,39 @@
+Git 1.8.1.6 Release Notes
+=========================
+
+Fixes since v1.8.1.5
+--------------------
+
+ * An earlier change to the attribute system introduced at v1.8.1.2 by
+   mistake stopped a pattern "dir" (without trailing slash) from
+   matching a directory "dir" (it only wanted to allow pattern "dir/"
+   to also match).
+
+ * The code to keep track of what directory names are known to Git on
+   platforms with case insensitive filesystems can get confused upon a
+   hash collision between these pathnames and looped forever.
+
+ * When the "--prefix" option is used to "checkout-index", the code
+   did not pick the correct output filter based on the attribute
+   setting.
+
+ * Annotated tags outside refs/tags/ hierarchy were not advertised
+   correctly to the ls-remote and fetch with recent version of Git.
+
+ * The logic used by "git diff -M --stat" to shorten the names of
+   files before and after a rename did not work correctly when the
+   common prefix and suffix between the two filenames overlapped.
+
+ * "git update-index -h" did not do the usual "-h(elp)" thing.
+
+ * perl/Git.pm::cat_blob slurped everything in core only to write it
+   out to a file descriptor, which was not a very smart thing to do.
+
+ * The SSL peer verification done by "git imap-send" did not ask for
+   Server Name Indication (RFC 4366), failing to connect SSL/TLS
+   sites that serve multiple hostnames on a single IP.
+
+ * "git bundle verify" did not say "records a complete history" for a
+   bundle that does not have any prerequisites.
+
+Also contains various documentation fixes.
diff --git a/Documentation/RelNotes/1.8.2.1.txt b/Documentation/RelNotes/1.8.2.1.txt
new file mode 100644 (file)
index 0000000..1354ad0
--- /dev/null
@@ -0,0 +1,115 @@
+Git v1.8.2.1 Release Notes
+==========================
+
+Fixes since v1.8.2
+------------------
+
+ * An earlier change to the attribute system introduced at v1.8.1.2 by
+   mistake stopped a pattern "dir" (without trailing slash) from
+   matching a directory "dir" (it only wanted to allow pattern "dir/"
+   to also match).
+
+ * Verification of signed tags were not done correctly when not in C
+   or en/US locale.
+
+ * 'git commit -m "$msg"' used to add an extra newline even when
+   $msg already ended with one.
+
+ * The "--match=<pattern>" option of "git describe", when used with
+   "--all" to allow refs that are not annotated tags to be used as a
+   base of description, did not restrict the output from the command
+   to those that match the given pattern.
+
+ * An aliased command spawned from a bare repository that does not say
+   it is bare with "core.bare = yes" is treated as non-bare by mistake.
+
+ * When "format-patch" quoted a non-ascii strings on the header files,
+   it incorrectly applied rfc2047 and chopped a single character in
+   the middle of it.
+
+ * "git archive" reports a failure when asked to create an archive out
+   of an empty tree.  It would be more intuitive to give an empty
+   archive back in such a case.
+
+ * "git tag -f <tag>" always said "Updated tag '<tag>'" even when
+   creating a new tag (i.e. not overwriting nor updating).
+
+ * "git cmd -- ':(top'" was not diagnosed as an invalid syntax, and
+   instead the parser kept reading beyond the end of the string.
+
+ * Annotated tags outside refs/tags/ hierarchy were not advertised
+   correctly to the ls-remote and fetch with recent version of Git.
+
+ * The code to keep track of what directory names are known to Git on
+   platforms with case insensitive filesystems can get confused upon a
+   hash collision between these pathnames and looped forever.
+
+ * The logic used by "git diff -M --stat" to shorten the names of
+   files before and after a rename did not work correctly when the
+   common prefix and suffix between the two filenames overlapped.
+
+ * "git submodule update", when recursed into sub-submodules, did not
+   acccumulate the prefix paths.
+
+ * "git am $maildir/" applied messages in an unexpected order; sort
+   filenames read from the maildir/ in a way that is more likely to
+   sort messages in the order the writing MUA meant to, by sorting
+   numeric segment in numeric order and non-numeric segment in
+   alphabetical order.
+
+ * When export-subst is used, "zip" output recorded incorrect
+   size of the file.
+
+ * Some platforms and users spell UTF-8 differently; retry with the
+   most official "UTF-8" when the system does not understand the
+   user-supplied encoding name that are the common alternative
+   spellings of UTF-8.
+
+ * "git branch" did not bother to check nonsense command line
+   parameters and issue errors in many cases.
+
+ * "git update-index -h" did not do the usual "-h(elp)" thing.
+
+ * perl/Git.pm::cat_blob slurped everything in core only to write it
+   out to a file descriptor, which was not a very smart thing to do.
+
+ * The SSL peer verification done by "git imap-send" did not ask for
+   Server Name Indication (RFC 4366), failing to connect SSL/TLS
+   sites that serve multiple hostnames on a single IP.
+
+ * "git index-pack" had a buffer-overflow while preparing an
+   informational message when the translated version of it was too
+   long.
+
+ * Clarify in the documentation "what" gets pushed to "where" when the
+   command line to "git push" does not say these explicitly.
+
+ * In "git reflog expire", REACHABLE bit was not cleared from the
+   correct objects.
+
+ * The "--color=<when>" argument to the commands in the diff family
+   was described poorly.
+
+ * The arguments given to pre-rebase hook were not documented.
+
+ * The v4 index format was not documented.
+
+ * The "--match=<pattern>" argument "git describe" takes uses glob
+   pattern but it wasn't obvious from the documentation.
+
+ * Some sources failed to compile on systems that lack NI_MAXHOST in
+   their system header (e.g. z/OS).
+
+ * Add an example use of "--env-filter" in "filter-branch"
+   documentation.
+
+ * "git bundle verify" did not say "records a complete history" for a
+   bundle that does not have any prerequisites.
+
+ * In the v1.8.0 era, we changed symbols that do not have to be global
+   to file scope static, but a few functions in graph.c were used by
+   CGit from sideways bypassing the entry points of the API the
+   in-tree users use.
+
+ * "git merge-tree" had a typo in the logic to detect d/f conflicts,
+   which caused it to segfault in some cases.
index bbba728d09bbb578f86c1ef171d24b53c1178fa3..bc750d579464a8c6c2e534e17ecae6d3a66287a9 100644 (file)
@@ -178,6 +178,10 @@ advice.*::
                the template shown when writing commit messages in
                linkgit:git-commit[1], and in the help message shown
                by linkgit:git-checkout[1] when switching branch.
+       statusUoption::
+               Advise to consider using the `-u` option to linkgit:git-status[1]
+               when the command takes more than 2 seconds to enumerate untracked
+               files.
        commitBeforeMerge::
                Advice shown when linkgit:git-merge[1] refuses to
                merge to avoid overwriting local changes.
@@ -443,7 +447,7 @@ core.sharedRepository::
 
 core.warnAmbiguousRefs::
        If true, Git will warn you if the ref name you passed it is ambiguous
-       and might match multiple refs in the .git/refs/ tree. True by default.
+       and might match multiple refs in the repository. True by default.
 
 core.compression::
        An integer -1..9, indicating a default compression level.
@@ -551,7 +555,7 @@ core.commentchar::
        (default '#').
 
 sequence.editor::
-       Text editor used by `git rebase -i` for editing the rebase insn file.
+       Text editor used by `git rebase -i` for editing the rebase instruction file.
        The value is meant to be interpreted by the shell when it is used.
        It can be overridden by the `GIT_SEQUENCE_EDITOR` environment variable.
        When not configured the default commit message editor is used instead.
index 869d965a3b93e25c71fd4c81a7f7742ff2222cfe..104579dc75128811e475d408035569ac09f3283b 100644 (file)
@@ -195,8 +195,8 @@ any of those replacements occurred.
 
 --color[=<when>]::
        Show colored diff.
-       The value must be `always` (the default for `<when>`), `never`, or `auto`.
-       The default value is `never`.
+       `--color` (i.e. without '=<when>') is the same as `--color=always`.
+       '<when>' can be one of `always`, `never`, or `auto`.
 ifdef::git-diff[]
        It can be changed by the `color.ui` and `color.diff`
        configuration settings.
index b4c2e24849b1154fb55608fa95cead9e405a03bf..250e5228a35165e72f2f55fd347941c3a2a1d08c 100644 (file)
@@ -56,7 +56,8 @@ OPTIONS
        Write the archive to <file> instead of stdout.
 
 --worktree-attributes::
-       Look for attributes in .gitattributes in working directory too.
+       Look for attributes in .gitattributes files in the working tree
+       as well (see <<ATTRIBUTES>>).
 
 <extra>::
        This can be any options that the archiver backend understands.
@@ -120,6 +121,7 @@ tar.<format>.remote::
        user-defined formats, but true for the "tar.gz" and "tgz"
        formats.
 
+[[ATTRIBUTES]]
 ATTRIBUTES
 ----------
 
index 0eb79ccdba6b74aaafec8cf71461053491b8c216..05f82973687bb3fd7fbb066f725d72d386cd446f 100644 (file)
@@ -137,6 +137,8 @@ OPTIONS
 -m <msg>::
 --message=<msg>::
        Use the given <msg> as the commit message.
+       If multiple `-m` options are given, their values are
+       concatenated as separate paragraphs.
 
 -t <file>::
 --template=<file>::
@@ -172,16 +174,25 @@ OPTIONS
        linkgit:git-commit-tree[1].
 
 --cleanup=<mode>::
-       This option sets how the commit message is cleaned up.
-       The  '<mode>' can be one of 'verbatim', 'whitespace', 'strip',
-       and 'default'. The 'default' mode will strip leading and
-       trailing empty lines and #commentary from the commit message
-       only if the message is to be edited. Otherwise only whitespace
-       removed. The 'verbatim' mode does not change message at all,
-       'whitespace' removes just leading/trailing whitespace lines
-       and 'strip' removes both whitespace and commentary. The default
-       can be changed by the 'commit.cleanup' configuration variable
-       (see linkgit:git-config[1]).
+       This option determines how the supplied commit message should be
+       cleaned up before committing.  The '<mode>' can be `strip`,
+       `whitespace`, `verbatim`, or `default`.
++
+--
+strip::
+       Strip leading and trailing empty lines, trailing whitespace, and
+       #commentary and collapse consecutive empty lines.
+whitespace::
+       Same as `strip` except #commentary is not removed.
+verbatim::
+       Do not change the message at all.
+default::
+       Same as `strip` if the message is to be edited.
+       Otherwise `whitespace`.
+--
++
+The default can be changed by the 'commit.cleanup' configuration
+variable (see linkgit:git-config[1]).
 
 -e::
 --edit::
index 472f00f607850d7298535eead2982915412400d9..7da0f13a5cb26e9e5d1cb7d9c73fd4af57443d72 100644 (file)
@@ -56,7 +56,7 @@ For example, if we want a password for
 `https://example.com/foo.git`, we might generate the following
 credential description (don't forget the blank line at the end; it
 tells `git credential` that the application finished feeding all the
-infomation it has):
+information it has):
 
         protocol=https
         host=example.com
index 32da244fd55db8f8e24ea64787b61930d67cfbda..3c81e85ec5cf1b3090a879d49ad2445176312872 100644 (file)
@@ -81,8 +81,9 @@ OPTIONS
        that points at object deadbee....).
 
 --match <pattern>::
-       Only consider tags matching the given pattern (can be used to avoid
-       leaking private tags made from the repository).
+       Only consider tags matching the given `glob(7)` pattern,
+       excluding the "refs/tags/" prefix.  This can be used to avoid
+       leaking private tags from the repository.
 
 --always::
        Show uniquely abbreviated commit object as fallback.
index dfd12c94e42b577e40665b0b10a78af184702abb..e4c8e82660ddf9aace717e269a50ffa9adf4405e 100644 (file)
@@ -64,8 +64,11 @@ argument is always evaluated in the shell context using the 'eval' command
 Prior to that, the $GIT_COMMIT environment variable will be set to contain
 the id of the commit being rewritten.  Also, GIT_AUTHOR_NAME,
 GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL,
-and GIT_COMMITTER_DATE are set according to the current commit.  The values
-of these variables after the filters have run, are used for the new commit.
+and GIT_COMMITTER_DATE are taken from the current commit and exported to
+the environment, in order to affect the author and committer identities of
+the replacement commit created by linkgit:git-commit-tree[1] after the
+filters have run.
+
 If any evaluation of <command> returns a non-zero exit status, the whole
 operation will be aborted.
 
@@ -329,6 +332,26 @@ git filter-branch --msg-filter '
 ' HEAD~10..HEAD
 --------------------------------------------------------
 
+The `--env-filter` option can be used to modify committer and/or author
+identity.  For example, if you found out that your commits have the wrong
+identity due to a misconfigured user.email, you can make a correction,
+before publishing the project, like this:
+
+--------------------------------------------------------
+git filter-branch --env-filter '
+       if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
+       then
+               GIT_AUTHOR_EMAIL=john@example.com
+               export GIT_AUTHOR_EMAIL
+       fi
+       if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
+       then
+               GIT_COMMITTER_EMAIL=john@example.com
+               export GIT_COMMITTER_EMAIL
+       fi
+' -- --all
+--------------------------------------------------------
+
 To restrict rewriting to only part of the history, specify a revision
 range in addition to the new branch name.  The new branch name will
 point to the top-most revision that a 'git rev-list' of this range
index c852a2677ab9e32801b0dc6ed8bc85b03982233d..42391f2ae76aa579605470b6cad8cf4812f29aae 100644 (file)
@@ -170,6 +170,30 @@ happens:
 If you tried a merge which resulted in complex conflicts and
 want to start over, you can recover with `git merge --abort`.
 
+MERGING TAG
+-----------
+
+When merging an annotated (and possibly signed) tag, Git always
+creates a merge commit even if a fast-forward merge is possible, and
+the commit message template is prepared with the tag message.
+Additionally, if the tag is signed, the signature check is reported
+as a comment in the message template. See also linkgit:git-tag[1].
+
+When you want to just integrate with the work leading to the commit
+that happens to be tagged, e.g. synchronizing with an upstream
+release point, you may not want to make an unnecessary merge commit.
+
+In such a case, you can "unwrap" the tag yourself before feeding it
+to `git merge`, or pass `--ff-only` when you do not have any work on
+your own. e.g.
+
+---
+git fetch origin
+git merge v1.2.3^0
+git merge --ff-only v1.2.3
+---
+
+
 HOW CONFLICTS ARE PRESENTED
 ---------------------------
 
index c97574323099bd5b831f2b1c12a54b8c5e06373b..24ab07a3f8f80c56cbbd7feffc1b5bf65e137968 100644 (file)
@@ -218,7 +218,7 @@ $ git merge origin/next
 ------------------------------------------------
 
 
-If you tried a pull which resulted in complex conflicts and
+If you tried a pull which resulted in complex conflicts and
 would want to start over, you can recover with 'git reset'.
 
 
index 13980257eecd3e275641c1ba3262f4d4489f77ff..577d201c006ab6c72acef9bd800aa36f6cc356d3 100644 (file)
@@ -23,6 +23,17 @@ You can make interesting things happen to a repository
 every time you push into it, by setting up 'hooks' there.  See
 documentation for linkgit:git-receive-pack[1].
 
+When the command line does not specify where to push with the
+`<repository>` argument, `branch.*.remote` configuration for the
+current branch is consulted to determine where to push.  If the
+configuration is missing, it defaults to 'origin'.
+
+When the command line does not specify what to push with `<refspec>...`
+arguments or `--all`, `--mirror`, `--tags` options, the command finds
+the default `<refspec>` by consulting `remote.*.push` configuration,
+and if it is not found, honors `push.default` configuration to decide
+what to push (See gitlink:git-config[1] for the meaning of `push.default`).
+
 
 OPTIONS[[OPTIONS]]
 ------------------
@@ -33,13 +44,10 @@ OPTIONS[[OPTIONS]]
        of a remote (see the section <<REMOTES,REMOTES>> below).
 
 <refspec>...::
+       Specify what destination ref to update with what source object.
        The format of a <refspec> parameter is an optional plus
-       `+`, followed by the source ref <src>, followed
+       `+`, followed by the source object <src>, followed
        by a colon `:`, followed by the destination ref <dst>.
-       It is used to specify with what <src> object the <dst> ref
-       in the remote repository is to be updated.  If not specified,
-       the behavior of the command is controlled by the `push.default`
-       configuration variable.
 +
 The <src> is often the name of the branch you would want to push, but
 it can be any arbitrary "SHA-1 expression", such as `master~4` or
@@ -66,10 +74,7 @@ the remote repository.
 The special refspec `:` (or `+:` to allow non-fast-forward updates)
 directs Git to push "matching" branches: for every branch that exists on
 the local side, the remote side is updated if a branch of the same name
-already exists on the remote side.  This is the default operation mode
-if no explicit refspec is found (that is neither on the command line
-nor in any Push line of the corresponding remotes file---see below) and
-no `push.default` configuration variable is set.
+already exists on the remote side.
 
 --all::
        Instead of naming each ref to push, specifies that all
index 58b7facb09915a1856613dfcfd32b28d30cf896c..8cfc748ae2da4fce4c7ef804dcd50d2d923068d5 100644 (file)
@@ -86,7 +86,7 @@ begins with `ext::`.  Examples:
        edit .ssh/config.
 
 "ext::socat -t3600 - ABSTRACT-CONNECT:/git-server %G/somerepo"::
-       Represents repository with path /somerepo accessable over
+       Represents repository with path /somerepo accessible over
        git protocol at abstract namespace address /git-server.
 
 "ext::git-server-alias foo %G/repo"::
index 0412c4017d07814804ab9e9adcbf2a8d0de0304f..9046df98a03fe11a203f06d79be0128309a201c5 100644 (file)
@@ -46,15 +46,21 @@ OPTIONS
        Show untracked files.
 +
 The mode parameter is optional (defaults to 'all'), and is used to
-specify the handling of untracked files; when -u is not used, the
-default is 'normal', i.e. show untracked files and directories.
+specify the handling of untracked files.
 +
 The possible options are:
 +
-       - 'no'     - Show no untracked files
-       - 'normal' - Shows untracked files and directories
+       - 'no'     - Show no untracked files.
+       - 'normal' - Shows untracked files and directories.
        - 'all'    - Also shows individual files in untracked directories.
 +
+When `-u` option is not used, untracked files and directories are
+shown (i.e. the same as specifying `normal`), to help you avoid
+forgetting to add newly created files.  Because it takes extra work
+to find untracked files in the filesystem, this mode may take some
+time in a large working tree.  You can use `no` to have `git status`
+return more quickly without showing untracked files.
++
 The default can be changed using the status.showUntrackedFiles
 configuration variable documented in linkgit:git-config[1].
 
index 1b8b6498cd8afa4e2581e3597c4787981dc042df..7706d41c8704679c00a302306651628e5b99d1c1 100644 (file)
@@ -245,7 +245,7 @@ first have already been pushed into SVN.
        patch), "all" (accept all patches), or "quit".
        +
        'git svn dcommit' returns immediately if answer if "no" or "quit", without
-       commiting anything to SVN.
+       committing anything to SVN.
 
 'branch'::
        Create a branch in the SVN repository.
@@ -856,7 +856,7 @@ HANDLING OF SVN BRANCHES
 ------------------------
 If 'git svn' is configured to fetch branches (and --follow-branches
 is in effect), it sometimes creates multiple Git branches for one
-SVN branch, where the addtional branches have names of the form
+SVN branch, where the additional branches have names of the form
 'branchname@nnn' (with nnn an SVN revision number).  These additional
 branches are created if 'git svn' cannot find a parent commit for the
 first commit in an SVN branch, to connect the branch to the history of
index e3032c46c637f39a5a3dd965f122365ece197a5e..b21aa87fe87a26f738c971f8c3dffdcf44fb13cd 100644 (file)
@@ -126,6 +126,12 @@ This option is only applicable when listing tags without annotation lines.
        linkgit:git-check-ref-format[1].  Some of these checks
        may restrict the characters allowed in a tag name.
 
+<commit>::
+<object>::
+       The object that the new tag will refer to, usually a commit.
+       Defaults to HEAD.
+
+
 CONFIGURATION
 -------------
 By default, 'git tag' in sign-with-default mode (-s) will use your
index ad8b823f7732fe05e911fe5e8f2a1d60983c7a26..78a0d955ec22e22fbb1028f4eb6bfceeafc976f7 100644 (file)
@@ -109,7 +109,7 @@ Others
 
    - *git.el* (contrib/)
 
-   This is an Emacs interface for Git. The user interface is modeled on
+   This is an Emacs interface for Git. The user interface is modelled on
    pcl-cvs. It has been developed on Emacs 21 and will probably need some
    tweaking to work on XEmacs.
 
index 77a912d4ea0421ad604b3271a1e36975906d95f0..c92775829bd26d3d993600fd5bb104e527de59f4 100644 (file)
@@ -145,7 +145,15 @@ you will need to handle the situation manually.
 
 --index-version <n>::
        Write the resulting index out in the named on-disk format version.
-       The current default version is 2.
+       Supported versions are 2, 3 and 4. The current default version is 2
+       or 3, depending on whether extra features are used, such as
+       `git add -N`.
++
+Version 4 performs a simple pathname compression that reduces index
+size by 30%-50% on large repositories, which results in faster load
+time. Version 4 is relatively young (first released in in 1.8.0 in
+October 2012). Other Git implementations such as JGit and libgit2
+may not support it yet.
 
 -z::
        Only meaningful with `--stdin` or `--index-info`; paths are
index 7efaa591b8f29b7d9ab415efb7ebe4f83e41a72b..6a875f2adefe34e27bc0fc3b6fdb9d7bcfd23301 100644 (file)
@@ -43,14 +43,16 @@ unreleased) version of Git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.8.2/git.html[documentation for release 1.8.2]
+* link:v1.8.2.1/git.html[documentation for release 1.8.2.1]
 
 * release notes for
+  link:RelNotes/1.8.2.1.txt[1.8.2.1].
   link:RelNotes/1.8.2.txt[1.8.2].
 
-* link:v1.8.1.5/git.html[documentation for release 1.8.1.5]
+* link:v1.8.1.6/git.html[documentation for release 1.8.1.6]
 
 * release notes for
+  link:RelNotes/1.8.1.6.txt[1.8.1.6],
   link:RelNotes/1.8.1.5.txt[1.8.1.5],
   link:RelNotes/1.8.1.4.txt[1.8.1.4],
   link:RelNotes/1.8.1.3.txt[1.8.1.3],
@@ -774,9 +776,12 @@ other
        If this environment variable is set then 'git fetch'
        and 'git push' will use this command instead
        of 'ssh' when they need to connect to a remote system.
-       The '$GIT_SSH' command will be given exactly two arguments:
-       the 'username@host' (or just 'host') from the URL and the
-       shell command to execute on that remote system.
+       The '$GIT_SSH' command will be given exactly two or
+       four arguments: the 'username@host' (or just 'host')
+       from the URL and the shell command to execute on that
+       remote system, optionally preceded by '-p' (literally) and
+       the 'port' from the URL when it specifies something other
+       than the default SSH port.
 +
 To pass options to the program that you want to list in GIT_SSH
 you will need to wrap the program and options into a shell script,
index dc9e617a10d58769a5338d06794f338ba9970d08..9ac5088acd3e0cf9541ef097c26f19c5f462b770 100644 (file)
@@ -107,13 +107,14 @@ couple of magic command line options:
 ---------------------------------------------
 $ git describe -h
 usage: git describe [options] <committish>*
+   or: git describe [options] --dirty
 
     --contains            find the tag that comes after the commit
     --debug               debug search strategy on stderr
-    --all                 use any ref in .git/refs
-    --tags                use any tag in .git/refs/tags
-    --abbrev [<n>]        use <n> digits to display SHA-1s
-    --candidates <n>      consider <n> most recent tags (default: 10)
+    --all                 use any ref
+    --tags                use any tag, even unannotated
+    --long                always use long format
+    --abbrev[=<n>]        use <n> digits to display SHA-1s
 ---------------------------------------------
 
 --help-all::
index eab9b356cd67cff9221aec16b34204622f15116f..dc6693fe482e2311a7d0ed5b5e60abec7c150c0c 100644 (file)
@@ -140,9 +140,11 @@ the outcome of 'git commit'.
 pre-rebase
 ~~~~~~~~~~
 
-This hook is called by 'git rebase' and can be used to prevent a branch
-from getting rebased.
-
+This hook is called by 'git rebase' and can be used to prevent a
+branch from getting rebased.  The hook may be called with one or
+two parameters.  The first parameter is the upstream from which
+the series was forked.  The second parameter is the branch being
+rebased, and is not set when rebasing the current branch.
 
 post-checkout
 ~~~~~~~~~~~~~
index 0bcbe0ac3c474ab12068f468476946b9db5ef3e8..34a844582846ae409e17347a65ac6cbeb28202a5 100644 (file)
@@ -30,7 +30,8 @@ set to `no` at the beginning of them.
 
 --no-ff::
        Create a merge commit even when the merge resolves as a
-       fast-forward.
+       fast-forward.  This is the default behaviour when merging an
+       annotated (and possibly signed) tag.
 
 --ff-only::
        Refuse to merge and exit with a non-zero status unless the
index 105f18a6f9fd9f4a5a388cb3ec8a0e6a99f7abe3..293965524e81b240996a795498ba127f723d18eb 100644 (file)
@@ -133,6 +133,7 @@ The placeholders are:
 - '%GG': raw verification message from GPG for a signed commit
 - '%G?': show either "G" for Good or "B" for Bad for a signed commit
 - '%GS': show the name of the signer for a signed commit
+- '%GK': show the key used to sign a signed commit
 - '%gD': reflog selector, e.g., `refs/stash@{1}`
 - '%gd': shortened reflog selector, e.g., `stash@{1}`
 - '%gn': reflog identity name
index 314e25da7344dda459ca5b3292aaaabdfc0d6495..b0f72206a09ffe6a703d923756b86c4964c1ad88 100644 (file)
@@ -55,7 +55,7 @@ when you run `git cherry-pick`.
 +
 Note that any of the 'refs/*' cases above may come either from
 the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file.
-While the ref name encoding is unspecified, UTF-8 is prefered as
+While the ref name encoding is unspecified, UTF-8 is preferred as
 some output processing may assume ref names in UTF-8.
 
 '<refname>@\{<date>\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}'::
index a959517b2339847e92464c86a73f9c472bfdb2d0..a6b7d83a8eb05086cb88a9168117aa54cf018551 100644 (file)
@@ -55,7 +55,7 @@ Functions
        initial, empty state.
 
 `argv_array_detach`::
-       Detach the argv array from the `struct argv_array`, transfering
+       Detach the argv array from the `struct argv_array`, transferring
        ownership of the allocated array and strings.
 
 `argv_array_free_detached`::
index 516fda74120c18f4d124ee8e5402dda39b72777a..c1b42a40d3c0c297994cd2966b60cd48629e57fa 100644 (file)
@@ -160,7 +160,7 @@ int foo_login(struct foo_connection *f)
                break;
        default:
                /*
-                * Some other error occured. We don't know if the
+                * Some other error occurred. We don't know if the
                 * credential is good or bad, so report nothing to the
                 * credential subsystem.
                 */
index dbbea95db7a8104dcd5de4b1ac59235f2eadaaa8..aa1c50f181eb20e27a8299ca8ec691eeffa9d51b 100644 (file)
@@ -35,7 +35,7 @@ Iteration functions
 * `head_ref_submodule()`, `for_each_ref_submodule()`,
   `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,
   `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`
-  do the same as the functions descibed above but for a specified
+  do the same as the functions described above but for a specified
   submodule.
 
 * `for_each_rawref()` can be used to learn about broken ref and symref.
index 27c716b15f5de5103eb6afe4b23a5a5a84a1fd7f..0810251f5a316de548d906bde65fba5af3507e4d 100644 (file)
@@ -12,7 +12,7 @@ Git index format
        The signature is { 'D', 'I', 'R', 'C' } (stands for "dircache")
 
      4-byte version number:
-       The current supported versions are 2 and 3.
+       The current supported versions are 2, 3 and 4.
 
      32-bit number of index entries.
 
@@ -93,8 +93,8 @@ Git index format
     12-bit name length if the length is less than 0xFFF; otherwise 0xFFF
     is stored in this field.
 
-  (Version 3) A 16-bit field, only applicable if the "extended flag"
-  above is 1, split into (high to low bits).
+  (Version 3 or later) A 16-bit field, only applicable if the
+  "extended flag" above is 1, split into (high to low bits).
 
     1-bit reserved for future
 
index 0e37ec9de51bd4ecb99cecce1958c6cea9bea715..a37f1378d05d6def0ea3cac840acf62875536a70 100644 (file)
@@ -26,7 +26,9 @@ Git pack format
 
      (deltified representation)
      n-byte type and length (3-bit type, (n-1)*7+4-bit length)
-     20-byte base object name
+     20-byte base object name if OBJ_REF_DELTA or a negative relative
+        offset from the delta object's position in the pack if this
+        is an OBJ_OFS_DELTA object
      compressed delta data
 
      Observation: length of each object is encoded in a variable
index 5f36f8115ffdceec7d3f9e57c9f2c645f3936ad1..e831cc2020b2b728d972c9e33f7fef8041381547 100644 (file)
@@ -19,7 +19,7 @@ Further chapters cover more specialized topics.
 
 Comprehensive reference documentation is available through the man
 pages, or linkgit:git-help[1] command.  For example, for the command
-"git clone <repo>", you can either use:
+`git clone <repo>`, you can either use:
 
 ------------------------------------------------
 $ man git-clone
@@ -66,11 +66,11 @@ $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
 The initial clone may be time-consuming for a large project, but you
 will only need to clone once.
 
-The clone command creates a new directory named after the project ("git"
-or "linux-2.6" in the examples above).  After you cd into this
+The clone command creates a new directory named after the project (`git`
+or `linux-2.6` in the examples above).  After you cd into this
 directory, you will see that it contains a copy of the project files,
 called the <<def_working_tree,working tree>>, together with a special
-top-level directory named ".git", which contains all the information
+top-level directory named `.git`, which contains all the information
 about the history of the project.
 
 [[how-to-check-out]]
@@ -188,7 +188,7 @@ As you can see, a commit shows who made the latest change, what they
 did, and why.
 
 Every commit has a 40-hexdigit id, sometimes called the "object name" or the
-"SHA-1 id", shown on the first line of the "git show" output.  You can usually
+"SHA-1 id", shown on the first line of the `git show` output.  You can usually
 refer to a commit by a shorter name, such as a tag or a branch name, but this
 longer name can also be useful.  Most importantly, it is a globally unique
 name for this commit: so if you tell somebody else the object name (for
@@ -268,35 +268,35 @@ Manipulating branches
 Creating, deleting, and modifying branches is quick and easy; here's
 a summary of the commands:
 
-git branch::
+`git branch`::
        list all branches
-git branch <branch>::
-       create a new branch named <branch>, referencing the same
+`git branch <branch>`::
+       create a new branch named `<branch>`, referencing the same
        point in history as the current branch
-git branch <branch> <start-point>::
-       create a new branch named <branch>, referencing
-       <start-point>, which may be specified any way you like,
+`git branch <branch> <start-point>`::
+       create a new branch named `<branch>`, referencing
+       `<start-point>`, which may be specified any way you like,
        including using a branch name or a tag name
-git branch -d <branch>::
-       delete the branch <branch>; if the branch you are deleting
+`git branch -d <branch>`::
+       delete the branch `<branch>`; if the branch you are deleting
        points to a commit which is not reachable from the current
        branch, this command will fail with a warning.
-git branch -D <branch>::
+`git branch -D <branch>`::
        even if the branch points to a commit not reachable
        from the current branch, you may know that that commit
        is still reachable from some other branch or tag.  In that
        case it is safe to use this command to force Git to delete
        the branch.
-git checkout <branch>::
-       make the current branch <branch>, updating the working
-       directory to reflect the version referenced by <branch>
-git checkout -b <new> <start-point>::
-       create a new branch <new> referencing <start-point>, and
+`git checkout <branch>`::
+       make the current branch `<branch>`, updating the working
+       directory to reflect the version referenced by `<branch>`
+`git checkout -b <new> <start-point>`::
+       create a new branch `<new>` referencing `<start-point>`, and
        check it out.
 
 The special symbol "HEAD" can always be used to refer to the current
-branch.  In fact, Git uses a file named "HEAD" in the .git directory to
-remember which branch is current:
+branch.  In fact, Git uses a file named `HEAD` in the `.git` directory
+to remember which branch is current:
 
 ------------------------------------------------
 $ cat .git/HEAD
@@ -346,7 +346,7 @@ of the HEAD in the repository that you cloned from.  That repository
 may also have had other branches, though, and your local repository
 keeps branches which track each of those remote branches, called
 remote-tracking branches, which you
-can view using the "-r" option to linkgit:git-branch[1]:
+can view using the `-r` option to linkgit:git-branch[1]:
 
 ------------------------------------------------
 $ git branch -r
@@ -364,7 +364,7 @@ In this example, "origin" is called a remote repository, or "remote"
 for short. The branches of this repository are called "remote
 branches" from our point of view. The remote-tracking branches listed
 above were created based on the remote branches at clone time and will
-be updated by "git fetch" (hence "git pull") and "git push". See
+be updated by `git fetch` (hence `git pull`) and `git push`. See
 <<Updating-a-repository-With-git-fetch>> for details.
 
 You might want to build on one of these remote-tracking branches
@@ -374,7 +374,7 @@ on a branch of your own, just as you would for a tag:
 $ git checkout -b my-todo-copy origin/todo
 ------------------------------------------------
 
-You can also check out "origin/todo" directly to examine it or
+You can also check out `origin/todo` directly to examine it or
 write a one-off patch.  See <<detached-head,detached head>>.
 
 Note that the name "origin" is just the name that Git uses by default
@@ -386,17 +386,17 @@ Naming branches, tags, and other references
 
 Branches, remote-tracking branches, and tags are all references to
 commits.  All references are named with a slash-separated path name
-starting with "refs"; the names we've been using so far are actually
+starting with `refs`; the names we've been using so far are actually
 shorthand:
 
-       - The branch "test" is short for "refs/heads/test".
-       - The tag "v2.6.18" is short for "refs/tags/v2.6.18".
-       - "origin/master" is short for "refs/remotes/origin/master".
+       - The branch `test` is short for `refs/heads/test`.
+       - The tag `v2.6.18` is short for `refs/tags/v2.6.18`.
+       - `origin/master` is short for `refs/remotes/origin/master`.
 
 The full name is occasionally useful if, for example, there ever
 exists a tag and a branch with the same name.
 
-(Newly created refs are actually stored in the .git/refs directory,
+(Newly created refs are actually stored in the `.git/refs` directory,
 under the path given by their name.  However, for efficiency reasons
 they may also be packed together in a single file; see
 linkgit:git-pack-refs[1]).
@@ -418,7 +418,7 @@ Eventually the developer cloned from will do additional work in her
 repository, creating new commits and advancing the branches to point
 at the new commits.
 
-The command "git fetch", with no arguments, will update all of the
+The command `git fetch`, with no arguments, will update all of the
 remote-tracking branches to the latest version found in her
 repository.  It will not touch any of your own branches--not even the
 "master" branch that was created for you on clone.
@@ -438,7 +438,7 @@ $ git fetch linux-nfs
 -------------------------------------------------
 
 New remote-tracking branches will be stored under the shorthand name
-that you gave "git remote add", in this case linux-nfs:
+that you gave `git remote add`, in this case `linux-nfs`:
 
 -------------------------------------------------
 $ git branch -r
@@ -446,10 +446,10 @@ linux-nfs/master
 origin/master
 -------------------------------------------------
 
-If you run "git fetch <remote>" later, the remote-tracking branches for the
-named <remote> will be updated.
+If you run `git fetch <remote>` later, the remote-tracking branches
+for the named `<remote>` will be updated.
 
-If you examine the file .git/config, you will see that Git has added
+If you examine the file `.git/config`, you will see that Git has added
 a new stanza:
 
 -------------------------------------------------
@@ -462,7 +462,7 @@ $ cat .git/config
 -------------------------------------------------
 
 This is what causes Git to track the remote's branches; you may modify
-or delete these configuration options by editing .git/config with a
+or delete these configuration options by editing `.git/config` with a
 text editor.  (See the "CONFIGURATION FILE" section of
 linkgit:git-config[1] for details.)
 
@@ -499,7 +499,7 @@ Bisecting: 3537 revisions left to test after this
 [65934a9a028b88e83e2b0f8b36618fe503349f8e] BLOCK: Make USB storage depend on SCSI rather than selecting it [try #6]
 -------------------------------------------------
 
-If you run "git branch" at this point, you'll see that Git has
+If you run `git branch` at this point, you'll see that Git has
 temporarily moved you in "(no branch)". HEAD is now detached from any
 branch and points directly to a commit (with commit id 65934...) that
 is reachable from "master" but not from v2.6.18. Compile and test it,
@@ -545,11 +545,11 @@ id, and check it out with:
 $ git reset --hard fb47ddb2db...
 -------------------------------------------------
 
-then test, run "bisect good" or "bisect bad" as appropriate, and
+then test, run `bisect good` or `bisect bad` as appropriate, and
 continue.
 
-Instead of "git bisect visualize" and then "git reset --hard
-fb47ddb2db...", you might just want to tell Git that you want to skip
+Instead of `git bisect visualize` and then `git reset --hard
+fb47ddb2db...`, you might just want to tell Git that you want to skip
 the current commit:
 
 -------------------------------------------------
@@ -561,8 +561,8 @@ bad one between some first skipped commits and a later bad commit.
 
 There are also ways to automate the bisecting process if you have a
 test script that can tell a good from a bad commit. See
-linkgit:git-bisect[1] for more information about this and other "git
-bisect" features.
+linkgit:git-bisect[1] for more information about this and other `git
+bisect` features.
 
 [[naming-commits]]
 Naming commits
@@ -591,7 +591,7 @@ $ git show HEAD~4   # the great-great-grandparent
 -------------------------------------------------
 
 Recall that merge commits may have more than one parent; by default,
-^ and ~ follow the first parent listed in the commit, but you can
+`^` and `~` follow the first parent listed in the commit, but you can
 also choose:
 
 -------------------------------------------------
@@ -640,7 +640,7 @@ running
 $ git tag stable-1 1b2e1d63ff
 -------------------------------------------------
 
-You can use stable-1 to refer to the commit 1b2e1d63ff.
+You can use `stable-1` to refer to the commit 1b2e1d63ff.
 
 This creates a "lightweight" tag.  If you would also like to include a
 comment with the tag, and possibly sign it cryptographically, then you
@@ -669,7 +669,7 @@ $ git log -S'foo()' # commits which add or remove any file data
 -------------------------------------------------
 
 And of course you can combine all of these; the following finds
-commits since v2.5 which touch the Makefile or any file under fs:
+commits since v2.5 which touch the `Makefile` or any file under `fs`:
 
 -------------------------------------------------
 $ git log v2.5.. Makefile fs/
@@ -681,7 +681,7 @@ You can also ask git log to show patches:
 $ git log -p
 -------------------------------------------------
 
-See the "--pretty" option in the linkgit:git-log[1] man page for more
+See the `--pretty` option in the linkgit:git-log[1] man page for more
 display options.
 
 Note that git log starts with the most recent commit and works
@@ -742,8 +742,8 @@ Examples
 Counting the number of commits on a branch
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Suppose you want to know how many commits you've made on "mybranch"
-since it diverged from "origin":
+Suppose you want to know how many commits you've made on `mybranch`
+since it diverged from `origin`:
 
 -------------------------------------------------
 $ git log --pretty=oneline origin..mybranch | wc -l
@@ -780,7 +780,7 @@ $ git rev-list master
 e05db0fd4f31dde7005f075a84f96b360d05984b
 -------------------------------------------------
 
-Or you could recall that the ... operator selects all commits
+Or you could recall that the `...` operator selects all commits
 contained reachable from either one reference or the other but not
 both; so
 
@@ -880,7 +880,7 @@ Showing commits unique to a given branch
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Suppose you would like to see all the commits reachable from the branch
-head named "master" but not from any other head in your repository.
+head named `master` but not from any other head in your repository.
 
 We can list all the heads in this repository with
 linkgit:git-show-ref[1]:
@@ -894,7 +894,7 @@ a07157ac624b2524a059a3414e99f6f44bebc1e7 refs/heads/master
 1e87486ae06626c2f31eaa63d26fc0fd646c8af2 refs/heads/tutorial-fixes
 -------------------------------------------------
 
-We can get just the branch-head names, and remove "master", with
+We can get just the branch-head names, and remove `master`, with
 the help of the standard utilities cut and grep:
 
 -------------------------------------------------
@@ -939,7 +939,7 @@ is preceded by `project/`.  The output file format is inferred from
 the output file extension if possible, see linkgit:git-archive[1] for
 details.
 
-Versions of Git older than 1.7.7 don't know about the 'tar.gz' format,
+Versions of Git older than 1.7.7 don't know about the `tar.gz` format,
 you'll need to use gzip explicitly:
 
 -------------------------------------------------
@@ -1062,7 +1062,7 @@ at step 3, Git maintains a snapshot of the tree's contents in a
 special staging area called "the index."
 
 At the beginning, the content of the index will be identical to
-that of the HEAD.  The command "git diff --cached", which shows
+that of the HEAD.  The command `git diff --cached`, which shows
 the difference between the HEAD and the index, should therefore
 produce no output at that point.
 
@@ -1101,7 +1101,7 @@ $ git diff
 
 shows the difference between the working tree and the index file.
 
-Note that "git add" always adds just the current contents of a file
+Note that `git add` always adds just the current contents of a file
 to the index; further changes to the same file will be ignored unless
 you run `git add` on the file again.
 
@@ -1172,8 +1172,9 @@ annoying to have these untracked files lying around; e.g. they make
 `git add .` practically useless, and they keep showing up in the output of
 `git status`.
 
-You can tell Git to ignore certain files by creating a file called .gitignore
-in the top level of your working directory, with contents such as:
+You can tell Git to ignore certain files by creating a file called
+`.gitignore` in the top level of your working directory, with contents
+such as:
 
 -------------------------------------------------
 # Lines starting with '#' are considered comments.
@@ -1197,10 +1198,10 @@ for other users who clone your repository.
 
 If you wish the exclude patterns to affect only certain repositories
 (instead of every repository for a given project), you may instead put
-them in a file in your repository named .git/info/exclude, or in any file
-specified by the `core.excludesfile` configuration variable.  Some Git
-commands can also take exclude patterns directly on the command line.
-See linkgit:gitignore[5] for the details.
+them in a file in your repository named `.git/info/exclude`, or in any
+file specified by the `core.excludesfile` configuration variable.
+Some Git commands can also take exclude patterns directly on the
+command line.  See linkgit:gitignore[5] for the details.
 
 [[how-to-merge]]
 How to merge
@@ -1213,10 +1214,10 @@ linkgit:git-merge[1]:
 $ git merge branchname
 -------------------------------------------------
 
-merges the development in the branch "branchname" into the current
+merges the development in the branch `branchname` into the current
 branch.
 
-A merge is made by combining the changes made in "branchname" and the
+A merge is made by combining the changes made in `branchname` and the
 changes made up to the latest commit in your current branch since
 their histories forked. The work tree is overwritten by the result of
 the merge when this combining is done cleanly, or overwritten by a
@@ -1338,7 +1339,7 @@ that part is not conflicting and is not shown.  Same for stage 3).
 
 The diff above shows the differences between the working-tree version of
 file.txt and the stage 2 and stage 3 versions.  So instead of preceding
-each line by a single "+" or "-", it now uses two columns: the first
+each line by a single `+` or `-`, it now uses two columns: the first
 column is used for differences between the first parent and the working
 directory copy, and the second for differences between the second parent
 and the working directory copy.  (See the "COMBINED DIFF FORMAT" section
@@ -1613,7 +1614,7 @@ dangling tree b24c2473f1fd3d91352a624795be026d64c8841f
 
 You will see informational messages on dangling objects. They are objects
 that still exist in the repository but are no longer referenced by any of
-your branches, and can (and will) be removed after a while with "gc".
+your branches, and can (and will) be removed after a while with `gc`.
 You can run `git fsck --no-dangling` to suppress these messages, and still
 view real errors.
 
@@ -1625,9 +1626,9 @@ Recovering lost changes
 Reflogs
 ^^^^^^^
 
-Say you modify a branch with +linkgit:git-reset[1] \--hard+, and then
-realize that the branch was the only reference you had to that point in
-history.
+Say you modify a branch with <<fixing-mistakes,`git reset --hard`>>,
+and then realize that the branch was the only reference you had to
+that point in history.
 
 Fortunately, Git also keeps a log, called a "reflog", of all the
 previous values of each branch.  So in this case you can still find the
@@ -1638,8 +1639,8 @@ $ git log master@{1}
 -------------------------------------------------
 
 This lists the commits reachable from the previous version of the
-"master" branch head.  This syntax can be used with any Git command
-that accepts a commit, not just with git log.  Some other examples:
+`master` branch head.  This syntax can be used with any Git command
+that accepts a commit, not just with `git log`.  Some other examples:
 
 -------------------------------------------------
 $ git show master@{2}          # See where the branch pointed 2,
@@ -1743,8 +1744,8 @@ one step:
 $ git pull origin master
 -------------------------------------------------
 
-In fact, if you have "master" checked out, then this branch has been
-configured by "git clone" to get changes from the HEAD branch of the
+In fact, if you have `master` checked out, then this branch has been
+configured by `git clone` to get changes from the HEAD branch of the
 origin repository.  So often you can
 accomplish the above with just a simple
 
@@ -1759,11 +1760,11 @@ the current branch.
 More generally, a branch that is created from a remote-tracking branch
 will pull
 by default from that branch.  See the descriptions of the
-branch.<name>.remote and branch.<name>.merge options in
+`branch.<name>.remote` and `branch.<name>.merge` options in
 linkgit:git-config[1], and the discussion of the `--track` option in
 linkgit:git-checkout[1], to learn how to control these defaults.
 
-In addition to saving you keystrokes, "git pull" also helps you by
+In addition to saving you keystrokes, `git pull` also helps you by
 producing a default commit message documenting the branch and
 repository that you pulled from.
 
@@ -1771,7 +1772,7 @@ repository that you pulled from.
 <<fast-forwards,fast-forward>>; instead, your branch will just be
 updated to point to the latest commit from the upstream branch.)
 
-The `git pull` command can also be given "." as the "remote" repository,
+The `git pull` command can also be given `.` as the "remote" repository,
 in which case it just merges in a branch from the current repository; so
 the commands
 
@@ -1796,7 +1797,7 @@ $ git format-patch origin
 -------------------------------------------------
 
 will produce a numbered series of files in the current directory, one
-for each patch in the current branch but not in origin/HEAD.
+for each patch in the current branch but not in `origin/HEAD`.
 
 `git format-patch` can include an initial "cover letter". You can insert
 commentary on individual patches after the three dash line which
@@ -1818,7 +1819,7 @@ Importing patches to a project
 Git also provides a tool called linkgit:git-am[1] (am stands for
 "apply mailbox"), for importing such an emailed series of patches.
 Just save all of the patch-containing messages, in order, into a
-single mailbox file, say "patches.mbox", then run
+single mailbox file, say `patches.mbox`, then run
 
 -------------------------------------------------
 $ git am -3 patches.mbox
@@ -1826,7 +1827,7 @@ $ git am -3 patches.mbox
 
 Git will apply each patch in order; if any conflicts are found, it
 will stop, and you can fix the conflicts as described in
-"<<resolving-a-merge,Resolving a merge>>".  (The "-3" option tells
+"<<resolving-a-merge,Resolving a merge>>".  (The `-3` option tells
 Git to perform a merge; if you would prefer it just to abort and
 leave your tree and index untouched, you may omit that option.)
 
@@ -1902,7 +1903,7 @@ We explain how to do this in the following sections.
 Setting up a public repository
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Assume your personal repository is in the directory ~/proj.  We
+Assume your personal repository is in the directory `~/proj`.  We
 first create a new clone of the repository and tell `git daemon` that it
 is meant to be public:
 
@@ -1912,10 +1913,10 @@ $ touch proj.git/git-daemon-export-ok
 -------------------------------------------------
 
 The resulting directory proj.git contains a "bare" git repository--it is
-just the contents of the ".git" directory, without any files checked out
+just the contents of the `.git` directory, without any files checked out
 around it.
 
-Next, copy proj.git to the server where you plan to host the
+Next, copy `proj.git` to the server where you plan to host the
 public repository.  You can use scp, rsync, or whatever is most
 convenient.
 
@@ -1926,8 +1927,8 @@ Exporting a Git repository via the Git protocol
 This is the preferred method.
 
 If someone else administers the server, they should tell you what
-directory to put the repository in, and what git:// URL it will appear
-at.  You can then skip to the section
+directory to put the repository in, and what `git://` URL it will
+appear at.  You can then skip to the section
 "<<pushing-changes-to-a-public-repository,Pushing changes to a public
 repository>>", below.
 
@@ -1962,7 +1963,7 @@ $ mv hooks/post-update.sample hooks/post-update
 (For an explanation of the last two lines, see
 linkgit:git-update-server-info[1] and linkgit:githooks[5].)
 
-Advertise the URL of proj.git.  Anybody else should then be able to
+Advertise the URL of `proj.git`.  Anybody else should then be able to
 clone or pull from that URL, for example with a command line like:
 
 -------------------------------------------------
@@ -1985,8 +1986,8 @@ access, which you will need to update the public repository with the
 latest changes created in your private repository.
 
 The simplest way to do this is using linkgit:git-push[1] and ssh; to
-update the remote branch named "master" with the latest state of your
-branch named "master", run
+update the remote branch named `master` with the latest state of your
+branch named `master`, run
 
 -------------------------------------------------
 $ git push ssh://yourserver.com/~you/proj.git master:master
@@ -2002,7 +2003,7 @@ As with `git fetch`, `git push` will complain if this does not result in a
 <<fast-forwards,fast-forward>>; see the following section for details on
 handling this case.
 
-Note that the target of a "push" is normally a
+Note that the target of a `push` is normally a
 <<def_bare_repository,bare>> repository.  You can also push to a
 repository that has a checked-out working tree, but a push to update the
 currently checked-out branch is denied by default to prevent confusion.
@@ -2030,9 +2031,9 @@ which lets you do the same push with just
 $ git push public-repo master
 -------------------------------------------------
 
-See the explanations of the remote.<name>.url, branch.<name>.remote,
-and remote.<name>.push options in linkgit:git-config[1] for
-details.
+See the explanations of the `remote.<name>.url`,
+`branch.<name>.remote`, and `remote.<name>.push` options in
+linkgit:git-config[1] for details.
 
 [[forcing-push]]
 What to do when a push fails
@@ -2167,7 +2168,7 @@ linkgit:git-fetch[1] to keep them up-to-date; see
 
 Now create the branches in which you are going to work; these start out
 at the current tip of origin/master branch, and should be set up (using
-the --track option to linkgit:git-branch[1]) to merge changes in from
+the `--track` option to linkgit:git-branch[1]) to merge changes in from
 Linus by default.
 
 -------------------------------------------------
@@ -2186,7 +2187,7 @@ Important note!  If you have any local changes in these branches, then
 this merge will create a commit object in the history (with no local
 changes Git will simply do a "fast-forward" merge).  Many people dislike
 the "noise" that this creates in the Linux history, so you should avoid
-doing this capriciously in the "release" branch, as these noisy commits
+doing this capriciously in the `release` branch, as these noisy commits
 will become part of the permanent history when you ask Linus to pull
 from the release branch.
 
@@ -2228,7 +2229,7 @@ patches), and create a new branch from a recent stable tag of
 Linus's branch. Picking a stable base for your branch will:
 1) help you: by avoiding inclusion of unrelated and perhaps lightly
 tested changes
-2) help future bug hunters that use "git bisect" to find problems
+2) help future bug hunters that use `git bisect` to find problems
 
 -------------------------------------------------
 $ git checkout -b speed-up-spinlocks v2.6.35
@@ -2253,9 +2254,9 @@ It is unlikely that you would have any conflicts here ... but you might if you
 spent a while on this step and had also pulled new versions from upstream.
 
 Some time later when enough time has passed and testing done, you can pull the
-same branch into the "release" tree ready to go upstream.  This is where you
+same branch into the `release` tree ready to go upstream.  This is where you
 see the value of keeping each patch (or patch series) in its own branch.  It
-means that the patches can be moved into the "release" tree in any order.
+means that the patches can be moved into the `release` tree in any order.
 
 -------------------------------------------------
 $ git checkout release && git pull . speed-up-spinlocks
@@ -2288,7 +2289,7 @@ If it has been merged, then there will be no output.)
 
 Once a patch completes the great cycle (moving from test to release,
 then pulled by Linus, and finally coming back into your local
-"origin/master" branch), the branch for this change is no longer needed.
+`origin/master` branch), the branch for this change is no longer needed.
 You detect this when the output from:
 
 -------------------------------------------------
@@ -2303,8 +2304,8 @@ $ git branch -d branchname
 
 Some changes are so trivial that it is not necessary to create a separate
 branch and then merge into each of the test and release branches.  For
-these changes, just apply directly to the "release" branch, and then
-merge that into the "test" branch.
+these changes, just apply directly to the `release` branch, and then
+merge that into the `test` branch.
 
 After pushing your work to `mytree`, you can use
 linkgit:git-request-pull[1] to prepare a "please pull" request message
@@ -2337,7 +2338,7 @@ origin)
        fi
        ;;
 *)
-       echo "Usage: $0 origin|test|release" 1>&2
+       echo "usage: $0 origin|test|release" 1>&2
        exit 1
        ;;
 esac
@@ -2351,7 +2352,7 @@ pname=$0
 
 usage()
 {
-       echo "Usage: $pname branch test|release" 1>&2
+       echo "usage: $pname branch test|release" 1>&2
        exit 1
 }
 
@@ -2475,8 +2476,8 @@ you are rewriting history.
 Keeping a patch series up to date using git rebase
 --------------------------------------------------
 
-Suppose that you create a branch "mywork" on a remote-tracking branch
-"origin", and create some commits on top of it:
+Suppose that you create a branch `mywork` on a remote-tracking branch
+`origin`, and create some commits on top of it:
 
 -------------------------------------------------
 $ git checkout -b mywork origin
@@ -2488,7 +2489,7 @@ $ git commit
 -------------------------------------------------
 
 You have performed no merges into mywork, so it is just a simple linear
-sequence of patches on top of "origin":
+sequence of patches on top of `origin`:
 
 ................................................
  o--o--O <-- origin
@@ -2497,7 +2498,7 @@ sequence of patches on top of "origin":
 ................................................
 
 Some more interesting work has been done in the upstream project, and
-"origin" has advanced:
+`origin` has advanced:
 
 ................................................
  o--o--O--o--o--o <-- origin
@@ -2505,7 +2506,7 @@ Some more interesting work has been done in the upstream project, and
          a--b--c <-- mywork
 ................................................
 
-At this point, you could use "pull" to merge your changes back in;
+At this point, you could use `pull` to merge your changes back in;
 the result would create a new merge commit, like this:
 
 ................................................
@@ -2524,7 +2525,7 @@ $ git rebase origin
 -------------------------------------------------
 
 This will remove each of your commits from mywork, temporarily saving
-them as patches (in a directory named ".git/rebase-apply"), update mywork to
+them as patches (in a directory named `.git/rebase-apply`), update mywork to
 point at the latest version of origin, then apply each of the saved
 patches to the new mywork.  The result will look like:
 
@@ -2795,10 +2796,10 @@ arbitrary name:
 $ git fetch origin todo:my-todo-work
 -------------------------------------------------
 
-The first argument, "origin", just tells Git to fetch from the
+The first argument, `origin`, just tells Git to fetch from the
 repository you originally cloned from.  The second argument tells Git
-to fetch the branch named "todo" from the remote repository, and to
-store it locally under the name refs/heads/my-todo-work.
+to fetch the branch named `todo` from the remote repository, and to
+store it locally under the name `refs/heads/my-todo-work`.
 
 You can also fetch branches from other repositories; so
 
@@ -2806,8 +2807,8 @@ You can also fetch branches from other repositories; so
 $ git fetch git://example.com/proj.git master:example-master
 -------------------------------------------------
 
-will create a new branch named "example-master" and store in it the
-branch named "master" from the repository at the given URL.  If you
+will create a new branch named `example-master` and store in it the
+branch named `master` from the repository at the given URL.  If you
 already have a branch named example-master, it will attempt to
 <<fast-forwards,fast-forward>> to the commit given by example.com's
 master branch.  In more detail:
@@ -2816,7 +2817,7 @@ master branch.  In more detail:
 git fetch and fast-forwards
 ---------------------------
 
-In the previous example, when updating an existing branch, "git fetch"
+In the previous example, when updating an existing branch, `git fetch`
 checks to make sure that the most recent commit on the remote
 branch is a descendant of the most recent commit on your copy of the
 branch before updating your copy of the branch to point at the new
@@ -2842,11 +2843,11 @@ resulting in a situation like:
             o--o--o <-- new head of the branch
 ................................................
 
-In this case, "git fetch" will fail, and print out a warning.
+In this case, `git fetch` will fail, and print out a warning.
 
 In that case, you can still force Git to update to the new head, as
 described in the following section.  However, note that in the
-situation above this may mean losing the commits labeled "a" and "b",
+situation above this may mean losing the commits labeled `a` and `b`,
 unless you've already created a reference of your own pointing to
 them.
 
@@ -2861,7 +2862,7 @@ descendant of the old head, you may force the update with:
 $ git fetch git://example.com/proj.git +master:refs/remotes/example/master
 -------------------------------------------------
 
-Note the addition of the "+" sign.  Alternatively, you can use the "-f"
+Note the addition of the `+` sign.  Alternatively, you can use the `-f`
 flag to force updates of all the fetched branches, as in:
 
 -------------------------------------------------
@@ -2875,7 +2876,7 @@ may be lost, as we saw in the previous section.
 Configuring remote-tracking branches
 ------------------------------------
 
-We saw above that "origin" is just a shortcut to refer to the
+We saw above that `origin` is just a shortcut to refer to the
 repository that you originally cloned from.  This information is
 stored in Git configuration variables, which you can see using
 linkgit:git-config[1]:
@@ -2984,7 +2985,7 @@ Commit Object
 ~~~~~~~~~~~~~
 
 The "commit" object links a physical state of a tree with a description
-of how we got there and why.  Use the --pretty=raw option to
+of how we got there and why.  Use the `--pretty=raw` option to
 linkgit:git-show[1] or linkgit:git-log[1] to examine your favorite
 commit:
 
@@ -3026,7 +3027,7 @@ of the tree referred to by this commit with the trees associated with
 its parents.  In particular, Git does not attempt to record file renames
 explicitly, though it can identify cases where the existence of the same
 file data at changing paths suggests a rename.  (See, for example, the
--M option to linkgit:git-diff[1]).
+`-M` option to linkgit:git-diff[1]).
 
 A commit is usually created by linkgit:git-commit[1], which creates a
 commit whose parent is normally the current HEAD, and whose tree is
@@ -3077,7 +3078,7 @@ Blob Object
 ~~~~~~~~~~~
 
 You can use linkgit:git-show[1] to examine the contents of a blob; take,
-for example, the blob in the entry for "COPYING" from the tree above:
+for example, the blob in the entry for `COPYING` from the tree above:
 
 ------------------------------------------------
 $ git show 6ff87c4664
@@ -3160,14 +3161,14 @@ nLE/L9aUXdWeTFPron96DLA=
 See the linkgit:git-tag[1] command to learn how to create and verify tag
 objects.  (Note that linkgit:git-tag[1] can also be used to create
 "lightweight tags", which are not tag objects at all, but just simple
-references whose names begin with "refs/tags/").
+references whose names begin with `refs/tags/`).
 
 [[pack-files]]
 How Git stores objects efficiently: pack files
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Newly created objects are initially created in a file named after the
-object's SHA-1 hash (stored in .git/objects).
+object's SHA-1 hash (stored in `.git/objects`).
 
 Unfortunately this system becomes inefficient once a project has a
 lot of objects.  Try this on an old project:
@@ -3208,9 +3209,9 @@ $ git prune
 
 to remove any of the "loose" objects that are now contained in the
 pack.  This will also remove any unreferenced objects (which may be
-created when, for example, you use "git reset" to remove a commit).
+created when, for example, you use `git reset` to remove a commit).
 You can verify that the loose objects are gone by looking at the
-.git/objects directory or by running
+`.git/objects` directory or by running
 
 ------------------------------------------------
 $ git count-objects
@@ -3237,7 +3238,7 @@ branch still exists, as does everything it pointed to. The branch
 pointer itself just doesn't, since you replaced it with another one.
 
 There are also other situations that cause dangling objects. For
-example, a "dangling blob" may arise because you did a "git add" of a
+example, a "dangling blob" may arise because you did a `git add` of a
 file, but then, before you actually committed it and made it part of the
 bigger picture, you changed something else in that file and committed
 that *updated* thing--the old state that you added originally ends up
@@ -3280,14 +3281,14 @@ $ git show <dangling-blob/tree-sha-goes-here>
 ------------------------------------------------
 
 to show what the contents of the blob were (or, for a tree, basically
-what the "ls" for that directory was), and that may give you some idea
+what the `ls` for that directory was), and that may give you some idea
 of what the operation was that left that dangling object.
 
 Usually, dangling blobs and trees aren't very interesting. They're
 almost always the result of either being a half-way mergebase (the blob
 will often even have the conflict markers from a merge in it, if you
 have had conflicting merges that you fixed up by hand), or simply
-because you interrupted a "git fetch" with ^C or something like that,
+because you interrupted a `git fetch` with ^C or something like that,
 leaving _some_ of the new objects in the object database, but just
 dangling and useless.
 
@@ -3298,16 +3299,16 @@ state, you can just prune all unreachable objects:
 $ git prune
 ------------------------------------------------
 
-and they'll be gone. But you should only run "git prune" on a quiescent
+and they'll be gone. But you should only run `git prune` on a quiescent
 repository--it's kind of like doing a filesystem fsck recovery: you
 don't want to do that while the filesystem is mounted.
 
-(The same is true of "git fsck" itself, btw, but since
+(The same is true of `git fsck` itself, btw, but since
 `git fsck` never actually *changes* the repository, it just reports
 on what it found, `git fsck` itself is never 'dangerous' to run.
 Running it while somebody is actually changing the repository can cause
 confusing and scary messages, but it won't actually do anything bad. In
-contrast, running "git prune" while somebody is actively changing the
+contrast, running `git prune` while somebody is actively changing the
 repository is a *BAD* idea).
 
 [[recovering-from-repository-corruption]]
@@ -3345,7 +3346,7 @@ missing blob 4b9458b3786228369c63936db65827de3cc06200
 Now you know that blob 4b9458b3 is missing, and that the tree 2d9263c6
 points to it.  If you could find just one copy of that missing blob
 object, possibly in some other repository, you could move it into
-.git/objects/4b/9458b3... and be done.  Suppose you can't.  You can
+`.git/objects/4b/9458b3...` and be done.  Suppose you can't.  You can
 still examine the tree that pointed to it with linkgit:git-ls-tree[1],
 which might output something like:
 
@@ -3360,10 +3361,10 @@ $ git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
 ------------------------------------------------
 
 So now you know that the missing blob was the data for a file named
-"myfile".  And chances are you can also identify the directory--let's
-say it's in "somedirectory".  If you're lucky the missing copy might be
+`myfile`.  And chances are you can also identify the directory--let's
+say it's in `somedirectory`.  If you're lucky the missing copy might be
 the same as the copy you have checked out in your working tree at
-"somedirectory/myfile"; you can test whether that's right with
+`somedirectory/myfile`; you can test whether that's right with
 linkgit:git-hash-object[1]:
 
 ------------------------------------------------
@@ -3418,7 +3419,7 @@ $ git hash-object -w <recreated-file>
 
 and your repository is good again!
 
-(Btw, you could have ignored the fsck, and started with doing a
+(Btw, you could have ignored the `fsck`, and started with doing a
 
 ------------------------------------------------
 $ git log --raw --all
@@ -3432,7 +3433,7 @@ just missing one particular blob version.
 The index
 -----------
 
-The index is a binary file (generally kept in .git/index) containing a
+The index is a binary file (generally kept in `.git/index`) containing a
 sorted list of path names, each with permissions and the SHA-1 of a blob
 object; linkgit:git-ls-files[1] can show you the contents of the index:
 
@@ -3572,7 +3573,7 @@ $ ls -a
 
 The `git submodule add <repo> <path>` command does a couple of things:
 
-- It clones the submodule from <repo> to the given <path> under the
+- It clones the submodule from `<repo>` to the given `<path>` under the
   current directory and by default checks out the master branch.
 - It adds the submodule's clone path to the linkgit:gitmodules[5] file and
   adds this file to the index, ready to be committed.
@@ -3700,11 +3701,11 @@ Unable to checkout '261dfac35cb99d380eb966e102c1197139f7fa24' in submodule path
 
 In older Git versions it could be easily forgotten to commit new or modified
 files in a submodule, which silently leads to similar problems as not pushing
-the submodule changes. Starting with Git 1.7.0 both "git status" and "git diff"
+the submodule changes. Starting with Git 1.7.0 both `git status` and `git diff`
 in the superproject show submodules as modified when they contain new or
-modified files to protect against accidentally committing such a state. "git
-diff" will also add a "-dirty" to the work tree side when generating patch
-output or used with the --submodule option:
+modified files to protect against accidentally committing such a state. `git
+diff` will also add a `-dirty` to the work tree side when generating patch
+output or used with the `--submodule` option:
 
 -------------------------------------------------
 $ git diff
@@ -3880,7 +3881,7 @@ or, if you want to check out all of the index, use `-a`.
 
 NOTE! `git checkout-index` normally refuses to overwrite old files, so
 if you have an old version of the tree already checked out, you will
-need to use the "-f" flag ('before' the "-a" flag or the filename) to
+need to use the `-f` flag ('before' the `-a` flag or the filename) to
 'force' the checkout.
 
 
@@ -3891,7 +3892,7 @@ from one representation to the other:
 Tying it all together
 ~~~~~~~~~~~~~~~~~~~~~
 
-To commit a tree you have instantiated with "git write-tree", you'd
+To commit a tree you have instantiated with `git write-tree`, you'd
 create a "commit" object that refers to that tree and the history
 behind it--most notably the "parent" commits that preceded it in
 history.
@@ -4152,8 +4153,9 @@ As a result, the general consistency of an object can always be tested
 independently of the contents or the type of the object: all objects can
 be validated by verifying that (a) their hashes match the content of the
 file and (b) the object successfully inflates to a stream of bytes that
-forms a sequence of <ascii type without space> {plus} <space> {plus} <ascii decimal
-size> {plus} <byte\0> {plus} <binary object data>.
+forms a sequence of
+`<ascii type without space> + <space> + <ascii decimal size> +
+<byte\0> + <binary object data>`.
 
 The structured objects can further have their structure and
 connectivity to other objects verified. This is generally done with
@@ -4632,10 +4634,10 @@ Think about how to create a clear chapter dependency graph that will
 allow people to get to important topics without necessarily reading
 everything in between.
 
-Scan Documentation/ for other stuff left out; in particular:
+Scan `Documentation/` for other stuff left out; in particular:
 
 - howto's
-- some of technical/?
+- some of `technical/`?
 - hooks
 - list of commands in linkgit:git[1]
 
index f189b7889e7b19fd1e8a5412c899d8b70fab9d9d..26422bfc22e979cf0497adad076e6b17fa50e2ca 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.8.2
+DEF_VER=v1.8.2.1
 
 LF='
 '
diff --git a/INSTALL b/INSTALL
index 2dc3b61d1fe1b675377a6ece96feaddf8a0721ba..ba01e7421eb892cfe2b86c4b26786ae9e5bb00af 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -101,7 +101,7 @@ Issues of note:
        - "openssl" library is used by git-imap-send to use IMAP over SSL.
          If you don't need it, use NO_OPENSSL.
 
-         By default, git uses OpenSSL for SHA1 but it will use it's own
+         By default, git uses OpenSSL for SHA1 but it will use its own
          library (inspired by Mozilla's) with either NO_OPENSSL or
          BLK_SHA1.  Also included is a version optimized for PowerPC
          (PPC_SHA1).
index bdce3136ea5164d82f0d25d0a7a8b50181f572f7..7a99a15f2fd9141247b100eb9a5d0b9b88b0f2b9 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.8.2.txt
\ No newline at end of file
+Documentation/RelNotes/1.8.2.1.txt
\ No newline at end of file
index 780f58da0f5b508eaa278c98dd15bdf6f919c468..3bc86260b8a2a809a379c91627f919ef0a529aa1 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -8,6 +8,7 @@ int advice_push_already_exists = 1;
 int advice_push_fetch_first = 1;
 int advice_push_needs_force = 1;
 int advice_status_hints = 1;
+int advice_status_u_option = 1;
 int advice_commit_before_merge = 1;
 int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
@@ -25,6 +26,7 @@ static struct {
        { "pushfetchfirst", &advice_push_fetch_first },
        { "pushneedsforce", &advice_push_needs_force },
        { "statushints", &advice_status_hints },
+       { "statusuoption", &advice_status_u_option },
        { "commitbeforemerge", &advice_commit_before_merge },
        { "resolveconflict", &advice_resolve_conflict },
        { "implicitidentity", &advice_implicit_identity },
index fad36df467f065bf7ff7a82d9d447ee4ac5cecb9..af0c983c686b9ca5be2e8631562e60bd19656c22 100644 (file)
--- a/advice.h
+++ b/advice.h
@@ -11,6 +11,7 @@ extern int advice_push_already_exists;
 extern int advice_push_fetch_first;
 extern int advice_push_needs_force;
 extern int advice_status_hints;
+extern int advice_status_u_option;
 extern int advice_commit_before_merge;
 extern int advice_resolve_conflict;
 extern int advice_implicit_identity;
index d3aef532b7e4b844f2ac9995b2e987d378737079..a8d119305ff5c0161e7239a8ad70a92c76122631 100644 (file)
@@ -240,7 +240,6 @@ static int write_zip_entry(struct archiver_args *args,
                        (mode & 0111) ? ((mode) << 16) : 0;
                if (S_ISREG(mode) && args->compression_level != 0 && size > 0)
                        method = 8;
-               compressed_size = (method == 0) ? size : 0;
 
                if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
                    size > big_file_threshold) {
@@ -259,6 +258,7 @@ static int write_zip_entry(struct archiver_args *args,
                        crc = crc32(crc, buffer, size);
                        out = buffer;
                }
+               compressed_size = (method == 0) ? size : 0;
        } else {
                return error("unsupported file mode: 0%o (SHA1: %s)", mode,
                                sha1_to_hex(sha1));
index 93e00bb4ae8ff9637be9e55fd41536b8837c3ba2..d254fa5d5cc32b0254dc863d015bc3d97dc59681 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -234,7 +234,7 @@ static void parse_pathspec_arg(const char **pathspec,
        ar_args->pathspec = pathspec = get_pathspec("", pathspec);
        if (pathspec) {
                while (*pathspec) {
-                       if (!path_exists(ar_args->tree, *pathspec))
+                       if (**pathspec && !path_exists(ar_args->tree, *pathspec))
                                die("path not found: %s", *pathspec);
                        pathspec++;
                }
diff --git a/attr.c b/attr.c
index e2f9377891a7f6e0d56803016726e3cd3137fdc2..689bc2a8961fac72a01e615764af53f49d01c3ec 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -657,24 +657,24 @@ static void prepare_attr_stack(const char *path, int dirlen)
 }
 
 static int path_matches(const char *pathname, int pathlen,
-                       const char *basename,
+                       int basename_offset,
                        const struct pattern *pat,
                        const char *base, int baselen)
 {
        const char *pattern = pat->pattern;
        int prefix = pat->nowildcardlen;
+       int isdir = (pathlen && pathname[pathlen - 1] == '/');
 
-       if ((pat->flags & EXC_FLAG_MUSTBEDIR) &&
-           ((!pathlen) || (pathname[pathlen-1] != '/')))
+       if ((pat->flags & EXC_FLAG_MUSTBEDIR) && !isdir)
                return 0;
 
        if (pat->flags & EXC_FLAG_NODIR) {
-               return match_basename(basename,
-                                     pathlen - (basename - pathname),
+               return match_basename(pathname + basename_offset,
+                                     pathlen - basename_offset - isdir,
                                      pattern, prefix,
                                      pat->patternlen, pat->flags);
        }
-       return match_pathname(pathname, pathlen,
+       return match_pathname(pathname, pathlen - isdir,
                              base, baselen,
                              pattern, prefix, pat->patternlen, pat->flags);
 }
@@ -703,7 +703,7 @@ static int fill_one(const char *what, struct match_attr *a, int rem)
        return rem;
 }
 
-static int fill(const char *path, int pathlen, const char *basename,
+static int fill(const char *path, int pathlen, int basename_offset,
                struct attr_stack *stk, int rem)
 {
        int i;
@@ -713,7 +713,7 @@ static int fill(const char *path, int pathlen, const char *basename,
                struct match_attr *a = stk->attrs[i];
                if (a->is_macro)
                        continue;
-               if (path_matches(path, pathlen, basename,
+               if (path_matches(path, pathlen, basename_offset,
                                 &a->u.pat, base, stk->originlen))
                        rem = fill_one("fill", a, rem);
        }
@@ -752,7 +752,8 @@ static void collect_all_attrs(const char *path)
 {
        struct attr_stack *stk;
        int i, pathlen, rem, dirlen;
-       const char *basename, *cp, *last_slash = NULL;
+       const char *cp, *last_slash = NULL;
+       int basename_offset;
 
        for (cp = path; *cp; cp++) {
                if (*cp == '/' && cp[1])
@@ -760,10 +761,10 @@ static void collect_all_attrs(const char *path)
        }
        pathlen = cp - path;
        if (last_slash) {
-               basename = last_slash + 1;
+               basename_offset = last_slash + 1 - path;
                dirlen = last_slash - path;
        } else {
-               basename = path;
+               basename_offset = 0;
                dirlen = 0;
        }
 
@@ -773,7 +774,7 @@ static void collect_all_attrs(const char *path)
 
        rem = attr_nr;
        for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
-               rem = fill(path, pathlen, basename, stk, rem);
+               rem = fill(path, pathlen, basename_offset, stk, rem);
 }
 
 int git_check_attr(const char *path, int num, struct git_attr_check *check)
index 06f5320b18bc5690ae944a722d19ec5496687228..f6a3c97dd5903a8b7d42383da370428067c3e14e 100644 (file)
@@ -1921,7 +1921,7 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
 }
 
 /*
- * Read the patch text in "buffer" taht extends for "size" bytes; stop
+ * Read the patch text in "buffer" that extends for "size" bytes; stop
  * reading after seeing a single patch (i.e. changes to a single file).
  * Create fragments (i.e. patch hunks) and hang them to the given patch.
  * Return the number of bytes consumed, so that the caller can call us
@@ -3025,7 +3025,7 @@ static struct patch *in_fn_table(const char *name)
  *
  * The latter is needed to deal with a case where two paths A and B
  * are swapped by first renaming A to B and then renaming B to A;
- * moving A to B should not be prevented due to presense of B as we
+ * moving A to B should not be prevented due to presence of B as we
  * will remove it in a later patch.
  */
 #define PATH_TO_BE_DELETED ((struct patch *) -2)
@@ -3509,7 +3509,7 @@ static int check_patch(struct patch *patch)
         *
         * A patch to swap-rename between A and B would first rename A
         * to B and then rename B to A.  While applying the first one,
-        * the presense of B should not stop A from getting renamed to
+        * the presence of B should not stop A from getting renamed to
         * B; ask to_be_deleted() about the later rename.  Removal of
         * B and rename from A to B is handled the same way by asking
         * was_deleted().
index 6371bf96c4841ca263f6bee8a844743c058a5561..00d17d25d1866323f9e1dffcb334a573f5de5221 100644 (file)
@@ -889,6 +889,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
        } else if (new_upstream) {
                struct branch *branch = branch_get(argv[0]);
 
+               if (argc > 1)
+                       die(_("too many branches to set new upstream"));
+
+               if (!branch) {
+                       if (!argc || !strcmp(argv[0], "HEAD"))
+                               die(_("could not set upstream of HEAD to %s when "
+                                     "it does not point to any branch."),
+                                   new_upstream);
+                       die(_("no such branch '%s'"), argv[0]);
+               }
+
                if (!ref_exists(branch->refname))
                        die(_("branch '%s' does not exist"), branch->name);
 
@@ -901,6 +912,16 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                struct branch *branch = branch_get(argv[0]);
                struct strbuf buf = STRBUF_INIT;
 
+               if (argc > 1)
+                       die(_("too many branches to unset upstream"));
+
+               if (!branch) {
+                       if (!argc || !strcmp(argv[0], "HEAD"))
+                               die(_("could not unset upstream of HEAD when "
+                                     "it does not point to any branch."));
+                       die(_("no such branch '%s'"), argv[0]);
+               }
+
                if (!branch_has_merge_config(branch)) {
                        die(_("Branch '%s' has no upstream information"), branch->name);
                }
@@ -916,6 +937,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                int branch_existed = 0, remote_tracking = 0;
                struct strbuf buf = STRBUF_INIT;
 
+               if (!strcmp(argv[0], "HEAD"))
+                       die(_("it does not make sense to create 'HEAD' manually"));
+
+               if (!branch)
+                       die(_("no such branch '%s'"), argv[0]);
+
                if (kinds != REF_LOCAL_BRANCH)
                        die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
 
index ad290007363120062b044ecb47cf976dbe118384..40f87b4649aa97ca1f33a02f09f5938ce5f41f74 100644 (file)
@@ -193,7 +193,7 @@ static int batch_one_object(const char *obj_name, int print_contents)
        unsigned char sha1[20];
        enum object_type type = 0;
        unsigned long size;
-       void *contents;
+       void *contents = NULL;
 
        if (!obj_name)
           return 1;
index 3348aa14e9d5a76fa06e43625c5d74cb047accb6..d21d07a1a8e9fbc365a4555a0f9e81d0c1f2a7d0 100644 (file)
@@ -124,8 +124,10 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
        if (unset)
                strbuf_setlen(buf, 0);
        else {
+               if (buf->len)
+                       strbuf_addch(buf, '\n');
                strbuf_addstr(buf, arg);
-               strbuf_addstr(buf, "\n\n");
+               strbuf_complete_line(buf);
        }
        return 0;
 }
index 04c185b1fbdc51ba9958fdb83d1c6616bcb0c18e..6636a68cd919ba227a10cfa39efcd5f4e77a801d 100644 (file)
@@ -137,40 +137,39 @@ static void add_to_known_names(const char *path,
 
 static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
 {
-       int might_be_tag = !prefixcmp(path, "refs/tags/");
+       int is_tag = !prefixcmp(path, "refs/tags/");
        unsigned char peeled[20];
-       int is_tag, prio;
+       int is_annotated, prio;
 
-       if (!all && !might_be_tag)
+       /* Reject anything outside refs/tags/ unless --all */
+       if (!all && !is_tag)
                return 0;
 
+       /* Accept only tags that match the pattern, if given */
+       if (pattern && (!is_tag || fnmatch(pattern, path + 10, 0)))
+               return 0;
+
+       /* Is it annotated? */
        if (!peel_ref(path, peeled)) {
-               is_tag = !!hashcmp(sha1, peeled);
+               is_annotated = !!hashcmp(sha1, peeled);
        } else {
                hashcpy(peeled, sha1);
-               is_tag = 0;
+               is_annotated = 0;
        }
 
-       /* If --all, then any refs are used.
-        * If --tags, then any tags are used.
-        * Otherwise only annotated tags are used.
+       /*
+        * By default, we only use annotated tags, but with --tags
+        * we fall back to lightweight ones (even without --tags,
+        * we still remember lightweight ones, only to give hints
+        * in an error message).  --all allows any refs to be used.
         */
-       if (might_be_tag) {
-               if (is_tag)
-                       prio = 2;
-               else
-                       prio = 1;
-
-               if (pattern && fnmatch(pattern, path + 10, 0))
-                       prio = 0;
-       }
+       if (is_annotated)
+               prio = 2;
+       else if (is_tag)
+               prio = 1;
        else
                prio = 0;
 
-       if (!all) {
-               if (!prio)
-                       return 0;
-       }
        add_to_known_names(all ? path + 5 : path + 10, peeled, prio, sha1);
        return 0;
 }
@@ -402,8 +401,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
        struct option options[] = {
                OPT_BOOLEAN(0, "contains",   &contains, N_("find the tag that comes after the commit")),
                OPT_BOOLEAN(0, "debug",      &debug, N_("debug search strategy on stderr")),
-               OPT_BOOLEAN(0, "all",        &all, N_("use any ref in .git/refs")),
-               OPT_BOOLEAN(0, "tags",       &tags, N_("use any tag in .git/refs/tags")),
+               OPT_BOOLEAN(0, "all",        &all, N_("use any ref")),
+               OPT_BOOLEAN(0, "tags",       &tags, N_("use any tag, even unannotated")),
                OPT_BOOLEAN(0, "long",       &longformat, N_("always use long format")),
                OPT__ABBREV(&abbrev),
                OPT_SET_INT(0, "exact-match", &max_candidates,
index 77dffd1ce3a5f809a81793f67b9297a555bab1fa..ad9d0c46e8e32471f7c2ede9620b66c0711a4de6 100644 (file)
@@ -43,7 +43,7 @@ static int parse_opt_signed_tag_mode(const struct option *opt,
        else if (!strcmp(arg, "strip"))
                signed_tag_mode = STRIP;
        else
-               return error("Unknown signed-tag mode: %s", arg);
+               return error("Unknown signed-tags mode: %s", arg);
        return 0;
 }
 
@@ -416,7 +416,7 @@ static void handle_tag(const char *name, struct tag *tag)
                        switch(signed_tag_mode) {
                        case ABORT:
                                die ("Encountered signed tag %s; use "
-                                    "--signed-tag=<mode> to handle it.",
+                                    "--signed-tags=<mode> to handle it.",
                                     sha1_to_hex(tag->object.sha1));
                        case WARN:
                                warning ("Exporting signed tag %s",
index b49612f0ce02e0c8503bee77477800297e84065d..265a9253bfd7cacd730789212fdb5284fcd270ac 100644 (file)
@@ -492,7 +492,7 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
 
                if (size == len)
                        ; /* merely annotated */
-               else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig)) {
+               else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig, NULL)) {
                        if (!sig.len)
                                strbuf_addstr(&sig, "gpg verification failed.\n");
                }
index 8025964987553b8f1ef21b8319b2085d6d31bb0c..159e65d47a41b56634bc3fb480f9c051d40e692c 100644 (file)
@@ -820,9 +820,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                unsigned char sha1[20];
                /* Is it a rev? */
                if (!get_sha1(arg, sha1)) {
-                       struct object *object = parse_object(sha1);
-                       if (!object)
-                               die(_("bad object %s"), arg);
+                       struct object *object = parse_object_or_die(sha1, arg);
                        if (!seen_dashdash)
                                verify_non_filename(prefix, arg);
                        add_object_array(object, arg, &list);
index 43d364b8d5e5b0cb4b78be517e78d64c96da4304..79dfe47320e244c3110ce65d5b19fa87ebca3cb5 100644 (file)
@@ -78,6 +78,7 @@ static int nr_threads;
 static int from_stdin;
 static int strict;
 static int verbose;
+static int show_stat;
 
 static struct progress *progress;
 
@@ -108,6 +109,10 @@ static pthread_mutex_t work_mutex;
 #define work_lock()            lock_mutex(&work_mutex)
 #define work_unlock()          unlock_mutex(&work_mutex)
 
+static pthread_mutex_t deepest_delta_mutex;
+#define deepest_delta_lock()   lock_mutex(&deepest_delta_mutex)
+#define deepest_delta_unlock() unlock_mutex(&deepest_delta_mutex)
+
 static pthread_key_t key;
 
 static inline void lock_mutex(pthread_mutex_t *mutex)
@@ -130,6 +135,8 @@ static void init_thread(void)
        init_recursive_mutex(&read_mutex);
        pthread_mutex_init(&counter_mutex, NULL);
        pthread_mutex_init(&work_mutex, NULL);
+       if (show_stat)
+               pthread_mutex_init(&deepest_delta_mutex, NULL);
        pthread_key_create(&key, NULL);
        thread_data = xcalloc(nr_threads, sizeof(*thread_data));
        threads_active = 1;
@@ -143,6 +150,8 @@ static void cleanup_thread(void)
        pthread_mutex_destroy(&read_mutex);
        pthread_mutex_destroy(&counter_mutex);
        pthread_mutex_destroy(&work_mutex);
+       if (show_stat)
+               pthread_mutex_destroy(&deepest_delta_mutex);
        pthread_key_delete(key);
        free(thread_data);
 }
@@ -158,6 +167,9 @@ static void cleanup_thread(void)
 #define work_lock()
 #define work_unlock()
 
+#define deepest_delta_lock()
+#define deepest_delta_unlock()
+
 #endif
 
 
@@ -833,9 +845,13 @@ static void resolve_delta(struct object_entry *delta_obj,
        void *base_data, *delta_data;
 
        delta_obj->real_type = base->obj->real_type;
-       delta_obj->delta_depth = base->obj->delta_depth + 1;
-       if (deepest_delta < delta_obj->delta_depth)
-               deepest_delta = delta_obj->delta_depth;
+       if (show_stat) {
+               delta_obj->delta_depth = base->obj->delta_depth + 1;
+               deepest_delta_lock();
+               if (deepest_delta < delta_obj->delta_depth)
+                       deepest_delta = delta_obj->delta_depth;
+               deepest_delta_unlock();
+       }
        delta_obj->base_object_no = base->obj - objects;
        delta_data = get_data_from_pack(delta_obj);
        base_data = get_base_data(base);
@@ -951,8 +967,10 @@ static void *threaded_second_pass(void *data)
        set_thread_data(data);
        for (;;) {
                int i;
-               work_lock();
+               counter_lock();
                display_progress(progress, nr_resolved_deltas);
+               counter_unlock();
+               work_lock();
                while (nr_dispatched < nr_objects &&
                       is_delta_type(objects[nr_dispatched].type))
                        nr_dispatched++;
@@ -1099,7 +1117,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
        if (fix_thin_pack) {
                struct sha1file *f;
                unsigned char read_sha1[20], tail_sha1[20];
-               char msg[48];
+               struct strbuf msg = STRBUF_INIT;
                int nr_unresolved = nr_deltas - nr_resolved_deltas;
                int nr_objects_initial = nr_objects;
                if (nr_unresolved <= 0)
@@ -1107,11 +1125,14 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
                objects = xrealloc(objects,
                                   (nr_objects + nr_unresolved + 1)
                                   * sizeof(*objects));
+               memset(objects + nr_objects + 1, 0,
+                      nr_unresolved * sizeof(*objects));
                f = sha1fd(output_fd, curr_pack);
                fix_unresolved_deltas(f, nr_unresolved);
-               sprintf(msg, _("completed with %d local objects"),
-                       nr_objects - nr_objects_initial);
-               stop_progress_msg(&progress, msg);
+               strbuf_addf(&msg, _("completed with %d local objects"),
+                           nr_objects - nr_objects_initial);
+               stop_progress_msg(&progress, msg.buf);
+               strbuf_release(&msg);
                sha1close(f, tail_sha1, 0);
                hashcpy(read_sha1, pack_sha1);
                fixup_pack_header_footer(output_fd, pack_sha1,
@@ -1462,7 +1483,7 @@ static void show_pack_info(int stat_only)
 
 int cmd_index_pack(int argc, const char **argv, const char *prefix)
 {
-       int i, fix_thin_pack = 0, verify = 0, stat_only = 0, stat = 0;
+       int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
        const char *curr_pack, *curr_index;
        const char *index_name = NULL, *pack_name = NULL;
        const char *keep_name = NULL, *keep_msg = NULL;
@@ -1495,10 +1516,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                                verify = 1;
                        } else if (!strcmp(arg, "--verify-stat")) {
                                verify = 1;
-                               stat = 1;
+                               show_stat = 1;
                        } else if (!strcmp(arg, "--verify-stat-only")) {
                                verify = 1;
-                               stat = 1;
+                               show_stat = 1;
                                stat_only = 1;
                        } else if (!strcmp(arg, "--keep")) {
                                keep_msg = "";
@@ -1606,7 +1627,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        if (strict)
                check_objects();
 
-       if (stat)
+       if (show_stat)
                show_pack_info(stat_only);
 
        idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
index 2d4327801e4f7766328389311c87dd63d4c5f8e4..06296d4bdf607431bfcb38f0bc6720f555d6917a 100644 (file)
@@ -130,6 +130,27 @@ static int populate_maildir_list(struct string_list *list, const char *path)
        return 0;
 }
 
+static int maildir_filename_cmp(const char *a, const char *b)
+{
+       while (*a && *b) {
+               if (isdigit(*a) && isdigit(*b)) {
+                       long int na, nb;
+                       na = strtol(a, (char **)&a, 10);
+                       nb = strtol(b, (char **)&b, 10);
+                       if (na != nb)
+                               return na - nb;
+                       /* strtol advanced our pointers */
+               }
+               else {
+                       if (*a != *b)
+                               return (unsigned char)*a - (unsigned char)*b;
+                       a++;
+                       b++;
+               }
+       }
+       return (unsigned char)*a - (unsigned char)*b;
+}
+
 static int split_maildir(const char *maildir, const char *dir,
        int nr_prec, int skip)
 {
@@ -139,6 +160,8 @@ static int split_maildir(const char *maildir, const char *dir,
        int i;
        struct string_list list = STRING_LIST_INIT_DUP;
 
+       list.cmp = maildir_filename_cmp;
+
        if (populate_maildir_list(&list, maildir) < 0)
                goto out;
 
index e0d0b7d28b9e1e67fe6ea6521a683df89f5c9416..bc912e399efa295615e9bfaac0de03904edff367 100644 (file)
@@ -245,7 +245,7 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3])
        unsigned dirmask = 0, mask = 0;
 
        for (i = 0; i < 3; i++) {
-               mask |= (1 << 1);
+               mask |= (1 << i);
                if (n[i].mode && S_ISDIR(n[i].mode))
                        dirmask |= (1 << i);
        }
index 8cb8b9186a3a268630680e4b224d3767017e1e38..85843d4f1728a907aafab9938b4c827990a7695f 100644 (file)
@@ -149,9 +149,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
                const char *name = *argv++;
 
                if (!get_sha1(name, sha1)) {
-                       struct object *object = parse_object(sha1);
-                       if (!object)
-                               die("bad object: %s", name);
+                       struct object *object = parse_object_or_die(sha1, name);
                        add_pending_object(&revs, object, "");
                }
                else
index 1fedf66329d73f192d80d3d42789c290a839d7b0..72a0af70c3dcd7d108887cd289bc7b3c606226aa 100644 (file)
@@ -414,7 +414,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
                if (cb.unreachable_expire_kind == UE_HEAD) {
                        struct commit_list *elem;
                        for (elem = tips; elem; elem = elem->next)
-                               clear_commit_marks(tip_commit, REACHABLE);
+                               clear_commit_marks(elem->item, REACHABLE);
                        free_commit_list(tips);
                } else {
                        clear_commit_marks(tip_commit, REACHABLE);
index f8266888cca97f492dc5b52a992b1dc7cab2909e..af3af3f64935c3f92ed3f85acd44ed2ca2a35b3f 100644 (file)
@@ -582,7 +582,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                die(_("%s: cannot lock the ref"), ref.buf);
        if (write_ref_sha1(lock, object, NULL) < 0)
                die(_("%s: cannot update the ref"), ref.buf);
-       if (force && hashcmp(prev, object))
+       if (force && !is_null_sha1(prev) && hashcmp(prev, object))
                printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev, DEFAULT_ABBREV));
 
        strbuf_release(&buf);
index ada1dff846f2b77d5f71d69db57a7eca5033b943..5c7762eef404e7ea21d88991a81407f1cb99f306 100644 (file)
@@ -796,7 +796,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
        };
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
-               usage(update_index_usage[0]);
+               usage_with_options(update_index_usage, options);
 
        git_config(git_default_config, NULL);
 
index a8eee886a5281965a0660308df9e94d14c1cb2b8..9cdf332333b95b3ab2ea6e133f345105bd67d019 100644 (file)
@@ -29,7 +29,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
        if (size == len)
                return error("no signature found");
 
-       return verify_signed_buffer(buf, len, buf + len, size - len, NULL);
+       return verify_signed_buffer(buf, len, buf + len, size - len, NULL, NULL);
 }
 
 static int verify_tag(const char *name, int verbose)
index 8d12816b9d0bc682ed9c019a7a5d5cec4b859171..505e07e93468b68454c7ec906f40eacea9746551 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -183,17 +183,17 @@ int verify_bundle(struct bundle_header *header, int verbose)
                struct ref_list *r;
 
                r = &header->references;
-               printf_ln(Q_("The bundle contains %d ref",
-                            "The bundle contains %d refs",
+               printf_ln(Q_("The bundle contains this ref:",
+                            "The bundle contains these %d refs:",
                             r->nr),
                          r->nr);
                list_refs(r, 0, NULL);
+               r = &header->prerequisites;
                if (!r->nr) {
                        printf_ln(_("The bundle records a complete history."));
                } else {
-                       r = &header->prerequisites;
-                       printf_ln(Q_("The bundle requires this ref",
-                                    "The bundle requires these %d refs",
+                       printf_ln(Q_("The bundle requires this ref:",
+                                    "The bundle requires these %d refs:",
                                     r->nr),
                                  r->nr);
                        list_refs(r, 0, NULL);
@@ -279,12 +279,12 @@ int create_bundle(struct bundle_header *header, const char *path,
                if (buf.len > 0 && buf.buf[0] == '-') {
                        write_or_die(bundle_fd, buf.buf, buf.len);
                        if (!get_sha1_hex(buf.buf + 1, sha1)) {
-                               struct object *object = parse_object(sha1);
+                               struct object *object = parse_object_or_die(sha1, buf.buf);
                                object->flags |= UNINTERESTING;
                                add_pending_object(&revs, object, xstrdup(buf.buf));
                        }
                } else if (!get_sha1_hex(buf.buf, sha1)) {
-                       struct object *object = parse_object(sha1);
+                       struct object *object = parse_object_or_die(sha1, buf.buf);
                        object->flags |= SHOWN;
                }
        }
@@ -361,7 +361,7 @@ int create_bundle(struct bundle_header *header, const char *path,
                                 * end up triggering "empty bundle"
                                 * error.
                                 */
-                               obj = parse_object(sha1);
+                               obj = parse_object_or_die(sha1, e->name);
                                obj->flags |= SHOWN;
                                add_pending_object(&revs, obj, e->name);
                        }
diff --git a/cache.h b/cache.h
index e493563f4c07e6adcd00a1b2476926d69a4a67f8..bb71bf8a7f92bafb16699e7a53cd206042d0465a 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -131,7 +131,6 @@ struct cache_entry {
        unsigned int ce_namelen;
        unsigned char sha1[20];
        struct cache_entry *next;
-       struct cache_entry *dir_next;
        char name[FLEX_ARRAY]; /* more */
 };
 
@@ -267,25 +266,15 @@ struct index_state {
        unsigned name_hash_initialized : 1,
                 initialized : 1;
        struct hash_table name_hash;
+       struct hash_table dir_hash;
 };
 
 extern struct index_state the_index;
 
 /* Name hashing */
 extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
-/*
- * We don't actually *remove* it, we can just mark it invalid so that
- * we won't find it in lookups.
- *
- * Not only would we have to search the lists (simple enough), but
- * we'd also have to rehash other hash buckets in case this makes the
- * hash bucket empty (common). So it's much better to just mark
- * it.
- */
-static inline void remove_name_hash(struct cache_entry *ce)
-{
-       ce->ce_flags |= CE_UNHASHED;
-}
+extern void remove_name_hash(struct index_state *istate, struct cache_entry *ce);
+extern void free_name_hash(struct index_state *istate);
 
 
 #ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
@@ -341,9 +330,11 @@ static inline enum object_type object_type(unsigned int mode)
                OBJ_BLOB;
 }
 
+/* Double-check local_repo_env below if you add to this list. */
 #define GIT_DIR_ENVIRONMENT "GIT_DIR"
 #define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE"
 #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
+#define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX"
 #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
 #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
@@ -365,13 +356,24 @@ static inline enum object_type object_type(unsigned int mode)
 #define GIT_LITERAL_PATHSPECS_ENVIRONMENT "GIT_LITERAL_PATHSPECS"
 
 /*
- * Repository-local GIT_* environment variables
- * The array is NULL-terminated to simplify its usage in contexts such
- * environment creation or simple walk of the list.
- * The number of non-NULL entries is available as a macro.
+ * This environment variable is expected to contain a boolean indicating
+ * whether we should or should not treat:
+ *
+ *   GIT_DIR=foo.git git ...
+ *
+ * as if GIT_WORK_TREE=. was given. It's not expected that users will make use
+ * of this, but we use it internally to communicate to sub-processes that we
+ * are in a bare repo. If not set, defaults to true.
+ */
+#define GIT_IMPLICIT_WORK_TREE_ENVIRONMENT "GIT_IMPLICIT_WORK_TREE"
+
+/*
+ * Repository-local GIT_* environment variables; these will be cleared
+ * when git spawns a sub-process that runs inside another repository.
+ * The array is NULL-terminated, which makes it easy to pass in the "env"
+ * parameter of a run-command invocation, or to do a simple walk.
  */
-#define LOCAL_REPO_ENV_SIZE 9
-extern const char *const local_repo_env[LOCAL_REPO_ENV_SIZE + 1];
+extern const char * const local_repo_env[];
 
 extern int is_bare_repository_cfg;
 extern int is_bare_repository(void);
index e8eb0aec5509a4fd09698bd15a37d1f4e8341f5e..1a41757ee377d804782ccfb4e27c54b607dcf91d 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -834,7 +834,7 @@ struct commit_list *get_merge_bases(struct commit *one, struct commit *two,
 }
 
 /*
- * Is "commit" a decendant of one of the elements on the "with_commit" list?
+ * Is "commit" a descendant of one of the elements on the "with_commit" list?
  */
 int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
 {
index 4138bb4c0850f95ba7215cb62f457cd682495968..252c7f871c1c90423ae11190ba98cea5b94422de 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -164,7 +164,7 @@ extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *r
 extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
 extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
 
-/* largest postive number a signed 32-bit integer can contain */
+/* largest positive number a signed 32-bit integer can contain */
 #define INFINITE_DEPTH 0x7fffffff
 
 extern int register_shallow(const unsigned char *sha1);
index ff7c2c4fd8642da754b1c85a9e177baf4ddc7136..1401a6727414480e181023f8de974bad76a04d24 100644 (file)
@@ -4778,7 +4778,7 @@ void* dlmalloc(size_t bytes) {
 
 void dlfree(void* mem) {
   /*
-     Consolidate freed chunks with preceeding or succeeding bordering
+     Consolidate freed chunks with preceding or succeeding bordering
      free chunks, if they exist, and then place in a bin.  Intermixed
      with special cases for top, dv, mmapped chunks, and usage errors.
   */
@@ -5680,10 +5680,10 @@ int mspace_mallopt(int param_number, int value) {
        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
       * Use last_remainder in more cases.
       * Pack bins using idea from  colin@nyx10.cs.du.edu
-      * Use ordered bins instead of best-fit threshhold
+      * Use ordered bins instead of best-fit threshold
       * Eliminate block-local decls to simplify tracing and debugging.
       * Support another case of realloc via move into top
-      * Fix error occuring when initial sbrk_base not word-aligned.
+      * Fix error occurring when initial sbrk_base not word-aligned.
       * Rely on page size for units instead of SBRK_UNIT to
        avoid surprises about sbrk alignment conventions.
       * Add mallinfo, mallopt. Thanks to Raymond Nijssen
index d178bd67162fd2b566364ac6dff84cecdcaa9473..ceb4bdbcdd6ed583ab3b7c9cc5d9d2783128dee6 100644 (file)
@@ -128,7 +128,7 @@ extern "C" {
 
 #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
 
-/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
+/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case
    where pointers can be converted to integers, aligned as integers,
    and converted back again.  If PTR_INT_TYPE is narrower than a
    pointer (e.g., the AS/400), play it safe and compute the alignment
index 8cf59558e1c6fcc6782b8eaf94534ea041599191..030174db515e764aa883b21afe9be8fb3ae41f2e 100644 (file)
@@ -134,7 +134,7 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir)
                        if (prec_dir->ic_precompose == (iconv_t)-1) {
                                die("iconv_open(%s,%s) failed, but needed:\n"
                                                "    precomposed unicode is not supported.\n"
-                                               "    If you wnat to use decomposed unicode, run\n"
+                                               "    If you want to use decomposed unicode, run\n"
                                                "    \"git config core.precomposeunicode false\"\n",
                                                repo_encoding, path_encoding);
                        } else {
index 8c96ed942c3f7139a4b161c75c6c81e42530c085..d0025bd58d48cfcf137e5ef3bba90881dc00ec68 100644 (file)
@@ -2095,7 +2095,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
 
 /* Entry point of the parser.
    Parse the regular expression REGEXP and return the structure tree.
-   If an error is occured, ERR is set by error code, and return NULL.
+   If an error has occurred, ERR is set by error code, and return NULL.
    This function build the following tree, from regular expression <reg_exp>:
           CAT
           / \
@@ -3715,7 +3715,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
 /* This is intended for the expressions like "a{1,3}".
    Fetch a number from `input', and return the number.
    Return -1, if the number field is empty like "{,1}".
-   Return -2, If an error is occured.  */
+   Return -2, if an error has occurred.  */
 
 static int
 fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
index 3dd8dfa01f2a6ab7a197ecddd481704150253c36..6aaae003274e268f274df4b76e02609d5f27e457 100644 (file)
@@ -22,7 +22,7 @@
 #include "config.h"
 #endif
 
-/* Make sure noone compiles this code with a C++ compiler.  */
+/* Make sure no one compiles this code with a C++ compiler.  */
 #ifdef __cplusplus
 # error "This is C code, use a C compiler"
 #endif
index 193854cf5b609d714b03218bd507af840d478c6e..d4121f2f4f1cfa9bf90c22b6e3c944f451225fdf 100644 (file)
@@ -1284,7 +1284,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
 
 /* Insert the new element ELEM to the re_node_set* SET.
    SET should not already have ELEM.
-   return -1 if an error is occured, return 1 otherwise.  */
+   return -1 if an error has occurred, return 1 otherwise.  */
 
 static int
 internal_function
@@ -1341,7 +1341,7 @@ re_node_set_insert (re_node_set *set, int elem)
 
 /* Insert the new element ELEM to the re_node_set* SET.
    SET should not already have any element greater than or equal to ELEM.
-   Return -1 if an error is occured, return 1 otherwise.  */
+   Return -1 if an error has occurred, return 1 otherwise.  */
 
 static int
 internal_function
@@ -1416,7 +1416,7 @@ re_node_set_remove_at (re_node_set *set, int idx)
 \f
 
 /* Add the token TOKEN to dfa->nodes, and return the index of the token.
-   Or return -1, if an error will be occured.  */
+   Or return -1, if an error has occurred.  */
 
 static int
 internal_function
index 41f61c5db3378d234b2d1f5e67d0fc180bea678a..f2cdefee605aebe6c577129ae2c8cd76a3555a96 100644 (file)
@@ -401,7 +401,7 @@ static void usage(const char *name)
        const char *basename = strrchr(name,'/');
 
        basename = (basename) ? basename + 1 : name;
-       fprintf(stderr, "Usage: %s <", basename);
+       fprintf(stderr, "usage: %s <", basename);
        while(try_op->name) {
                fprintf(stderr,"%s",(try_op++)->name);
                if(try_op->name)
index 6beed123ab1f46f43b35059384d6ecfdc571ee7c..3940202b36ce00a77bdc2e17a6002dac158afcb6 100644 (file)
@@ -154,7 +154,7 @@ static void read_credential(void)
 int main(int argc, const char **argv)
 {
        const char *usage =
-               "Usage: git credential-osxkeychain <get|store|erase>";
+               "usage: git credential-osxkeychain <get|store|erase>";
 
        if (!argv[1])
                die(usage);
index dac19eac81665b4f809688255b2eb9aca6874f20..a1d38f035bea404aa9a5fa37518f0af21143dbf0 100644 (file)
@@ -259,7 +259,7 @@ static void read_credential(void)
 int main(int argc, char *argv[])
 {
        const char *usage =
-           "Usage: git credential-wincred <get|store|erase>\n";
+           "usage: git credential-wincred <get|store|erase>\n";
 
        if (!argv[1])
                die(usage);
index b17952a785d9e45dea8a71c211f76f0271e659da..d42df7b4188672e01dd7c95d5dcd73939f0fd600 100755 (executable)
@@ -347,7 +347,7 @@ sub rm_remote {
 }
 
 sub add_usage {
-       print STDERR "Usage: git remote add [-f] [-t track]* [-m master] <name> <url>\n";
+       print STDERR "usage: git remote add [-f] [-t track]* [-m master] <name> <url>\n";
        exit(1);
 }
 
@@ -380,7 +380,7 @@ sub add_usage {
                }
        }
        if ($i >= @ARGV) {
-               print STDERR "Usage: git remote show <remote>\n";
+               print STDERR "usage: git remote show <remote>\n";
                exit(1);
        }
        my $status = 0;
@@ -410,7 +410,7 @@ sub add_usage {
                }
        }
        if ($i >= @ARGV) {
-               print STDERR "Usage: git remote prune <remote>\n";
+               print STDERR "usage: git remote prune <remote>\n";
                exit(1);
        }
        my $status = 0;
@@ -458,13 +458,13 @@ sub add_usage {
 }
 elsif ($ARGV[0] eq 'rm') {
        if (@ARGV <= 1) {
-               print STDERR "Usage: git remote rm <remote>\n";
+               print STDERR "usage: git remote rm <remote>\n";
                exit(1);
        }
        exit(rm_remote($ARGV[1]));
 }
 else {
-       print STDERR "Usage: git remote\n";
+       print STDERR "usage: git remote\n";
        print STDERR "       git remote add <name> <url>\n";
        print STDERR "       git remote rm <name>\n";
        print STDERR "       git remote show <name>\n";
index b09ff8f12f7e5b5b6faeaf857d7c61973de8590e..c414f0d9c7ecfac7074d0e052c19f73cae4344d1 100755 (executable)
@@ -36,7 +36,7 @@
 
 sub usage() {
        print STDERR <<END;
-Usage: ${\basename $0}     # fetch/update GIT from SVN
+usage: ${\basename $0}     # fetch/update GIT from SVN
        [-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]
        [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
        [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
index f9fef6db28dbba0ef67589f05eeb937760d2facf..0891b9e366725cc7bbf9ce996839fdf182a6422c 100755 (executable)
@@ -7,7 +7,7 @@
 use strict;
 use File::Find;
 
-my $USAGE = 'Usage: git-import branch import-message';
+my $USAGE = 'usage: git-import branch import-message';
 my $branch = shift or die "$USAGE\n";
 my $message = shift or die "$USAGE\n";
 
index 0ca7718d0518db2e559ecd17eb6f7f57338b80fd..f8d803c5e2bea65f1fb458d23f80bd7717f2a8c9 100755 (executable)
@@ -5,7 +5,7 @@
 # but is meant to be a simple fast-import example.
 
 if [ -z "$1" -o -z "$2" ]; then
-       echo "Usage: git-import branch import-message"
+       echo "usage: git-import branch import-message"
        exit 1
 fi
 
index 5cec9b012994de61ba6ed1e4c17992edbfd8a07d..d12c2962230b80b5e6310ade8424d9b60cc37d20 100755 (executable)
 from zipfile import ZipFile
 
 if hexversion < 0x01060000:
-        # The limiter is the zipfile module
-        sys.stderr.write("import-zips.py: requires Python 1.6.0 or later.\n")
-        sys.exit(1)
+    # The limiter is the zipfile module
+    stderr.write("import-zips.py: requires Python 1.6.0 or later.\n")
+    exit(1)
 
 if len(argv) < 2:
-       print 'Usage:', argv[0], '<zipfile>...'
-       exit(1)
+    print 'usage:', argv[0], '<zipfile>...'
+    exit(1)
 
 branch_ref = 'refs/heads/import-zips'
 committer_name = 'Z Ip Creator'
 
 fast_import = popen('git fast-import --quiet', 'w')
 def printlines(list):
-       for str in list:
-               fast_import.write(str + "\n")
+    for str in list:
+        fast_import.write(str + "\n")
 
 for zipfile in argv[1:]:
-       commit_time = 0
-       next_mark = 1
-       common_prefix = None
-       mark = dict()
-
-       zip = ZipFile(zipfile, 'r')
-       for name in zip.namelist():
-               if name.endswith('/'):
-                       continue
-               info = zip.getinfo(name)
-
-               if commit_time < info.date_time:
-                       commit_time = info.date_time
-               if common_prefix == None:
-                       common_prefix = name[:name.rfind('/') + 1]
-               else:
-                       while not name.startswith(common_prefix):
-                               last_slash = common_prefix[:-1].rfind('/') + 1
-                               common_prefix = common_prefix[:last_slash]
-
-               mark[name] = ':' + str(next_mark)
-               next_mark += 1
-
-               printlines(('blob', 'mark ' + mark[name], \
-                                       'data ' + str(info.file_size)))
-               fast_import.write(zip.read(name) + "\n")
-
-       committer = committer_name + ' <' + committer_email + '> %d +0000' % \
-               mktime(commit_time + (0, 0, 0))
-
-       printlines(('commit ' + branch_ref, 'committer ' + committer, \
-               'data <<EOM', 'Imported from ' + zipfile + '.', 'EOM', \
-               '', 'deleteall'))
-
-       for name in mark.keys():
-               fast_import.write('M 100644 ' + mark[name] + ' ' +
-                       name[len(common_prefix):] + "\n")
-
-       printlines(('',  'tag ' + path.basename(zipfile), \
-               'from ' + branch_ref, 'tagger ' + committer, \
-               'data <<EOM', 'Package ' + zipfile, 'EOM', ''))
+    commit_time = 0
+    next_mark = 1
+    common_prefix = None
+    mark = dict()
+
+    zip = ZipFile(zipfile, 'r')
+    for name in zip.namelist():
+        if name.endswith('/'):
+            continue
+        info = zip.getinfo(name)
+
+        if commit_time < info.date_time:
+            commit_time = info.date_time
+        if common_prefix == None:
+            common_prefix = name[:name.rfind('/') + 1]
+        else:
+            while not name.startswith(common_prefix):
+                last_slash = common_prefix[:-1].rfind('/') + 1
+                common_prefix = common_prefix[:last_slash]
+
+        mark[name] = ':' + str(next_mark)
+        next_mark += 1
+
+        printlines(('blob', 'mark ' + mark[name], \
+                    'data ' + str(info.file_size)))
+        fast_import.write(zip.read(name) + "\n")
+
+    committer = committer_name + ' <' + committer_email + '> %d +0000' % \
+        mktime(commit_time + (0, 0, 0))
+
+    printlines(('commit ' + branch_ref, 'committer ' + committer, \
+        'data <<EOM', 'Imported from ' + zipfile + '.', 'EOM', \
+        '', 'deleteall'))
+
+    for name in mark.keys():
+        fast_import.write('M 100644 ' + mark[name] + ' ' +
+            name[len(common_prefix):] + "\n")
+
+    printlines(('',  'tag ' + path.basename(zipfile), \
+        'from ' + branch_ref, 'tagger ' + committer, \
+        'data <<EOM', 'Package ' + zipfile, 'EOM', ''))
 
 if fast_import.close():
-       exit(1)
+    exit(1)
index a577ad095f1cfea1c11efe53c4cd82625e508594..2770a1b1d205ee6b6edaec291a7dce3fc417027f 100644 (file)
@@ -24,7 +24,7 @@
 use File::Basename;
 
 my $usage =
-"Usage: setgitperms.perl [OPTION]... <--read|--write>
+"usage: setgitperms.perl [OPTION]... <--read|--write>
 This program uses a file `.gitmeta` to store/restore permissions and uid/gid
 info for all files/dirs tracked by git in the repository.
 
index 094129de09ca92643d98f34f20a35479089bcbcb..9c14c1f88d3a8f23df54db2adc7985eb00722c12 100755 (executable)
@@ -28,7 +28,7 @@
 use constant SLASH_REPLACEMENT => "%2F";
 
 # It's not always possible to delete pages (may require some
-# priviledges). Deleted pages are replaced with this content.
+# privileges). Deleted pages are replaced with this content.
 use constant DELETED_CONTENT => "[[Category:Deleted]]\n";
 
 # It's not possible to create empty pages. New empty files in Git are
@@ -841,7 +841,7 @@ sub mw_import_ref {
        if ($fetch_from == 1 && $n == 0) {
                print STDERR "You appear to have cloned an empty MediaWiki.\n";
                # Something has to be done remote-helper side. If nothing is done, an error is
-               # thrown saying that HEAD is refering to unknown object 0000000000000000000
+               # thrown saying that HEAD is referring to unknown object 0000000000000000000
                # and the clone fails.
        }
 }
@@ -1067,7 +1067,7 @@ sub mw_push_file {
                my $file_content;
                if ($page_deleted) {
                        # Deleting a page usually requires
-                       # special priviledges. A common
+                       # special privileges. A common
                        # convention is to replace the page
                        # with this content instead:
                        $file_content = DELETED_CONTENT;
index 4d211f5b81ae3f96938211c4bd2e20789d38fcdb..23b7ef9f6208720310d2a8d93812cbe6fb3a42ca 100644 (file)
@@ -4,4 +4,4 @@ objects from mediawiki just as one would do with a classic git
 repository thanks to remote-helpers.
 
 For more information, visit the wiki at
-https://github.com/Bibzball/Git-Mediawiki/wiki
+https://github.com/moy/Git-Mediawiki/wiki
index 96e97390cf90822e771bc8ccf600c394792f2b96..03f6ee5d72f5096e287c23e048746fe1f756f062 100644 (file)
@@ -25,7 +25,7 @@ Principles and Technical Choices
 
 The test environment makes it easy to install and manipulate one or
 several MediaWiki instances. To allow developers to run the testsuite
-easily, the environment does not require root priviledge (except to
+easily, the environment does not require root privilege (except to
 install the required packages if needed). It starts a webserver
 instance on the user's account (using lighttpd greatly helps for
 that), and does not need a separate database daemon (thanks to the use
@@ -81,7 +81,7 @@ parameters, please refer to the `test-gitmw-lib.sh` and
 
 ** `test_check_wiki_precond`:
 Check if the tests must be skipped or not. Please use this function
-at the beggining of each new test file.
+at the beginning of each new test file.
 
 ** `wiki_getpage`:
 Fetch a given page from the wiki and puts its content in the
@@ -113,7 +113,7 @@ Tests if a given page exists on the wiki.
 
 ** `wiki_reset`:
 Reset the wiki, i.e. flush the database. Use this function at the
-begining of each new test, except if the test re-uses the same wiki
+beginning of each new test, except if the test re-uses the same wiki
 (and history) as the previous test.
 
 How to write a new test
index c6d6fa3aefafa8f782be20b7919f2acfc7667a6f..70a53f67fd06bd2ce6f2f544655b03b99c6b2ee9 100755 (executable)
@@ -15,7 +15,7 @@ fi
 
 . "$WIKI_TEST_DIR"/test-gitmw-lib.sh
 usage () {
-       echo "Usage: "
+       echo "usage: "
        echo "  ./install-wiki.sh <install | delete | --help>"
        echo "          install | -i :  Install a wiki on your computer."
        echo "          delete | -d : Delete the wiki and all its pages and "
index 29f125116b59ed408339a37dbf82f2d913877d78..745e47e88173cac83c65b1c47d087cc98ec28621 100644 (file)
@@ -88,7 +88,7 @@ $wgShellLocale = "en_US.utf8";
 
 ## Set $wgCacheDirectory to a writable directory on the web server
 ## to make your wiki go slightly faster. The directory should not
-## be publically accessible from the web.
+## be publicly accessible from the web.
 #$wgCacheDirectory = "$IP/cache";
 
 # Site language code, should be one of the list in ./languages/Names.php
index b6405ce2628480240fc92ac5d69307991f2d5c69..37021e200a32d36e37f5c0ca7f6cacdca7d80187 100755 (executable)
@@ -139,7 +139,7 @@ test_expect_success 'character $ in file name (git -> mw) ' '
 '
 
 
-test_expect_failure 'capital at the begining of file names' '
+test_expect_failure 'capital at the beginning of file names' '
        wiki_reset &&
        git clone mediawiki::'"$WIKI_URL"' mw_dir_10 &&
        (
@@ -156,7 +156,7 @@ test_expect_failure 'capital at the begining of file names' '
 '
 
 
-test_expect_failure 'special character at the begining of file name from mw to git' '
+test_expect_failure 'special character at the beginning of file name from mw to git' '
        wiki_reset &&
        git clone mediawiki::'"$WIKI_URL"' mw_dir_11 &&
        wiki_editpage {char_1 "expect to be renamed {char_1" false &&
@@ -189,7 +189,7 @@ test_expect_success 'Push page with title containing ":" other than namespace se
        wiki_page_exist NotANameSpace:Page
 '
 
-test_expect_success 'test of correct formating for file name from mw to git' '
+test_expect_success 'test of correct formatting for file name from mw to git' '
        wiki_reset &&
        git clone mediawiki::'"$WIKI_URL"' mw_dir_12 &&
        wiki_editpage char_%_7b_1 "expect to be renamed char{_1" false &&
@@ -207,7 +207,7 @@ test_expect_success 'test of correct formating for file name from mw to git' '
 '
 
 
-test_expect_failure 'test of correct formating for file name begining with special character' '
+test_expect_failure 'test of correct formatting for file name beginning with special character' '
        wiki_reset &&
        git clone mediawiki::'"$WIKI_URL"' mw_dir_13 &&
        (
@@ -215,7 +215,7 @@ test_expect_failure 'test of correct formating for file name begining with speci
                echo "my new file {char_1" >\{char_1.mw &&
                echo "my new file [char_2" >\[char_2.mw &&
                git add . &&
-               git commit -am "commiting some exotic file name..." &&
+               git commit -am "committing some exotic file name..." &&
                git push &&
                git pull
        ) &&
@@ -226,7 +226,7 @@ test_expect_failure 'test of correct formating for file name begining with speci
 '
 
 
-test_expect_success 'test of correct formating for file name from git to mw' '
+test_expect_success 'test of correct formatting for file name from git to mw' '
        wiki_reset &&
        git clone mediawiki::'"$WIKI_URL"' mw_dir_14 &&
        (
@@ -234,7 +234,7 @@ test_expect_success 'test of correct formating for file name from git to mw' '
                echo "my new file char{_1" >Char\{_1.mw &&
                echo "my new file char[_2" >Char\[_2.mw &&
                git add . &&
-               git commit -m "commiting some exotic file name..." &&
+               git commit -m "committing some exotic file name..." &&
                git push
        ) &&
        wiki_getallpage ref_page_14 &&
index 5f81dfae6c4a31f11ed766dd467fdd4a542afdf3..7bb81f2f8e0e288eb7e392075491fc1df0bd91d1 100755 (executable)
@@ -115,7 +115,7 @@ test_expect_success 'update bookmark' '
   git push
   ) &&
 
-  hg -R hgrepo bookmarks | grep "devel\s\+3:"
+  hg -R hgrepo bookmarks | egrep "devel[        ]+3:"
 '
 
 test_done
index 80d339960bbd5f70d17472a6f39f715dd8ec9182..b0f8536fca58d910f85334727b89925651bfa8ae 100755 (executable)
@@ -419,7 +419,7 @@ test_expect_success 'add main-sub5' '
 test_expect_success 'split for main-sub5 without --onto' '
         # also test that we still can split out an entirely new subtree
         # if the parent of the first commit in the tree is not empty,
-        # then the new subtree has accidently been attached to something
+       # then the new subtree has accidentally been attached to something
         git subtree split --prefix subdir2 --branch mainsub5 &&
         check_equal ''"$(git log --pretty=format:%P -1 mainsub5)"'' ""
 '
index 4602b46a5c39e1d501143ab4e95b55aff5c8f23b..df8c0ab0588e70ad6e6f56195535030055782d85 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -9,10 +9,6 @@
 #define HOST_NAME_MAX 256
 #endif
 
-#ifndef NI_MAXSERV
-#define NI_MAXSERV 32
-#endif
-
 #ifdef NO_INITGROUPS
 #define initgroups(x, y) (0) /* nothing */
 #endif
diff --git a/diff.c b/diff.c
index 052974eb9729cca92c9e86be6e71f46052bcb788..0eb26535f52adf516961672628f2810e55a31a9d 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1264,6 +1264,7 @@ static char *pprint_rename(const char *a, const char *b)
        const char *new = b;
        struct strbuf name = STRBUF_INIT;
        int pfx_length, sfx_length;
+       int pfx_adjust_for_slash;
        int len_a = strlen(a);
        int len_b = strlen(b);
        int a_midlen, b_midlen;
@@ -1290,7 +1291,18 @@ static char *pprint_rename(const char *a, const char *b)
        old = a + len_a;
        new = b + len_b;
        sfx_length = 0;
-       while (a <= old && b <= new && *old == *new) {
+       /*
+        * If there is a common prefix, it must end in a slash.  In
+        * that case we let this loop run 1 into the prefix to see the
+        * same slash.
+        *
+        * If there is no common prefix, we cannot do this as it would
+        * underrun the input strings.
+        */
+       pfx_adjust_for_slash = (pfx_length ? 1 : 0);
+       while (a + pfx_length - pfx_adjust_for_slash <= old &&
+              b + pfx_length - pfx_adjust_for_slash <= new &&
+              *old == *new) {
                if (*old == '/')
                        sfx_length = len_a - (old - a);
                old--;
@@ -1553,7 +1565,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
         * Binary files are displayed with "Bin XXX -> YYY bytes"
         * instead of the change count and graph. This part is treated
         * similarly to the graph part, except that it is not
-        * "scaled". If total width is too small to accomodate the
+        * "scaled". If total width is too small to accommodate the
         * guaranteed minimum width of the filename part and the
         * separators and this message, this message will "overflow"
         * making the line longer than the maximum width.
diff --git a/dir.c b/dir.c
index 57394e452eb0de117b27f64804e529b617a6c7e0..1e42b2b1509e2cf154a1d9722138fbeae437daf5 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -59,6 +59,35 @@ inline int git_fnmatch(const char *pattern, const char *string,
        return fnmatch(pattern, string, fnm_flags);
 }
 
+static int fnmatch_icase_mem(const char *pattern, int patternlen,
+                            const char *string, int stringlen,
+                            int flags)
+{
+       int match_status;
+       struct strbuf pat_buf = STRBUF_INIT;
+       struct strbuf str_buf = STRBUF_INIT;
+       const char *use_pat = pattern;
+       const char *use_str = string;
+
+       if (pattern[patternlen]) {
+               strbuf_add(&pat_buf, pattern, patternlen);
+               use_pat = pat_buf.buf;
+       }
+       if (string[stringlen]) {
+               strbuf_add(&str_buf, string, stringlen);
+               use_str = str_buf.buf;
+       }
+
+       if (ignore_case)
+               flags |= WM_CASEFOLD;
+       match_status = wildmatch(use_pat, use_str, flags, NULL);
+
+       strbuf_release(&pat_buf);
+       strbuf_release(&str_buf);
+
+       return match_status;
+}
+
 static size_t common_prefix_len(const char **pathspec)
 {
        const char *n, *first;
@@ -626,15 +655,20 @@ int match_basename(const char *basename, int basenamelen,
                   int flags)
 {
        if (prefix == patternlen) {
-               if (!strcmp_icase(pattern, basename))
+               if (patternlen == basenamelen &&
+                   !strncmp_icase(pattern, basename, basenamelen))
                        return 1;
        } else if (flags & EXC_FLAG_ENDSWITH) {
+               /* "*literal" matching against "fooliteral" */
                if (patternlen - 1 <= basenamelen &&
-                   !strcmp_icase(pattern + 1,
-                                 basename + basenamelen - patternlen + 1))
+                   !strncmp_icase(pattern + 1,
+                                  basename + basenamelen - (patternlen - 1),
+                                  patternlen - 1))
                        return 1;
        } else {
-               if (fnmatch_icase(pattern, basename, 0) == 0)
+               if (fnmatch_icase_mem(pattern, patternlen,
+                                     basename, basenamelen,
+                                     0) == 0)
                        return 1;
        }
        return 0;
@@ -654,6 +688,7 @@ int match_pathname(const char *pathname, int pathlen,
         */
        if (*pattern == '/') {
                pattern++;
+               patternlen--;
                prefix--;
        }
 
@@ -680,13 +715,22 @@ int match_pathname(const char *pathname, int pathlen,
                if (strncmp_icase(pattern, name, prefix))
                        return 0;
                pattern += prefix;
+               patternlen -= prefix;
                name    += prefix;
                namelen -= prefix;
+
+               /*
+                * If the whole pattern did not have a wildcard,
+                * then our prefix match is all we need; we
+                * do not need to call fnmatch at all.
+                */
+               if (!patternlen && !namelen)
+                       return 1;
        }
 
-       return wildmatch(pattern, name,
-                        WM_PATHNAME | (ignore_case ? WM_CASEFOLD : 0),
-                        NULL) == 0;
+       return fnmatch_icase_mem(pattern, patternlen,
+                                name, namelen,
+                                WM_PATHNAME) == 0;
 }
 
 /*
diff --git a/entry.c b/entry.c
index 17a6bccec64e0e523aacc124611c43bd818372e3..63c52edf600b5fd966e24cc5758bdab7dbeaf41b 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -145,7 +145,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
        struct stat st;
 
        if (ce_mode_s_ifmt == S_IFREG) {
-               struct stream_filter *filter = get_stream_filter(path, ce->sha1);
+               struct stream_filter *filter = get_stream_filter(ce->name, ce->sha1);
                if (filter &&
                    !streaming_write_entry(ce, path, filter,
                                           state, to_tempfile,
index 89d6c70c15a95aff82f0063e3c0dd6bdab026213..e2e75c16602d8e5841c2461defaba7b9866115d8 100644 (file)
@@ -83,20 +83,20 @@ static const char *git_dir;
 static char *git_object_dir, *git_index_file, *git_graft_file;
 
 /*
- * Repository-local GIT_* environment variables
- * Remember to update local_repo_env_size in cache.h when
- * the size of the list changes
+ * Repository-local GIT_* environment variables; see cache.h for details.
  */
-const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
+const char * const local_repo_env[] = {
        ALTERNATE_DB_ENVIRONMENT,
        CONFIG_ENVIRONMENT,
        CONFIG_DATA_ENVIRONMENT,
        DB_ENVIRONMENT,
        GIT_DIR_ENVIRONMENT,
        GIT_WORK_TREE_ENVIRONMENT,
+       GIT_IMPLICIT_WORK_TREE_ENVIRONMENT,
        GRAFT_ENVIRONMENT,
        INDEX_ENVIRONMENT,
        NO_REPLACE_OBJECTS_ENVIRONMENT,
+       GIT_PREFIX_ENVIRONMENT,
        NULL
 };
 
index a0c2c2ff14f471c4ffa6ff1f4ec9085562378ad1..5f539d7d8f7e087423734fb1d19e0d5e580fbe6e 100644 (file)
@@ -2465,6 +2465,7 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout)
                hashcpy(sha1, oe->idx.sha1);
        } else if (!prefixcmp(p, "inline ")) {
                inline_data = 1;
+               oe = NULL; /* not used with inline_data, but makes gcc happy */
                p += strlen("inline");  /* advance to space */
        } else {
                if (get_sha1_hex(p, sha1))
index 710764abb132f16e393fd16178b845d8160e37cf..d2c4ce6e1e88f543bd06cd8347e8949fef11a381 100755 (executable)
@@ -1247,7 +1247,7 @@ sub summarize_hunk {
 
 
 # Print a one-line summary of each hunk in the array ref in
-# the first argument, starting wih the index in the 2nd.
+# the first argument, starting with the index in the 2nd.
 sub display_hunks {
        my ($hunks, $i) = @_;
        my $ctr = 0;
index bc32f18d6d9cbf915eb7797817390adbbc111506..9cb123a07df88c975cf1b0d6c5832cb410175dd0 100755 (executable)
@@ -75,7 +75,7 @@ =head1 Devel Notes
 
 sub usage() {
     print STDERR <<END;
-Usage: git archimport     # fetch/update GIT from Arch
+usage: git archimport     # fetch/update GIT from Arch
        [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ] [ -D depth ] [ -t tempdir ]
        repository/arch-branch [ repository/arch-branch] ...
 END
index b636e0dd0c2ea8284ed6f34e32c448eae433a20a..e715285e7c2e0a3d0b959505921b344dda55089d 100644 (file)
@@ -213,6 +213,17 @@ extern char *gitbasename(char *);
 #include <openssl/err.h>
 #endif
 
+/* On most systems <netdb.h> would have given us this, but
+ * not on some systems (e.g. z/OS).
+ */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+
+#ifndef NI_MAXSERV
+#define NI_MAXSERV 32
+#endif
+
 /* On most systems <limits.h> would have given us this, but
  * not on some systems (e.g. GNU/Hurd).
  */
index e6bf25232c4ec27fc98f78e076678ae4d0a524c1..d13f02da95f3b9b3921c3ccff9e3b6a7511cd666 100755 (executable)
 
 sub usage {
        print STDERR <<END;
-Usage: GIT_DIR=/path/to/.git git cvsexportcommit [-h] [-p] [-v] [-c] [-f] [-u] [-k] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
+usage: GIT_DIR=/path/to/.git git cvsexportcommit [-h] [-p] [-v] [-c] [-f] [-u] [-k] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
 END
        exit(1);
 }
index 344f1206d111a57ec529c34785ff8b1a6537e4d1..73d367cea8f130bc7721803e397df710e7cfff58 100755 (executable)
@@ -38,7 +38,7 @@ (;$)
        my $msg = shift;
        print(STDERR "Error: $msg\n") if $msg;
        print STDERR <<END;
-Usage: git cvsimport     # fetch/update GIT from CVS
+usage: git cvsimport     # fetch/update GIT from CVS
        [-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file]
        [-p opts-for-cvsps] [-P file] [-C GIT_repository] [-z fuzz] [-i] [-k]
        [-u] [-s subst] [-a] [-m] [-M regex] [-S regex] [-L commitlimit]
index 36790749830251854fa475f2bd8d33ece07203f6..a0d796e57087e0ca5bac94520997ecacec9fd295 100755 (executable)
 $log->info("--------------- STARTING -----------------");
 
 my $usage =
-    "Usage: git cvsserver [options] [pserver|server] [<directory> ...]\n".
+    "usage: git cvsserver [options] [pserver|server] [<directory> ...]\n".
     "    --base-path <path>  : Prepend to requested CVSROOT\n".
     "                          Can be read from GIT_CVSSERVER_BASE_PATH\n".
     "    --strict-paths      : Don't allow recursing into subdirectories\n".
@@ -2911,7 +2911,7 @@ sub filenamesplit
 }
 
 # Cleanup various junk in filename (try to canonicalize it), and
-# add prependdir to accomodate running CVS client from a
+# add prependdir to accommodate running CVS client from a
 # subdirectory (so the output is relative to top directory of the project).
 sub filecleanup
 {
@@ -4583,7 +4583,7 @@ sub getmeta
     #     the numerical value of the corresponding byte plus
     #     100.
     #      - "plus 100" avoids "0"s, and also reduces the
-    #        likelyhood of a collision in the case that someone someday
+    #        likelihood of a collision in the case that someone someday
     #        writes an import tool that tries to preserve original
     #        CVS revision numbers, and the original CVS data had done
     #        lots of branches off of branches and other strangeness to
index f612cb847aca981e16cb6006fa08d870497c6263..3373c040d4aae221386fac5ec2cd9a29344c1840 100755 (executable)
@@ -18,7 +18,7 @@
 
 USAGE='<orig blob> <our blob> <their blob> <path>'
 USAGE="$USAGE <orig mode> <our mode> <their mode>"
-LONG_USAGE="Usage: git merge-one-file $USAGE
+LONG_USAGE="usage: git merge-one-file $USAGE
 
 Blob ids and modes should be empty for missing files."
 
index 9a6ba2b9874e12d31adeba354d8d44436ceadaf3..8e17525dd86aa614000d9b335f9671a829678901 100755 (executable)
@@ -59,7 +59,7 @@ tmp_patch="$tmp_dir/patch"
 tmp_info="$tmp_dir/info"
 
 
-# Find the intial commit
+# Find the initial commit
 commit=$(git rev-parse HEAD)
 
 mkdir $tmp_dir || exit 2
index f29285c411a6dc9b58cffb47b91577bb2d023bc6..236a3521a19260f5f49b81a39d7193a68b25b64b 100755 (executable)
@@ -163,7 +163,7 @@ ($$)
 
 
 sub usage() {
-       print("Usage: git relink [--safe] <dir>... <master_dir> \n");
+       print("usage: git relink [--safe] <dir>... <master_dir> \n");
        print("All directories should contain a .git/objects/ subdirectory.\n");
        print("Options\n");
        print("\t--safe\t" .
index be809e5b59394a4fd2f4f2b73cad6bac47a39600..70cad15ec46d0ed32f3b97c792e9d975ece53fd8 100755 (executable)
@@ -512,8 +512,9 @@ sub split_addrs {
 
 ($sender) = expand_aliases($sender) if defined $sender;
 
-# returns 1 if the conflict must be solved using it as a format-patch argument
-sub check_file_rev_conflict($) {
+# is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if
+# $f is a revision list specification to be passed to format-patch.
+sub is_format_patch_arg {
        return unless $repo;
        my $f = shift;
        try {
@@ -529,6 +530,7 @@ ($)
     * Giving --format-patch option if you mean a range.
 EOF
        } catch Git::Error::Command with {
+               # Not a valid revision.  Treat it as a filename.
                return 0;
        }
 }
@@ -540,14 +542,14 @@ ($)
        if ($f eq "--") {
                push @rev_list_opts, "--", @ARGV;
                @ARGV = ();
-       } elsif (-d $f and !check_file_rev_conflict($f)) {
+       } elsif (-d $f and !is_format_patch_arg($f)) {
                opendir my $dh, $f
                        or die "Failed to opendir $f: $!";
 
                push @files, grep { -f $_ } map { catfile($f, $_) }
                                sort readdir $dh;
                closedir $dh;
-       } elsif ((-f $f or -p $f) and !check_file_rev_conflict($f)) {
+       } elsif ((-f $f or -p $f) and !is_format_patch_arg($f)) {
                push @files, $f;
        } else {
                push @rev_list_opts, $f;
@@ -711,7 +713,7 @@ sub ask {
                        }
                }
        }
-       return undef;
+       return;
 }
 
 my %broken_encoding;
@@ -833,7 +835,7 @@ sub extract_valid_address {
        # less robust/correct than the monster regexp in Email::Valid,
        # but still does a 99% job, and one less dependency
        return $1 if $address =~ /($local_part_regexp\@$domain_regexp)/;
-       return undef;
+       return;
 }
 
 sub extract_valid_address_or_die {
@@ -1438,7 +1440,7 @@ sub recipients_cmd {
 
        my $sanitized_sender = sanitize_address($sender);
        my @addresses = ();
-       open my $fh, "$cmd \Q$file\E |"
+       open my $fh, "-|", "$cmd \Q$file\E"
            or die "($prefix) Could not execute '$cmd'";
        while (my $address = <$fh>) {
                $address =~ s/^\s*//g;
@@ -1484,7 +1486,7 @@ sub validate_patch {
                        return "$.: patch contains a line longer than 998 characters";
                }
        }
-       return undef;
+       return;
 }
 
 sub file_has_nonascii {
index 795edd2852aa1c680c3db1776bb84aca7662899d..9cfbe7f1435e073eeb39ab2190eda2d2dda300a5 100644 (file)
@@ -84,14 +84,14 @@ if test -n "$OPTIONS_SPEC"; then
 else
        dashless=$(basename "$0" | sed -e 's/-/ /')
        usage() {
-               die "Usage: $dashless $USAGE"
+               die "usage: $dashless $USAGE"
        }
 
        if [ -z "$LONG_USAGE" ]
        then
-               LONG_USAGE="Usage: $dashless $USAGE"
+               LONG_USAGE="usage: $dashless $USAGE"
        else
-               LONG_USAGE="Usage: $dashless $USAGE
+               LONG_USAGE="usage: $dashless $USAGE
 
 $LONG_USAGE"
        fi
index 004c034bc09449416ff6d66b7570d48b651f96cb..b3108b8ea9983c524eb06831972c22773b3a56b1 100755 (executable)
@@ -266,6 +266,11 @@ module_clone()
        (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b")
 }
 
+isnumber()
+{
+       n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
+}
+
 #
 # Add a new submodule to the working tree, .gitmodules and the index
 #
@@ -622,7 +627,7 @@ cmd_update()
                die_if_unmatched "$mode"
                if test "$stage" = U
                then
-                       echo >&2 "Skipping unmerged submodule $sm_path"
+                       echo >&2 "Skipping unmerged submodule $prefix$sm_path"
                        continue
                fi
                name=$(module_name "$sm_path") || exit
@@ -637,7 +642,7 @@ cmd_update()
 
                if test "$update_module" = "none"
                then
-                       echo "Skipping submodule '$sm_path'"
+                       echo "Skipping submodule '$prefix$sm_path'"
                        continue
                fi
 
@@ -646,7 +651,7 @@ cmd_update()
                        # Only mention uninitialized submodules when its
                        # path have been specified
                        test "$#" != "0" &&
-                       say "$(eval_gettext "Submodule path '\$sm_path' not initialized
+                       say "$(eval_gettext "Submodule path '\$prefix\$sm_path' not initialized
 Maybe you want to use 'update --init'?")"
                        continue
                fi
@@ -659,7 +664,7 @@ Maybe you want to use 'update --init'?")"
                else
                        subsha1=$(clear_local_git_env; cd "$sm_path" &&
                                git rev-parse --verify HEAD) ||
-                       die "$(eval_gettext "Unable to find current revision in submodule path '\$sm_path'")"
+                       die "$(eval_gettext "Unable to find current revision in submodule path '\$prefix\$sm_path'")"
                fi
 
                if test -n "$remote"
@@ -692,7 +697,7 @@ Maybe you want to use 'update --init'?")"
                                (clear_local_git_env; cd "$sm_path" &&
                                        ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
                                         test -z "$rev") || git-fetch)) ||
-                               die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+                               die "$(eval_gettext "Unable to fetch in submodule path '\$prefix\$sm_path'")"
                        fi
 
                        # Is this something we just cloned?
@@ -706,20 +711,20 @@ Maybe you want to use 'update --init'?")"
                        case "$update_module" in
                        rebase)
                                command="git rebase"
-                               die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$sm_path'")"
-                               say_msg="$(eval_gettext "Submodule path '\$sm_path': rebased into '\$sha1'")"
+                               die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': rebased into '\$sha1'")"
                                must_die_on_failure=yes
                                ;;
                        merge)
                                command="git merge"
-                               die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$sm_path'")"
-                               say_msg="$(eval_gettext "Submodule path '\$sm_path': merged in '\$sha1'")"
+                               die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': merged in '\$sha1'")"
                                must_die_on_failure=yes
                                ;;
                        *)
                                command="git checkout $subforce -q"
-                               die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$sm_path'")"
-                               say_msg="$(eval_gettext "Submodule path '\$sm_path': checked out '\$sha1'")"
+                               die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': checked out '\$sha1'")"
                                ;;
                        esac
 
@@ -737,11 +742,16 @@ Maybe you want to use 'update --init'?")"
 
                if test -n "$recursive"
                then
-                       (clear_local_git_env; cd "$sm_path" && eval cmd_update "$orig_flags")
+                       (
+                               prefix="$prefix$sm_path/"
+                               clear_local_git_env
+                               cd "$sm_path" &&
+                               eval cmd_update "$orig_flags"
+                       )
                        res=$?
                        if test $res -gt 0
                        then
-                               die_msg="$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")"
+                               die_msg="$(eval_gettext "Failed to recurse into submodule path '\$prefix\$sm_path'")"
                                if test $res -eq 1
                                then
                                        err="${err};$die_msg"
@@ -809,14 +819,14 @@ cmd_summary() {
                        for_status="$1"
                        ;;
                -n|--summary-limit)
-                       if summary_limit=$(($2 + 0)) 2>/dev/null && test "$summary_limit" = "$2"
-                       then
-                               :
-                       else
-                               usage
-                       fi
+                       summary_limit="$2"
+                       isnumber "$summary_limit" || usage
                        shift
                        ;;
+               --summary-limit=*)
+                       summary_limit="${1#--summary-limit=}"
+                       isnumber "$summary_limit" || usage
+                       ;;
                --)
                        shift
                        break
index b46795f5935dd3d61a2f3e45f979aec04d12afcb..6c7bd95032b890d2f79cff0d18ac6aa688a74757 100755 (executable)
@@ -382,7 +382,7 @@ sub usage {
        my $fd = $exit ? \*STDERR : \*STDOUT;
        print $fd <<"";
 git-svn - bidirectional operations between a single Subversion tree and git
-Usage: git svn <command> [options] [arguments]\n
+usage: git svn <command> [options] [arguments]\n
 
        print $fd "Available commands:\n" unless $cmd;
 
@@ -534,7 +534,7 @@ sub cmd_fetch {
        }
        my ($remote) = @_;
        if (@_ > 1) {
-               die "Usage: $0 fetch [--all] [--parent] [svn-remote]\n";
+               die "usage: $0 fetch [--all] [--parent] [svn-remote]\n";
        }
        $Git::SVN::no_reuse_existing = undef;
        if ($_fetch_parent) {
@@ -1404,7 +1404,7 @@ sub cmd_multi_fetch {
 # this command is special because it requires no metadata
 sub cmd_commit_diff {
        my ($ta, $tb, $url) = @_;
-       my $usage = "Usage: $0 commit-diff -r<revision> ".
+       my $usage = "usage: $0 commit-diff -r<revision> ".
                    "<tree-ish> <tree-ish> [<URL>]";
        fatal($usage) if (!defined $ta || !defined $tb);
        my $svn_path = '';
diff --git a/git.c b/git.c
index 39ba6b14618389bc9312df43a376b52f9a21d881..850d3f5527f4100f45cb5eb1a7d8772e04ae4443 100644 (file)
--- a/git.c
+++ b/git.c
@@ -125,6 +125,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        static char git_dir[PATH_MAX+1];
                        is_bare_repository_cfg = 1;
                        setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);
+                       setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
                        if (envchanged)
                                *envchanged = 1;
                } else if (!strcmp(cmd, "-c")) {
index 6d4540679731bdfd33af61635c59b798b19a8888..08f3dda02d43f9b2e994ee2f7a8dccaecb82733e 100644 (file)
@@ -244,7 +244,7 @@ for gitweb (in gitweb/README), and gitweb.conf(5) manpage.
   through the GITWEB_CONFIG_SYSTEM environment variable.
 
   Note that if per-instance configuration file exists, then system-wide
-  configuration is _not used at all_.  This is quite untypical and suprising
+  configuration is _not used at all_.  This is quite untypical and surprising
   behavior.  On the other hand changing current behavior would break backwards
   compatibility and can lead to unexpected changes in gitweb behavior.
   Therefore gitweb also looks for common system-wide configuration file,
index 1309196d27e675013825cdac8afd6d7328e44b1f..80950c018d54f3bbb7b700286b4923d39cbe2d00 100755 (executable)
@@ -683,7 +683,7 @@ sub evaluate_gitweb_config {
        our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
        our $GITWEB_CONFIG_COMMON = $ENV{'GITWEB_CONFIG_COMMON'} || "++GITWEB_CONFIG_COMMON++";
 
-       # Protect agains duplications of file names, to not read config twice.
+       # Protect against duplications of file names, to not read config twice.
        # Only one of $GITWEB_CONFIG and $GITWEB_CONFIG_SYSTEM is used, so
        # there possibility of duplication of filename there doesn't matter.
        $GITWEB_CONFIG = ""        if ($GITWEB_CONFIG eq $GITWEB_CONFIG_COMMON);
@@ -1136,7 +1136,7 @@ sub handle_errors_html {
 
        # to avoid infinite loop where error occurs in die_error,
        # change handler to default handler, disabling handle_errors_html
-       set_message("Error occured when inside die_error:\n$msg");
+       set_message("Error occurred when inside die_error:\n$msg");
 
        # you cannot jump out of die_error when called as error handler;
        # the subroutine set via CGI::Carp::set_message is called _after_
@@ -7485,7 +7485,7 @@ sub git_object {
                system(git_cmd(), "cat-file", '-e', $hash_base) == 0
                        or die_error(404, "Base object does not exist");
 
-               # here errors should not hapen
+               # here errors should not happen
                open my $fd, "-|", git_cmd(), "ls-tree", $hash_base, "--", $file_name
                        or die_error(500, "Open git-ls-tree failed");
                my $line = <$fd>;
index 45590330aa3131da69174899783913cee9a44c31..8b0e87436b687ce26e3e4987129a2fc171069280 100644 (file)
@@ -96,15 +96,18 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
 /*
  * Run "gpg" to see if the payload matches the detached signature.
  * gpg_output, when set, receives the diagnostic output from GPG.
+ * gpg_status, when set, receives the status output from GPG.
  */
 int verify_signed_buffer(const char *payload, size_t payload_size,
                         const char *signature, size_t signature_size,
-                        struct strbuf *gpg_output)
+                        struct strbuf *gpg_output, struct strbuf *gpg_status)
 {
        struct child_process gpg;
-       const char *args_gpg[] = {NULL, "--verify", "FILE", "-", NULL};
+       const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL};
        char path[PATH_MAX];
        int fd, ret;
+       struct strbuf buf = STRBUF_INIT;
+       struct strbuf *pbuf = &buf;
 
        args_gpg[0] = gpg_program;
        fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
@@ -119,9 +122,10 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
        memset(&gpg, 0, sizeof(gpg));
        gpg.argv = args_gpg;
        gpg.in = -1;
+       gpg.out = -1;
        if (gpg_output)
                gpg.err = -1;
-       args_gpg[2] = path;
+       args_gpg[3] = path;
        if (start_command(&gpg)) {
                unlink(path);
                return error(_("could not run gpg."));
@@ -134,9 +138,17 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
                strbuf_read(gpg_output, gpg.err, 0);
                close(gpg.err);
        }
+       if (gpg_status)
+               pbuf = gpg_status;
+       strbuf_read(pbuf, gpg.out, 0);
+       close(gpg.out);
+
        ret = finish_command(&gpg);
 
        unlink_or_warn(path);
 
+       ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG ");
+       strbuf_release(&buf); /* no matter it was used or not */
+
        return ret;
 }
index b9c36088cea3c1d419c23354e095320ebebd90a4..cf9902184272d20c6d5826cf9f10dcaebeb3e6e8 100644 (file)
@@ -2,7 +2,7 @@
 #define GPG_INTERFACE_H
 
 extern int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key);
-extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output);
+extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status);
 extern int git_gpg_config(const char *, const char *, void *);
 extern void set_signing_key(const char *);
 extern const char *get_signing_key(void);
diff --git a/graph.c b/graph.c
index 2a3fc5c0ec128ba2b6d024b3172bd3a110e361fd..b24d04c4066dd4d09200bb27d09c91d93c1bb5b0 100644 (file)
--- a/graph.c
+++ b/graph.c
@@ -7,34 +7,6 @@
 
 /* Internal API */
 
-/*
- * Output the next line for a graph.
- * This formats the next graph line into the specified strbuf.  It is not
- * terminated with a newline.
- *
- * Returns 1 if the line includes the current commit, and 0 otherwise.
- * graph_next_line() will return 1 exactly once for each time
- * graph_update() is called.
- */
-static int graph_next_line(struct git_graph *graph, struct strbuf *sb);
-
-/*
- * Set up a custom scheme for column colors.
- *
- * The default column color scheme inserts ANSI color escapes to colorize
- * the graph. The various color escapes are stored in an array of strings
- * where each entry corresponds to a color, except for the last entry,
- * which denotes the escape for resetting the color back to the default.
- * When generating the graph, strings from this array are inserted before
- * and after the various column characters.
- *
- * This function allows you to enable a custom array of color escapes.
- * The 'colors_max' argument is the index of the last "reset" entry.
- *
- * This functions must be called BEFORE graph_init() is called.
- */
-static void graph_set_column_colors(const char **colors, unsigned short colors_max);
-
 /*
  * Output a padding line in the graph.
  * This is similar to graph_next_line().  However, it is guaranteed to
@@ -90,7 +62,7 @@ enum graph_state {
 static const char **column_colors;
 static unsigned short column_colors_max;
 
-static void graph_set_column_colors(const char **colors, unsigned short colors_max)
+void graph_set_column_colors(const char **colors, unsigned short colors_max)
 {
        column_colors = colors;
        column_colors_max = colors_max;
@@ -1144,7 +1116,7 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf
                graph_update_state(graph, GRAPH_PADDING);
 }
 
-static int graph_next_line(struct git_graph *graph, struct strbuf *sb)
+int graph_next_line(struct git_graph *graph, struct strbuf *sb)
 {
        switch (graph->state) {
        case GRAPH_PADDING:
diff --git a/graph.h b/graph.h
index 19b0f6631654f428cb76e9493325646163899a0b..0be62bd8b1227a16b8e67f6309605d6f4a98c247 100644 (file)
--- a/graph.h
+++ b/graph.h
@@ -4,6 +4,25 @@
 /* A graph is a pointer to this opaque structure */
 struct git_graph;
 
+/*
+ * Set up a custom scheme for column colors.
+ *
+ * The default column color scheme inserts ANSI color escapes to colorize
+ * the graph. The various color escapes are stored in an array of strings
+ * where each entry corresponds to a color, except for the last entry,
+ * which denotes the escape for resetting the color back to the default.
+ * When generating the graph, strings from this array are inserted before
+ * and after the various column characters.
+ *
+ * This function allows you to enable a custom array of color escapes.
+ * The 'colors_max' argument is the index of the last "reset" entry.
+ *
+ * This functions must be called BEFORE graph_init() is called.
+ *
+ * NOTE: This function isn't used in Git outside graph.c but it is used
+ * by CGit (http://git.zx2c4.com/cgit/) to use HTML for colors.
+ */
+void graph_set_column_colors(const char **colors, unsigned short colors_max);
 
 /*
  * Create a new struct git_graph.
@@ -33,6 +52,20 @@ void graph_update(struct git_graph *graph, struct commit *commit);
  */
 int graph_is_commit_finished(struct git_graph const *graph);
 
+/*
+ * Output the next line for a graph.
+ * This formats the next graph line into the specified strbuf.  It is not
+ * terminated with a newline.
+ *
+ * Returns 1 if the line includes the current commit, and 0 otherwise.
+ * graph_next_line() will return 1 exactly once for each time
+ * graph_update() is called.
+ *
+ * NOTE: This function isn't used in Git outside graph.c but it is used
+ * by CGit (http://git.zx2c4.com/cgit/) to wrap HTML around graph lines.
+ */
+int graph_next_line(struct git_graph *graph, struct strbuf *sb);
+
 
 /*
  * graph_show_*: helper functions for printing to stdout
index 43ac4e0bdfdba8850eff176b53d6bd071e8f424c..d9bcfb44dc334d86363fd60b576fcc2e2121f971 100644 (file)
@@ -304,6 +304,17 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
                return -1;
        }
 
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+       /*
+        * SNI (RFC4366)
+        * OpenSSL does not document this function, but the implementation
+        * returns 1 on success, 0 on failure after calling SSLerr().
+        */
+       ret = SSL_set_tlsext_host_name(sock->ssl, server.host);
+       if (ret != 1)
+               warning("SSL_set_tlsext_host_name(%s) failed.", server.host);
+#endif
+
        ret = SSL_connect(sock->ssl);
        if (ret <= 0) {
                socket_perror("SSL_connect", sock, ret);
diff --git a/kwset.c b/kwset.c
index 51b2ab6c7e61413851a958f7a4009a0194744b68..5800999b4c16cd8f5eeb2301f72c33ec62c5ea71 100644 (file)
--- a/kwset.c
+++ b/kwset.c
@@ -26,7 +26,7 @@
    The author may be reached (Email) at the address mike@ai.mit.edu,
    or (US mail) as Mike Haertel c/o Free Software Foundation. */
 
-/* The algorithm implemented by these routines bears a startling resemblence
+/* The algorithm implemented by these routines bears a startling resemblance
    to one discovered by Beate Commentz-Walter, although it is not identical.
    See "A String Matching Algorithm Fast on the Average," Technical Report,
    IBM-Germany, Scientific Center Heidelberg, Tiergartenstrasse 15, D-6900
@@ -435,7 +435,7 @@ kwsprep (kwset_t kws)
          /* Update the delta table for the descendents of this node. */
          treedelta(curr->links, curr->depth, delta);
 
-         /* Compute the failure function for the decendents of this node. */
+         /* Compute the failure function for the descendants of this node. */
          treefails(curr->links, curr->fail, kwset->trie);
 
          /* Update the shifts at each node in the current node's chain
index 5dc45c4812bdfd0d7a6b71d529eaa37df8178186..3d888238711364338a83e7d81bf27f555352bdca 100644 (file)
@@ -444,7 +444,7 @@ static void show_signature(struct rev_info *opt, struct commit *commit)
 
        status = verify_signed_buffer(payload.buf, payload.len,
                                      signature.buf, signature.len,
-                                     &gpg_output);
+                                     &gpg_output, NULL);
        if (status && !gpg_output.len)
                strbuf_addstr(&gpg_output, "No signature\n");
 
@@ -508,20 +508,17 @@ static void show_one_mergetag(struct rev_info *opt,
        gpg_message_offset = verify_message.len;
 
        payload_size = parse_signature(extra->value, extra->len);
-       if ((extra->len <= payload_size) ||
-           (verify_signed_buffer(extra->value, payload_size,
-                                 extra->value + payload_size,
-                                 extra->len - payload_size,
-                                 &verify_message) &&
-            verify_message.len <= gpg_message_offset)) {
-               strbuf_addstr(&verify_message, "No signature\n");
-               status = -1;
-       }
-       else if (strstr(verify_message.buf + gpg_message_offset,
-                       ": Good signature from "))
-               status = 0;
-       else
-               status = -1;
+       status = -1;
+       if (extra->len > payload_size)
+               if (verify_signed_buffer(extra->value, payload_size,
+                                        extra->value + payload_size,
+                                        extra->len - payload_size,
+                                        &verify_message, NULL)) {
+                       if (verify_message.len <= gpg_message_offset)
+                               strbuf_addstr(&verify_message, "No signature\n");
+                       else
+                               status = 0;
+               }
 
        show_sig_lines(opt, status, verify_message.buf);
        strbuf_release(&verify_message);
index 942c45962252eba4c6f88b4f4f7593c9247749ae..6d7e1980c62f96fc3614ddd130ce25a765fceae5 100644 (file)
@@ -32,38 +32,96 @@ static unsigned int hash_name(const char *name, int namelen)
        return hash;
 }
 
-static void hash_index_entry_directories(struct index_state *istate, struct cache_entry *ce)
+struct dir_entry {
+       struct dir_entry *next;
+       struct dir_entry *parent;
+       struct cache_entry *ce;
+       int nr;
+       unsigned int namelen;
+};
+
+static struct dir_entry *find_dir_entry(struct index_state *istate,
+               const char *name, unsigned int namelen)
+{
+       unsigned int hash = hash_name(name, namelen);
+       struct dir_entry *dir;
+
+       for (dir = lookup_hash(hash, &istate->dir_hash); dir; dir = dir->next)
+               if (dir->namelen == namelen &&
+                   !strncasecmp(dir->ce->name, name, namelen))
+                       return dir;
+       return NULL;
+}
+
+static struct dir_entry *hash_dir_entry(struct index_state *istate,
+               struct cache_entry *ce, int namelen)
 {
        /*
         * Throw each directory component in the hash for quick lookup
         * during a git status. Directory components are stored with their
         * closing slash.  Despite submodules being a directory, they never
         * reach this point, because they are stored without a closing slash
-        * in the cache.
+        * in index_state.name_hash (as ordinary cache_entries).
         *
-        * Note that the cache_entry stored with the directory does not
-        * represent the directory itself.  It is a pointer to an existing
-        * filename, and its only purpose is to represent existence of the
-        * directory in the cache.  It is very possible multiple directory
-        * hash entries may point to the same cache_entry.
+        * Note that the cache_entry stored with the dir_entry merely
+        * supplies the name of the directory (up to dir_entry.namelen). We
+        * track the number of 'active' files in a directory in dir_entry.nr,
+        * so we can tell if the directory is still relevant, e.g. for git
+        * status. However, if cache_entries are removed, we cannot pinpoint
+        * an exact cache_entry that's still active. It is very possible that
+        * multiple dir_entries point to the same cache_entry.
         */
-       unsigned int hash;
-       void **pos;
+       struct dir_entry *dir;
+
+       /* get length of parent directory */
+       while (namelen > 0 && !is_dir_sep(ce->name[namelen - 1]))
+               namelen--;
+       if (namelen <= 0)
+               return NULL;
+
+       /* lookup existing entry for that directory */
+       dir = find_dir_entry(istate, ce->name, namelen);
+       if (!dir) {
+               /* not found, create it and add to hash table */
+               void **pdir;
+               unsigned int hash = hash_name(ce->name, namelen);
 
-       const char *ptr = ce->name;
-       while (*ptr) {
-               while (*ptr && *ptr != '/')
-                       ++ptr;
-               if (*ptr == '/') {
-                       ++ptr;
-                       hash = hash_name(ce->name, ptr - ce->name);
-                       pos = insert_hash(hash, ce, &istate->name_hash);
-                       if (pos) {
-                               ce->dir_next = *pos;
-                               *pos = ce;
-                       }
+               dir = xcalloc(1, sizeof(struct dir_entry));
+               dir->namelen = namelen;
+               dir->ce = ce;
+
+               pdir = insert_hash(hash, dir, &istate->dir_hash);
+               if (pdir) {
+                       dir->next = *pdir;
+                       *pdir = dir;
                }
+
+               /* recursively add missing parent directories */
+               dir->parent = hash_dir_entry(istate, ce, namelen - 1);
        }
+       return dir;
+}
+
+static void add_dir_entry(struct index_state *istate, struct cache_entry *ce)
+{
+       /* Add reference to the directory entry (and parents if 0). */
+       struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce));
+       while (dir && !(dir->nr++))
+               dir = dir->parent;
+}
+
+static void remove_dir_entry(struct index_state *istate, struct cache_entry *ce)
+{
+       /*
+        * Release reference to the directory entry (and parents if 0).
+        *
+        * Note: we do not remove / free the entry because there's no
+        * hash.[ch]::remove_hash and dir->next may point to other entries
+        * that are still valid, so we must not free the memory.
+        */
+       struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce));
+       while (dir && dir->nr && !(--dir->nr))
+               dir = dir->parent;
 }
 
 static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
@@ -74,7 +132,7 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
        if (ce->ce_flags & CE_HASHED)
                return;
        ce->ce_flags |= CE_HASHED;
-       ce->next = ce->dir_next = NULL;
+       ce->next = NULL;
        hash = hash_name(ce->name, ce_namelen(ce));
        pos = insert_hash(hash, ce, &istate->name_hash);
        if (pos) {
@@ -82,8 +140,8 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
                *pos = ce;
        }
 
-       if (ignore_case)
-               hash_index_entry_directories(istate, ce);
+       if (ignore_case && !(ce->ce_flags & CE_UNHASHED))
+               add_dir_entry(istate, ce);
 }
 
 static void lazy_init_name_hash(struct index_state *istate)
@@ -99,11 +157,33 @@ static void lazy_init_name_hash(struct index_state *istate)
 
 void add_name_hash(struct index_state *istate, struct cache_entry *ce)
 {
+       /* if already hashed, add reference to directory entries */
+       if (ignore_case && (ce->ce_flags & CE_STATE_MASK) == CE_STATE_MASK)
+               add_dir_entry(istate, ce);
+
        ce->ce_flags &= ~CE_UNHASHED;
        if (istate->name_hash_initialized)
                hash_index_entry(istate, ce);
 }
 
+/*
+ * We don't actually *remove* it, we can just mark it invalid so that
+ * we won't find it in lookups.
+ *
+ * Not only would we have to search the lists (simple enough), but
+ * we'd also have to rehash other hash buckets in case this makes the
+ * hash bucket empty (common). So it's much better to just mark
+ * it.
+ */
+void remove_name_hash(struct index_state *istate, struct cache_entry *ce)
+{
+       /* if already hashed, release reference to directory entries */
+       if (ignore_case && (ce->ce_flags & CE_STATE_MASK) == CE_HASHED)
+               remove_dir_entry(istate, ce);
+
+       ce->ce_flags |= CE_UNHASHED;
+}
+
 static int slow_same_name(const char *name1, int len1, const char *name2, int len2)
 {
        if (len1 != len2)
@@ -137,18 +217,7 @@ static int same_name(const struct cache_entry *ce, const char *name, int namelen
        if (!icase)
                return 0;
 
-       /*
-        * If the entry we're comparing is a filename (no trailing slash), then compare
-        * the lengths exactly.
-        */
-       if (name[namelen - 1] != '/')
-               return slow_same_name(name, namelen, ce->name, len);
-
-       /*
-        * For a directory, we point to an arbitrary cache_entry filename.  Just
-        * make sure the directory portion matches.
-        */
-       return slow_same_name(name, namelen, ce->name, namelen < len ? namelen : len);
+       return slow_same_name(name, namelen, ce->name, len);
 }
 
 struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase)
@@ -164,27 +233,54 @@ struct cache_entry *index_name_exists(struct index_state *istate, const char *na
                        if (same_name(ce, name, namelen, icase))
                                return ce;
                }
-               if (icase && name[namelen - 1] == '/')
-                       ce = ce->dir_next;
-               else
-                       ce = ce->next;
+               ce = ce->next;
        }
 
        /*
-        * Might be a submodule.  Despite submodules being directories,
+        * When looking for a directory (trailing '/'), it might be a
+        * submodule or a directory. Despite submodules being directories,
         * they are stored in the name hash without a closing slash.
-        * When ignore_case is 1, directories are stored in the name hash
-        * with their closing slash.
+        * When ignore_case is 1, directories are stored in a separate hash
+        * table *with* their closing slash.
         *
         * The side effect of this storage technique is we have need to
+        * lookup the directory in a separate hash table, and if not found
         * remove the slash from name and perform the lookup again without
         * the slash.  If a match is made, S_ISGITLINK(ce->mode) will be
         * true.
         */
        if (icase && name[namelen - 1] == '/') {
+               struct dir_entry *dir = find_dir_entry(istate, name, namelen);
+               if (dir && dir->nr)
+                       return dir->ce;
+
                ce = index_name_exists(istate, name, namelen - 1, icase);
                if (ce && S_ISGITLINK(ce->ce_mode))
                        return ce;
        }
        return NULL;
 }
+
+static int free_dir_entry(void *entry, void *unused)
+{
+       struct dir_entry *dir = entry;
+       while (dir) {
+               struct dir_entry *next = dir->next;
+               free(dir);
+               dir = next;
+       }
+       return 0;
+}
+
+void free_name_hash(struct index_state *istate)
+{
+       if (!istate->name_hash_initialized)
+               return;
+       istate->name_hash_initialized = 0;
+       if (ignore_case)
+               /* free directory entries */
+               for_each_hash(&istate->dir_hash, free_dir_entry, NULL);
+
+       free_hash(&istate->name_hash);
+       free_hash(&istate->dir_hash);
+}
index 4af3451bf89471a0ab7a148aad4924a8ac8ae053..20703f52ed24aa227d451bec332ac73cc3d49d3a 100644 (file)
--- a/object.c
+++ b/object.c
@@ -185,6 +185,16 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
        return obj;
 }
 
+struct object *parse_object_or_die(const unsigned char *sha1,
+                                  const char *name)
+{
+       struct object *o = parse_object(sha1);
+       if (o)
+               return o;
+
+       die(_("unable to parse object: %s"), name ? name : sha1_to_hex(sha1));
+}
+
 struct object *parse_object(const unsigned char *sha1)
 {
        unsigned long size;
index 6a97b6ba1a43e1d38eb07515ad298e0067628127..97d384b80a5dbf0cac88b59cbb8a2d333d2b9582 100644 (file)
--- a/object.h
+++ b/object.h
@@ -54,9 +54,20 @@ struct object *lookup_object(const unsigned char *sha1);
 
 extern void *create_object(const unsigned char *sha1, int type, void *obj);
 
-/** Returns the object, having parsed it to find out what it is. **/
+/*
+ * Returns the object, having parsed it to find out what it is.
+ *
+ * Returns NULL if the object is missing or corrupt.
+ */
 struct object *parse_object(const unsigned char *sha1);
 
+/*
+ * Like parse_object, but will die() instead of returning NULL. If the
+ * "name" parameter is not NULL, it is included in the error message
+ * (otherwise, the sha1 hex is given).
+ */
+struct object *parse_object_or_die(const unsigned char *sha1, const char *name);
+
 /* Given the result of read_sha1_file(), returns the object after
  * parsing it.  eaten_p indicates if the object has a borrowed copy
  * of buffer and the caller should not free() it.
index f09a05422854c919cd31c542b82b057624275959..4461f71a37bea5d935409761cc8a838bff443439 100644 (file)
@@ -27,6 +27,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
                          int flags, void *cb_data)
 {
        struct pack_refs_cb_data *cb = cb_data;
+       struct object *o;
        int is_tag_ref;
 
        /* Do not pack the symbolic refs */
@@ -39,14 +40,13 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
                return 0;
 
        fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
-       if (is_tag_ref) {
-               struct object *o = parse_object(sha1);
-               if (o->type == OBJ_TAG) {
-                       o = deref_tag(o, path, 0);
-                       if (o)
-                               fprintf(cb->refs_file, "^%s\n",
-                                       sha1_to_hex(o->sha1));
-               }
+
+       o = parse_object_or_die(sha1, path);
+       if (o->type == OBJ_TAG) {
+               o = deref_tag(o, path, 0);
+               if (o)
+                       fprintf(cb->refs_file, "^%s\n",
+                               sha1_to_hex(o->sha1));
        }
 
        if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) {
@@ -128,7 +128,7 @@ int pack_refs(unsigned int flags)
                die_errno("unable to create ref-pack file structure");
 
        /* perhaps other traits later as well */
-       fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
+       fprintf(cbdata.refs_file, "# pack-refs with: peeled fully-peeled \n");
 
        for_each_ref(handle_one_ref, &cbdata);
        if (ferror(cbdata.refs_file))
index a56d1e76f797cdba83510a5488945425f1936c2d..f207b47183a00fc02320a3785a8d4085b42259fe 100644 (file)
@@ -965,20 +965,22 @@ sub cat_blob {
        my $size = $1;
 
        my $blob;
-       my $bytesRead = 0;
+       my $bytesLeft = $size;
 
        while (1) {
-               my $bytesLeft = $size - $bytesRead;
                last unless $bytesLeft;
 
                my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
-               my $read = read($in, $blob, $bytesToRead, $bytesRead);
+               my $read = read($in, $blob, $bytesToRead);
                unless (defined($read)) {
                        $self->_close_cat_blob();
                        throw Error::Simple("in pipe went bad");
                }
-
-               $bytesRead += $read;
+               unless (print $fh $blob) {
+                       $self->_close_cat_blob();
+                       throw Error::Simple("couldn't write to passed in filehandle");
+               }
+               $bytesLeft -= $read;
        }
 
        # Skip past the trailing newline.
@@ -993,11 +995,6 @@ sub cat_blob {
                throw Error::Simple("didn't find newline after blob");
        }
 
-       unless (print $fh $blob) {
-               $self->_close_cat_blob();
-               throw Error::Simple("couldn't write to passed in filehandle");
-       }
-
        return $size;
 }
 
@@ -1029,7 +1026,7 @@ sub _close_cat_blob {
 
 =item temp_acquire ( NAME )
 
-Attempts to retreive the temporary file mapped to the string C<NAME>. If an
+Attempts to retrieve the temporary file mapped to the string C<NAME>. If an
 associated temp file has not been created this session or was closed, it is
 created, cached, and set for autoflush and binmode.
 
index 40dd8971912d6b387bde7c9bb04cc6896521acec..f889fd6da91d2d9b6a7469442a02e5478f094f8d 100644 (file)
@@ -68,7 +68,7 @@ =head1 SYNOPSIS
 
        print __("Welcome to Git!\n");
 
-       printf __("The following error occured: %s\n"), $error;
+       printf __("The following error occurred: %s\n"), $error;
 
 =head1 DESCRIPTION
 
index 11e9cd9a02eb3f85a9150c6fb06d1fc76abd9b09..6098135ae2b2d473729373b69e776f475cf919dd 100644 (file)
@@ -630,7 +630,7 @@ =head1 CLASS INTERFACE
 =head2 CONSTRUCTORS
 
 The C<Error> object is implemented as a HASH. This HASH is initialized
-with the arguments that are passed to it's constructor. The elements
+with the arguments that are passed to its constructor. The elements
 that are used by, or are retrievable by the C<Error> class are listed
 below, other classes may add to these.
 
@@ -763,13 +763,13 @@ =head1 PRE-DEFINED ERROR CLASSES
 
 =item Error::Simple
 
-This class can be used to hold simple error strings and values. It's
+This class can be used to hold simple error strings and values. Its
 constructor takes two arguments. The first is a text value, the second
 is a numeric value. These values are what will be returned by the
 overload methods.
 
 If the text value ends with C<at file line 1> as $@ strings do, then
-this infomation will be used to set the C<-file> and C<-line> arguments
+this information will be used to set the C<-file> and C<-line> arguments
 of the error object.
 
 This class is used internally if an eval'd block die's with an error
index c1520e8cdeaf5ab5c52d2ae057582cd8f32b7fe6..d8c9111c82a541a39d71465c9b18a626d2dea94e 100644 (file)
--- a/po/README
+++ b/po/README
@@ -232,7 +232,7 @@ Shell:
 
        # To interpolate variables:
        details="oh noes"
-       eval_gettext "An error occured: \$details"; echo
+       eval_gettext "An error occurred: \$details"; echo
 
    In addition we have wrappers for messages that end with a trailing
    newline. I.e. you could write the above as:
@@ -242,7 +242,7 @@ Shell:
 
        # To interpolate variables:
        details="oh noes"
-       eval_gettextln "An error occured: \$details"
+       eval_gettextln "An error occurred: \$details"
 
    More documentation about the interface is available in the GNU info
    page: `info '(gettext)sh'`. Looking at git-am.sh (the first shell
@@ -257,7 +257,7 @@ Perl:
 
        use Git::I18N;
        print __("Welcome to Git!\n");
-       printf __("The following error occured: %s\n"), $error;
+       printf __("The following error occurred: %s\n"), $error;
 
    Run `perldoc perl/Git/I18N.pm` for more info.
 
index eae57ad9d7f3b06a5a76f9d934825f9824def477..41f04e669d3b9c38f49e0853053a6ba27b97357a 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -345,7 +345,7 @@ static int needs_rfc2047_encoding(const char *line, int len,
        return 0;
 }
 
-static void add_rfc2047(struct strbuf *sb, const char *line, int len,
+static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
                       const char *encoding, enum rfc2047_type type)
 {
        static const int max_encoded_length = 76; /* per rfc2047 */
@@ -355,9 +355,22 @@ static void add_rfc2047(struct strbuf *sb, const char *line, int len,
        strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
        strbuf_addf(sb, "=?%s?q?", encoding);
        line_len += strlen(encoding) + 5; /* 5 for =??q? */
-       for (i = 0; i < len; i++) {
-               unsigned ch = line[i] & 0xFF;
-               int is_special = is_rfc2047_special(ch, type);
+
+       while (len) {
+               /*
+                * RFC 2047, section 5 (3):
+                *
+                * Each 'encoded-word' MUST represent an integral number of
+                * characters.  A multi-octet character may not be split across
+                * adjacent 'encoded- word's.
+                */
+               const unsigned char *p = (const unsigned char *)line;
+               int chrlen = mbs_chrlen(&line, &len, encoding);
+               int is_special = (chrlen > 1) || is_rfc2047_special(*p, type);
+
+               /* "=%02X" * chrlen, or the byte itself */
+               const char *encoded_fmt = is_special ? "=%02X"    : "%c";
+               int         encoded_len = is_special ? 3 * chrlen : 1;
 
                /*
                 * According to RFC 2047, we could encode the special character
@@ -367,18 +380,15 @@ static void add_rfc2047(struct strbuf *sb, const char *line, int len,
                 * causes ' ' to be encoded as '=20', avoiding this problem.
                 */
 
-               if (line_len + 2 + (is_special ? 3 : 1) > max_encoded_length) {
+               if (line_len + encoded_len + 2 > max_encoded_length) {
+                       /* It won't fit with trailing "?=" --- break the line */
                        strbuf_addf(sb, "?=\n =?%s?q?", encoding);
                        line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
                }
 
-               if (is_special) {
-                       strbuf_addf(sb, "=%02X", ch);
-                       line_len += 3;
-               } else {
-                       strbuf_addch(sb, ch);
-                       line_len++;
-               }
+               for (i = 0; i < chrlen; i++)
+                       strbuf_addf(sb, encoded_fmt, p[i]);
+               line_len += encoded_len;
        }
        strbuf_addstr(sb, "?=");
 }
@@ -759,8 +769,10 @@ struct format_commit_context {
        unsigned commit_signature_parsed:1;
        struct {
                char *gpg_output;
+               char *gpg_status;
                char good_bad;
                char *signer;
+               char *key;
        } signature;
        char *message;
        size_t width, indent1, indent2;
@@ -948,13 +960,13 @@ static struct {
        char result;
        const char *check;
 } signature_check[] = {
-       { 'G', ": Good signature from " },
-       { 'B', ": BAD signature from " },
+       { 'G', "\n[GNUPG:] GOODSIG " },
+       { 'B', "\n[GNUPG:] BADSIG " },
 };
 
 static void parse_signature_lines(struct format_commit_context *ctx)
 {
-       const char *buf = ctx->signature.gpg_output;
+       const char *buf = ctx->signature.gpg_status;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(signature_check); i++) {
@@ -964,6 +976,8 @@ static void parse_signature_lines(struct format_commit_context *ctx)
                        continue;
                ctx->signature.good_bad = signature_check[i].result;
                found += strlen(signature_check[i].check);
+               ctx->signature.key = xmemdupz(found, 16);
+               found += 17;
                next = strchrnul(found, '\n');
                ctx->signature.signer = xmemdupz(found, next - found);
                break;
@@ -975,6 +989,7 @@ static void parse_commit_signature(struct format_commit_context *ctx)
        struct strbuf payload = STRBUF_INIT;
        struct strbuf signature = STRBUF_INIT;
        struct strbuf gpg_output = STRBUF_INIT;
+       struct strbuf gpg_status = STRBUF_INIT;
        int status;
 
        ctx->commit_signature_parsed = 1;
@@ -984,13 +999,15 @@ static void parse_commit_signature(struct format_commit_context *ctx)
                goto out;
        status = verify_signed_buffer(payload.buf, payload.len,
                                      signature.buf, signature.len,
-                                     &gpg_output);
+                                     &gpg_output, &gpg_status);
        if (status && !gpg_output.len)
                goto out;
        ctx->signature.gpg_output = strbuf_detach(&gpg_output, NULL);
+       ctx->signature.gpg_status = strbuf_detach(&gpg_status, NULL);
        parse_signature_lines(ctx);
 
  out:
+       strbuf_release(&gpg_status);
        strbuf_release(&gpg_output);
        strbuf_release(&payload);
        strbuf_release(&signature);
@@ -1200,6 +1217,10 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                        if (c->signature.signer)
                                strbuf_addstr(sb, c->signature.signer);
                        break;
+               case 'K':
+                       if (c->signature.key)
+                               strbuf_addstr(sb, c->signature.key);
+                       break;
                }
                return 2;
        }
index bf7970661f26664e461ed5d6fd7a1982f7e8fadd..e7e6a1e342200bbf4c37bd561e6a68222349418e 100644 (file)
@@ -152,11 +152,9 @@ static int add_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
 
 static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
 {
-       struct object *object = parse_object(sha1);
+       struct object *object = parse_object_or_die(sha1, path);
        struct rev_info *revs = (struct rev_info *)cb_data;
 
-       if (!object)
-               die("bad object ref: %s:%s", path, sha1_to_hex(sha1));
        add_pending_object(revs, object, "");
 
        return 0;
index 827ae55c508addf5c058872e554a3d914389e324..5a9704f4e5b974a46bc5486373a26816c5b3b4bd 100644 (file)
@@ -46,7 +46,7 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
 {
        struct cache_entry *old = istate->cache[nr];
 
-       remove_name_hash(old);
+       remove_name_hash(istate, old);
        set_index_entry(istate, nr, ce);
        istate->cache_changed = 1;
 }
@@ -460,7 +460,7 @@ int remove_index_entry_at(struct index_state *istate, int pos)
        struct cache_entry *ce = istate->cache[pos];
 
        record_resolve_undo(istate, ce);
-       remove_name_hash(ce);
+       remove_name_hash(istate, ce);
        istate->cache_changed = 1;
        istate->cache_nr--;
        if (pos >= istate->cache_nr)
@@ -483,7 +483,7 @@ void remove_marked_cache_entries(struct index_state *istate)
 
        for (i = j = 0; i < istate->cache_nr; i++) {
                if (ce_array[i]->ce_flags & CE_REMOVE)
-                       remove_name_hash(ce_array[i]);
+                       remove_name_hash(istate, ce_array[i]);
                else
                        ce_array[j++] = ce_array[i];
        }
@@ -1260,7 +1260,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
        if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
                return error("bad signature");
        hdr_version = ntohl(hdr->hdr_version);
-       if (hdr_version < 2 || 4 < hdr_version)
+       if (hdr_version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < hdr_version)
                return error("bad index version %d", hdr_version);
        git_SHA1_Init(&c);
        git_SHA1_Update(&c, hdr, size - 20);
@@ -1515,8 +1515,7 @@ int discard_index(struct index_state *istate)
        istate->cache_changed = 0;
        istate->timestamp.sec = 0;
        istate->timestamp.nsec = 0;
-       istate->name_hash_initialized = 0;
-       free_hash(&istate->name_hash);
+       free_name_hash(istate);
        cache_tree_free(&(istate->cache_tree));
        istate->initialized = 0;
 
diff --git a/refs.c b/refs.c
index 175b9fcaa25eba2ad02564b32eba04c3351978c5..e2b760d0baffd6db6b49e6014a58efa062f1a119 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -803,11 +803,38 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
        return line;
 }
 
+/*
+ * Read f, which is a packed-refs file, into dir.
+ *
+ * A comment line of the form "# pack-refs with: " may contain zero or
+ * more traits. We interpret the traits as follows:
+ *
+ *   No traits:
+ *
+ *      Probably no references are peeled. But if the file contains a
+ *      peeled value for a reference, we will use it.
+ *
+ *   peeled:
+ *
+ *      References under "refs/tags/", if they *can* be peeled, *are*
+ *      peeled in this file. References outside of "refs/tags/" are
+ *      probably not peeled even if they could have been, but if we find
+ *      a peeled value for such a reference we will use it.
+ *
+ *   fully-peeled:
+ *
+ *      All references in the file that can be peeled are peeled.
+ *      Inversely (and this is more important), any references in the
+ *      file for which no peeled value is recorded is not peelable. This
+ *      trait should typically be written alongside "peeled" for
+ *      compatibility with older clients, but we do not require it
+ *      (i.e., "peeled" is a no-op if "fully-peeled" is set).
+ */
 static void read_packed_refs(FILE *f, struct ref_dir *dir)
 {
        struct ref_entry *last = NULL;
        char refline[PATH_MAX];
-       int flag = REF_ISPACKED;
+       enum { PEELED_NONE, PEELED_TAGS, PEELED_FULLY } peeled = PEELED_NONE;
 
        while (fgets(refline, sizeof(refline), f)) {
                unsigned char sha1[20];
@@ -816,15 +843,20 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
 
                if (!strncmp(refline, header, sizeof(header)-1)) {
                        const char *traits = refline + sizeof(header) - 1;
-                       if (strstr(traits, " peeled "))
-                               flag |= REF_KNOWS_PEELED;
+                       if (strstr(traits, " fully-peeled "))
+                               peeled = PEELED_FULLY;
+                       else if (strstr(traits, " peeled "))
+                               peeled = PEELED_TAGS;
                        /* perhaps other traits later as well */
                        continue;
                }
 
                refname = parse_ref_line(refline, sha1);
                if (refname) {
-                       last = create_ref_entry(refname, sha1, flag, 1);
+                       last = create_ref_entry(refname, sha1, REF_ISPACKED, 1);
+                       if (peeled == PEELED_FULLY ||
+                           (peeled == PEELED_TAGS && !prefixcmp(refname, "refs/tags/")))
+                               last->flag |= REF_KNOWS_PEELED;
                        add_ref(dir, last);
                        continue;
                }
@@ -832,8 +864,15 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
                    refline[0] == '^' &&
                    strlen(refline) == 42 &&
                    refline[41] == '\n' &&
-                   !get_sha1_hex(refline + 1, sha1))
+                   !get_sha1_hex(refline + 1, sha1)) {
                        hashcpy(last->u.value.peeled, sha1);
+                       /*
+                        * Regardless of what the file header said,
+                        * we definitely know the value of *this*
+                        * reference:
+                        */
+                       last->flag |= REF_KNOWS_PEELED;
+               }
        }
 }
 
index ef6020541282770b9edc4c921cadb7ab1506da56..cf620c6b3693e2d18b2cacd33574a03b34e4c48e 100644 (file)
@@ -709,7 +709,7 @@ static int still_interesting(struct commit_list *src, unsigned long date, int sl
         * Does the destination list contain entries with a date
         * before the source list? Definitely _not_ done.
         */
-       if (date < src->item->date)
+       if (date <= src->item->date)
                return SLOP;
 
        /*
index aef5e8a0170c5b337f1aa3ac7a35be3b54957729..bad5077911667e11e522043ae09875489d4591c4 100644 (file)
@@ -133,7 +133,7 @@ static void print_advice(int show_hint, struct replay_opts *opts)
        if (msg) {
                fprintf(stderr, "%s\n", msg);
                /*
-                * A conflict has occured but the porcelain
+                * A conflict has occurred but the porcelain
                 * (typically rebase --interactive) wants to take care
                 * of the commit itself so remove CHERRY_PICK_HEAD
                 */
diff --git a/setup.c b/setup.c
index 1dee47e0850369c87408c540ce2b2251db17be3d..94c1e61bda747ed5c664bbbf8431234dc8276d29 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -207,10 +207,11 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
                     *copyfrom && *copyfrom != ')';
                     copyfrom = nextat) {
                        size_t len = strcspn(copyfrom, ",)");
-                       if (copyfrom[len] == ')')
-                               nextat = copyfrom + len;
-                       else
+                       if (copyfrom[len] == ',')
                                nextat = copyfrom + len + 1;
+                       else
+                               /* handle ')' and '\0' */
+                               nextat = copyfrom + len;
                        if (!len)
                                continue;
                        for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
@@ -223,8 +224,9 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
                                die("Invalid pathspec magic '%.*s' in '%s'",
                                    (int) len, copyfrom, elt);
                }
-               if (*copyfrom == ')')
-                       copyfrom++;
+               if (*copyfrom != ')')
+                       die("Missing ')' at the end of pathspec magic in '%s'", elt);
+               copyfrom++;
        } else {
                /* shorthand */
                for (copyfrom = elt + 1;
@@ -523,6 +525,12 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
                        set_git_work_tree(core_worktree);
                }
        }
+       else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
+               /* #16d */
+               set_git_dir(gitdirenv);
+               free(gitfile);
+               return NULL;
+       }
        else /* #2, #10 */
                set_git_work_tree(".");
 
@@ -601,6 +609,8 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
        if (check_repository_format_gently(".", nongit_ok))
                return NULL;
 
+       setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
+
        /* --work-tree is set without --git-dir; use discovered one */
        if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
                const char *gitdir;
@@ -794,9 +804,9 @@ const char *setup_git_directory_gently(int *nongit_ok)
 
        prefix = setup_git_directory_gently_1(nongit_ok);
        if (prefix)
-               setenv("GIT_PREFIX", prefix, 1);
+               setenv(GIT_PREFIX_ENVIRONMENT, prefix, 1);
        else
-               setenv("GIT_PREFIX", "", 1);
+               setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
 
        if (startup_info) {
                startup_info->have_repository = !nongit_ok || !*nongit_ok;
index e4128e5769722473f7fd1024fdf8a5100bd8ccf6..f8bf3ec318f24b883efc75a4b157919687e34156 100644 (file)
--- a/t/README
+++ b/t/README
@@ -86,7 +86,10 @@ appropriately before running "make".
 
 --immediate::
        This causes the test to immediately exit upon the first
-       failed test.
+       failed test. Cleanup commands requested with
+       test_when_finished are not executed if the test failed,
+       in order to keep the state for inspection by the tester
+       to diagnose the bug.
 
 --long-tests::
        This causes additional long-running tests to be run (where
@@ -610,6 +613,11 @@ use these, and "test_set_prereq" for how to define your own.
    The process retains the same pid across exec(2). See fb9a2bea for
    details.
 
+ - PIPE
+
+   The filesystem we're on supports creation of FIFOs (named pipes)
+   via mkfifo(1).
+
  - SYMLINKS
 
    The filesystem we're on supports symbolic links. E.g. a FAT
index 199f22c231b5ac1479929a89cdf988ac7aff4268..c5e55b190bfbb06eef5a03d701b956e32ad22048 100644 (file)
@@ -148,7 +148,7 @@ stop_httpd () {
 convert_to_rev_db () {
        "$PERL_PATH" -w -- - "$@" <<\EOF
 use strict;
-@ARGV == 2 or die "Usage: convert_to_rev_db <input> <output>";
+@ARGV == 2 or die "usage: convert_to_rev_db <input> <output>";
 open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]";
 open my $rd, '<', $ARGV[0] or die "$!: couldn't open: $ARGV[0]";
 my $size = (stat($rd))[7];
index 5378787e1b23bf18796c28c33533f677b389289c..4e9fa3cd68426942357d8f89ffa97ed3099e1084 100755 (executable)
@@ -3,12 +3,6 @@
 test_description='respect crlf in git archive'
 
 . ./test-lib.sh
-GIT_UNZIP=${GIT_UNZIP:-unzip}
-
-test_lazy_prereq UNZIP '
-       "$GIT_UNZIP" -v
-       test $? -ne 127
-'
 
 test_expect_success setup '
 
index d8b7f2ffbcc0427b1ae9d48feb4387f580e81d61..9820f70c84d93b9461ae6663e6ab5b3cd735e3d5 100755 (executable)
@@ -116,9 +116,9 @@ tree_pretty_content="100644 blob $hello_sha1        hello"
 
 run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content"
 
-commit_message="Intial commit"
+commit_message="Initial commit"
 commit_sha1=$(echo_without_newline "$commit_message" | git commit-tree $tree_sha1)
-commit_size=176
+commit_size=177
 commit_content="tree $tree_sha1
 author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0000000000 +0000
 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0000000000 +0000
index c5334a8fa416aedd66a12416c75e85dbd9b6ac70..62691172e34f0d7b5bdfff2920bab4261f9d3b5c 100755 (executable)
@@ -14,7 +14,7 @@ xmkdir() {
 
 R="$1"
 
-[ -n "$R" ] || die "Usage: prepare-chroot.sh <root>"
+[ -n "$R" ] || die "usage: prepare-chroot.sh <root>"
 [ -x git ] || die "This script needs to be executed at git source code's top directory"
 [ -x /bin/busybox ] || die "You need busybox"
 
index 80aedfca8c15bea1104b4985023f338059ae751c..cf2ee7885ac9c2172deccc27dfb994546593e842 100755 (executable)
@@ -517,6 +517,25 @@ test_expect_success '#16c: bare .git has no worktree' '
                "$here/16c/.git" "(null)" "$here/16c/sub" "(null)"
 '
 
+test_expect_success '#16d: bareness preserved across alias' '
+       setup_repo 16d unset "" unset &&
+       (
+               cd 16d/.git &&
+               test_must_fail git status &&
+               git config alias.st status &&
+               test_must_fail git st
+       )
+'
+
+test_expect_success '#16e: bareness preserved by --bare' '
+       setup_repo 16e unset "" unset &&
+       (
+               cd 16e/.git &&
+               test_must_fail git status &&
+               test_must_fail git --bare status
+       )
+'
+
 test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
        # Just like #16.
        setup_repo 17a unset "" true &&
index 02a4fc5d36a08d1046b9384c799f697640da0c4e..ff163cf6750f6d82c36964eb694efbcfae06135f 100755 (executable)
@@ -12,85 +12,108 @@ the GIT controlled paths.
 
 . ./test-lib.sh
 
-test_expect_success \
-    'setup' \
-    'mkdir path1 &&
-    echo frotz >path0 &&
-    echo rezrov >path1/file1 &&
-    git update-index --add path0 path1/file1'
+test_expect_success 'setup' '
+       mkdir path1 &&
+       echo frotz >path0 &&
+       echo rezrov >path1/file1 &&
+       git update-index --add path0 path1/file1
+'
+
+test_expect_success SYMLINKS 'have symlink in place where dir is expected.' '
+       rm -fr path0 path1 &&
+       mkdir path2 &&
+       ln -s path2 path1 &&
+       git checkout-index -f -a &&
+       test ! -h path1 && test -d path1 &&
+       test -f path1/file1 && test ! -f path2/file1
+'
 
-test_expect_success SYMLINKS \
-    'have symlink in place where dir is expected.' \
-    'rm -fr path0 path1 &&
-     mkdir path2 &&
-     ln -s path2 path1 &&
-     git checkout-index -f -a &&
-     test ! -h path1 && test -d path1 &&
-     test -f path1/file1 && test ! -f path2/file1'
+test_expect_success 'use --prefix=path2/' '
+       rm -fr path0 path1 path2 &&
+       mkdir path2 &&
+       git checkout-index --prefix=path2/ -f -a &&
+       test -f path2/path0 &&
+       test -f path2/path1/file1 &&
+       test ! -f path0 &&
+       test ! -f path1/file1
+'
+
+test_expect_success 'use --prefix=tmp-' '
+       rm -fr path0 path1 path2 tmp* &&
+       git checkout-index --prefix=tmp- -f -a &&
+       test -f tmp-path0 &&
+       test -f tmp-path1/file1 &&
+       test ! -f path0 &&
+       test ! -f path1/file1
+'
 
-test_expect_success \
-    'use --prefix=path2/' \
-    'rm -fr path0 path1 path2 &&
-     mkdir path2 &&
-     git checkout-index --prefix=path2/ -f -a &&
-     test -f path2/path0 &&
-     test -f path2/path1/file1 &&
-     test ! -f path0 &&
-     test ! -f path1/file1'
+test_expect_success 'use --prefix=tmp- but with a conflicting file and dir' '
+       rm -fr path0 path1 path2 tmp* &&
+       echo nitfol >tmp-path1 &&
+       mkdir tmp-path0 &&
+       git checkout-index --prefix=tmp- -f -a &&
+       test -f tmp-path0 &&
+       test -f tmp-path1/file1 &&
+       test ! -f path0 &&
+       test ! -f path1/file1
+'
 
-test_expect_success \
-    'use --prefix=tmp-' \
-    'rm -fr path0 path1 path2 tmp* &&
-     git checkout-index --prefix=tmp- -f -a &&
-     test -f tmp-path0 &&
-     test -f tmp-path1/file1 &&
-     test ! -f path0 &&
-     test ! -f path1/file1'
+test_expect_success SYMLINKS 'use --prefix=tmp/orary/ where tmp is a symlink' '
+       rm -fr path0 path1 path2 tmp* &&
+       mkdir tmp1 tmp1/orary &&
+       ln -s tmp1 tmp &&
+       git checkout-index --prefix=tmp/orary/ -f -a &&
+       test -d tmp1/orary &&
+       test -f tmp1/orary/path0 &&
+       test -f tmp1/orary/path1/file1 &&
+       test -h tmp
+'
 
-test_expect_success \
-    'use --prefix=tmp- but with a conflicting file and dir' \
-    'rm -fr path0 path1 path2 tmp* &&
-     echo nitfol >tmp-path1 &&
-     mkdir tmp-path0 &&
-     git checkout-index --prefix=tmp- -f -a &&
-     test -f tmp-path0 &&
-     test -f tmp-path1/file1 &&
-     test ! -f path0 &&
-     test ! -f path1/file1'
+test_expect_success SYMLINKS 'use --prefix=tmp/orary- where tmp is a symlink' '
+       rm -fr path0 path1 path2 tmp* &&
+       mkdir tmp1 &&
+       ln -s tmp1 tmp &&
+       git checkout-index --prefix=tmp/orary- -f -a &&
+       test -f tmp1/orary-path0 &&
+       test -f tmp1/orary-path1/file1 &&
+       test -h tmp
+'
 
-# Linus fix #1
-test_expect_success SYMLINKS \
-    'use --prefix=tmp/orary/ where tmp is a symlink' \
-    'rm -fr path0 path1 path2 tmp* &&
-     mkdir tmp1 tmp1/orary &&
-     ln -s tmp1 tmp &&
-     git checkout-index --prefix=tmp/orary/ -f -a &&
-     test -d tmp1/orary &&
-     test -f tmp1/orary/path0 &&
-     test -f tmp1/orary/path1/file1 &&
-     test -h tmp'
+test_expect_success SYMLINKS 'use --prefix=tmp- where tmp-path1 is a symlink' '
+       rm -fr path0 path1 path2 tmp* &&
+       mkdir tmp1 &&
+       ln -s tmp1 tmp-path1 &&
+       git checkout-index --prefix=tmp- -f -a &&
+       test -f tmp-path0 &&
+       test ! -h tmp-path1 &&
+       test -d tmp-path1 &&
+       test -f tmp-path1/file1
+'
 
-# Linus fix #2
-test_expect_success SYMLINKS \
-    'use --prefix=tmp/orary- where tmp is a symlink' \
-    'rm -fr path0 path1 path2 tmp* &&
-     mkdir tmp1 &&
-     ln -s tmp1 tmp &&
-     git checkout-index --prefix=tmp/orary- -f -a &&
-     test -f tmp1/orary-path0 &&
-     test -f tmp1/orary-path1/file1 &&
-     test -h tmp'
+test_expect_success 'apply filter from working tree .gitattributes with --prefix' '
+       rm -fr path0 path1 path2 tmp* &&
+       mkdir path1 &&
+       mkdir tmp &&
+       git config filter.replace-all.smudge "sed -e s/./,/g" &&
+       git config filter.replace-all.clean cat &&
+       git config filter.replace-all.required true &&
+       echo "file1 filter=replace-all" >path1/.gitattributes &&
+       git checkout-index --prefix=tmp/ -f -a &&
+       echo frotz >expected &&
+       test_cmp expected tmp/path0 &&
+       echo ,,,,,, >expected &&
+       test_cmp expected tmp/path1/file1
+'
 
-# Linus fix #3
-test_expect_success SYMLINKS \
-    'use --prefix=tmp- where tmp-path1 is a symlink' \
-    'rm -fr path0 path1 path2 tmp* &&
-     mkdir tmp1 &&
-     ln -s tmp1 tmp-path1 &&
-     git checkout-index --prefix=tmp- -f -a &&
-     test -f tmp-path0 &&
-     test ! -h tmp-path1 &&
-     test -d tmp-path1 &&
-     test -f tmp-path1/file1'
+test_expect_success 'apply CRLF filter from working tree .gitattributes with --prefix' '
+       rm -fr path0 path1 path2 tmp* &&
+       mkdir path1 &&
+       mkdir tmp &&
+       echo "file1 eol=crlf" >path1/.gitattributes &&
+       git checkout-index --prefix=tmp/ -f -a &&
+       echo rezrovQ >expected &&
+       tr \\015 Q <tmp/path1/file1 >actual &&
+       test_cmp expected actual
+'
 
 test_done
index f3e0e4a38c3188760df8cb5bd4c096e2209fed9f..12f1e4a63c33b2f394ea37db71e1cd4467cee8f5 100755 (executable)
@@ -42,6 +42,10 @@ test_expect_success \
     'git branch a/b/c should create a branch' \
     'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c'
 
+test_expect_success \
+    'git branch HEAD should fail' \
+    'test_must_fail git branch HEAD'
+
 cat >expect <<EOF
 $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000        branch: Created from master
 EOF
@@ -388,6 +392,14 @@ test_expect_success \
     'git tag foobar &&
      test_must_fail git branch --track my11 foobar'
 
+test_expect_success '--set-upstream-to fails on multiple branches' \
+    'test_must_fail git branch --set-upstream-to master a b c'
+
+test_expect_success '--set-upstream-to fails on detached HEAD' \
+    'git checkout HEAD^{} &&
+     test_must_fail git branch --set-upstream-to master &&
+     git checkout -'
+
 test_expect_success 'use --set-upstream-to modify HEAD' \
     'test_config branch.master.remote foo &&
      test_config branch.master.merge foo &&
@@ -417,6 +429,15 @@ test_expect_success 'test --unset-upstream on HEAD' \
      test_must_fail git branch --unset-upstream
 '
 
+test_expect_success '--unset-upstream should fail on multiple branches' \
+    'test_must_fail git branch --unset-upstream a b c'
+
+test_expect_success '--unset-upstream should fail on detached HEAD' \
+    'git checkout HEAD^{} &&
+     test_must_fail git branch --unset-upstream &&
+     git checkout -
+'
+
 test_expect_success 'test --unset-upstream on a particular branch' \
     'git branch my15
      git branch --set-upstream-to master my14 &&
diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh
new file mode 100755 (executable)
index 0000000..d4d7792
--- /dev/null
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+test_description='tests for the peel_ref optimization of packed-refs'
+. ./test-lib.sh
+
+test_expect_success 'create annotated tag in refs/tags' '
+       test_commit base &&
+       git tag -m annotated foo
+'
+
+test_expect_success 'create annotated tag outside of refs/tags' '
+       git update-ref refs/outside/foo refs/tags/foo
+'
+
+# This matches show-ref's output
+print_ref() {
+       echo "$(git rev-parse "$1") $1"
+}
+
+test_expect_success 'set up expected show-ref output' '
+       {
+               print_ref "refs/heads/master" &&
+               print_ref "refs/outside/foo" &&
+               print_ref "refs/outside/foo^{}" &&
+               print_ref "refs/tags/base" &&
+               print_ref "refs/tags/foo" &&
+               print_ref "refs/tags/foo^{}"
+       } >expect
+'
+
+test_expect_success 'refs are peeled outside of refs/tags (loose)' '
+       git show-ref -d >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'refs are peeled outside of refs/tags (packed)' '
+       git pack-refs --all &&
+       git show-ref -d >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'create old-style pack-refs without fully-peeled' '
+       # Git no longer writes without fully-peeled, so we just write our own
+       # from scratch; we could also munge the existing file to remove the
+       # fully-peeled bits, but that seems even more prone to failure,
+       # especially if the format ever changes again. At least this way we
+       # know we are emulating exactly what an older git would have written.
+       {
+               echo "# pack-refs with: peeled " &&
+               print_ref "refs/heads/master" &&
+               print_ref "refs/outside/foo" &&
+               print_ref "refs/tags/base" &&
+               print_ref "refs/tags/foo" &&
+               echo "^$(git rev-parse "refs/tags/foo^{}")"
+       } >tmp &&
+       mv tmp .git/packed-refs
+'
+
+test_expect_success 'refs are peeled outside of refs/tags (old packed)' '
+       git show-ref -d >actual &&
+       test_cmp expect actual
+'
+
+test_done
index 098a6ae4a086ccfeb8c658a80773eb07c9d66441..9fab25cc96b079349a3ca3caffbd8d2bc322265c 100755 (executable)
@@ -319,7 +319,7 @@ test_expect_success PERL 'split hunk "add -p (edit)"' '
        # times to get out.
        #
        # 2. Correct version applies the (not)edited version, and asks
-       #    about the next hunk, against wich we say q and program
+       #    about the next hunk, against which we say q and program
        #    exits.
        for a in s e     q n q q
        do
index 844277cfa605f51cccd5d78a48a83fb75c03af9b..2f327b749588af7eda57187cba4d365233a25ef9 100755 (executable)
@@ -102,4 +102,58 @@ test_expect_success 'setup for many rename source candidates' '
        grep warning actual.err
 '
 
+test_expect_success 'rename pretty print with nothing in common' '
+       mkdir -p a/b/ &&
+       : >a/b/c &&
+       git add a/b/c &&
+       git commit -m "create a/b/c" &&
+       mkdir -p c/b/ &&
+       git mv a/b/c c/b/a &&
+       git commit -m "a/b/c -> c/b/a" &&
+       git diff -M --summary HEAD^ HEAD >output &&
+       test_i18ngrep " a/b/c => c/b/a " output &&
+       git diff -M --stat HEAD^ HEAD >output &&
+       test_i18ngrep " a/b/c => c/b/a " output
+'
+
+test_expect_success 'rename pretty print with common prefix' '
+       mkdir -p c/d &&
+       git mv c/b/a c/d/e &&
+       git commit -m "c/b/a -> c/d/e" &&
+       git diff -M --summary HEAD^ HEAD >output &&
+       test_i18ngrep " c/{b/a => d/e} " output &&
+       git diff -M --stat HEAD^ HEAD >output &&
+       test_i18ngrep " c/{b/a => d/e} " output
+'
+
+test_expect_success 'rename pretty print with common suffix' '
+       mkdir d &&
+       git mv c/d/e d/e &&
+       git commit -m "c/d/e -> d/e" &&
+       git diff -M --summary HEAD^ HEAD >output &&
+       test_i18ngrep " {c/d => d}/e " output &&
+       git diff -M --stat HEAD^ HEAD >output &&
+       test_i18ngrep " {c/d => d}/e " output
+'
+
+test_expect_success 'rename pretty print with common prefix and suffix' '
+       mkdir d/f &&
+       git mv d/e d/f/e &&
+       git commit -m "d/e -> d/f/e" &&
+       git diff -M --summary HEAD^ HEAD >output &&
+       test_i18ngrep " d/{ => f}/e " output &&
+       git diff -M --stat HEAD^ HEAD >output &&
+       test_i18ngrep " d/{ => f}/e " output
+'
+
+test_expect_success 'rename pretty print common prefix and suffix overlap' '
+       mkdir d/f/f &&
+       git mv d/f/e d/f/f/e &&
+       git commit -m "d/f/e d/f/f/e" &&
+       git diff -M --summary HEAD^ HEAD >output &&
+       test_i18ngrep " d/f/{ => f}/e " output &&
+       git diff -M --stat HEAD^ HEAD >output &&
+       test_i18ngrep " d/f/{ => f}/e " output
+'
+
 test_done
index 7fa3647514b616b1a40b233b23123a00c4d3ff6c..183fbe5bb3ea533f8f5f76f397d53671f912d6b0 100755 (executable)
@@ -742,21 +742,21 @@ test_expect_success 'format-patch --signature --cover-letter' '
        test 2 = $(grep "my sig" output | wc -l)
 '
 
-test_expect_success 'format.signature="" supresses signatures' '
+test_expect_success 'format.signature="" suppresses signatures' '
        git config format.signature "" &&
        git format-patch --stdout -1 >output &&
        check_patch output &&
        ! grep "^-- \$" output
 '
 
-test_expect_success 'format-patch --no-signature supresses signatures' '
+test_expect_success 'format-patch --no-signature suppresses signatures' '
        git config --unset-all format.signature &&
        git format-patch --stdout --no-signature -1 >output &&
        check_patch output &&
        ! grep "^-- \$" output
 '
 
-test_expect_success 'format-patch --signature="" supresses signatures' '
+test_expect_success 'format-patch --signature="" suppresses signatures' '
        git format-patch --stdout --signature="" -1 >output &&
        check_patch output &&
        ! grep "^-- \$" output
@@ -837,25 +837,26 @@ Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
  =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
  =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
  =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
- =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
- =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
- =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
  =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
  =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
  =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
- =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
- =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
- =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
  =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
  =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
  =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
- =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
- =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
- =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
- =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar?=
 EOF
 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
        rm -rf patches/ &&
index 082d3e83bddf242fb02f5124fd52d125520af6b8..38a092a0dadbe09b903484c1d34e240a9d819c77 100755 (executable)
@@ -93,11 +93,6 @@ sed -e '
        s/song;/song();/
 ' <Beer.perl >Beer-correct.perl
 
-test_config () {
-       git config "$1" "$2" &&
-       test_when_finished "git config --unset $1"
-}
-
 test_expect_funcname () {
        lang=${2-java}
        test_expect_code 1 git diff --no-index -U1 \
index 6f6ee88b28bc5417035b45d87aaf4a9c974ab6c5..581a801649f20a74e81c32f9503f233c3cd3d507 100755 (executable)
@@ -47,7 +47,7 @@ test_fix () {
        # find touched lines
        $DIFF file target | sed -n -e "s/^> //p" >fixed
 
-       # the changed lines are all expeced to change
+       # the changed lines are all expected to change
        fixed_cnt=$(wc -l <fixed)
        case "$1" in
        '') expect_cnt=$fixed_cnt ;;
index 0c847fb45482b67266dc6eb9ec62b8cc7b5a9d76..6667d159ab0950f10a3271f1cb81a63953214f17 100755 (executable)
@@ -27,6 +27,25 @@ test_expect_success 'setup' '
        echo ignored-only-if-dir/ export-ignore >>.git/info/attributes &&
        git add ignored-only-if-dir &&
 
+       mkdir -p ignored-without-slash &&
+       echo "ignored without slash" >ignored-without-slash/foo &&
+       git add ignored-without-slash/foo &&
+       echo "ignored-without-slash export-ignore" >>.git/info/attributes &&
+
+       mkdir -p wildcard-without-slash &&
+       echo "ignored without slash" >wildcard-without-slash/foo &&
+       git add wildcard-without-slash/foo &&
+       echo "wild*-without-slash export-ignore" >>.git/info/attributes &&
+
+       mkdir -p deep/and/slashless &&
+       echo "ignored without slash" >deep/and/slashless/foo &&
+       git add deep/and/slashless/foo &&
+       echo "deep/and/slashless export-ignore" >>.git/info/attributes &&
+
+       mkdir -p deep/with/wildcard &&
+       echo "ignored without slash" >deep/with/wildcard/foo &&
+       git add deep/with/wildcard/foo &&
+       echo "deep/*t*/wildcard export-ignore" >>.git/info/attributes &&
 
        mkdir -p one-level-lower/two-levels-lower/ignored-only-if-dir &&
        echo ignored by ignored dir >one-level-lower/two-levels-lower/ignored-only-if-dir/ignored-by-ignored-dir &&
@@ -49,6 +68,14 @@ test_expect_exists   archive/not-ignored-dir/ignored-only-if-dir
 test_expect_exists     archive/not-ignored-dir/
 test_expect_missing    archive/ignored-only-if-dir/
 test_expect_missing    archive/ignored-ony-if-dir/ignored-by-ignored-dir
+test_expect_missing    archive/ignored-without-slash/ &&
+test_expect_missing    archive/ignored-without-slash/foo &&
+test_expect_missing    archive/wildcard-without-slash/
+test_expect_missing    archive/wildcard-without-slash/foo &&
+test_expect_missing    archive/deep/and/slashless/ &&
+test_expect_missing    archive/deep/and/slashless/foo &&
+test_expect_missing    archive/deep/with/wildcard/ &&
+test_expect_missing    archive/deep/with/wildcard/foo &&
 test_expect_exists     archive/one-level-lower/
 test_expect_missing    archive/one-level-lower/two-levels-lower/ignored-only-if-dir/
 test_expect_missing    archive/one-level-lower/two-levels-lower/ignored-ony-if-dir/ignored-by-ignored-dir
index 7cfe9ca3dacb1488aa44ea3643e1333d346feac7..4e7b05dd2391125b1c9e58404c552647107099cd 100755 (executable)
@@ -3,15 +3,9 @@
 test_description='git archive --format=zip test'
 
 . ./test-lib.sh
-GIT_UNZIP=${GIT_UNZIP:-unzip}
 
 SUBSTFORMAT=%H%n
 
-test_lazy_prereq UNZIP '
-       "$GIT_UNZIP" -v
-       test $? -ne 127
-'
-
 test_lazy_prereq UNZIP_SYMLINKS '
        (
                mkdir unzip-symlinks &&
@@ -76,6 +70,12 @@ test_expect_success \
      git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \
      git commit-tree $treeid </dev/null)'
 
+test_expect_success 'setup export-subst' '
+       echo "substfile?" export-subst >>.git/info/attributes &&
+       git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
+               >a/substfile1
+'
+
 test_expect_success \
     'create bare clone' \
     'git clone --bare . bare.git &&
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
new file mode 100755 (executable)
index 0000000..cdb7d7a
--- /dev/null
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+test_description='test corner cases of git-archive'
+. ./test-lib.sh
+
+test_expect_success 'create commit with empty tree' '
+       git commit --allow-empty -m foo
+'
+
+# Make a dir and clean it up afterwards
+make_dir() {
+       mkdir "$1" &&
+       test_when_finished "rm -rf '$1'"
+}
+
+# Check that the dir given in "$1" contains exactly the
+# set of paths given as arguments.
+check_dir() {
+       dir=$1; shift
+       {
+               echo "$dir" &&
+               for i in "$@"; do
+                       echo "$dir/$i"
+               done
+       } | sort >expect &&
+       find "$dir" -print | sort >actual &&
+       test_cmp expect actual
+}
+
+test_expect_success 'tar archive of empty tree is empty' '
+       git archive --format=tar HEAD >empty.tar &&
+       make_dir extract &&
+       "$TAR" xf empty.tar -C extract &&
+       check_dir extract
+'
+
+test_expect_success 'tar archive of empty tree with prefix' '
+       git archive --format=tar --prefix=foo/ HEAD >prefix.tar &&
+       make_dir extract &&
+       "$TAR" xf prefix.tar -C extract &&
+       check_dir extract foo
+'
+
+test_expect_success UNZIP 'zip archive of empty tree is empty' '
+       # Detect the exit code produced when our particular flavor of unzip
+       # sees an empty archive. Infozip will generate a warning and exit with
+       # code 1. But in the name of sanity, we do not expect other unzip
+       # implementations to do the same thing (it would be perfectly
+       # reasonable to exit 0, for example).
+       #
+       # This makes our test less rigorous on some platforms (unzip may not
+       # handle the empty repo at all, making our later check of its exit code
+       # a no-op). But we cannot do anything reasonable except skip the test
+       # on such platforms anyway, and this is the moral equivalent.
+       "$GIT_UNZIP" "$TEST_DIRECTORY"/t5004/empty.zip
+       expect_code=$?
+
+       git archive --format=zip HEAD >empty.zip &&
+       make_dir extract &&
+       (
+               cd extract &&
+               test_expect_code $expect_code "$GIT_UNZIP" ../empty.zip
+       ) &&
+       check_dir extract
+'
+
+test_expect_success UNZIP 'zip archive of empty tree with prefix' '
+       # We do not have to play exit-code tricks here, because our
+       # result should not be empty; it has a directory in it.
+       git archive --format=zip --prefix=foo/ HEAD >prefix.zip &&
+       make_dir extract &&
+       (
+               cd extract &&
+               "$GIT_UNZIP" ../prefix.zip
+       ) &&
+       check_dir extract foo
+'
+
+test_expect_success 'archive complains about pathspec on empty tree' '
+       test_must_fail git archive --format=tar HEAD -- foo >/dev/null
+'
+
+test_expect_success 'create a commit with an empty subtree' '
+       empty_tree=$(git hash-object -t tree /dev/null) &&
+       root_tree=$(printf "040000 tree $empty_tree\tsub\n" | git mktree)
+'
+
+test_expect_success 'archive empty subtree with no pathspec' '
+       git archive --format=tar $root_tree >subtree-all.tar &&
+       make_dir extract &&
+       "$TAR" xf subtree-all.tar -C extract &&
+       check_dir extract sub
+'
+
+test_expect_success 'archive empty subtree by direct pathspec' '
+       git archive --format=tar $root_tree -- sub >subtree-path.tar &&
+       make_dir extract &&
+       "$TAR" xf subtree-path.tar -C extract &&
+       check_dir extract sub
+'
+
+test_done
diff --git a/t/t5004/empty.zip b/t/t5004/empty.zip
new file mode 100644 (file)
index 0000000..1a76bb6
Binary files /dev/null and b/t/t5004/empty.zip differ
index 354d32c584741daffa03891c5bee7fdc469a20da..d574085696e81522669119c9b7480ba4c682c968 100755 (executable)
@@ -364,6 +364,15 @@ EOF
        test_cmp count7.expected count7.actual
 '
 
+test_expect_success 'clone shallow with packed refs' '
+       git pack-refs --all &&
+       git clone --depth 1 --branch A "file://$(pwd)/." shallow8 &&
+       echo "in-pack: 4" > count8.expected &&
+       GIT_DIR=shallow8/.git git count-objects -v |
+               grep "^in-pack" > count8.actual &&
+       test_cmp count8.expected count8.actual
+'
+
 test_expect_success 'setup tests for the --stdin parameter' '
        for head in C D E F
        do
index c31e5c1c525eea5a9f4677b03c5d7314d70c6136..9a21cd61d7c5efa13990e474d6c5f1ba0e939b71 100755 (executable)
@@ -230,10 +230,10 @@ test_expect_success 'push with pushInsteadOf' '
 
 test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
        mk_empty &&
-       TRASH="$(pwd)/" &&
-       git config "url.trash2/.pushInsteadOf" trash/ &&
+       git config "url.trash2/.pushInsteadOf" testrepo/ &&
+       git config "url.trash3/.pusnInsteadOf" trash/wrong &&
        git config remote.r.url trash/wrong &&
-       git config remote.r.pushurl "$TRASH/testrepo" &&
+       git config remote.r.pushurl "testrepo/" &&
        git push r refs/heads/master:refs/remotes/origin/master &&
        (
                cd testrepo &&
index 30507407ff6375f96c632c7c3f62ae3d338ed5ea..66cda17ef342a2791ce7bac873eecfd4cf319faf 100755 (executable)
@@ -133,4 +133,17 @@ test_expect_success 'dodecapus' '
        check_revlist "--min-parents=13" &&
        check_revlist "--min-parents=4 --max-parents=11" tetrapus
 '
+
+test_expect_success 'ancestors with the same commit time' '
+
+       test_tick_keep=$test_tick &&
+       for i in 1 2 3 4 5 6 7 8; do
+               test_tick=$test_tick_keep
+               test_commit t$i
+       done &&
+       git rev-list t1^! --not t$i >result &&
+       >expect &&
+       test_cmp expect result
+'
+
 test_done
index 3e0e15fb3e0b92ab7e95789d27db34d9a1fa423c..8bf99e10a3f862e8502fc901b1ea5d7c16e947c9 100755 (executable)
@@ -190,7 +190,7 @@ test_expect_success 'bisect start: no ".git/BISECT_START" if checkout error' '
 # $HASH1 is good, $HASH4 is bad, we skip $HASH3
 # but $HASH2 is bad,
 # so we should find $HASH2 as the first bad commit
-test_expect_success 'bisect skip: successfull result' '
+test_expect_success 'bisect skip: successful result' '
        git bisect reset &&
        git bisect start $HASH4 $HASH1 &&
        git bisect skip &&
index f5a79b13aecf4020b8a453f5f27568ce4f88bbbc..c8d6e9f88cc36f7e6a1208721ea6c45991452b9e 100755 (executable)
@@ -104,6 +104,18 @@ test_expect_success 'creating a tag using HEAD directly should succeed' '
        tag_exists myhead
 '
 
+test_expect_success '--force can create a tag with the name of one existing' '
+       tag_exists mytag &&
+       git tag --force mytag &&
+       tag_exists mytag'
+
+test_expect_success '--force is moot with a non-existing tag name' '
+       git tag newtag >expect &&
+       git tag --force forcetag >actual &&
+       test_cmp expect actual
+'
+git tag -d newtag forcetag
+
 # deleting tags:
 
 test_expect_success 'trying to delete an unknown tag should fail' '
index f4f38a5e7387694e16ff6f4a54020843630c2ac7..52ef06b0005aabf2a201d20dbb5f232e3a26766a 100755 (executable)
@@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
 . ./test-lib.sh
 
 test_expect_success setup '
+       git config --global advice.statusuoption false &&
        test_commit A &&
        test_commit B oneside added &&
        git checkout A^0 &&
diff --git a/t/t7062-wtstatus-ignorecase.sh b/t/t7062-wtstatus-ignorecase.sh
new file mode 100755 (executable)
index 0000000..73709db
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+test_description='git-status with core.ignorecase=true'
+
+. ./test-lib.sh
+
+test_expect_success 'status with hash collisions' '
+       # note: "V/", "V/XQANY/" and "WURZAUP/" produce the same hash code
+       # in name-hash.c::hash_name
+       mkdir V &&
+       mkdir V/XQANY &&
+       mkdir WURZAUP &&
+       touch V/XQANY/test &&
+       git config core.ignorecase true &&
+       git add . &&
+       # test is successful if git status completes (no endless loop)
+       git status
+'
+
+test_done
index 4975ec07ce614c8473f7f5638a008d7058730f06..1a3d20bdc36c63c5261090d76858d43bd7f64113 100755 (executable)
@@ -643,7 +643,8 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re
        rm -rf super_update_r2 &&
        git clone super_update_r super_update_r2 &&
        (cd super_update_r2 &&
-        git submodule update --init --recursive &&
+        git submodule update --init --recursive >actual &&
+        test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual &&
         (cd submodule/subsubmodule &&
          git log > ../../expected
         ) &&
index cbd7a45927eb2d4b04649f21f82192091782ce90..292bc082b2ecc74c652a740b55b888568a0b8eb2 100755 (executable)
@@ -177,12 +177,20 @@ test_expect_success 'verbose respects diff config' '
        git config --unset color.diff
 '
 
+mesg_with_comment_and_newlines='
+# text
+
+'
+
+test_expect_success 'prepare file with comment line and trailing newlines'  '
+       printf "%s" "$mesg_with_comment_and_newlines" >expect
+'
+
 test_expect_success 'cleanup commit messages (verbatim option,-t)' '
 
        echo >>negative &&
-       { echo;echo "# text";echo; } >expect &&
-       git commit --cleanup=verbatim -t expect -a &&
-       git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual &&
+       git commit --cleanup=verbatim --no-status -t expect -a &&
+       git cat-file -p HEAD |sed -e "1,/^\$/d" >actual &&
        test_cmp expect actual
 
 '
@@ -199,7 +207,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-F)' '
 test_expect_success 'cleanup commit messages (verbatim option,-m)' '
 
        echo >>negative &&
-       git commit --cleanup=verbatim -m "$(cat expect)" -a &&
+       git commit --cleanup=verbatim -m "$mesg_with_comment_and_newlines" -a &&
        git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
        test_cmp expect actual
 
index a79c032ffd941a68e737b844ea5b28fffe58686c..aecb4d1e5fdc1e966aad07ee1f1e7af834388bb2 100755 (executable)
@@ -8,6 +8,7 @@ test_description='git status'
 . ./test-lib.sh
 
 test_expect_success 'status -h in broken repository' '
+       git config --global advice.statusuoption false &&
        mkdir broken &&
        test_when_finished "rm -fr broken" &&
        (
index d2da89a5f572134c55c690b1439ffde66ecdd6cb..9d4610629d725c22b9de5187abf71b2b8544292d 100755 (executable)
@@ -14,6 +14,7 @@ test_description='git status advice'
 set_fake_editor
 
 test_expect_success 'prepare for conflicts' '
+       git config --global advice.statusuoption false &&
        test_commit init main.txt init &&
        git branch conflicts &&
        test_commit on_master main.txt on_master &&
index b44b29395049308b30e61b00a55e2eb39f4355a1..25dac798894f6a3cb4b62c8b9ba944bfc1d82d9f 100755 (executable)
@@ -109,7 +109,7 @@ test_expect_success 'setup conflicted merge' '
 '
 
 # First do the merge with resolve and recursive then verify that
-# recusive is choosen.
+# recusive is chosen.
 
 test_expect_success 'merge picks up the best result' '
        git config --unset-all pull.twohead &&
index bc38737b2a5ebd9b7ba20fcb92ac87c48b9496c8..d526b1d96a2e98bc304f4d36eaaa60858080e63d 100755 (executable)
@@ -237,7 +237,7 @@ test_expect_success 'mergetool takes partial path' '
     git submodule update -N &&
     test_must_fail git merge master &&
 
-    #shouldnt need these lines
+    #should not need these lines
     #( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
     #( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
     #( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
index a8957782cfb8fae4b7c171d4c9db24ce6cd5505e..e1951a5cbb759a0f233b624a1a1a7e9c55ff9640 100755 (executable)
@@ -125,11 +125,6 @@ test_expect_success 'modified file' '
        test_cmp empty out
 '
 
-test_config() {
-       git config "$1" "$2" &&
-       test_when_finished "git config --unset $1"
-}
-
 test_expect_success 'copes with color settings' '
        rm -f actual &&
        echo grep.h >expect &&
index 97d6f4c7de57c54adfd5fed6401dbd168b5f3064..ebd5c5db45c8816f39b2d8c60775f455ab9c48aa 100755 (executable)
@@ -101,7 +101,7 @@ test_expect_success $PREREQ \
 
 test_expect_success $PREREQ 'Send patches with --envelope-sender' '
     clean_fake_sendmail &&
-     git send-email --envelope-sender="Patch Contributer <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
+     git send-email --envelope-sender="Patch Contributor <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
 '
 
 test_expect_success $PREREQ 'setup expect' '
@@ -787,7 +787,7 @@ test_expect_success $PREREQ 'confirm detects EOF (auto causes failure)' '
        test $ret = "0"
 '
 
-test_expect_success $PREREQ 'confirm doesnt loop forever' '
+test_expect_success $PREREQ 'confirm does not loop forever' '
        CONFIRM=$(git config --get sendemail.confirm) &&
        git config sendemail.confirm auto &&
        GIT_SEND_EMAIL_NOTTY=1 &&
index b7eed2489fa169aa1c6e5c98f59a0349ba8118fa..6dafe7e99ab4bd0006ed4f7204062fca31750689 100755 (executable)
@@ -54,14 +54,6 @@ text_no_props () {
 
 >empty
 
-test_expect_success 'setup: have pipes?' '
-       rm -f frob &&
-       if mkfifo frob
-       then
-               test_set_prereq PIPE
-       fi
-'
-
 test_expect_success PIPE 'empty dump' '
        reinit_git &&
        echo "SVN-fs-dump-format-version: 2" >input &&
index 2fcf2694696fedb5e7e3d57c869f7dbbbf23dbec..ac6f3b6af25c67ae3a2c0748c34f99b4cd0d4b32 100755 (executable)
@@ -49,14 +49,6 @@ echo "$@"'
 
 >empty
 
-test_expect_success 'setup: have pipes?' '
-       rm -f frob &&
-       if mkfifo frob
-       then
-               test_set_prereq PIPE
-       fi
-'
-
 ###
 ### series A
 ###
index 9e7f6b424d77ee88c3cd36507cd421a437ec7bfa..8d76cf23d46c813991fbf59da2f1f3b79110547c 100644 (file)
@@ -727,6 +727,11 @@ test_i18ngrep () {
        fi
 }
 
+test_lazy_prereq PIPE '
+       # test whether the filesystem supports FIFOs
+       rm -f testfifo && mkfifo testfifo
+'
+
 test_lazy_prereq SYMLINKS '
        # test whether the filesystem supports symbolic links
        ln -s x y && test -h y
@@ -760,3 +765,9 @@ test_lazy_prereq AUTOIDENT '
 # When the tests are run as root, permission tests will report that
 # things are writable when they shouldn't be.
 test -w / || test_set_prereq SANITY
+
+GIT_UNZIP=${GIT_UNZIP:-unzip}
+test_lazy_prereq UNZIP '
+       "$GIT_UNZIP" -v
+       test $? -ne 127
+'
index 71ab04edc09be7aeefa1e8a0f609a974ffd55a9f..d84758373da1d3121ec907435ae5d598c5c14b26 100755 (executable)
@@ -38,7 +38,7 @@ if [ -z "$GIT_DIR" ]; then
 fi
 
 if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
-       echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+       echo "usage: $0 <ref> <oldrev> <newrev>" >&2
        exit 1
 fi
 
index 92713d16da5431e9c8395967ab0e116402dfed67..02b42badd550a4b775aab084b38a63c2f4f561a9 100644 (file)
@@ -114,6 +114,6 @@ int main(int argc, const char *argv[])
        return 0;
 
 usage:
-       fprintf(stderr, "Usage: %s %s\n", argv[0], usage_str);
+       fprintf(stderr, "usage: %s %s\n", argv[0], usage_str);
        return -1;
 }
index af40a3c49ee0df5f0caaebae8e9bc6e9ffdb092b..4595cd6433f9fd543791ee5a8a59a9112b50c046 100644 (file)
@@ -23,7 +23,7 @@ int main(int argc, char *argv[])
        unsigned long from_size, data_size, out_size;
 
        if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p"))) {
-               fprintf(stderr, "Usage: %s\n", usage_str);
+               fprintf(stderr, "usage: %s\n", usage_str);
                return 1;
        }
 
index b3c28d9a1c1102f2862af68b0bda7e9b0424f5cc..54824d075421e792f337beb5cdce170a33b00e68 100644 (file)
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
        unsigned char *c;
 
        if (argc < 2 || argc > 3) {
-               fprintf(stderr, "Usage: %s <seed_string> [<size>]\n", argv[0]);
+               fprintf(stderr, "usage: %s <seed_string> [<size>]\n", argv[0]);
                return 1;
        }
 
index cb3ef7d38e475480a5d81ce6077c4c87ea09a318..dcd8d97411dd15e01ba1480a44b2a998043b424a 100644 (file)
@@ -991,7 +991,7 @@ struct unidirectional_transfer {
        int src_is_sock;
        /* Is destination socket? */
        int dest_is_sock;
-       /* Transfer state (TRANSFERING/FLUSHING/FINISHED) */
+       /* Transfer state (TRANSFERRING/FLUSHING/FINISHED) */
        int state;
        /* Buffer. */
        char buf[BUFFERSIZE];
index 87b8f145acfce5579b05c5bf0fef6e1865477f9f..e6f9346c762416b9c0e97f9023062f99e4542dbc 100644 (file)
@@ -106,7 +106,8 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
                return;
 
        for (;;) {
-               int cmp, len;
+               int cmp = 0; /* assigned before used */
+               int len;
 
                if (!fgets(buffer, sizeof(buffer), f)) {
                        fclose(f);
index a3450e97c0d0d94778a4b635efdd53b724eb70c2..e7beb815dd546cf67cb84255d3ca894878f48ae7 100644 (file)
@@ -74,7 +74,7 @@ struct transport {
                       const char *executable, int fd[2]);
 
        /** get_refs_list(), fetch(), and push_refs() can keep
-        * resources (such as a connection) reserved for futher
+        * resources (such as a connection) reserved for further
         * use. disconnect() releases these resources.
         **/
        int (*disconnect)(struct transport *connection);
index 30146a04f7a271ffaa033c0c6567ad1036f4bc49..948cfffe13376742cc46276652048cd6f5edaa7c 100644 (file)
@@ -325,9 +325,7 @@ static int got_sha1(char *hex, unsigned char *sha1)
        if (!has_sha1_file(sha1))
                return -1;
 
-       o = lookup_object(sha1);
-       if (!(o && o->parsed))
-               o = parse_object(sha1);
+       o = parse_object(sha1);
        if (!o)
                die("oops (%s)", sha1_to_hex(sha1));
        if (o->type == OBJ_COMMIT) {
@@ -640,7 +638,7 @@ static void receive_needs(void)
                if (parse_feature_request(features, "include-tag"))
                        use_include_tag = 1;
 
-               o = lookup_object(sha1_buf);
+               o = parse_object(sha1_buf);
                if (!o)
                        die("git upload-pack: not our ref %s",
                            sha1_to_hex(sha1_buf));
diff --git a/utf8.c b/utf8.c
index 1087870c51caff3dd86a852ec5e8bf5875f6d797..7f648574a550432e3160fcef178f894faf0bdd54 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -507,11 +507,66 @@ char *reencode_string(const char *in, const char *out_encoding, const char *in_e
 
        if (!in_encoding)
                return NULL;
+
        conv = iconv_open(out_encoding, in_encoding);
-       if (conv == (iconv_t) -1)
-               return NULL;
+       if (conv == (iconv_t) -1) {
+               /*
+                * Some platforms do not have the variously spelled variants of
+                * UTF-8, so let's fall back to trying the most official
+                * spelling. We do so only as a fallback in case the platform
+                * does understand the user's spelling, but not our official
+                * one.
+                */
+               if (is_encoding_utf8(in_encoding))
+                       in_encoding = "UTF-8";
+               if (is_encoding_utf8(out_encoding))
+                       out_encoding = "UTF-8";
+               conv = iconv_open(out_encoding, in_encoding);
+               if (conv == (iconv_t) -1)
+                       return NULL;
+       }
+
        out = reencode_string_iconv(in, strlen(in), conv);
        iconv_close(conv);
        return out;
 }
 #endif
+
+/*
+ * Returns first character length in bytes for multi-byte `text` according to
+ * `encoding`.
+ *
+ * - The `text` pointer is updated to point at the next character.
+ * - When `remainder_p` is not NULL, on entry `*remainder_p` is how much bytes
+ *   we can consume from text, and on exit `*remainder_p` is reduced by returned
+ *   character length. Otherwise `text` is treated as limited by NUL.
+ */
+int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding)
+{
+       int chrlen;
+       const char *p = *text;
+       size_t r = (remainder_p ? *remainder_p : SIZE_MAX);
+
+       if (r < 1)
+               return 0;
+
+       if (is_encoding_utf8(encoding)) {
+               pick_one_utf8_char(&p, &r);
+
+               chrlen = p ? (p - *text)
+                          : 1 /* not valid UTF-8 -> raw byte sequence */;
+       }
+       else {
+               /*
+                * TODO use iconv to decode one char and obtain its chrlen
+                * for now, let's treat encodings != UTF-8 as one-byte
+                */
+               chrlen = 1;
+       }
+
+       *text += chrlen;
+       if (remainder_p)
+               *remainder_p -= chrlen;
+
+       return chrlen;
+}
diff --git a/utf8.h b/utf8.h
index 501b2bd9c4fd3fdce6dcbba1a3e3f7c0211d6c8f..1f8ecad1e88451c622de08ea14414021da64f402 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -22,4 +22,6 @@ char *reencode_string(const char *in, const char *out_encoding, const char *in_e
 #define reencode_string(a,b,c) NULL
 #endif
 
+int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding);
+
 #endif
index 75558177860d14120636859e2dcc29b48b72a721..81e4fa519f4b0efbc54dab1475b8bdbb19f9ece2 100644 (file)
@@ -499,9 +499,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
 {
        int i;
        struct dir_struct dir;
+       struct timeval t_begin;
 
        if (!s->show_untracked_files)
                return;
+
+       if (advice_status_u_option)
+               gettimeofday(&t_begin, NULL);
+
        memset(&dir, 0, sizeof(dir));
        if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
                dir.flags |=
@@ -533,6 +538,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
        }
 
        free(dir.entries);
+
+       if (advice_status_u_option) {
+               struct timeval t_end;
+               gettimeofday(&t_end, NULL);
+               s->untracked_in_ms =
+                       (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 -
+                       ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000);
+       }
 }
 
 void wt_status_collect(struct wt_status *s)
@@ -1100,6 +1113,14 @@ void wt_status_print(struct wt_status *s)
                wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
                if (s->show_ignored_files)
                        wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
+               if (advice_status_u_option && 2000 < s->untracked_in_ms) {
+                       status_printf_ln(s, GIT_COLOR_NORMAL, "");
+                       status_printf_ln(s, GIT_COLOR_NORMAL,
+                                        _("It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
+                                          "may speed it up, but you have to be careful not to forget to add\n"
+                                          "new files yourself (see 'git help status')."),
+                                        s->untracked_in_ms / 1000.0);
+               }
        } else if (s->commitable)
                status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
                        advice_status_hints
index 81e1dcf84dbfbea76657d3b4c65e3e63890396e9..74208c06fd08b49041489c869d3c5f16804493da 100644 (file)
@@ -69,6 +69,7 @@ struct wt_status {
        struct string_list change;
        struct string_list untracked;
        struct string_list ignored;
+       uint32_t untracked_in_ms;
 };
 
 struct wt_status_state {
index 1b7012a119ad3ea7e2ebe0aad80891529d4936da..b2eb6db2c851aea7eb08b17d802155876bef211c 100644 (file)
@@ -490,7 +490,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
 
                /*
                 * Try to move back the possibly merged group of changes, to match
-                * the recorded postion in the other file.
+                * the recorded position in the other file.
                 */
                while (ixref < ix) {
                        rchg[--ixs] = 1;
index bf99787c3e4c791426311495dda9d4da81cbb571..73210cb6f3fb5d1cb90b1c5959a5a90e058ea1f2 100644 (file)
@@ -55,7 +55,7 @@ struct histindex {
        struct record {
                unsigned int ptr, cnt;
                struct record *next;
-       } **records, /* an ocurrence */
+       } **records, /* an occurrence */
          **line_map; /* map of line to record chain */
        chastore_t rcha;
        unsigned int *next_ptrs;