Merge branch 'sh/finish-tmp-packfile'
authorJunio C Hamano <gitster@pobox.com>
Tue, 18 Mar 2014 20:50:24 +0000 (13:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Mar 2014 20:50:24 +0000 (13:50 -0700)
* sh/finish-tmp-packfile:
finish_tmp_packfile():use strbuf for pathname construction

141 files changed:
Documentation/CodingGuidelines
Documentation/RelNotes/2.0.0.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/git-add.txt
Documentation/git-am.txt
Documentation/git-archive.txt
Documentation/git-cvsimport.txt
Documentation/git-filter-branch.txt
Documentation/git-push.txt
Documentation/git-stash.txt
Documentation/git-submodule.txt
Documentation/git-upload-archive.txt
Documentation/git.txt
Documentation/gitcore-tutorial.txt
Documentation/gitcvs-migration.txt
Documentation/gitignore.txt
Documentation/gitremote-helpers.txt
Documentation/gitweb.txt
Documentation/technical/http-protocol.txt
GIT-VERSION-GEN
Makefile
RelNotes
advice.c
advice.h
archive.c
attr.c
builtin/add.c
builtin/apply.c
builtin/branch.c
builtin/check-attr.c
builtin/clean.c
builtin/config.c
builtin/describe.c
builtin/for-each-ref.c
builtin/fsck.c
builtin/gc.c
builtin/index-pack.c
builtin/ls-remote.c
builtin/mktree.c
builtin/mv.c
builtin/name-rev.c
builtin/notes.c
builtin/pack-objects.c
builtin/prune-packed.c
builtin/prune.c
builtin/push.c
builtin/reflog.c
builtin/replace.c
builtin/reset.c
builtin/show-branch.c
builtin/tag.c
builtin/unpack-objects.c
bundle.c
cache-tree.c
cache.h
combine-diff.c
commit.c
compat/fnmatch/fnmatch.c [deleted file]
compat/fnmatch/fnmatch.h [deleted file]
config.c
config.mak.uname
configure.ac
contrib/completion/git-completion.bash
contrib/contacts/git-contacts
contrib/remote-helpers/git-remote-bzr
contrib/remote-helpers/test-bzr.sh
contrib/remote-helpers/test-hg.sh
daemon.c
date.c
diff-lib.c
diff-no-index.c
diff.c
diff.h
diffcore-order.c
diffcore-rename.c
diffcore.h
dir.c
environment.c
fsck.c
git-add--interactive.perl
git-bisect.sh
git-compat-util.h
git-difftool.perl
git-remote-testgit.sh
git-submodule.sh
git.c
gitweb/gitweb.perl
gitweb/static/gitweb.css
help.c
http.c
http.h
log-tree.c
notes-utils.c
object.c
object.h
patch-ids.c
po/fr.po
pretty.c
progress.c
read-cache.c
reflog-walk.c
refs.c
remote-curl.c
remote.c
replace_object.c
revision.c
setup.c
sha1_file.c
strbuf.c
strbuf.h
streaming.c
t/lib-git-daemon.sh
t/lib-httpd.sh
t/t0003-attributes.sh
t/t0008-ignores.sh
t/t1300-repo-config.sh
t/t1305-config-include.sh
t/t1450-fsck.sh
t/t1600-index.sh [new file with mode: 0755]
t/t2104-update-index-skip-worktree.sh
t/t2200-add-update.sh
t/t3070-wildmatch.sh
t/t3301-notes.sh
t/t4020-diff-external.sh
t/t4056-diff-order.sh
t/t4057-diff-combined-paths.sh [new file with mode: 0755]
t/t4212-log-corrupt.sh
t/t5000-tar-tree.sh
t/t5400-send-pack.sh
t/t5516-fetch-push.sh
t/t5801-remote-helpers.sh
t/t7102-reset.sh
t/t7300-clean.sh
t/t7800-difftool.sh
t/test-lib-functions.sh
t/test-lib.sh
test-wildmatch.c
transport-helper.c
unpack-trees.c
upload-pack.c
utf8.c
index ef67b53f721f28e5442c00273dec5f1582f555be..ed432a80ca62eeb6a75e08870d9c8f8eaf4ab6d8 100644 (file)
@@ -126,6 +126,17 @@ For C programs:
    "char * string".  This makes it easier to understand code
    like "char *string, c;".
 
+ - Use whitespace around operators and keywords, but not inside
+   parentheses and not around functions. So:
+
+        while (condition)
+               func(bar + 1);
+
+   and not:
+
+        while( condition )
+               func (bar+1);
+
  - We avoid using braces unnecessarily.  I.e.
 
        if (bla) {
diff --git a/Documentation/RelNotes/2.0.0.txt b/Documentation/RelNotes/2.0.0.txt
new file mode 100644 (file)
index 0000000..0c71d9d
--- /dev/null
@@ -0,0 +1,207 @@
+Git v2.0 Release Notes
+======================
+
+Backward compatibility notes
+----------------------------
+
+When "git push [$there]" does not say what to push, we have used the
+traditional "matching" semantics so far (all your branches were sent
+to the remote as long as there already are branches of the same name
+over there).  In Git 2.0, the default is now the "simple" semantics,
+which pushes:
+
+ - only the current branch to the branch with the same name, and only
+   when the current branch is set to integrate with that remote
+   branch, if you are pushing to the same remote as you fetch from; or
+
+ - only the current branch to the branch with the same name, if you
+   are pushing to a remote that is not where you usually fetch from.
+
+You can use the configuration variable "push.default" to change
+this.  If you are an old-timer who wants to keep using the
+"matching" semantics, you can set the variable to "matching", for
+example.  Read the documentation for other possibilities.
+
+When "git add -u" and "git add -A" are run inside a subdirectory
+without specifying which paths to add on the command line, they
+operate on the entire tree for consistency with "git commit -a" and
+other commands (these commands used to operate only on the current
+subdirectory).  Say "git add -u ." or "git add -A ." if you want to
+limit the operation to the current directory.
+
+"git add <path>" is the same as "git add -A <path>" now, so that
+"git add dir/" will notice paths you removed from the directory and
+record the removal.  In older versions of Git, "git add <path>" used
+to ignore removals.  You can say "git add --ignore-removal <path>" to
+add only added or modified paths in <path>, if you really want to.
+
+The "-q" option to "git diff-files", which does *NOT* mean "quiet",
+has been removed (it told Git to ignore deletion, which you can do
+with "git diff-files --diff-filter=d").
+
+
+Updates since v1.9 series
+-------------------------
+
+Foreign interfaces, subsystems and ports.
+
+
+UI, Workflows & Features
+
+ * The "simple" mode is the default for "git push".
+
+ * "git add -u" and "git add -A", when run without any pathspec, is a
+   tree-wide operation even when run inside a subdirectory of a
+   working tree.
+
+ * "git add <path> is the same as "git add -A <path>" now.
+
+ * "core.statinfo" configuration variable, which is a
+   never-advertised synonym to "core.checkstat", has been removed.
+
+ * The "-q" option to "git diff-files", which does *NOT* mean
+   "quiet", has been removed (it told Git to ignore deletion, which
+   you can do with "git diff-files --diff-filter=d").
+
+ * Server operators can loosen the "tips of refs only" restriction for
+   the remote archive service with the uploadarchive.allowUnreachable
+   configuration option.
+
+ * The progress indicators from various time-consuming commands have
+   been marked for i18n/l10n.
+
+ * "git notes -C <blob>" diagnoses an attempt to use an object that
+   is not a blob as an error.
+
+ * "git config" learned to read from the standard input when "-" is
+   given as the value to its "--file" parameter (attempting an
+   operation to update the configuration in the standard input of
+   course is rejected).
+
+ * Trailing whitespaces in .gitignore files, unless they are quoted
+   for fnmatch(3), e.g. "path\ ", are warned and ignored.  Strictly
+   speaking, this is a backward incompatible change, but very unlikely
+   to bite any sane user and adjusting should be obvious and easy.
+
+ * Many commands that create commits, e.g. "pull", "rebase",
+   learned to take the --gpg-sign option on the command line.
+
+ * "git commit" can be told to always GPG sign the resulting commit
+   by setting "commit.gpgsign" configuration variable to true (the
+   command line option --no-gpg-sign should override it).
+
+ * "git pull" can be told to only accept fast-forward by setting the
+   new "pull.ff" configuration.
+
+ * "git reset" learned "-N" option, which does not reset the index
+   fully for paths the index knows about but the tree-ish the command
+   resets to does not (these paths are kept as intend-to-add entries).
+
+ * Newly cloned submodule repositories by "git submodule update",
+   when the "checkout" update mode is used, will be on a local
+   branch instead of on a detached HEAD, just like submodules added
+   with "git submodule add".
+
+
+Performance, Internal Implementation, etc.
+
+ * We started using wildmatch() in place of fnmatch(3) a few releases
+   ago; complete the process and stop using fnmatch(3).
+
+ * Uses of curl's "multi" interface and "easy" interface do not mix
+   well when we attempt to reuse outgoing connections.  Teach the RPC
+   over http code, used in the smart HTTP transport, not to use the
+   "easy" interface.
+
+ * The bitmap-index feature from JGit has been ported, which should
+   significantly improve performance when serving objects form a
+   repository that uses it.
+
+ * The way "git log --cc" shows a combined diff against multiple
+   parents have been optimized.
+
+ * The prefixcmp() and suffixcmp() functions are gone.  Use
+   starts_with() and ends_with(), and also consider if skip_prefix()
+   suits your needs better when using the former.
+
+
+Also contains various documentation updates and code clean-ups.  Many
+of them came from flurry of activities as GSoC candidate microproject
+exercises.
+
+
+Fixes since v1.9 series
+-----------------------
+
+Unless otherwise noted, all the fixes since v1.9 in the maintenance
+track are contained in this release (see the maintenance releases'
+notes for details).
+
+ * "git difftool" misbehaved when the repository is bound to the
+   working tree with the ".git file" mechanism, where a textual file
+   ".git" tells us where it is.
+   (merge fcfec8b da/difftool-git-files later to maint).
+
+ * "git push" did not pay attention to branch.*.pushremote if it is
+   defined earlier than remote.pushdefault; the order of these two
+   variables in the configuration file should not matter, but it did
+   by mistake.
+   (merge 98b406f jk/remote-pushremote-config-reading later to maint).
+
+ * Codepaths that parse timestamps in commit objects have been
+   tightened.
+   (merge 3f419d4 jk/commit-dates-parsing-fix later to maint).
+
+ * "git diff --external-diff" incorrectly fed the submodule directory
+   in the working tree to the external diff driver when it knew it is
+   the same as one of the versions being compared.
+   (merge aba4727 tr/diff-submodule-no-reuse-worktree later to maint).
+
+ * "git reset" needs to refresh the index when working in a working
+   tree (it can also be used to match the index to the HEAD in an
+   otherwise bare repository), but it failed to set up the working
+   tree properly, causing GIT_WORK_TREE to be ignored.
+   (merge b7756d4 nd/reset-setup-worktree later to maint).
+
+ * "git check-attr" when working on a repository with a working tree
+   did not work well when the working tree was specified via the
+   --work-tree (and obviously with --git-dir) option.
+   (merge cdbf623 jc/check-attr-honor-working-tree later to maint).
+
+ * "merge-recursive" was broken in 1.7.7 era and stopped working in
+   an empty (temporary) working tree, when there are renames
+   involved.  This has been corrected.
+   (merge 6e2068a bk/refresh-missing-ok-in-merge-recursive later to maint.)
+
+ * "git rev-parse" was loose in rejecting command line arguments
+   that do not make sense, e.g. "--default" without the required
+   value for that option.
+   (merge a43219f ds/rev-parse-required-args later to maint.)
+
+ * include.path variable (or any variable that expects a path that
+   can use ~username expansion) in the configuration file is not a
+   boolean, but the code failed to check it.
+   (merge 67beb60 jk/config-path-include-fix later to maint.)
+
+ * Commands that take pathspecs on the command line misbehaved when
+   the pathspec is given as an absolute pathname (which is a
+   practice not particularly encouraged) that points at a symbolic
+   link in the working tree.
+   (merge later 655ee9e mw/symlinks to maint.)
+
+ * "git diff --quiet -- pathspec1 pathspec2" sometimes did not return
+   correct status value.
+   (merge f34b205 nd/diff-quiet-stat-dirty later to maint.)
+
+ * Attempting to deepen a shallow repository by fetching over smart
+   HTTP transport failed in the protocol exchange, when no-done
+   extension was used.  The fetching side waited for the list of
+   shallow boundary commits after the sending end stopped talking to
+   it.
+   (merge 0232852 nd/http-fetch-shallow-fix later to maint.)
+
+ * Allow "git cmd path/", when the 'path' is where a submodule is
+   bound to the top-level working tree, to match 'path', despite the
+   extra and unnecessary trailing slash (such a slash is often
+   given by command line completion).
+   (merge 2e70c01 nd/submodule-pathspec-ending-with-slash later to maint.)
index 040197b10ea5a46e6ba643b28de17d2100cb129b..79e576878af5eb44b21fc0763faeb30519e022c3 100644 (file)
@@ -142,19 +142,13 @@ advice.*::
 --
        pushUpdateRejected::
                Set this variable to 'false' if you want to disable
-               'pushNonFFCurrent', 'pushNonFFDefault',
+               'pushNonFFCurrent',
                'pushNonFFMatching', 'pushAlreadyExists',
                'pushFetchFirst', and 'pushNeedsForce'
                simultaneously.
        pushNonFFCurrent::
                Advice shown when linkgit:git-push[1] fails due to a
                non-fast-forward update to the current branch.
-       pushNonFFDefault::
-               Advice to set 'push.default' to 'upstream' or 'current'
-               when you ran linkgit:git-push[1] and pushed 'matching
-               refs' by default (i.e. you did not provide an explicit
-               refspec, and no 'push.default' configuration was set)
-               and it resulted in a non-fast-forward error.
        pushNonFFMatching::
                Advice shown when you ran linkgit:git-push[1] and pushed
                'matching refs' explicitly (i.e. you used ':', or
@@ -1175,6 +1169,10 @@ gc.autopacklimit::
        --auto` consolidates them into one larger pack.  The
        default value is 50.  Setting this to 0 disables it.
 
+gc.autodetach::
+       Make `git gc --auto` return immediately andrun in background
+       if the system supports it. Default is true.
+
 gc.packrefs::
        Running `git pack-refs` in a repository renders it
        unclonable by Git versions prior to 1.5.1.2 over dumb
@@ -1609,6 +1607,10 @@ imap::
        The configuration variables in the 'imap' section are described
        in linkgit:git-imap-send[1].
 
+index.version::
+       Specify the version with which new index files should be
+       initialized.  This does not affect existing repositories.
+
 init.templatedir::
        Specify the directory from which templates will be copied.
        (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
@@ -1641,7 +1643,7 @@ interactive.singlekey::
        linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
        linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
        setting is silently ignored if portable keystroke input
-       is not available.
+       is not available; requires the Perl module Term::ReadKey.
 
 log.abbrevCommit::
        If true, makes linkgit:git-log[1], linkgit:git-show[1], and
@@ -1976,7 +1978,7 @@ When pushing to a remote that is different from the remote you normally
 pull from, work as `current`.  This is the safest option and is suited
 for beginners.
 +
-This mode will become the default in Git 2.0.
+This mode has become the default in Git 2.0.
 
 * `matching` - push all branches having the same name on both ends.
   This makes the repository you are pushing to remember the set of
@@ -1995,8 +1997,8 @@ suitable for pushing into a shared central repository, as other
 people may add new branches there, or update the tip of existing
 branches outside your control.
 +
-This is currently the default, but Git 2.0 will change the default
-to `simple`.
+This used to be the default, but not since Git 2.0 (`simple` is the
+new default).
 
 --
 
@@ -2334,6 +2336,13 @@ transfer.unpackLimit::
        not set, the value of this variable is used instead.
        The default value is 100.
 
+uploadarchive.allowUnreachable::
+       If true, allow clients to use `git archive --remote` to request
+       any tree, whether reachable from the ref tips or not. See the
+       discussion in the `SECURITY` section of
+       linkgit:git-upload-archive[1] for more details. Defaults to
+       `false`.
+
 uploadpack.hiderefs::
        String(s) `upload-pack` uses to decide which refs to omit
        from its initial advertisement.  Use more than one
index 48754cbc67a2cc3819fac272cdef9d9d0d76c0d7..895922e27cc4250d26818b4ca4ba42f1d2004fed 100644 (file)
@@ -53,8 +53,14 @@ OPTIONS
        Files to add content from.  Fileglobs (e.g. `*.c`) can
        be given to add all matching files.  Also a
        leading directory name (e.g. `dir` to add `dir/file1`
-       and `dir/file2`) can be given to add all files in the
-       directory, recursively.
+       and `dir/file2`) can be given to update the index to
+       match the current state of the directory as a whole (e.g.
+       specifying `dir` will record not just a file `dir/file1`
+       modified in the working tree, a file `dir/file2` added to
+       the working tree, but also a file `dir/file3` removed from
+       the working tree.  Note that older versions of Git used
+       to ignore removed files; use `--no-all` option if you want
+       to add modified or new files but ignore removed ones.
 
 -n::
 --dry-run::
@@ -104,10 +110,10 @@ apply to the index. See EDITING PATCHES below.
        <pathspec>.  This removes as well as modifies index entries to
        match the working tree, but adds no new files.
 +
-If no <pathspec> is given, the current version of Git defaults to
-"."; in other words, update all tracked files in the current directory
-and its subdirectories. This default will change in a future version
-of Git, hence the form without <pathspec> should not be used.
+If no <pathspec> is given when `-u` option is used, all
+tracked files in the entire working tree are updated (old versions
+of Git used to limit the update to the current directory and its
+subdirectories).
 
 -A::
 --all::
@@ -117,10 +123,10 @@ of Git, hence the form without <pathspec> should not be used.
        entry.  This adds, modifies, and removes index entries to
        match the working tree.
 +
-If no <pathspec> is given, the current version of Git defaults to
-"."; in other words, update all files in the current directory
-and its subdirectories. This default will change in a future version
-of Git, hence the form without <pathspec> should not be used.
+If no <pathspec> is given when `-A` option is used, all
+files in the entire working tree are updated (old versions
+of Git used to limit the update to the current directory and its
+subdirectories).
 
 --no-all::
 --ignore-removal::
@@ -129,11 +135,9 @@ of Git, hence the form without <pathspec> should not be used.
        files that have been removed from the working tree.  This
        option is a no-op when no <pathspec> is used.
 +
-This option is primarily to help the current users of Git, whose
-"git add <pathspec>..." ignores removed files.  In future versions
-of Git, "git add <pathspec>..." will be a synonym to "git add -A
-<pathspec>..." and "git add --ignore-removal <pathspec>..." will behave like
-today's "git add <pathspec>...", ignoring removed files.
+This option is primarily to help users who are used to older
+versions of Git, whose "git add <pathspec>..." was a synonym
+for "git add --no-all <pathspec>...", i.e. ignored removed files.
 
 -N::
 --intent-to-add::
index 17924d0f3ff3cf525b5ab93b50020929d6ea24c0..a2b97582fe010ffcab70db30e006a7a94d6b767b 100644 (file)
@@ -193,6 +193,11 @@ commits, like running 'git am' on the wrong branch or an error in the
 commits that is more easily fixed by changing the mailbox (e.g.
 errors in the "From:" lines).
 
+HOOKS
+-----
+This command can run `applypatch-msg`, `pre-applypatch`,
+and `post-applypatch` hooks.  See linkgit:githooks[5] for more
+information.
 
 SEE ALSO
 --------
index b97aaab4edfc33f407f7d167f015b174c2ddccb5..cfa1e4ebe4860d4905c44c5428b541ce3967826b 100644 (file)
@@ -65,7 +65,10 @@ OPTIONS
 
 --remote=<repo>::
        Instead of making a tar archive from the local repository,
-       retrieve a tar archive from a remote repository.
+       retrieve a tar archive from a remote repository. Note that the
+       remote repository may place restrictions on which sha1
+       expressions may be allowed in `<tree-ish>`. See
+       linkgit:git-upload-archive[1] for details.
 
 --exec=<git-upload-archive>::
        Used with --remote to specify the path to the
index 2df9953968ce19e7baf460a9c33de8f56398f11d..260f39fd40db2078635fecf8c7fe27976175d13f 100644 (file)
@@ -21,8 +21,8 @@ DESCRIPTION
 *WARNING:* `git cvsimport` uses cvsps version 2, which is considered
 deprecated; it does not work with cvsps version 3 and later.  If you are
 performing a one-shot import of a CVS repository consider using
-link:http://cvs2svn.tigris.org/cvs2git.html[cvs2git] or
-link:https://github.com/BartMassey/parsecvs[parsecvs].
+http://cvs2svn.tigris.org/cvs2git.html[cvs2git] or
+https://github.com/BartMassey/parsecvs[parsecvs].
 
 Imports a CVS repository into Git. It will either create a new
 repository, or incrementally import into an existing one.
index 2eba6271704adb6179a1c31d9d6974fbe70b66f4..09535f2a083b9a8af9fb76f43ced94bf1df641e7 100644 (file)
@@ -436,7 +436,7 @@ git-filter-branch allows you to make complex shell-scripted rewrites
 of your Git history, but you probably don't need this flexibility if
 you're simply _removing unwanted data_ like large files or passwords.
 For those operations you may want to consider
-link:http://rtyley.github.io/bfg-repo-cleaner/[The BFG Repo-Cleaner],
+http://rtyley.github.io/bfg-repo-cleaner/[The BFG Repo-Cleaner],
 a JVM-based alternative to git-filter-branch, typically at least
 10-50x faster for those use-cases, and with quite different
 characteristics:
@@ -455,7 +455,7 @@ characteristics:
   _is_ possible to write filters that include their own parallellism,
   in the scripts executed against each commit.
 
-* The link:http://rtyley.github.io/bfg-repo-cleaner/#examples[command options]
+* The http://rtyley.github.io/bfg-repo-cleaner/#examples[command options]
   are much more restrictive than git-filter branch, and dedicated just
   to the tasks of removing unwanted data- e.g:
   `--strip-blobs-bigger-than 1M`.
index 2b7f4f939f38626dbd796b808cc21285ad5c8c3d..14862fb203b8c269fc391eee886520b1675e540a 100644 (file)
@@ -83,8 +83,8 @@ the local side, the remote side is updated if a branch of the same name
 already exists on the remote side.
 
 --all::
-       Instead of naming each ref to push, specifies that all
-       refs under `refs/heads/` be pushed.
+       Push all branches (i.e. refs under `refs/heads/`); cannot be
+       used with other <refspec>.
 
 --prune::
        Remove remote branches that don't have a local counterpart. For example
@@ -442,8 +442,10 @@ Examples
        configured for the current branch).
 
 `git push origin`::
-       Without additional configuration, works like
-       `git push origin :`.
+       Without additional configuration, pushes the current branch to
+       the configured upstream (`remote.origin.merge` configuration
+       variable) if it has the same name as the current branch, and
+       errors out without pushing otherwise.
 +
 The default behavior of this command when no <refspec> is given can be
 configured by setting the `push` option of the remote, or the `push.default`
index db7e803038090510609a6534ab7d086245c15270..375213fe463fa3cd9cb7644cff60ee656c13dcd8 100644 (file)
@@ -44,7 +44,7 @@ is also possible).
 OPTIONS
 -------
 
-save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::
+save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::
 
        Save your local modifications to a new 'stash', and run `git reset
        --hard` to revert them.  The <message> part is optional and gives
index 21cb59a6d6d9dd87754e2b20ec47bc67147370c7..46c1eebb938dad182aeafafd9e680226c253dd65 100644 (file)
@@ -15,7 +15,7 @@ SYNOPSIS
 'git submodule' [--quiet] init [--] [<path>...]
 'git submodule' [--quiet] deinit [-f|--force] [--] <path>...
 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]
-             [-f|--force] [--rebase|--merge|--checkout] [--reference <repository>]
+             [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>]
              [--depth <depth>] [--recursive] [--] [<path>...]
 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
              [commit] [--] [<path>...]
@@ -315,6 +315,15 @@ the submodule itself.
        This option is only valid for the update command.
        Don't fetch new objects from the remote site.
 
+--checkout::
+       This option is only valid for the update command.
+       Checkout the commit recorded in the superproject on a detached HEAD
+       in the submodule. This is the default behavior, the main use of
+       this option is to override `submodule.$name.update` when set to
+       `merge`, `rebase` or `none`.
+       If the key `submodule.$name.update` is either not explicitly set or
+       set to `checkout`, this option is implicit.
+
 --merge::
        This option is only valid for the update command.
        Merge the commit recorded in the superproject into the current branch
index d09bbb52b1bb85d5db5fcadc31afd4bb86a82fcd..cbef61ba88788b6b3dc89e5031b3addfcf0a2e7b 100644 (file)
@@ -20,6 +20,38 @@ This command is usually not invoked directly by the end user.  The UI
 for the protocol is on the 'git archive' side, and the program pair
 is meant to be used to get an archive from a remote repository.
 
+SECURITY
+--------
+
+In order to protect the privacy of objects that have been removed from
+history but may not yet have been pruned, `git-upload-archive` avoids
+serving archives for commits and trees that are not reachable from the
+repository's refs.  However, because calculating object reachability is
+computationally expensive, `git-upload-archive` implements a stricter
+but easier-to-check set of rules:
+
+  1. Clients may request a commit or tree that is pointed to directly by
+     a ref. E.g., `git archive --remote=origin v1.0`.
+
+  2. Clients may request a sub-tree within a commit or tree using the
+     `ref:path` syntax. E.g., `git archive --remote=origin v1.0:Documentation`.
+
+  3. Clients may _not_ use other sha1 expressions, even if the end
+     result is reachable. E.g., neither a relative commit like `master^`
+     nor a literal sha1 like `abcd1234` is allowed, even if the result
+     is reachable from the refs.
+
+Note that rule 3 disallows many cases that do not have any privacy
+implications. These rules are subject to change in future versions of
+git, and the server accessed by `git archive --remote` may or may not
+follow these exact rules.
+
+If the config option `uploadArchive.allowUnreachable` is true, these
+rules are ignored, and clients may use arbitrary sha1 expressions.
+This is useful if you do not care about the privacy of unreachable
+objects, or if your object database is already publicly available for
+access via non-smart-http.
+
 OPTIONS
 -------
 <directory>::
index 02bbc084b8d72b33af08a6fee7d8f1943e870e24..27a199ca1af53c25f7b3e41501402244b11614d4 100644 (file)
@@ -720,6 +720,11 @@ Git so take care if using Cogito etc.
        index file. If not specified, the default of `$GIT_DIR/index`
        is used.
 
+'GIT_INDEX_VERSION'::
+       This environment variable allows the specification of an index
+       version for new repositories.  It won't affect existing index
+       files.  By default index file version [23] is used.
+
 'GIT_OBJECT_DIRECTORY'::
        If the object storage directory is specified via this
        environment variable then the sha1 directories are created
index 058a3529809e41dfaf29dc510c2cb626dedb5402..d2d7c213dd56f3886b7ab7e3651e1e80eec3b2ef 100644 (file)
@@ -1443,7 +1443,7 @@ Although Git is a truly distributed system, it is often
 convenient to organize your project with an informal hierarchy
 of developers. Linux kernel development is run this way. There
 is a nice illustration (page 17, "Merges to Mainline") in
-link:http://www.xenotime.net/linux/mentor/linux-mentoring-2006.pdf[Randy Dunlap's presentation].
+http://www.xenotime.net/linux/mentor/linux-mentoring-2006.pdf[Randy Dunlap's presentation].
 
 It should be stressed that this hierarchy is purely *informal*.
 There is nothing fundamental in Git that enforces the "chain of
index 5ea94cbceb56369d155f66399fdd1f8e62d4b48a..5f4e89005c5e554353920fe858bc74399e438a14 100644 (file)
@@ -117,7 +117,7 @@ Importing a CVS archive
 -----------------------
 
 First, install version 2.1 or higher of cvsps from
-link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
+http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
 sure it is in your path.  Then cd to a checked out CVS working directory
 of the project you are interested in and run linkgit:git-cvsimport[1]:
 
index b08d34d84ec92eec6aa54572e3823062424c23bf..8734c1566ca918e8c62f759aebdf7d0b497e860b 100644 (file)
@@ -77,6 +77,9 @@ PATTERN FORMAT
    Put a backslash ("`\`") in front of the first hash for patterns
    that begin with a hash.
 
+ - Trailing spaces are ignored unless they are quoted with backlash
+   ("`\`").
+
  - An optional prefix "`!`" which negates the pattern; any
    matching file excluded by a previous pattern will become
    included again. It is not possible to re-include a file if a parent
index c2908db76317c91cf5502065e9c4bf1d97da19bd..64f7ad26b40085ced91e73fd806c11e90ad2eb9a 100644 (file)
@@ -437,6 +437,10 @@ set by Git if the remote helper has the 'option' capability.
 'option check-connectivity' \{'true'|'false'\}::
        Request the helper to check connectivity of a clone.
 
+'option force' \{'true'|'false'\}::
+       Request the helper to perform a force update.  Defaults to
+       'false'.
+
 'option cloning \{'true'|'false'\}::
        Notify the helper this is a clone request (i.e. the current
        repository is guaranteed empty).
index cca14b8cc365c021e8da629ebfd56acd66ee14ca..cd9c8951b281207abfabecafefdebf7f0975a0a8 100644 (file)
@@ -84,7 +84,7 @@ separator (rules for Perl's "`split(" ", $line)`").
 
 * Fields use modified URI encoding, defined in RFC 3986, section 2.1
 (Percent-Encoding), or rather "Query string encoding" (see
-link:http://en.wikipedia.org/wiki/Query_string#URL_encoding[]), the difference
+http://en.wikipedia.org/wiki/Query_string#URL_encoding[]), the difference
 being that SP (" ") can be encoded as "{plus}" (and therefore "{plus}" has to be
 also percent-encoded).
 +
index 544373b16f766c8c317dc0352f42372e6c0c6e9d..20525d98bb67cd3710c9738f99020c01f2d1d885 100644 (file)
@@ -500,7 +500,7 @@ TODO: Document this further.
 References
 ----------
 
-link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]
-link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]
+http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]
+http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]
 link:technical/pack-protocol.html
 link:technical/protocol-capabilities.html
index 2b97352dd3b113b46bbd53248315ab91f0a9356b..a651d68656617182ef79e9bad5d539d74346b83c 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.9.0
+DEF_VER=v1.9.0.GIT
 
 LF='
 '
index d4ce53a71b3ffd3b2a9d115279880d3e1aeb03a6..f818eecaf380c109be248f424d5c8f3a537359e0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -101,14 +101,6 @@ all::
 #
 # Define NO_MKSTEMPS if you don't have mkstemps in the C library.
 #
-# Define NO_FNMATCH if you don't have fnmatch in the C library.
-#
-# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
-# FNM_CASEFOLD GNU extension.
-#
-# Define NO_WILDMATCH if you do not want to use Git's wildmatch
-# implementation as fnmatch
-#
 # Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd
 # in the C library.
 #
@@ -342,6 +334,10 @@ all::
 # Define DEFAULT_HELP_FORMAT to "man", "info" or "html"
 # (defaults to "man") if you want to have a different default when
 # "git help" is called without a parameter specifying the format.
+#
+# Define TEST_GIT_INDEX_VERSION to 2, 3 or 4 to run the test suite
+# with a different indexfile format version.  If it isn't set the index
+# file format used is index-v[23].
 
 GIT-VERSION-FILE: FORCE
        @$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -1283,20 +1279,6 @@ endif
 ifdef NO_STRTOULL
        COMPAT_CFLAGS += -DNO_STRTOULL
 endif
-ifdef NO_FNMATCH
-       COMPAT_CFLAGS += -Icompat/fnmatch
-       COMPAT_CFLAGS += -DNO_FNMATCH
-       COMPAT_OBJS += compat/fnmatch/fnmatch.o
-else
-ifdef NO_FNMATCH_CASEFOLD
-       COMPAT_CFLAGS += -Icompat/fnmatch
-       COMPAT_CFLAGS += -DNO_FNMATCH_CASEFOLD
-       COMPAT_OBJS += compat/fnmatch/fnmatch.o
-endif
-endif
-ifndef NO_WILDMATCH
-       COMPAT_CFLAGS += -DUSE_WILDMATCH
-endif
 ifdef NO_SETENV
        COMPAT_CFLAGS += -DNO_SETENV
        COMPAT_OBJS += compat/setenv.o
@@ -2234,6 +2216,9 @@ endif
 ifdef GIT_PERF_MAKE_OPTS
        @echo GIT_PERF_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_OPTS)))'\' >>$@
 endif
+ifdef TEST_GIT_INDEX_VERSION
+       @echo TEST_GIT_INDEX_VERSION=\''$(subst ','\'',$(subst ','\'',$(TEST_GIT_INDEX_VERSION)))'\' >>$@
+endif
 
 ### Detect Python interpreter path changes
 ifndef NO_PYTHON
index bb52cf9476df53ddb9788f16082e2e92e76a4db5..e50885caa1043665dfe2d995e0a2f7a7a7bb51ca 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.9.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.0.0.txt
\ No newline at end of file
index 3eca9f5ffdd6e3596584ed0aa79e2634683bd496..486f823c78118212080a48e74debd7adae241cda 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -2,7 +2,6 @@
 
 int advice_push_update_rejected = 1;
 int advice_push_non_ff_current = 1;
-int advice_push_non_ff_default = 1;
 int advice_push_non_ff_matching = 1;
 int advice_push_already_exists = 1;
 int advice_push_fetch_first = 1;
@@ -23,7 +22,6 @@ static struct {
 } advice_config[] = {
        { "pushupdaterejected", &advice_push_update_rejected },
        { "pushnonffcurrent", &advice_push_non_ff_current },
-       { "pushnonffdefault", &advice_push_non_ff_default },
        { "pushnonffmatching", &advice_push_non_ff_matching },
        { "pushalreadyexists", &advice_push_already_exists },
        { "pushfetchfirst", &advice_push_fetch_first },
index 08fbc8ee3ce79f265bbe15b63e2ae561ee8a0857..5ecc6c154e5a7207d18bbb05da5e35b2b4eae230 100644 (file)
--- a/advice.h
+++ b/advice.h
@@ -5,7 +5,6 @@
 
 extern int advice_push_update_rejected;
 extern int advice_push_non_ff_current;
-extern int advice_push_non_ff_default;
 extern int advice_push_non_ff_matching;
 extern int advice_push_already_exists;
 extern int advice_push_fetch_first;
index 346f3b2f1ab0d522638475b729274d992d5b82d5..7d0976fe55b8ef7b9009d080f7c1c0651a05def7 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -17,6 +17,7 @@ static char const * const archive_usage[] = {
 static const struct archiver **archivers;
 static int nr_archivers;
 static int alloc_archivers;
+static int remote_allow_unreachable;
 
 void register_archiver(struct archiver *ar)
 {
@@ -257,7 +258,7 @@ static void parse_treeish_arg(const char **argv,
        unsigned char sha1[20];
 
        /* Remotes are only allowed to fetch actual refs */
-       if (remote) {
+       if (remote && !remote_allow_unreachable) {
                char *ref = NULL;
                const char *colon = strchr(name, ':');
                int refnamelen = colon ? colon - name : strlen(name);
@@ -401,6 +402,14 @@ static int parse_archive_args(int argc, const char **argv,
        return argc;
 }
 
+static int git_default_archive_config(const char *var, const char *value,
+                                     void *cb)
+{
+       if (!strcmp(var, "uploadarchive.allowunreachable"))
+               remote_allow_unreachable = git_config_bool(var, value);
+       return git_default_config(var, value, cb);
+}
+
 int write_archive(int argc, const char **argv, const char *prefix,
                  int setup_prefix, const char *name_hint, int remote)
 {
@@ -411,7 +420,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
        if (setup_prefix && prefix == NULL)
                prefix = setup_git_directory_gently(&nongit);
 
-       git_config(git_default_config, NULL);
+       git_config(git_default_archive_config, NULL);
        init_tar_archiver();
        init_zip_archiver();
 
diff --git a/attr.c b/attr.c
index 8d13d70e80d6d52794d53ed071b8800f9c905a05..734222dc45c588736f963dea7907258e76024415 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -338,12 +338,7 @@ static void handle_attr_line(struct attr_stack *res,
        a = parse_attr_line(line, src, lineno, macro_ok);
        if (!a)
                return;
-       if (res->alloc <= res->num_matches) {
-               res->alloc = alloc_nr(res->num_matches);
-               res->attrs = xrealloc(res->attrs,
-                                     sizeof(struct match_attr *) *
-                                     res->alloc);
-       }
+       ALLOC_GROW(res->attrs, res->num_matches + 1, res->alloc);
        res->attrs[res->num_matches++] = a;
 }
 
index 672adc01ffc07fa97c305f9110cfa3995658b922..4b045bace12c1fa951785dc09c05a46b09cd9fc7 100644 (file)
@@ -26,55 +26,8 @@ static int take_worktree_changes;
 struct update_callback_data {
        int flags;
        int add_errors;
-       const char *implicit_dot;
-       size_t implicit_dot_len;
-
-       /* only needed for 2.0 transition preparation */
-       int warn_add_would_remove;
 };
 
-static const char *option_with_implicit_dot;
-static const char *short_option_with_implicit_dot;
-
-static void warn_pathless_add(void)
-{
-       static int shown;
-       assert(option_with_implicit_dot && short_option_with_implicit_dot);
-
-       if (shown)
-               return;
-       shown = 1;
-
-       /*
-        * To be consistent with "git add -p" and most Git
-        * commands, we should default to being tree-wide, but
-        * this is not the original behavior and can't be
-        * changed until users trained themselves not to type
-        * "git add -u" or "git add -A". For now, we warn and
-        * keep the old behavior. Later, the behavior can be changed
-        * to tree-wide, keeping the warning for a while, and
-        * eventually we can drop the warning.
-        */
-       warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
-                 "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
-                 "To add content for the whole tree, run:\n"
-                 "\n"
-                 "  git add %s :/\n"
-                 "  (or git add %s :/)\n"
-                 "\n"
-                 "To restrict the command to the current directory, run:\n"
-                 "\n"
-                 "  git add %s .\n"
-                 "  (or git add %s .)\n"
-                 "\n"
-                 "With the current Git version, the command is restricted to "
-                 "the current directory.\n"
-                 ""),
-               option_with_implicit_dot, short_option_with_implicit_dot,
-               option_with_implicit_dot, short_option_with_implicit_dot,
-               option_with_implicit_dot, short_option_with_implicit_dot);
-}
-
 static int fix_unmerged_status(struct diff_filepair *p,
                               struct update_callback_data *data)
 {
@@ -96,49 +49,15 @@ static int fix_unmerged_status(struct diff_filepair *p,
                return DIFF_STATUS_MODIFIED;
 }
 
-static const char *add_would_remove_warning = N_(
-       "You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n"
-"whose behaviour will change in Git 2.0 with respect to paths you removed.\n"
-"Paths like '%s' that are\n"
-"removed from your working tree are ignored with this version of Git.\n"
-"\n"
-"* 'git add --ignore-removal <pathspec>', which is the current default,\n"
-"  ignores paths you removed from your working tree.\n"
-"\n"
-"* 'git add --all <pathspec>' will let you also record the removals.\n"
-"\n"
-"Run 'git status' to check the paths you removed from your working tree.\n");
-
-static void warn_add_would_remove(const char *path)
-{
-       warning(_(add_would_remove_warning), path);
-}
-
 static void update_callback(struct diff_queue_struct *q,
                            struct diff_options *opt, void *cbdata)
 {
        int i;
        struct update_callback_data *data = cbdata;
-       const char *implicit_dot = data->implicit_dot;
-       size_t implicit_dot_len = data->implicit_dot_len;
 
        for (i = 0; i < q->nr; i++) {
                struct diff_filepair *p = q->queue[i];
                const char *path = p->one->path;
-               /*
-                * Check if "git add -A" or "git add -u" was run from a
-                * subdirectory with a modified file outside that directory,
-                * and warn if so.
-                *
-                * "git add -u" will behave like "git add -u :/" instead of
-                * "git add -u ." in the future.  This warning prepares for
-                * that change.
-                */
-               if (implicit_dot &&
-                   strncmp_icase(path, implicit_dot, implicit_dot_len)) {
-                       warn_pathless_add();
-                       continue;
-               }
                switch (fix_unmerged_status(p, data)) {
                default:
                        die(_("unexpected diff status %c"), p->status);
@@ -151,10 +70,6 @@ static void update_callback(struct diff_queue_struct *q,
                        }
                        break;
                case DIFF_STATUS_DELETED:
-                       if (data->warn_add_would_remove) {
-                               warn_add_would_remove(path);
-                               data->warn_add_would_remove = 0;
-                       }
                        if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
                                break;
                        if (!(data->flags & ADD_CACHE_PRETEND))
@@ -166,37 +81,28 @@ static void update_callback(struct diff_queue_struct *q,
        }
 }
 
-static void update_files_in_cache(const char *prefix,
-                                 const struct pathspec *pathspec,
-                                 struct update_callback_data *data)
+int add_files_to_cache(const char *prefix,
+                      const struct pathspec *pathspec, int flags)
 {
+       struct update_callback_data data;
        struct rev_info rev;
 
+       memset(&data, 0, sizeof(data));
+       data.flags = flags;
+
        init_revisions(&rev, prefix);
        setup_revisions(0, NULL, &rev, NULL);
        if (pathspec)
                copy_pathspec(&rev.prune_data, pathspec);
        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = update_callback;
-       rev.diffopt.format_callback_data = data;
+       rev.diffopt.format_callback_data = &data;
        rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
-}
-
-int add_files_to_cache(const char *prefix,
-                      const struct pathspec *pathspec, int flags)
-{
-       struct update_callback_data data;
-
-       memset(&data, 0, sizeof(data));
-       data.flags = flags;
-       update_files_in_cache(prefix, pathspec, &data);
        return !!data.add_errors;
 }
 
-#define WARN_IMPLICIT_DOT (1u << 0)
-static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
-                            int prefix, unsigned flag)
+static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
 {
        char *seen;
        int i;
@@ -210,16 +116,6 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
                struct dir_entry *entry = *src++;
                if (dir_path_match(entry, pathspec, prefix, seen))
                        *dst++ = entry;
-               else if (flag & WARN_IMPLICIT_DOT)
-                       /*
-                        * "git add -A" was run from a subdirectory with a
-                        * new file outside that directory.
-                        *
-                        * "git add -A" will behave like "git add -A :/"
-                        * instead of "git add -A ." in the future.
-                        * Warn about the coming behavior change.
-                        */
-                       warn_pathless_add();
        }
        dir->nr = dst - dir->entries;
        add_pathspec_matches_against_index(pathspec, seen);
@@ -338,7 +234,7 @@ N_("The following paths are ignored by one of your .gitignore files:\n");
 static int verbose, show_only, ignored_too, refresh_only;
 static int ignore_add_errors, intent_to_add, ignore_missing;
 
-#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
+#define ADDREMOVE_DEFAULT 1
 static int addremove = ADDREMOVE_DEFAULT;
 static int addremove_explicit = -1; /* unspecified */
 
@@ -411,8 +307,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        int add_new_files;
        int require_pathspec;
        char *seen = NULL;
-       int implicit_dot = 0;
-       struct update_callback_data update_data;
 
        git_config(add_config, NULL);
 
@@ -436,36 +330,17 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        if (addremove && take_worktree_changes)
                die(_("-A and -u are mutually incompatible"));
 
-       /*
-        * Warn when "git add pathspec..." was given without "-u" or "-A"
-        * and pathspec... covers a removed path.
-        */
-       memset(&update_data, 0, sizeof(update_data));
-       if (!take_worktree_changes && addremove_explicit < 0)
-               update_data.warn_add_would_remove = 1;
-
        if (!take_worktree_changes && addremove_explicit < 0 && argc)
-               /*
-                * Turn "git add pathspec..." to "git add -A pathspec..."
-                * in Git 2.0 but not yet
-                */
-               ; /* addremove = 1; */
+               /* Turn "git add pathspec..." to "git add -A pathspec..." */
+               addremove = 1;
 
        if (!show_only && ignore_missing)
                die(_("Option --ignore-missing can only be used together with --dry-run"));
-       if (addremove) {
-               option_with_implicit_dot = "--all";
-               short_option_with_implicit_dot = "-A";
-       }
-       if (take_worktree_changes) {
-               option_with_implicit_dot = "--update";
-               short_option_with_implicit_dot = "-u";
-       }
-       if (option_with_implicit_dot && !argc) {
-               static const char *here[2] = { ".", NULL };
+
+       if ((0 < addremove_explicit || take_worktree_changes) && !argc) {
+               static const char *whole[2] = { ":/", NULL };
                argc = 1;
-               argv = here;
-               implicit_dot = 1;
+               argv = whole;
        }
 
        add_new_files = !take_worktree_changes && !refresh_only;
@@ -478,8 +353,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
                 (intent_to_add ? ADD_CACHE_INTENT : 0) |
                 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
                 (!(addremove || take_worktree_changes)
-                 ? ADD_CACHE_IGNORE_REMOVAL : 0)) |
-                (implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
+                 ? ADD_CACHE_IGNORE_REMOVAL : 0));
 
        if (require_pathspec && argc == 0) {
                fprintf(stderr, _("Nothing specified, nothing added.\n"));
@@ -513,18 +387,15 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
                memset(&empty_pathspec, 0, sizeof(empty_pathspec));
                /* This picks up the paths that are not tracked */
-               baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec);
+               baselen = fill_directory(&dir, &pathspec);
                if (pathspec.nr)
-                       seen = prune_directory(&dir, &pathspec, baselen,
-                                       implicit_dot ? WARN_IMPLICIT_DOT : 0);
+                       seen = prune_directory(&dir, &pathspec, baselen);
        }
 
        if (refresh_only) {
                refresh(verbose, &pathspec);
                goto finish;
        }
-       if (implicit_dot && prefix)
-               refresh_cache(REFRESH_QUIET);
 
        if (pathspec.nr) {
                int i;
@@ -564,21 +435,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
        plug_bulk_checkin();
 
-       if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) {
-               /*
-                * Check for modified files throughout the worktree so
-                * update_callback has a chance to warn about changes
-                * outside the cwd.
-                */
-               update_data.implicit_dot = prefix;
-               update_data.implicit_dot_len = strlen(prefix);
-               free_pathspec(&pathspec);
-               memset(&pathspec, 0, sizeof(pathspec));
-       }
-       update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
-       update_files_in_cache(prefix, &pathspec, &update_data);
+       exit_status |= add_files_to_cache(prefix, &pathspec, flags);
 
-       exit_status |= !!update_data.add_errors;
        if (add_new_files)
                exit_status |= add_files(&dir, flags);
 
index a7e72d57ab0d23ef3becb3fd7d4564d6050efe6e..0189523798f31711ad74eaf3dd90ece9c12fa61a 100644 (file)
@@ -4152,7 +4152,7 @@ static int use_patch(struct patch *p)
        /* See if it matches any of exclude/include rule */
        for (i = 0; i < limit_by_name.nr; i++) {
                struct string_list_item *it = &limit_by_name.items[i];
-               if (!fnmatch(it->string, pathname, 0))
+               if (!wildmatch(it->string, pathname, 0, NULL))
                        return (it->util != NULL);
        }
 
index b4d771673e7e9dccacbae8b29f4f1cd6a835151f..652b1d2d1484032fab51165f1d0b0a41426d114f 100644 (file)
@@ -315,7 +315,7 @@ static int match_patterns(const char **pattern, const char *refname)
        if (!*pattern)
                return 1; /* no pattern always matches */
        while (*pattern) {
-               if (!fnmatch(*pattern, refname, 0))
+               if (!wildmatch(*pattern, refname, 0, NULL))
                        return 1;
                pattern++;
        }
index e9af7b2bfb932d75cdface880be9814885068a50..5600ec3f6165ae04682f30481142452438f856af 100644 (file)
@@ -102,6 +102,9 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
        struct git_attr_check *check;
        int cnt, i, doubledash, filei;
 
+       if (!is_bare_repository())
+               setup_work_tree();
+
        git_config(git_default_config, NULL);
 
        argc = parse_options(argc, argv, prefix, check_attr_options,
index 114d7bf879690fb1c1c33f768b86776b6ff60ef8..cf76b1f412e5423df42528c928c557764f31ad02 100644 (file)
@@ -947,17 +947,15 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
                if (pathspec.nr)
                        matches = dir_path_match(ent, &pathspec, 0, NULL);
 
-               if (S_ISDIR(st.st_mode)) {
-                       if (remove_directories || (matches == MATCHED_EXACTLY)) {
-                               rel = relative_path(ent->name, prefix, &buf);
-                               string_list_append(&del_list, rel);
-                       }
-               } else {
-                       if (pathspec.nr && !matches)
-                               continue;
-                       rel = relative_path(ent->name, prefix, &buf);
-                       string_list_append(&del_list, rel);
-               }
+               if (pathspec.nr && !matches)
+                       continue;
+
+               if (S_ISDIR(st.st_mode) && !remove_directories &&
+                   matches != MATCHED_EXACTLY)
+                       continue;
+
+               rel = relative_path(ent->name, prefix, &buf);
+               string_list_append(&del_list, rel);
        }
 
        if (interactive && del_list.nr > 0)
index 92ebf23f0a9aa0e052ad68d60e17d0783f633a1c..5677c942b6936f3332b1b4ed12541f45c4228dfb 100644 (file)
@@ -21,8 +21,7 @@ static char key_delim = ' ';
 static char term = '\n';
 
 static int use_global_config, use_system_config, use_local_config;
-static const char *given_config_file;
-static const char *given_config_blob;
+static struct git_config_source given_config_source;
 static int actions, types;
 static const char *get_color_slot, *get_colorbool_slot;
 static int end_null;
@@ -55,8 +54,8 @@ static struct option builtin_config_options[] = {
        OPT_BOOL(0, "global", &use_global_config, N_("use global config file")),
        OPT_BOOL(0, "system", &use_system_config, N_("use system config file")),
        OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")),
-       OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")),
-       OPT_STRING(0, "blob", &given_config_blob, N_("blob-id"), N_("read config from given blob object")),
+       OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")),
+       OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object")),
        OPT_GROUP(N_("Action")),
        OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
        OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
@@ -224,8 +223,7 @@ static int get_value(const char *key_, const char *regex_)
        }
 
        git_config_with_options(collect_config, &values,
-                               given_config_file, given_config_blob,
-                               respect_includes);
+                               &given_config_source, respect_includes);
 
        ret = !values.nr;
 
@@ -309,8 +307,7 @@ static void get_color(const char *def_color)
        get_color_found = 0;
        parsed_color[0] = '\0';
        git_config_with_options(git_get_color_config, NULL,
-                               given_config_file, given_config_blob,
-                               respect_includes);
+                               &given_config_source, respect_includes);
 
        if (!get_color_found && def_color)
                color_parse(def_color, "command line", parsed_color);
@@ -339,8 +336,7 @@ static int get_colorbool(int print)
        get_diff_color_found = -1;
        get_color_ui_found = -1;
        git_config_with_options(git_get_colorbool_config, NULL,
-                               given_config_file, given_config_blob,
-                               respect_includes);
+                               &given_config_source, respect_includes);
 
        if (get_colorbool_found < 0) {
                if (!strcmp(get_colorbool_slot, "color.diff"))
@@ -362,9 +358,12 @@ static int get_colorbool(int print)
                return get_colorbool_found ? 0 : 1;
 }
 
-static void check_blob_write(void)
+static void check_write(void)
 {
-       if (given_config_blob)
+       if (given_config_source.use_stdin)
+               die("writing to stdin is not supported");
+
+       if (given_config_source.blob)
                die("writing config blobs is not supported");
 }
 
@@ -435,7 +434,7 @@ static int get_urlmatch(const char *var, const char *url)
        }
 
        git_config_with_options(urlmatch_config_entry, &config,
-                               given_config_file, NULL, respect_includes);
+                               &given_config_source, respect_includes);
 
        for_each_string_list_item(item, &values) {
                struct urlmatch_current_candidate_value *matched = item->util;
@@ -464,18 +463,24 @@ int cmd_config(int argc, const char **argv, const char *prefix)
        int nongit = !startup_info->have_repository;
        char *value;
 
-       given_config_file = getenv(CONFIG_ENVIRONMENT);
+       given_config_source.file = getenv(CONFIG_ENVIRONMENT);
 
        argc = parse_options(argc, argv, prefix, builtin_config_options,
                             builtin_config_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
 
        if (use_global_config + use_system_config + use_local_config +
-           !!given_config_file + !!given_config_blob > 1) {
+           !!given_config_source.file + !!given_config_source.blob > 1) {
                error("only one config file at a time.");
                usage_with_options(builtin_config_usage, builtin_config_options);
        }
 
+       if (given_config_source.file &&
+                       !strcmp(given_config_source.file, "-")) {
+               given_config_source.file = NULL;
+               given_config_source.use_stdin = 1;
+       }
+
        if (use_global_config) {
                char *user_config = NULL;
                char *xdg_config = NULL;
@@ -493,24 +498,24 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 
                if (access_or_warn(user_config, R_OK, 0) &&
                    xdg_config && !access_or_warn(xdg_config, R_OK, 0))
-                       given_config_file = xdg_config;
+                       given_config_source.file = xdg_config;
                else
-                       given_config_file = user_config;
+                       given_config_source.file = user_config;
        }
        else if (use_system_config)
-               given_config_file = git_etc_gitconfig();
+               given_config_source.file = git_etc_gitconfig();
        else if (use_local_config)
-               given_config_file = git_pathdup("config");
-       else if (given_config_file) {
-               if (!is_absolute_path(given_config_file) && prefix)
-                       given_config_file =
+               given_config_source.file = git_pathdup("config");
+       else if (given_config_source.file) {
+               if (!is_absolute_path(given_config_source.file) && prefix)
+                       given_config_source.file =
                                xstrdup(prefix_filename(prefix,
                                                        strlen(prefix),
-                                                       given_config_file));
+                                                       given_config_source.file));
        }
 
        if (respect_includes == -1)
-               respect_includes = !given_config_file;
+               respect_includes = !given_config_source.file;
 
        if (end_null) {
                term = '\0';
@@ -549,57 +554,58 @@ int cmd_config(int argc, const char **argv, const char *prefix)
        if (actions == ACTION_LIST) {
                check_argc(argc, 0, 0);
                if (git_config_with_options(show_all_config, NULL,
-                                           given_config_file,
-                                           given_config_blob,
+                                           &given_config_source,
                                            respect_includes) < 0) {
-                       if (given_config_file)
+                       if (given_config_source.file)
                                die_errno("unable to read config file '%s'",
-                                         given_config_file);
+                                         given_config_source.file);
                        else
                                die("error processing config file(s)");
                }
        }
        else if (actions == ACTION_EDIT) {
                check_argc(argc, 0, 0);
-               if (!given_config_file && nongit)
+               if (!given_config_source.file && nongit)
                        die("not in a git directory");
-               if (given_config_blob)
+               if (given_config_source.use_stdin)
+                       die("editing stdin is not supported");
+               if (given_config_source.blob)
                        die("editing blobs is not supported");
                git_config(git_default_config, NULL);
-               launch_editor(given_config_file ?
-                             given_config_file : git_path("config"),
+               launch_editor(given_config_source.file ?
+                             given_config_source.file : git_path("config"),
                              NULL, NULL);
        }
        else if (actions == ACTION_SET) {
                int ret;
-               check_blob_write();
+               check_write();
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
-               ret = git_config_set_in_file(given_config_file, argv[0], value);
+               ret = git_config_set_in_file(given_config_source.file, argv[0], value);
                if (ret == CONFIG_NOTHING_SET)
                        error("cannot overwrite multiple values with a single value\n"
                        "       Use a regexp, --add or --replace-all to change %s.", argv[0]);
                return ret;
        }
        else if (actions == ACTION_SET_ALL) {
-               check_blob_write();
+               check_write();
                check_argc(argc, 2, 3);
                value = normalize_value(argv[0], argv[1]);
-               return git_config_set_multivar_in_file(given_config_file,
+               return git_config_set_multivar_in_file(given_config_source.file,
                                                       argv[0], value, argv[2], 0);
        }
        else if (actions == ACTION_ADD) {
-               check_blob_write();
+               check_write();
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
-               return git_config_set_multivar_in_file(given_config_file,
+               return git_config_set_multivar_in_file(given_config_source.file,
                                                       argv[0], value, "^$", 0);
        }
        else if (actions == ACTION_REPLACE_ALL) {
-               check_blob_write();
+               check_write();
                check_argc(argc, 2, 3);
                value = normalize_value(argv[0], argv[1]);
-               return git_config_set_multivar_in_file(given_config_file,
+               return git_config_set_multivar_in_file(given_config_source.file,
                                                       argv[0], value, argv[2], 1);
        }
        else if (actions == ACTION_GET) {
@@ -623,26 +629,26 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                return get_urlmatch(argv[0], argv[1]);
        }
        else if (actions == ACTION_UNSET) {
-               check_blob_write();
+               check_write();
                check_argc(argc, 1, 2);
                if (argc == 2)
-                       return git_config_set_multivar_in_file(given_config_file,
+                       return git_config_set_multivar_in_file(given_config_source.file,
                                                               argv[0], NULL, argv[1], 0);
                else
-                       return git_config_set_in_file(given_config_file,
+                       return git_config_set_in_file(given_config_source.file,
                                                      argv[0], NULL);
        }
        else if (actions == ACTION_UNSET_ALL) {
-               check_blob_write();
+               check_write();
                check_argc(argc, 1, 2);
-               return git_config_set_multivar_in_file(given_config_file,
+               return git_config_set_multivar_in_file(given_config_source.file,
                                                       argv[0], NULL, argv[1], 1);
        }
        else if (actions == ACTION_RENAME_SECTION) {
                int ret;
-               check_blob_write();
+               check_write();
                check_argc(argc, 2, 2);
-               ret = git_config_rename_section_in_file(given_config_file,
+               ret = git_config_rename_section_in_file(given_config_source.file,
                                                        argv[0], argv[1]);
                if (ret < 0)
                        return ret;
@@ -651,9 +657,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
        }
        else if (actions == ACTION_REMOVE_SECTION) {
                int ret;
-               check_blob_write();
+               check_write();
                check_argc(argc, 1, 1);
-               ret = git_config_rename_section_in_file(given_config_file,
+               ret = git_config_rename_section_in_file(given_config_source.file,
                                                        argv[0], NULL);
                if (ret < 0)
                        return ret;
index dadd999c41f6aebe488d057e94e239dfb7dffaec..24d740c8b1705f9c8993bd808c9a618acecc300c 100644 (file)
@@ -138,7 +138,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
                return 0;
 
        /* Accept only tags that match the pattern, if given */
-       if (pattern && (!is_tag || fnmatch(pattern, path + 10, 0)))
+       if (pattern && (!is_tag || wildmatch(pattern, path + 10, 0, NULL)))
                return 0;
 
        /* Is it annotated? */
index 51798b48b54266fccd2f7b4687646d152ab70588..3e1d5c3334e50035fdbf835cfdafbb39c0bacfd0 100644 (file)
@@ -864,7 +864,7 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
                             refname[plen] == '/' ||
                             p[plen-1] == '/'))
                                break;
-                       if (!fnmatch(p, refname, FNM_PATHNAME))
+                       if (!wildmatch(p, refname, WM_PATHNAME, NULL))
                                break;
                }
                if (!*pattern)
index 1affdd5e924c9e71605be603f253e34f6a995f36..fc150c882122c53965fd246ad862e3a75d8768e2 100644 (file)
@@ -144,7 +144,7 @@ static int traverse_reachable(void)
        unsigned int nr = 0;
        int result = 0;
        if (show_progress)
-               progress = start_progress_delay("Checking connectivity", 0, 0, 2);
+               progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);
        while (pending.nr) {
                struct object_array_entry *entry;
                struct object *obj;
@@ -541,7 +541,7 @@ static void fsck_object_dir(const char *path)
                fprintf(stderr, "Checking object directory\n");
 
        if (show_progress)
-               progress = start_progress("Checking object directories", 256);
+               progress = start_progress(_("Checking object directories"), 256);
        for (i = 0; i < 256; i++) {
                static char dir[4096];
                sprintf(dir, "%s/%02x", path, i);
@@ -630,7 +630,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
        struct alternate_object_database *alt;
 
        errors_found = 0;
-       read_replace_refs = 0;
+       check_replace_refs = 0;
 
        argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
 
@@ -670,7 +670,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                                total += p->num_objects;
                        }
 
-                       progress = start_progress("Checking objects", total);
+                       progress = start_progress(_("Checking objects"), total);
                }
                for (p = packed_git; p; p = p->next) {
                        /* verify gives error messages itself */
index 5bbb5e3cc6e3c75ad41a0a92594006a659459634..63d400bcb2092b1751427994b35057f72b04de17 100644 (file)
@@ -29,6 +29,7 @@ static int pack_refs = 1;
 static int aggressive_window = 250;
 static int gc_auto_threshold = 6700;
 static int gc_auto_pack_limit = 50;
+static int detach_auto = 1;
 static const char *prune_expire = "2.weeks.ago";
 
 static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT;
@@ -73,6 +74,10 @@ static int gc_config(const char *var, const char *value, void *cb)
                gc_auto_pack_limit = git_config_int(var, value);
                return 0;
        }
+       if (!strcmp(var, "gc.autodetach")) {
+               detach_auto = git_config_bool(var, value);
+               return 0;
+       }
        if (!strcmp(var, "gc.pruneexpire")) {
                if (value && strcmp(value, "now")) {
                        unsigned long now = approxidate("now");
@@ -302,11 +307,19 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                 */
                if (!need_to_gc())
                        return 0;
-               if (!quiet)
-                       fprintf(stderr,
-                                       _("Auto packing the repository for optimum performance. You may also\n"
-                                       "run \"git gc\" manually. See "
-                                       "\"git help gc\" for more information.\n"));
+               if (!quiet) {
+                       if (detach_auto)
+                               fprintf(stderr, _("Auto packing the repository in background for optimum performance.\n"));
+                       else
+                               fprintf(stderr, _("Auto packing the repository for optimum performance.\n"));
+                       fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
+               }
+               if (detach_auto)
+                       /*
+                        * failure to daemonize is ok, we'll continue
+                        * in foreground
+                        */
+                       daemonize();
        } else
                add_repack_all_option();
 
index 2f37a38fbcdf131ab5897e47728c5773ba36b861..a6b1c17996da28cef97560378e7586bbf1bd8b6b 100644 (file)
@@ -1502,7 +1502,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage(index_pack_usage);
 
-       read_replace_refs = 0;
+       check_replace_refs = 0;
 
        reset_pack_idx_option(&opts);
        git_config(git_index_pack_config, &opts);
index 39e5144b9e38f1319f8fb881af6b1d34ad0c4089..3e9eefb0915a4496ead9ddbf3836a4455351dba0 100644 (file)
@@ -22,7 +22,7 @@ static int tail_match(const char **pattern, const char *path)
        if (snprintf(pathbuf, sizeof(pathbuf), "/%s", path) > sizeof(pathbuf))
                return error("insanely long ref %.*s...", 20, path);
        while ((p = *(pattern++)) != NULL) {
-               if (!fnmatch(p, pathbuf, 0))
+               if (!wildmatch(p, pathbuf, 0, NULL))
                        return 1;
        }
        return 0;
index f92ba404abd5cea0cde344936f697e46c1a46045..a964d6be521c09a241ab0ccdc9f313e182769412 100644 (file)
@@ -23,10 +23,7 @@ static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
        if (strchr(path, '/'))
                die("path %s contains slash", path);
 
-       if (alloc <= used) {
-               alloc = alloc_nr(used);
-               entries = xrealloc(entries, sizeof(*entries) * alloc);
-       }
+       ALLOC_GROW(entries, used + 1, alloc);
        ent = entries[used++] = xmalloc(sizeof(**entries) + len + 1);
        ent->mode = mode;
        ent->len = len;
index 21c46d1636e6e87dd9eaaca60ac08ebbbc4efec3..7e26eb5229a0c8a526314cecb9860c3dfb0fed00 100644 (file)
@@ -162,7 +162,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                        if (strncmp(path, src_w_slash, len_w_slash))
                                                break;
                                }
-                               free((char *)src_w_slash);
+                               if (src_w_slash != src)
+                                       free((char *)src_w_slash);
 
                                if (last - first < 1)
                                        bad = _("source directory is empty");
index 0b21d7e5b297ff3d2d1a73d8a74c8bc37e672ccb..c824d4ec5f1c076e4833c690dad378125dde6da9 100644 (file)
@@ -87,7 +87,7 @@ static int subpath_matches(const char *path, const char *filter)
        const char *subpath = path;
 
        while (subpath) {
-               if (!fnmatch(filter, subpath, 0))
+               if (!wildmatch(filter, subpath, 0, NULL))
                        return subpath - path;
                subpath = strchr(subpath, '/');
                if (subpath)
index 2b24d059b509d28d587066440ed131ce2f85464f..bb89930373451eb0637bb92eedd0613513d959fb 100644 (file)
@@ -269,7 +269,11 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
                die(_("Failed to resolve '%s' as a valid ref."), arg);
        if (!(buf = read_sha1_file(object, &type, &len)) || !len) {
                free(buf);
-               die(_("Failed to read object '%s'."), arg);;
+               die(_("Failed to read object '%s'."), arg);
+       }
+       if (type != OBJ_BLOB) {
+               free(buf);
+               die(_("Cannot read note data from non-blob object '%s'."), arg);
        }
        strbuf_add(&(msg->buf), buf, len);
        free(buf);
index 3f427b4e4ba35c2313c149903bb173c675a56e2d..61a55b3c7ea47136d73425924d4a96f4257fe040 100644 (file)
@@ -755,7 +755,7 @@ static void write_pack_file(void)
        struct object_entry **write_order;
 
        if (progress > pack_to_stdout)
-               progress_state = start_progress("Writing objects", nr_result);
+               progress_state = start_progress(_("Writing objects"), nr_result);
        written_list = xmalloc(to_pack.nr_objects * sizeof(*written_list));
        write_order = compute_write_order();
 
@@ -1210,12 +1210,9 @@ static int check_pbase_path(unsigned hash)
        if (0 <= pos)
                return 1;
        pos = -pos - 1;
-       if (done_pbase_paths_alloc <= done_pbase_paths_num) {
-               done_pbase_paths_alloc = alloc_nr(done_pbase_paths_alloc);
-               done_pbase_paths = xrealloc(done_pbase_paths,
-                                           done_pbase_paths_alloc *
-                                           sizeof(unsigned));
-       }
+       ALLOC_GROW(done_pbase_paths,
+                  done_pbase_paths_num + 1,
+                  done_pbase_paths_alloc);
        done_pbase_paths_num++;
        if (pos < done_pbase_paths_num)
                memmove(done_pbase_paths + pos + 1,
@@ -2151,7 +2148,7 @@ static void prepare_pack(int window, int depth)
        if (nr_deltas && n > 1) {
                unsigned nr_done = 0;
                if (progress)
-                       progress_state = start_progress("Compressing objects",
+                       progress_state = start_progress(_("Compressing objects"),
                                                        nr_deltas);
                qsort(delta_list, n, sizeof(*delta_list), type_size_sort);
                ll_find_deltas(delta_list, n, window+1, depth, &nr_done);
@@ -2609,7 +2606,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                OPT_END(),
        };
 
-       read_replace_refs = 0;
+       check_replace_refs = 0;
 
        reset_pack_idx_option(&pack_idx_opts);
        git_config(git_pack_config, NULL);
@@ -2684,7 +2681,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        prepare_packed_git();
 
        if (progress)
-               progress_state = start_progress("Counting objects", 0);
+               progress_state = start_progress(_("Counting objects"), 0);
        if (!use_internal_rev_list)
                read_object_list_from_stdin();
        else {
index fcf5fb6129c05156c7fd7bbb22ac380dbd0b3245..6879468c46a7baca69e5e28b0c6e38ff7099a6ff 100644 (file)
@@ -46,7 +46,7 @@ void prune_packed_objects(int opts)
 
        strbuf_addstr(&pathname, dir);
        if (opts & PRUNE_PACKED_VERBOSE)
-               progress = start_progress_delay("Removing duplicate objects",
+               progress = start_progress_delay(_("Removing duplicate objects"),
                        256, 95, 2);
 
        if (pathname.len && pathname.buf[pathname.len - 1] != '/')
index de43b26cfe9c7610c13e3320bdac9fa2049e4db6..144a3bdb33956f291df7e6cbf0ee1fdc8461cf3c 100644 (file)
@@ -150,7 +150,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
 
        expire = ULONG_MAX;
        save_commit_buffer = 0;
-       read_replace_refs = 0;
+       check_replace_refs = 0;
        init_revisions(&revs, prefix);
 
        argc = parse_options(argc, argv, prefix, options, prune_usage, 0);
@@ -169,7 +169,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
        if (show_progress == -1)
                show_progress = isatty(2);
        if (show_progress)
-               progress = start_progress_delay("Checking connectivity", 0, 0, 2);
+               progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);
 
        mark_reachable_objects(&revs, 1, progress);
        stop_progress(&progress);
index 0e50ddbb01342128d9118217118726000bdeaff6..f8dfea41e1ad8b6d888c1a2adc13eee87083491e 100644 (file)
@@ -26,7 +26,6 @@ static struct push_cas_option cas;
 static const char **refspec;
 static int refspec_nr;
 static int refspec_alloc;
-static int default_matching_used;
 
 static void add_refspec(const char *ref)
 {
@@ -59,7 +58,7 @@ static const char *map_refspec(const char *ref,
        }
 
        if (push_default == PUSH_DEFAULT_UPSTREAM &&
-           !prefixcmp(matched->name, "refs/heads/")) {
+           starts_with(matched->name, "refs/heads/")) {
                struct branch *branch = branch_get(matched->name + 11);
                if (branch->merge_nr == 1 && branch->merge[0]->src) {
                        struct strbuf buf = STRBUF_INIT;
@@ -204,9 +203,9 @@ static void setup_push_current(struct remote *remote, struct branch *branch)
 }
 
 static char warn_unspecified_push_default_msg[] =
-N_("push.default is unset; its implicit value is changing in\n"
+N_("push.default is unset; its implicit value has changed in\n"
    "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
-   "and maintain the current behavior after the default changes, use:\n"
+   "and maintain the traditional behavior, use:\n"
    "\n"
    "  git config --global push.default matching\n"
    "\n"
@@ -217,7 +216,7 @@ N_("push.default is unset; its implicit value is changing in\n"
    "When push.default is set to 'matching', git will push local branches\n"
    "to the remote branches that already exist with the same name.\n"
    "\n"
-   "In Git 2.0, Git will default to the more conservative 'simple'\n"
+   "Since Git 2.0, Git defaults to the more conservative 'simple'\n"
    "behavior, which only pushes the current branch to the corresponding\n"
    "remote branch that 'git pull' uses to update the current branch.\n"
    "\n"
@@ -247,14 +246,14 @@ static void setup_default_push_refspecs(struct remote *remote)
 
        switch (push_default) {
        default:
-       case PUSH_DEFAULT_UNSPECIFIED:
-               default_matching_used = 1;
-               warn_unspecified_push_default_configuration();
-               /* fallthru */
        case PUSH_DEFAULT_MATCHING:
                add_refspec(":");
                break;
 
+       case PUSH_DEFAULT_UNSPECIFIED:
+               warn_unspecified_push_default_configuration();
+               /* fallthru */
+
        case PUSH_DEFAULT_SIMPLE:
                if (triangular)
                        setup_push_current(remote, branch);
@@ -283,12 +282,6 @@ static const char message_advice_pull_before_push[] =
           "'git pull ...') before pushing again.\n"
           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 
-static const char message_advice_use_upstream[] =
-       N_("Updates were rejected because a pushed branch tip is behind its remote\n"
-          "counterpart. If you did not intend to push that branch, you may want to\n"
-          "specify branches to push or set the 'push.default' configuration variable\n"
-          "to 'simple', 'current' or 'upstream' to push only the current branch.");
-
 static const char message_advice_checkout_pull_push[] =
        N_("Updates were rejected because a pushed branch tip is behind its remote\n"
           "counterpart. Check out this branch and integrate the remote changes\n"
@@ -317,13 +310,6 @@ static void advise_pull_before_push(void)
        advise(_(message_advice_pull_before_push));
 }
 
-static void advise_use_upstream(void)
-{
-       if (!advice_push_non_ff_default || !advice_push_update_rejected)
-               return;
-       advise(_(message_advice_use_upstream));
-}
-
 static void advise_checkout_pull_push(void)
 {
        if (!advice_push_non_ff_matching || !advice_push_update_rejected)
@@ -385,10 +371,7 @@ static int push_with_options(struct transport *transport, int flags)
        if (reject_reasons & REJECT_NON_FF_HEAD) {
                advise_pull_before_push();
        } else if (reject_reasons & REJECT_NON_FF_OTHER) {
-               if (default_matching_used)
-                       advise_use_upstream();
-               else
-                       advise_checkout_pull_push();
+               advise_checkout_pull_push();
        } else if (reject_reasons & REJECT_ALREADY_EXISTS) {
                advise_ref_already_exists();
        } else if (reject_reasons & REJECT_FETCH_FIRST) {
index 852cff60b784d316cddb59234b6276dfe18fd75d..c12a9784e6b45d50129b786a45bb5f4e4dd0801a 100644 (file)
@@ -561,7 +561,7 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
                return; /* both given explicitly -- nothing to tweak */
 
        for (ent = reflog_expire_cfg; ent; ent = ent->next) {
-               if (!fnmatch(ent->pattern, ref, 0)) {
+               if (!wildmatch(ent->pattern, ref, 0, NULL)) {
                        if (!(slot & EXPIRE_TOTAL))
                                cb->expire_total = ent->expire_total;
                        if (!(slot & EXPIRE_UNREACH))
index 2336325ce330f5268800a7bc949c066ce028852c..b62420a01af820225f23d08b4d0e885505640c77 100644 (file)
@@ -36,7 +36,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
 {
        struct show_data *data = cb_data;
 
-       if (!fnmatch(data->pattern, refname, 0)) {
+       if (!wildmatch(data->pattern, refname, 0, NULL)) {
                if (data->format == REPLACE_FORMAT_SHORT)
                        printf("%s\n", refname);
                else if (data->format == REPLACE_FORMAT_MEDIUM)
@@ -178,7 +178,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                OPT_END()
        };
 
-       read_replace_refs = 0;
+       check_replace_refs = 0;
 
        argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0);
 
index 4fd1c6c51d3ce5af60f2978f3839c0e595d3fece..f4e087596b6337d2306af4cf45119752b4a049ea 100644 (file)
@@ -333,7 +333,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
        if (reset_type == NONE)
                reset_type = MIXED; /* by default */
 
-       if (reset_type != SOFT && reset_type != MIXED)
+       if (reset_type != SOFT && (reset_type != MIXED || get_git_work_tree()))
                setup_work_tree();
 
        if (reset_type == MIXED && is_bare_repository())
@@ -356,8 +356,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
                        int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
                        if (read_from_tree(&pathspec, sha1, intent_to_add))
                                return 1;
-                       refresh_index(&the_index, flags, NULL, NULL,
-                                     _("Unstaged changes after reset:"));
+                       if (get_git_work_tree())
+                               refresh_index(&the_index, flags, NULL, NULL,
+                                             _("Unstaged changes after reset:"));
                } else {
                        int err = reset_index(sha1, reset_type, quiet);
                        if (reset_type == KEEP && !err)
index d9217ce1e1a957462284224c08786db77f5a8f15..d87317290c0bbfffb7ac66fb7cff5c608f092d93 100644 (file)
@@ -450,7 +450,7 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
                        slash--;
        if (!*tail)
                return 0;
-       if (fnmatch(match_ref_pattern, tail, 0))
+       if (wildmatch(match_ref_pattern, tail, 0, NULL))
                return 0;
        if (starts_with(refname, "refs/heads/"))
                return append_head_ref(refname, sha1, flag, cb_data);
index 74d3780b77548fc8a7bb2f51b47a51cbfb51969a..169c676636ff6b320f32f13126a5ff46b222f879 100644 (file)
@@ -42,7 +42,7 @@ static int match_pattern(const char **patterns, const char *ref)
        if (!*patterns)
                return 1;
        for (; *patterns; patterns++)
-               if (!fnmatch(*patterns, ref, 0))
+               if (!wildmatch(*patterns, ref, 0, NULL))
                        return 1;
        return 0;
 }
index 62ff673f68b48cc2147fc7f7b17dc5269da022bf..99cde45879401350355083f773a2ff2b78113d1a 100644 (file)
@@ -480,7 +480,7 @@ static void unpack_all(void)
        use(sizeof(struct pack_header));
 
        if (!quiet)
-               progress = start_progress("Unpacking objects", nr_objects);
+               progress = start_progress(_("Unpacking objects"), nr_objects);
        obj_list = xcalloc(nr_objects, sizeof(*obj_list));
        for (i = 0; i < nr_objects; i++) {
                unpack_one(i);
@@ -497,7 +497,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
        int i;
        unsigned char sha1[20];
 
-       read_replace_refs = 0;
+       check_replace_refs = 0;
 
        git_config(git_default_config, NULL);
 
index e99065ce425ad6e816d946626ef83075ab70bf85..1388a3e6fdf352fe670e4236f305c1b1e97b74f2 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -14,11 +14,7 @@ static const char bundle_signature[] = "# v2 git bundle\n";
 static void add_to_ref_list(const unsigned char *sha1, const char *name,
                struct ref_list *list)
 {
-       if (list->nr + 1 >= list->alloc) {
-               list->alloc = alloc_nr(list->nr + 1);
-               list->list = xrealloc(list->list,
-                               list->alloc * sizeof(list->list[0]));
-       }
+       ALLOC_GROW(list->list, list->nr + 1, list->alloc);
        memcpy(list->list[list->nr].sha1, sha1, 20);
        list->list[list->nr].name = xstrdup(name);
        list->nr++;
index 0bbec432165874bd36b1f220301de7f1363626dc..30149d1c42f94cf28e10db317ad3337c8e534ae1 100644 (file)
@@ -75,11 +75,7 @@ static struct cache_tree_sub *find_subtree(struct cache_tree *it,
                return NULL;
 
        pos = -pos-1;
-       if (it->subtree_alloc <= it->subtree_nr) {
-               it->subtree_alloc = alloc_nr(it->subtree_alloc);
-               it->down = xrealloc(it->down, it->subtree_alloc *
-                                   sizeof(*it->down));
-       }
+       ALLOC_GROW(it->down, it->subtree_nr + 1, it->subtree_alloc);
        it->subtree_nr++;
 
        down = xmalloc(sizeof(*down) + pathlen + 1);
diff --git a/cache.h b/cache.h
index db223e8048a50d9f37d523226dfdda05a4f5dd8e..b66cb49b7486e905993fef636b4d3696a57015d5 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -433,6 +433,7 @@ extern int set_git_dir_init(const char *git_dir, const char *real_git_dir, int);
 extern int init_db(const char *template_dir, unsigned int flags);
 
 extern void sanitize_stdfds(void);
+extern int daemonize(void);
 
 #define alloc_nr(x) (((x)+16)*3/2)
 
@@ -482,7 +483,6 @@ extern int remove_file_from_index(struct index_state *, const char *path);
 #define ADD_CACHE_IGNORE_ERRORS        4
 #define ADD_CACHE_IGNORE_REMOVAL 8
 #define ADD_CACHE_INTENT 16
-#define ADD_CACHE_IMPLICIT_DOT 32      /* internal to "git add -u/-A" */
 extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags);
 extern int add_file_to_index(struct index_state *, const char *path, int flags);
 extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options);
@@ -581,7 +581,17 @@ extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
 extern unsigned long big_file_threshold;
 extern unsigned long pack_size_limit_cfg;
-extern int read_replace_refs;
+
+/*
+ * Do replace refs need to be checked this run?  This variable is
+ * initialized to true unless --no-replace-object is used or
+ * $GIT_NO_REPLACE_OBJECTS is set, but is set to false by some
+ * commands that do not want replace references to be active.  As an
+ * optimization it is also set to false if replace references have
+ * been sought but there were none.
+ */
+extern int check_replace_refs;
+
 extern int fsync_object_files;
 extern int core_preload_index;
 extern int core_apply_sparse_checkout;
@@ -660,9 +670,28 @@ extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)
 extern char *git_path_submodule(const char *path, const char *fmt, ...)
        __attribute__((format (printf, 2, 3)));
 
-extern char *sha1_file_name(const unsigned char *sha1);
+/*
+ * Return the name of the file in the local object database that would
+ * be used to store a loose object with the specified sha1.  The
+ * return value is a pointer to a statically allocated buffer that is
+ * overwritten each time the function is called.
+ */
+extern const char *sha1_file_name(const unsigned char *sha1);
+
+/*
+ * Return the name of the (local) packfile with the specified sha1 in
+ * its name.  The return value is a pointer to memory that is
+ * overwritten each time this function is called.
+ */
 extern char *sha1_pack_name(const unsigned char *sha1);
+
+/*
+ * Return the name of the (local) pack index file with the specified
+ * sha1 in its name.  The return value is a pointer to memory that is
+ * overwritten each time this function is called.
+ */
 extern char *sha1_pack_index_name(const unsigned char *sha1);
+
 extern const char *find_unique_abbrev(const unsigned char *sha1, int);
 extern const unsigned char null_sha1[20];
 
@@ -789,13 +818,26 @@ static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *
 {
        return read_sha1_file_extended(sha1, type, size, LOOKUP_REPLACE_OBJECT);
 }
+
+/*
+ * This internal function is only declared here for the benefit of
+ * lookup_replace_object().  Please do not call it directly.
+ */
 extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
+
+/*
+ * If object sha1 should be replaced, return the replacement object's
+ * name (replaced recursively, if necessary).  The return value is
+ * either sha1 or a pointer to a permanently-allocated value.  When
+ * object replacement is suppressed, always return sha1.
+ */
 static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
 {
-       if (!read_replace_refs)
+       if (!check_replace_refs)
                return sha1;
        return do_lookup_replace_object(sha1);
 }
+
 static inline const unsigned char *lookup_replace_object_extended(const unsigned char *sha1, unsigned flag)
 {
        if (!(flag & LOOKUP_REPLACE_OBJECT))
@@ -822,7 +864,19 @@ extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned l
 extern int move_temp_to_file(const char *tmpfile, const char *filename);
 
 extern int has_sha1_pack(const unsigned char *sha1);
+
+/*
+ * Return true iff we have an object named sha1, whether local or in
+ * an alternate object database, and whether packed or loose.  This
+ * function does not respect replace references.
+ */
 extern int has_sha1_file(const unsigned char *sha1);
+
+/*
+ * Return true iff an alternate object database has a loose object
+ * with the specified name.  This function does not respect replace
+ * references.
+ */
 extern int has_loose_object_nonlocal(const unsigned char *sha1);
 
 extern int has_pack_index(const unsigned char *sha1);
@@ -961,6 +1015,7 @@ void datestamp(char *buf, int bufsize);
 unsigned long approxidate_careful(const char *, int *);
 unsigned long approxidate_relative(const char *date, const struct timeval *now);
 enum date_mode parse_date_format(const char *format);
+int date_overflows(unsigned long date);
 
 #define IDENT_STRICT          1
 #define IDENT_NO_DATE         2
@@ -1085,17 +1140,46 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
                                         struct packed_git *packs);
 
 extern void pack_report(void);
+
+/*
+ * mmap the index file for the specified packfile (if it is not
+ * already mmapped).  Return 0 on success.
+ */
 extern int open_pack_index(struct packed_git *);
+
+/*
+ * munmap the index file for the specified packfile (if it is
+ * currently mmapped).
+ */
 extern void close_pack_index(struct packed_git *);
+
 extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
 extern void close_pack_windows(struct packed_git *);
 extern void unuse_pack(struct pack_window **);
 extern void free_pack_by_name(const char *);
 extern void clear_delta_base_cache(void);
 extern struct packed_git *add_packed_git(const char *, int, int);
-extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
-extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);
-extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
+
+/*
+ * Return the SHA-1 of the nth object within the specified packfile.
+ * Open the index if it is not already open.  The return value points
+ * at the SHA-1 within the mmapped index.  Return NULL if there is an
+ * error.
+ */
+extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t n);
+
+/*
+ * Return the offset of the nth object within the specified packfile.
+ * The index must already be opened.
+ */
+extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t n);
+
+/*
+ * If the object named sha1 is present in the specified packfile,
+ * return its offset within the packfile; otherwise, return 0.
+ */
+extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *);
+
 extern int is_pack_valid(struct packed_git *);
 extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
 extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
@@ -1148,6 +1232,12 @@ extern int update_server_info(int);
 #define CONFIG_INVALID_PATTERN 6
 #define CONFIG_GENERIC_ERROR 7
 
+struct git_config_source {
+       unsigned int use_stdin:1;
+       const char *file;
+       const char *blob;
+};
+
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int git_default_config(const char *, const char *, void *);
 extern int git_config_from_file(config_fn_t fn, const char *, void *);
@@ -1157,8 +1247,7 @@ extern void git_config_push_parameter(const char *text);
 extern int git_config_from_parameters(config_fn_t fn, void *data);
 extern int git_config(config_fn_t fn, void *);
 extern int git_config_with_options(config_fn_t fn, void *,
-                                  const char *filename,
-                                  const char *blob_ref,
+                                  struct git_config_source *config_source,
                                   int respect_includes);
 extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
 extern int git_parse_ulong(const char *, unsigned long *);
index 3b92c44880228a94f71a428b0f11bb1caf693c67..24ca7e2334b68e06afd24051ad1aafcc129bcba4 100644 (file)
 static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
 {
        struct diff_queue_struct *q = &diff_queued_diff;
-       struct combine_diff_path *p;
-       int i;
+       struct combine_diff_path *p, **tail = &curr;
+       int i, cmp;
 
        if (!n) {
-               struct combine_diff_path *list = NULL, **tail = &list;
                for (i = 0; i < q->nr; i++) {
                        int len;
                        const char *path;
@@ -31,7 +30,6 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
                        p->path = (char *) &(p->parent[num_parent]);
                        memcpy(p->path, path, len);
                        p->path[len] = 0;
-                       p->len = len;
                        p->next = NULL;
                        memset(p->parent, 0,
                               sizeof(p->parent[0]) * num_parent);
@@ -44,31 +42,37 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
                        *tail = p;
                        tail = &p->next;
                }
-               return list;
+               return curr;
        }
 
-       for (p = curr; p; p = p->next) {
-               int found = 0;
-               if (!p->len)
+       /*
+        * paths in curr (linked list) and q->queue[] (array) are
+        * both sorted in the tree order.
+        */
+       i = 0;
+       while ((p = *tail) != NULL) {
+               cmp = ((i >= q->nr)
+                      ? -1 : strcmp(p->path, q->queue[i]->two->path));
+
+               if (cmp < 0) {
+                       /* p->path not in q->queue[]; drop it */
+                       *tail = p->next;
+                       free(p);
                        continue;
-               for (i = 0; i < q->nr; i++) {
-                       const char *path;
-                       int len;
+               }
 
-                       if (diff_unmodified_pair(q->queue[i]))
-                               continue;
-                       path = q->queue[i]->two->path;
-                       len = strlen(path);
-                       if (len == p->len && !memcmp(path, p->path, len)) {
-                               found = 1;
-                               hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1);
-                               p->parent[n].mode = q->queue[i]->one->mode;
-                               p->parent[n].status = q->queue[i]->status;
-                               break;
-                       }
+               if (cmp > 0) {
+                       /* q->queue[i] not in p->path; skip it */
+                       i++;
+                       continue;
                }
-               if (!found)
-                       p->len = 0;
+
+               hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1);
+               p->parent[n].mode = q->queue[i]->one->mode;
+               p->parent[n].status = q->queue[i]->status;
+
+               tail = &p->next;
+               i++;
        }
        return curr;
 }
@@ -1219,8 +1223,6 @@ void show_combined_diff(struct combine_diff_path *p,
 {
        struct diff_options *opt = &rev->diffopt;
 
-       if (!p->len)
-               return;
        if (opt->output_format & (DIFF_FORMAT_RAW |
                                  DIFF_FORMAT_NAME |
                                  DIFF_FORMAT_NAME_STATUS))
@@ -1284,17 +1286,21 @@ static void handle_combined_callback(struct diff_options *opt,
        q.queue = xcalloc(num_paths, sizeof(struct diff_filepair *));
        q.alloc = num_paths;
        q.nr = num_paths;
-       for (i = 0, p = paths; p; p = p->next) {
-               if (!p->len)
-                       continue;
+       for (i = 0, p = paths; p; p = p->next)
                q.queue[i++] = combined_pair(p, num_parent);
-       }
        opt->format_callback(&q, opt, opt->format_callback_data);
        for (i = 0; i < num_paths; i++)
                free_combined_pair(q.queue[i]);
        free(q.queue);
 }
 
+static const char *path_path(void *obj)
+{
+       struct combine_diff_path *path = (struct combine_diff_path *)obj;
+
+       return path->path;
+}
+
 void diff_tree_combined(const unsigned char *sha1,
                        const struct sha1_array *parents,
                        int dense,
@@ -1310,6 +1316,8 @@ void diff_tree_combined(const unsigned char *sha1,
        diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
        DIFF_OPT_SET(&diffopts, RECURSIVE);
        DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
+       /* tell diff_tree to emit paths in sorted (=tree) order */
+       diffopts.orderfile = NULL;
 
        show_log_first = !!rev->loginfo && !rev->no_commit_id;
        needsep = 0;
@@ -1335,22 +1343,46 @@ void diff_tree_combined(const unsigned char *sha1,
                                printf("%s%c", diff_line_prefix(opt),
                                       opt->line_termination);
                }
+
+               /* if showing diff, show it in requested order */
+               if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT &&
+                   opt->orderfile) {
+                       diffcore_order(opt->orderfile);
+               }
+
                diff_flush(&diffopts);
        }
 
-       /* find out surviving paths */
-       for (num_paths = 0, p = paths; p; p = p->next) {
-               if (p->len)
-                       num_paths++;
+       /* find out number of surviving paths */
+       for (num_paths = 0, p = paths; p; p = p->next)
+               num_paths++;
+
+       /* order paths according to diffcore_order */
+       if (opt->orderfile && num_paths) {
+               struct obj_order *o;
+
+               o = xmalloc(sizeof(*o) * num_paths);
+               for (i = 0, p = paths; p; p = p->next, i++)
+                       o[i].obj = p;
+               order_objects(opt->orderfile, path_path, o, num_paths);
+               for (i = 0; i < num_paths - 1; i++) {
+                       p = o[i].obj;
+                       p->next = o[i+1].obj;
+               }
+
+               p = o[num_paths-1].obj;
+               p->next = NULL;
+               paths = o[0].obj;
+               free(o);
        }
+
+
        if (num_paths) {
                if (opt->output_format & (DIFF_FORMAT_RAW |
                                          DIFF_FORMAT_NAME |
                                          DIFF_FORMAT_NAME_STATUS)) {
-                       for (p = paths; p; p = p->next) {
-                               if (p->len)
-                                       show_raw_diff(p, num_parent, rev);
-                       }
+                       for (p = paths; p; p = p->next)
+                               show_raw_diff(p, num_parent, rev);
                        needsep = 1;
                }
                else if (opt->output_format &
@@ -1363,11 +1395,9 @@ void diff_tree_combined(const unsigned char *sha1,
                        if (needsep)
                                printf("%s%c", diff_line_prefix(opt),
                                       opt->line_termination);
-                       for (p = paths; p; p = p->next) {
-                               if (p->len)
-                                       show_patch_diff(p, num_parent, dense,
-                                                       0, rev);
-                       }
+                       for (p = paths; p; p = p->next)
+                               show_patch_diff(p, num_parent, dense,
+                                               0, rev);
                }
        }
 
index 6bf4fe00d4b0365eca75fd9988852650660b6884..0f28902bc351fef9d621cfe290f887921ec779c4 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -10,6 +10,7 @@
 #include "mergesort.h"
 #include "commit-slab.h"
 #include "prio-queue.h"
+#include "sha1-lookup.h"
 
 static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
 
@@ -114,23 +115,16 @@ static unsigned long parse_commit_date(const char *buf, const char *tail)
 static struct commit_graft **commit_graft;
 static int commit_graft_alloc, commit_graft_nr;
 
+static const unsigned char *commit_graft_sha1_access(size_t index, void *table)
+{
+       struct commit_graft **commit_graft_table = table;
+       return commit_graft_table[index]->sha1;
+}
+
 static int commit_graft_pos(const unsigned char *sha1)
 {
-       int lo, hi;
-       lo = 0;
-       hi = commit_graft_nr;
-       while (lo < hi) {
-               int mi = (lo + hi) / 2;
-               struct commit_graft *graft = commit_graft[mi];
-               int cmp = hashcmp(sha1, graft->sha1);
-               if (!cmp)
-                       return mi;
-               if (cmp < 0)
-                       hi = mi;
-               else
-                       lo = mi + 1;
-       }
-       return -lo - 1;
+       return sha1_pos(sha1, commit_graft, commit_graft_nr,
+                       commit_graft_sha1_access);
 }
 
 int register_commit_graft(struct commit_graft *graft, int ignore_dups)
@@ -147,12 +141,8 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
                return 1;
        }
        pos = -pos - 1;
-       if (commit_graft_alloc <= ++commit_graft_nr) {
-               commit_graft_alloc = alloc_nr(commit_graft_alloc);
-               commit_graft = xrealloc(commit_graft,
-                                       sizeof(*commit_graft) *
-                                       commit_graft_alloc);
-       }
+       ALLOC_GROW(commit_graft, commit_graft_nr + 1, commit_graft_alloc);
+       commit_graft_nr++;
        if (pos < commit_graft_nr)
                memmove(commit_graft + pos + 1,
                        commit_graft + pos,
@@ -548,7 +538,7 @@ define_commit_slab(author_date_slab, unsigned long);
 static void record_author_date(struct author_date_slab *author_date,
                               struct commit *commit)
 {
-       const char *buf, *line_end;
+       const char *buf, *line_end, *ident_line;
        char *buffer = NULL;
        struct ident_split ident;
        char *date_end;
@@ -566,14 +556,14 @@ static void record_author_date(struct author_date_slab *author_date,
             buf;
             buf = line_end + 1) {
                line_end = strchrnul(buf, '\n');
-               if (!starts_with(buf, "author ")) {
+               ident_line = skip_prefix(buf, "author ");
+               if (!ident_line) {
                        if (!line_end[0] || line_end[1] == '\n')
                                return; /* end of header */
                        continue;
                }
                if (split_ident_line(&ident,
-                                    buf + strlen("author "),
-                                    line_end - (buf + strlen("author "))) ||
+                                    ident_line, line_end - ident_line) ||
                    !ident.date_begin || !ident.date_end)
                        goto fail_exit; /* malformed "author" line */
                break;
@@ -1193,10 +1183,8 @@ static void parse_gpg_output(struct signature_check *sigc)
        for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) {
                const char *found, *next;
 
-               if (starts_with(buf, sigcheck_gpg_status[i].check + 1)) {
-                       /* At the very beginning of the buffer */
-                       found = buf + strlen(sigcheck_gpg_status[i].check + 1);
-               } else {
+               found = skip_prefix(buf, sigcheck_gpg_status[i].check + 1);
+               if (!found) {
                        found = strstr(buf, sigcheck_gpg_status[i].check);
                        if (!found)
                                continue;
diff --git a/compat/fnmatch/fnmatch.c b/compat/fnmatch/fnmatch.c
deleted file mode 100644 (file)
index 378c467..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with this library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/* Enable GNU extensions in fnmatch.h.  */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE   1
-#endif
-
-#include <stddef.h>
-#include <errno.h>
-#include <fnmatch.h>
-#include <ctype.h>
-
-#if HAVE_STRING_H || defined _LIBC
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-
-#if defined STDC_HEADERS || defined _LIBC
-# include <stdlib.h>
-#endif
-
-/* For platforms which support the ISO C amendment 1 functionality we
-   support user defined character classes.  */
-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
-# include <wchar.h>
-# include <wctype.h>
-#endif
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-#if defined NO_FNMATCH || defined NO_FNMATCH_CASEFOLD || \
-    defined _LIBC || !defined __GNU_LIBRARY__
-
-
-# if defined STDC_HEADERS || !defined isascii
-#  define ISASCII(c) 1
-# else
-#  define ISASCII(c) isascii(c)
-# endif
-
-# ifdef isblank
-#  define ISBLANK(c) (ISASCII (c) && isblank (c))
-# else
-#  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
-# endif
-# ifdef isgraph
-#  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
-# else
-#  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
-# endif
-
-# define ISPRINT(c) (ISASCII (c) && isprint (c))
-# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
-# define ISALNUM(c) (ISASCII (c) && isalnum (c))
-# define ISALPHA(c) (ISASCII (c) && isalpha (c))
-# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
-# define ISLOWER(c) (ISASCII (c) && islower (c))
-# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
-# define ISSPACE(c) (ISASCII (c) && isspace (c))
-# define ISUPPER(c) (ISASCII (c) && isupper (c))
-# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
-
-# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
-
-# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-/* The GNU C library provides support for user-defined character classes
-   and the functions from ISO C amendment 1.  */
-#  ifdef CHARCLASS_NAME_MAX
-#   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
-#  else
-/* This shouldn't happen but some implementation might still have this
-   problem.  Use a reasonable default value.  */
-#   define CHAR_CLASS_MAX_LENGTH 256
-#  endif
-
-#  ifdef _LIBC
-#   define IS_CHAR_CLASS(string) __wctype (string)
-#  else
-#   define IS_CHAR_CLASS(string) wctype (string)
-#  endif
-# else
-#  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
-
-#  define IS_CHAR_CLASS(string)                                                      \
-   (STREQ (string, "alpha") || STREQ (string, "upper")                       \
-    || STREQ (string, "lower") || STREQ (string, "digit")                    \
-    || STREQ (string, "alnum") || STREQ (string, "xdigit")                   \
-    || STREQ (string, "space") || STREQ (string, "print")                    \
-    || STREQ (string, "punct") || STREQ (string, "graph")                    \
-    || STREQ (string, "cntrl") || STREQ (string, "blank"))
-# endif
-
-/* Avoid depending on library functions or files
-   whose names are inconsistent.  */
-
-# if !defined _LIBC && !defined getenv
-extern char *getenv (const char *name);
-# endif
-
-# ifndef errno
-extern int errno;
-# endif
-
-# ifndef NULL
-#  define NULL 0
-# endif
-
-/* This function doesn't exist on most systems.  */
-
-# if !defined HAVE___STRCHRNUL && !defined _LIBC
-static char *
-__strchrnul (const char *s, int c)
-
-
-{
-  char *result = strchr (s, c);
-  if (result == NULL)
-    result = strchr (s, '\0');
-  return result;
-}
-# endif
-
-# ifndef internal_function
-/* Inside GNU libc we mark some function in a special way.  In other
-   environments simply ignore the marking.  */
-#  define internal_function
-# endif
-
-/* Match STRING against the filename pattern PATTERN, returning zero if
-   it matches, nonzero if not.  */
-static int internal_fnmatch __P ((const char *pattern, const char *string,
-                                 int no_leading_period, int flags))
-     internal_function;
-static int
-internal_function
-internal_fnmatch (const char *pattern, const char *string, int no_leading_period, int flags)
-
-
-
-
-{
-  register const char *p = pattern, *n = string;
-  register unsigned char c;
-
-/* Note that this evaluates C many times.  */
-# ifdef _LIBC
-#  define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
-# else
-#  define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
-# endif
-
-  while ((c = *p++) != '\0')
-    {
-      c = FOLD (c);
-
-      switch (c)
-       {
-       case '?':
-         if (*n == '\0')
-           return FNM_NOMATCH;
-         else if (*n == '/' && (flags & FNM_FILE_NAME))
-           return FNM_NOMATCH;
-         else if (*n == '.' && no_leading_period
-                  && (n == string
-                      || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
-           return FNM_NOMATCH;
-         break;
-
-       case '\\':
-         if (!(flags & FNM_NOESCAPE))
-           {
-             c = *p++;
-             if (c == '\0')
-               /* Trailing \ loses.  */
-               return FNM_NOMATCH;
-             c = FOLD (c);
-           }
-         if (FOLD ((unsigned char) *n) != c)
-           return FNM_NOMATCH;
-         break;
-
-       case '*':
-         if (*n == '.' && no_leading_period
-             && (n == string
-                 || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
-           return FNM_NOMATCH;
-
-         for (c = *p++; c == '?' || c == '*'; c = *p++)
-           {
-             if (*n == '/' && (flags & FNM_FILE_NAME))
-               /* A slash does not match a wildcard under FNM_FILE_NAME.  */
-               return FNM_NOMATCH;
-             else if (c == '?')
-               {
-                 /* A ? needs to match one character.  */
-                 if (*n == '\0')
-                   /* There isn't another character; no match.  */
-                   return FNM_NOMATCH;
-                 else
-                   /* One character of the string is consumed in matching
-                      this ? wildcard, so *??? won't match if there are
-                      less than three characters.  */
-                   ++n;
-               }
-           }
-
-         if (c == '\0')
-           /* The wildcard(s) is/are the last element of the pattern.
-              If the name is a file name and contains another slash
-              this does mean it cannot match.  */
-           return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
-                   ? FNM_NOMATCH : 0);
-         else
-           {
-             const char *endp;
-
-             endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
-
-             if (c == '[')
-               {
-                 int flags2 = ((flags & FNM_FILE_NAME)
-                               ? flags : (flags & ~FNM_PERIOD));
-
-                 for (--p; n < endp; ++n)
-                   if (internal_fnmatch (p, n,
-                                         (no_leading_period
-                                          && (n == string
-                                              || (n[-1] == '/'
-                                                  && (flags
-                                                      & FNM_FILE_NAME)))),
-                                         flags2)
-                       == 0)
-                     return 0;
-               }
-             else if (c == '/' && (flags & FNM_FILE_NAME))
-               {
-                 while (*n != '\0' && *n != '/')
-                   ++n;
-                 if (*n == '/'
-                     && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
-                                           flags) == 0))
-                   return 0;
-               }
-             else
-               {
-                 int flags2 = ((flags & FNM_FILE_NAME)
-                               ? flags : (flags & ~FNM_PERIOD));
-
-                 if (c == '\\' && !(flags & FNM_NOESCAPE))
-                   c = *p;
-                 c = FOLD (c);
-                 for (--p; n < endp; ++n)
-                   if (FOLD ((unsigned char) *n) == c
-                       && (internal_fnmatch (p, n,
-                                             (no_leading_period
-                                              && (n == string
-                                                  || (n[-1] == '/'
-                                                      && (flags
-                                                          & FNM_FILE_NAME)))),
-                                             flags2) == 0))
-                     return 0;
-               }
-           }
-
-         /* If we come here no match is possible with the wildcard.  */
-         return FNM_NOMATCH;
-
-       case '[':
-         {
-           /* Nonzero if the sense of the character class is inverted.  */
-           static int posixly_correct;
-           register int not;
-           char cold;
-
-           if (posixly_correct == 0)
-             posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
-
-           if (*n == '\0')
-             return FNM_NOMATCH;
-
-           if (*n == '.' && no_leading_period && (n == string
-                                                  || (n[-1] == '/'
-                                                      && (flags
-                                                          & FNM_FILE_NAME))))
-             return FNM_NOMATCH;
-
-           if (*n == '/' && (flags & FNM_FILE_NAME))
-             /* `/' cannot be matched.  */
-             return FNM_NOMATCH;
-
-           not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
-           if (not)
-             ++p;
-
-           c = *p++;
-           for (;;)
-             {
-               unsigned char fn = FOLD ((unsigned char) *n);
-
-               if (!(flags & FNM_NOESCAPE) && c == '\\')
-                 {
-                   if (*p == '\0')
-                     return FNM_NOMATCH;
-                   c = FOLD ((unsigned char) *p);
-                   ++p;
-
-                   if (c == fn)
-                     goto matched;
-                 }
-               else if (c == '[' && *p == ':')
-                 {
-                   /* Leave room for the null.  */
-                   char str[CHAR_CLASS_MAX_LENGTH + 1];
-                   size_t c1 = 0;
-# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-                   wctype_t wt;
-# endif
-                   const char *startp = p;
-
-                   for (;;)
-                     {
-                       if (c1 > CHAR_CLASS_MAX_LENGTH)
-                         /* The name is too long and therefore the pattern
-                            is ill-formed.  */
-                         return FNM_NOMATCH;
-
-                       c = *++p;
-                       if (c == ':' && p[1] == ']')
-                         {
-                           p += 2;
-                           break;
-                         }
-                       if (c < 'a' || c >= 'z')
-                         {
-                           /* This cannot possibly be a character class name.
-                              Match it as a normal range.  */
-                           p = startp;
-                           c = '[';
-                           goto normal_bracket;
-                         }
-                       str[c1++] = c;
-                     }
-                   str[c1] = '\0';
-
-# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-                   wt = IS_CHAR_CLASS (str);
-                   if (wt == 0)
-                     /* Invalid character class name.  */
-                     return FNM_NOMATCH;
-
-                   if (__iswctype (__btowc ((unsigned char) *n), wt))
-                     goto matched;
-# else
-                   if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
-                       || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
-                       || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
-                       || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
-                       || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
-                       || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
-                       || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
-                       || (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
-                       || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
-                       || (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
-                       || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
-                       || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
-                     goto matched;
-# endif
-                 }
-               else if (c == '\0')
-                 /* [ (unterminated) loses.  */
-                 return FNM_NOMATCH;
-               else
-                 {
-                 normal_bracket:
-                   if (FOLD (c) == fn)
-                     goto matched;
-
-                   cold = c;
-                   c = *p++;
-
-                   if (c == '-' && *p != ']')
-                     {
-                       /* It is a range.  */
-                       unsigned char cend = *p++;
-                       if (!(flags & FNM_NOESCAPE) && cend == '\\')
-                         cend = *p++;
-                       if (cend == '\0')
-                         return FNM_NOMATCH;
-
-                       if (cold <= fn && fn <= FOLD (cend))
-                         goto matched;
-
-                       c = *p++;
-                     }
-                 }
-
-               if (c == ']')
-                 break;
-             }
-
-           if (!not)
-             return FNM_NOMATCH;
-           break;
-
-         matched:
-           /* Skip the rest of the [...] that already matched.  */
-           while (c != ']')
-             {
-               if (c == '\0')
-                 /* [... (unterminated) loses.  */
-                 return FNM_NOMATCH;
-
-               c = *p++;
-               if (!(flags & FNM_NOESCAPE) && c == '\\')
-                 {
-                   if (*p == '\0')
-                     return FNM_NOMATCH;
-                   /* XXX 1003.2d11 is unclear if this is right.  */
-                   ++p;
-                 }
-               else if (c == '[' && *p == ':')
-                 {
-                   do
-                     if (*++p == '\0')
-                       return FNM_NOMATCH;
-                   while (*p != ':' || p[1] == ']');
-                   p += 2;
-                   c = *p;
-                 }
-             }
-           if (not)
-             return FNM_NOMATCH;
-         }
-         break;
-
-       default:
-         if (c != FOLD ((unsigned char) *n))
-           return FNM_NOMATCH;
-       }
-
-      ++n;
-    }
-
-  if (*n == '\0')
-    return 0;
-
-  if ((flags & FNM_LEADING_DIR) && *n == '/')
-    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
-    return 0;
-
-  return FNM_NOMATCH;
-
-# undef FOLD
-}
-
-
-int
-fnmatch (const char *pattern, const char *string, int flags)
-
-
-
-{
-  return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
-}
-
-#endif /* _LIBC or not __GNU_LIBRARY__.  */
diff --git a/compat/fnmatch/fnmatch.h b/compat/fnmatch/fnmatch.h
deleted file mode 100644 (file)
index cc3ec37..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#ifndef        _FNMATCH_H
-#define        _FNMATCH_H      1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
-# if !defined __GLIBC__ || !defined __P
-#  undef       __P
-#  define __P(protos)  protos
-# endif
-#else /* Not C++ or ANSI C.  */
-# undef        __P
-# define __P(protos)   ()
-/* We can get away without defining `const' here only because in this file
-   it is used only inside the prototype for `fnmatch', which is elided in
-   non-ANSI C where `const' is problematical.  */
-#endif /* C++ or ANSI C.  */
-
-#ifndef const
-# if (defined __STDC__ && __STDC__) || defined __cplusplus
-#  define __const      const
-# else
-#  define __const
-# endif
-#endif
-
-/* We #undef these before defining them because some losing systems
-   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
-#undef FNM_PATHNAME
-#undef FNM_NOESCAPE
-#undef FNM_PERIOD
-
-/* Bits set in the FLAGS argument to `fnmatch'.  */
-#define        FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
-#define        FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
-#define        FNM_PERIOD      (1 << 2) /* Leading `.' is matched only explicitly.  */
-
-#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
-# define FNM_FILE_NAME  FNM_PATHNAME   /* Preferred GNU name.  */
-# define FNM_LEADING_DIR (1 << 3)      /* Ignore `/...' after a match.  */
-# define FNM_CASEFOLD   (1 << 4)       /* Compare without regard to case.  */
-#endif
-
-/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
-#define        FNM_NOMATCH     1
-
-/* This value is returned if the implementation does not support
-   `fnmatch'.  Since this is not the case here it will never be
-   returned but the conformance test suites still require the symbol
-   to be defined.  */
-#ifdef _XOPEN_SOURCE
-# define FNM_NOSYS     (-1)
-#endif
-
-/* Match NAME against the filename pattern PATTERN,
-   returning zero if it matches, FNM_NOMATCH if not.  */
-extern int fnmatch __P ((__const char *__pattern, __const char *__name,
-                        int __flags));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* fnmatch.h */
index 314d8ee740bea488d8c79d80b3d91530ad15252d..6821cef00a0da56fbdadbd34d179ba5bd125c3a6 100644 (file)
--- a/config.c
+++ b/config.c
@@ -21,6 +21,7 @@ struct config_source {
                } buf;
        } u;
        const char *name;
+       const char *path;
        int die_on_error;
        int linenr;
        int eof;
@@ -101,12 +102,12 @@ static int handle_path_include(const char *path, struct config_include_data *inc
        if (!is_absolute_path(path)) {
                char *slash;
 
-               if (!cf || !cf->name)
+               if (!cf || !cf->path)
                        return error("relative config includes must come from files");
 
-               slash = find_last_dir_sep(cf->name);
+               slash = find_last_dir_sep(cf->path);
                if (slash)
-                       strbuf_add(&buf, cf->name, slash - cf->name + 1);
+                       strbuf_add(&buf, cf->path, slash - cf->path + 1);
                strbuf_addstr(&buf, path);
                path = buf.buf;
        }
@@ -667,20 +668,7 @@ static int git_default_core_config(const char *var, const char *value)
                trust_ctime = git_config_bool(var, value);
                return 0;
        }
-       if (!strcmp(var, "core.statinfo") ||
-           !strcmp(var, "core.checkstat")) {
-               /*
-                * NEEDSWORK: statinfo was a typo in v1.8.2 that has
-                * never been advertised.  we will remove it at Git
-                * 2.0 boundary.
-                */
-               if (!strcmp(var, "core.statinfo")) {
-                       static int warned;
-                       if (!warned++) {
-                               warning("'core.statinfo' will be removed in Git 2.0; "
-                                       "use 'core.checkstat' instead.");
-                       }
-               }
+       if (!strcmp(var, "core.checkstat")) {
                if (!strcasecmp(value, "default"))
                        check_stat = 1;
                else if (!strcasecmp(value, "minimal"))
@@ -1034,24 +1022,35 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data)
        return ret;
 }
 
-int git_config_from_file(config_fn_t fn, const char *filename, void *data)
+static int do_config_from_file(config_fn_t fn,
+               const char *name, const char *path, FILE *f, void *data)
 {
-       int ret;
-       FILE *f = fopen(filename, "r");
+       struct config_source top;
 
-       ret = -1;
-       if (f) {
-               struct config_source top;
+       top.u.file = f;
+       top.name = name;
+       top.path = path;
+       top.die_on_error = 1;
+       top.do_fgetc = config_file_fgetc;
+       top.do_ungetc = config_file_ungetc;
+       top.do_ftell = config_file_ftell;
 
-               top.u.file = f;
-               top.name = filename;
-               top.die_on_error = 1;
-               top.do_fgetc = config_file_fgetc;
-               top.do_ungetc = config_file_ungetc;
-               top.do_ftell = config_file_ftell;
+       return do_config_from(&top, fn, data);
+}
+
+static int git_config_from_stdin(config_fn_t fn, void *data)
+{
+       return do_config_from_file(fn, "<stdin>", NULL, stdin, data);
+}
 
-               ret = do_config_from(&top, fn, data);
+int git_config_from_file(config_fn_t fn, const char *filename, void *data)
+{
+       int ret = -1;
+       FILE *f;
 
+       f = fopen(filename, "r");
+       if (f) {
+               ret = do_config_from_file(fn, filename, filename, f, data);
                fclose(f);
        }
        return ret;
@@ -1066,6 +1065,7 @@ int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,
        top.u.buf.len = len;
        top.u.buf.pos = 0;
        top.name = name;
+       top.path = NULL;
        top.die_on_error = 0;
        top.do_fgetc = config_buf_fgetc;
        top.do_ungetc = config_buf_ungetc;
@@ -1174,8 +1174,7 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
 }
 
 int git_config_with_options(config_fn_t fn, void *data,
-                           const char *filename,
-                           const char *blob_ref,
+                           struct git_config_source *config_source,
                            int respect_includes)
 {
        char *repo_config = NULL;
@@ -1193,10 +1192,12 @@ int git_config_with_options(config_fn_t fn, void *data,
         * If we have a specific filename, use it. Otherwise, follow the
         * regular lookup sequence.
         */
-       if (filename)
-               return git_config_from_file(fn, filename, data);
-       else if (blob_ref)
-               return git_config_from_blob_ref(fn, blob_ref, data);
+       if (config_source && config_source->use_stdin)
+               return git_config_from_stdin(fn, data);
+       else if (config_source && config_source->file)
+               return git_config_from_file(fn, config_source->file, data);
+       else if (config_source && config_source->blob)
+               return git_config_from_blob_ref(fn, config_source->blob, data);
 
        repo_config = git_pathdup("config");
        ret = git_config_early(fn, data, repo_config);
@@ -1207,7 +1208,7 @@ int git_config_with_options(config_fn_t fn, void *data,
 
 int git_config(config_fn_t fn, void *data)
 {
-       return git_config_with_options(fn, data, NULL, NULL, 1);
+       return git_config_with_options(fn, data, NULL, 1);
 }
 
 /*
index 7d31fad241761e41de655de6f42ddfb8c87ea4f2..6069a4435008e02b5043927e11439aabf64c3e2d 100644 (file)
@@ -108,7 +108,6 @@ ifeq ($(uname_S),SunOS)
        NO_MKDTEMP = YesPlease
        NO_MKSTEMPS = YesPlease
        NO_REGEX = YesPlease
-       NO_FNMATCH_CASEFOLD = YesPlease
        NO_MSGFMT_EXTENDED_OPTIONS = YesPlease
        HAVE_DEV_TTY = YesPlease
        ifeq ($(uname_R),5.6)
@@ -259,7 +258,6 @@ ifeq ($(uname_S),IRIX)
        # issue, comment out the NO_MMAP statement.
        NO_MMAP = YesPlease
        NO_REGEX = YesPlease
-       NO_FNMATCH_CASEFOLD = YesPlease
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH = /usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
@@ -279,7 +277,6 @@ ifeq ($(uname_S),IRIX64)
        # issue, comment out the NO_MMAP statement.
        NO_MMAP = YesPlease
        NO_REGEX = YesPlease
-       NO_FNMATCH_CASEFOLD = YesPlease
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH = /usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
@@ -296,7 +293,6 @@ ifeq ($(uname_S),HP-UX)
        NO_UNSETENV = YesPlease
        NO_HSTRERROR = YesPlease
        NO_SYS_SELECT_H = YesPlease
-       NO_FNMATCH_CASEFOLD = YesPlease
        SNPRINTF_RETURNS_BOGUS = YesPlease
        NO_NSEC = YesPlease
        ifeq ($(uname_R),B.11.00)
@@ -327,7 +323,6 @@ ifeq ($(uname_S),Windows)
        NO_UNSETENV = YesPlease
        NO_STRCASESTR = YesPlease
        NO_STRLCPY = YesPlease
-       NO_FNMATCH = YesPlease
        NO_MEMMEM = YesPlease
        # NEEDS_LIBICONV = YesPlease
        NO_ICONV = YesPlease
@@ -389,13 +384,11 @@ ifeq ($(uname_S),Interix)
                NO_INET_NTOP = YesPlease
                NO_INET_PTON = YesPlease
                NO_SOCKADDR_STORAGE = YesPlease
-               NO_FNMATCH_CASEFOLD = YesPlease
        endif
        ifeq ($(uname_R),5.2)
                NO_INET_NTOP = YesPlease
                NO_INET_PTON = YesPlease
                NO_SOCKADDR_STORAGE = YesPlease
-               NO_FNMATCH_CASEFOLD = YesPlease
        endif
 endif
 ifeq ($(uname_S),Minix)
@@ -440,7 +433,6 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
        NO_D_TYPE_IN_DIRENT = YesPlease
        NO_HSTRERROR = YesPlease
        NO_STRCASESTR = YesPlease
-       NO_FNMATCH_CASEFOLD = YesPlease
        NO_MEMMEM = YesPlease
        NO_STRLCPY = YesPlease
        NO_SETENV = YesPlease
@@ -484,7 +476,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
        NO_UNSETENV = YesPlease
        NO_STRCASESTR = YesPlease
        NO_STRLCPY = YesPlease
-       NO_FNMATCH = YesPlease
        NO_MEMMEM = YesPlease
        NEEDS_LIBICONV = YesPlease
        NO_STRTOUMAX = YesPlease
@@ -538,7 +529,6 @@ ifeq ($(uname_S),QNX)
        EXPAT_NEEDS_XMLPARSE_H = YesPlease
        HAVE_STRINGS_H = YesPlease
        NEEDS_SOCKET = YesPlease
-       NO_FNMATCH_CASEFOLD = YesPlease
        NO_GETPAGESIZE = YesPlease
        NO_ICONV = YesPlease
        NO_MEMMEM = YesPlease
index 2f433939dc9d9001c7ace83bfeadf567eb90c30c..24ab7383aecf36e010f838d04b671903d1d8a79f 100644 (file)
@@ -901,34 +901,6 @@ GIT_CHECK_FUNC(strcasestr,
 [NO_STRCASESTR=YesPlease])
 GIT_CONF_SUBST([NO_STRCASESTR])
 #
-# Define NO_FNMATCH if you don't have fnmatch
-GIT_CHECK_FUNC(fnmatch,
-[NO_FNMATCH=],
-[NO_FNMATCH=YesPlease])
-GIT_CONF_SUBST([NO_FNMATCH])
-#
-# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
-# FNM_CASEFOLD GNU extension.
-AC_CACHE_CHECK([whether the fnmatch function supports the FNMATCH_CASEFOLD GNU extension],
- [ac_cv_c_excellent_fnmatch], [
-AC_EGREP_CPP(yippeeyeswehaveit,
-       AC_LANG_PROGRAM([
-#include <fnmatch.h>
-],
-[#ifdef FNM_CASEFOLD
-yippeeyeswehaveit
-#endif
-]),
-       [ac_cv_c_excellent_fnmatch=yes],
-       [ac_cv_c_excellent_fnmatch=no])
-])
-if test $ac_cv_c_excellent_fnmatch = yes; then
-       NO_FNMATCH_CASEFOLD=
-else
-       NO_FNMATCH_CASEFOLD=YesPlease
-fi
-GIT_CONF_SUBST([NO_FNMATCH_CASEFOLD])
-#
 # Define NO_MEMMEM if you don't have memmem.
 GIT_CHECK_FUNC(memmem,
 [NO_MEMMEM=],
index 9525343fcd34ce5009fcfd9b2bf2c6356282e259..87de809d23146c2cee818555028cf8a24dc6c908 100644 (file)
@@ -1221,14 +1221,20 @@ _git_difftool ()
        __git_complete_revlist_file
 }
 
+__git_fetch_recurse_submodules="yes on-demand no"
+
 __git_fetch_options="
        --quiet --verbose --append --upload-pack --force --keep --depth=
-       --tags --no-tags --all --prune --dry-run
+       --tags --no-tags --all --prune --dry-run --recurse-submodules=
 "
 
 _git_fetch ()
 {
        case "$cur" in
+       --recurse-submodules=*)
+               __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
+               return
+               ;;
        --*)
                __gitcomp "$__git_fetch_options"
                return
@@ -1583,6 +1589,10 @@ _git_pull ()
        __git_complete_strategy && return
 
        case "$cur" in
+       --recurse-submodules=*)
+               __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
+               return
+               ;;
        --*)
                __gitcomp "
                        --rebase --no-rebase
@@ -1595,6 +1605,8 @@ _git_pull ()
        __git_complete_remote_or_refspec
 }
 
+__git_push_recurse_submodules="check on-demand"
+
 _git_push ()
 {
        case "$prev" in
@@ -1607,10 +1619,15 @@ _git_push ()
                __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
                return
                ;;
+       --recurse-submodules=*)
+               __gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}"
+               return
+               ;;
        --*)
                __gitcomp "
                        --all --mirror --tags --dry-run --force --verbose
                        --receive-pack= --repo= --set-upstream
+                       --recurse-submodules=
                "
                return
                ;;
index 428cc1a9a1367e36c2739cb226a0ffdd2704ce82..dbe2abf27730e20fcbd692012e9dd07a2e70404f 100755 (executable)
@@ -96,8 +96,6 @@ sub scan_patches {
                next unless $id;
                if (m{^--- (?:a/(.+)|/dev/null)$}) {
                        $source = $1;
-               } elsif (/^--- /) {
-                       die "Cannot parse hunk source: $_\n";
                } elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) {
                        my $len = defined($2) ? $2 : 1;
                        push @{$sources->{$source}{$id}}, [$1, $len] if $len;
index 332aba784b8810120df8e1ddfafeb034a55337a3..5f4b2e3e160f60955e25f8b8fedf8c122dd5c73c 100755 (executable)
@@ -684,7 +684,8 @@ def do_export(parser):
                 peer = bzrlib.branch.Branch.open(peers[name],
                                                  possible_transports=transports)
                 try:
-                    peer.bzrdir.push_branch(branch, revision_id=revid)
+                    peer.bzrdir.push_branch(branch, revision_id=revid,
+                                            overwrite=force)
                 except bzrlib.errors.DivergedBranches:
                     print "error %s non-fast forward" % ref
                     continue
@@ -718,8 +719,32 @@ def do_capabilities(parser):
         print "*import-marks %s" % path
     print "*export-marks %s" % path
 
+    print "option"
     print
 
+class InvalidOptionValue(Exception):
+    pass
+
+def get_bool_option(val):
+    if val == 'true':
+        return True
+    elif val == 'false':
+        return False
+    else:
+        raise InvalidOptionValue()
+
+def do_option(parser):
+    global force
+    opt, val = parser[1:3]
+    try:
+        if opt == 'force':
+            force = get_bool_option(val)
+            print 'ok'
+        else:
+            print 'unsupported'
+    except InvalidOptionValue:
+        print "error '%s' is not a valid value for option '%s'" % (val, opt)
+
 def ref_is_valid(name):
     return not True in [c in name for c in '~^: \\']
 
@@ -882,6 +907,7 @@ def main(args):
     global is_tmp
     global branches, peers
     global transports
+    global force
 
     marks = None
     is_tmp = False
@@ -904,6 +930,7 @@ def main(args):
     branches = {}
     peers = {}
     transports = []
+    force = False
 
     if alias[5:] == url:
         is_tmp = True
@@ -936,6 +963,8 @@ def main(args):
             do_import(parser)
         elif parser.check('export'):
             do_export(parser)
+        elif parser.check('option'):
+            do_option(parser)
         else:
             die('unhandled command: %s' % line)
         sys.stdout.flush()
index 1e53ff9a584a302366dcbd647a2e27db3fd1b9fe..4f379c2ab499f2ca5556f844cbdcacb98fffa13c 100755 (executable)
@@ -66,13 +66,33 @@ test_expect_success 'pushing' '
        test_cmp expected actual
 '
 
+test_expect_success 'forced pushing' '
+       (
+       cd gitrepo &&
+       echo three-new >content &&
+       git commit -a --amend -m three-new &&
+       git push -f
+       ) &&
+
+       (
+       cd bzrrepo &&
+       # the forced update overwrites the bzr branch but not the bzr
+       # working directory (it tries to merge instead)
+       bzr revert
+       ) &&
+
+       echo three-new >expected &&
+       cat bzrrepo/content >actual &&
+       test_cmp expected actual
+'
+
 test_expect_success 'roundtrip' '
        (
        cd gitrepo &&
        git pull &&
        git log --format="%s" -1 origin/master >actual
        ) &&
-       echo three >expected &&
+       echo three-new >expected &&
        test_cmp expected actual &&
 
        (cd gitrepo && git push && git pull) &&
index 5d128a5da9a1afd3bf441f58e75d4f02a64509d5..a933b1e30c6fe82393f3df1446333386d9795b12 100755 (executable)
@@ -680,7 +680,7 @@ test_expect_success 'remote big push fetch first' '
        )
 '
 
-test_expect_failure 'remote big push force' '
+test_expect_success 'remote big push force' '
        test_when_finished "rm -rf hgrepo gitrepo*" &&
 
        setup_big_push
@@ -710,7 +710,7 @@ test_expect_failure 'remote big push force' '
        check_bookmark hgrepo new_bmark six
 '
 
-test_expect_failure 'remote big push dry-run' '
+test_expect_success 'remote big push dry-run' '
        test_when_finished "rm -rf hgrepo gitrepo*" &&
 
        setup_big_push
index 503e03906c5c7f921e4d67a53835f771ea695d0c..eba12556848e975cd6f1a55ae25760823e90cdc8 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -1056,11 +1056,6 @@ static void drop_privileges(struct credentials *cred)
        /* nothing */
 }
 
-static void daemonize(void)
-{
-       die("--detach not supported on this platform");
-}
-
 static struct credentials *prepare_credentials(const char *user_name,
     const char *group_name)
 {
@@ -1102,24 +1097,6 @@ static struct credentials *prepare_credentials(const char *user_name,
 
        return &c;
 }
-
-static void daemonize(void)
-{
-       switch (fork()) {
-               case 0:
-                       break;
-               case -1:
-                       die_errno("fork failed");
-               default:
-                       exit(0);
-       }
-       if (setsid() == -1)
-               die_errno("setsid failed");
-       close(0);
-       close(1);
-       close(2);
-       sanitize_stdfds();
-}
 #endif
 
 static void store_pid(const char *path)
@@ -1333,9 +1310,10 @@ int main(int argc, char **argv)
        if (inetd_mode || serve_mode)
                return execute();
 
-       if (detach)
-               daemonize();
-       else
+       if (detach) {
+               if (daemonize())
+                       die("--detach not supported on this platform");
+       } else
                sanitize_stdfds();
 
        if (pid_file)
diff --git a/date.c b/date.c
index 83b4166344b31ea615603acaeb95a873f2c05077..e1a2cee5688a64555d7820e8e02e3e86839c9641 100644 (file)
--- a/date.c
+++ b/date.c
@@ -184,8 +184,10 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
                tz = local_tzoffset(time);
 
        tm = time_to_tm(time, tz);
-       if (!tm)
-               return NULL;
+       if (!tm) {
+               tm = time_to_tm(0, 0);
+               tz = 0;
+       }
 
        strbuf_reset(&timebuf);
        if (mode == DATE_SHORT)
@@ -1113,3 +1115,20 @@ unsigned long approxidate_careful(const char *date, int *error_ret)
        gettimeofday(&tv, NULL);
        return approxidate_str(date, &tv, error_ret);
 }
+
+int date_overflows(unsigned long t)
+{
+       time_t sys;
+
+       /* If we overflowed our unsigned long, that's bad... */
+       if (t == ULONG_MAX)
+               return 1;
+
+       /*
+        * ...but we also are going to feed the result to system
+        * functions that expect time_t, which is often "signed long".
+        * Make sure that we fit into time_t, as well.
+        */
+       sys = t;
+       return t != sys || (t < 1) != (sys < 1);
+}
index 2eddc66bbd5cf37e4649e219a28c951ed134557c..044872935c30d84affb1955a7ae03c0986c90bda 100644 (file)
@@ -91,9 +91,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
        unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
                              ? CE_MATCH_RACY_IS_DIRTY : 0);
 
-       if (option & DIFF_SILENT_ON_REMOVED)
-               handle_deprecated_show_diff_q(&revs->diffopt);
-
        diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
 
        if (diff_unmerged_stage < 0)
@@ -125,7 +122,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                        dpath->path = (char *) &(dpath->parent[5]);
 
                        dpath->next = NULL;
-                       dpath->len = path_len;
                        memcpy(dpath->path, ce->name, path_len);
                        dpath->path[path_len] = '\0';
                        hashclr(dpath->sha1);
@@ -327,7 +323,6 @@ static int show_modified(struct rev_info *revs,
                p = xmalloc(combine_diff_path_size(2, pathlen));
                p->path = (char *) &p->parent[2];
                p->next = NULL;
-               p->len = pathlen;
                memcpy(p->path, new->name, pathlen);
                p->path[pathlen] = 0;
                p->mode = mode;
index 33e5982a1c61a5726580f40df0a07dadc7e2aaf1..8e10bff30e5269687e67866c2d3c66d62e3bb883 100644 (file)
@@ -186,7 +186,6 @@ void diff_no_index(struct rev_info *revs,
                   const char *prefix)
 {
        int i, prefixlen;
-       unsigned deprecated_show_diff_q_option_used = 0;
        const char *paths[2];
 
        diff_setup(&revs->diffopt);
@@ -194,10 +193,6 @@ void diff_no_index(struct rev_info *revs,
                int j;
                if (!strcmp(argv[i], "--no-index"))
                        i++;
-               else if (!strcmp(argv[i], "-q")) {
-                       deprecated_show_diff_q_option_used = 1;
-                       i++;
-               }
                else if (!strcmp(argv[i], "--"))
                        i++;
                else {
@@ -230,9 +225,6 @@ void diff_no_index(struct rev_info *revs,
        revs->max_count = -2;
        diff_setup_done(&revs->diffopt);
 
-       if (deprecated_show_diff_q_option_used)
-               handle_deprecated_show_diff_q(&revs->diffopt);
-
        setup_diff_pager(&revs->diffopt);
        DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
 
diff --git a/diff.c b/diff.c
index e8006666d8a528689157aed0e84d23a5477111be..9ae8116fcab890872a725121f37f69a277271783 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1361,11 +1361,7 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
 {
        struct diffstat_file *x;
        x = xcalloc(sizeof (*x), 1);
-       if (diffstat->nr == diffstat->alloc) {
-               diffstat->alloc = alloc_nr(diffstat->alloc);
-               diffstat->files = xrealloc(diffstat->files,
-                               diffstat->alloc * sizeof(x));
-       }
+       ALLOC_GROW(diffstat->files, diffstat->nr + 1, diffstat->alloc);
        diffstat->files[diffstat->nr++] = x;
        if (name_b) {
                x->from_name = xstrdup(name_a);
@@ -2845,8 +2841,9 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
                remove_tempfile_installed = 1;
        }
 
-       if (!one->sha1_valid ||
-           reuse_worktree_file(name, one->sha1, 1)) {
+       if (!S_ISGITLINK(one->mode) &&
+           (!one->sha1_valid ||
+            reuse_worktree_file(name, one->sha1, 1))) {
                struct stat st;
                if (lstat(name, &st) < 0) {
                        if (errno == ENOENT)
@@ -3599,14 +3596,6 @@ static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt)
        return 0;
 }
 
-/* Used only by "diff-files" and "diff --no-index" */
-void handle_deprecated_show_diff_q(struct diff_options *opt)
-{
-       warning("'diff -q' and 'diff-files -q' are deprecated.");
-       warning("Use 'diff --diff-filter=d' instead to ignore deleted filepairs.");
-       parse_diff_filter_opt("d", opt);
-}
-
 static void enable_patch_output(int *fmt) {
        *fmt &= ~DIFF_FORMAT_NO_OUTPUT;
        *fmt |= DIFF_FORMAT_PATCH;
@@ -3965,11 +3954,7 @@ struct diff_queue_struct diff_queued_diff;
 
 void diff_q(struct diff_queue_struct *queue, struct diff_filepair *dp)
 {
-       if (queue->alloc <= queue->nr) {
-               queue->alloc = alloc_nr(queue->alloc);
-               queue->queue = xrealloc(queue->queue,
-                                       sizeof(dp) * queue->alloc);
-       }
+       ALLOC_GROW(queue->queue, queue->nr + 1, queue->alloc);
        queue->queue[queue->nr++] = dp;
 }
 
diff --git a/diff.h b/diff.h
index ce123fa06fee6fb6e5e76d6a92ea8284a5bbbcf1..a24a767db78d8e864175cf342f03fc48e159e06e 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -198,7 +198,6 @@ extern int diff_root_tree_sha1(const unsigned char *new, const char *base,
 
 struct combine_diff_path {
        struct combine_diff_path *next;
-       int len;
        char *path;
        unsigned int mode;
        unsigned char sha1[20];
@@ -346,8 +345,6 @@ extern int parse_rename_score(const char **cp_p);
 
 extern long parse_algorithm_value(const char *value);
 
-extern void handle_deprecated_show_diff_q(struct diff_options *);
-
 extern int print_stat_summary(FILE *fp, int files,
                              int insertions, int deletions);
 extern void setup_diff_pager(struct diff_options *);
index fe7f1f4647a16a5882cc4c1e63738c7faa4bc677..97dd3d0095723c194288db0da1b9cfbf400e7e26 100644 (file)
@@ -57,12 +57,6 @@ static void prepare_order(const char *orderfile)
        }
 }
 
-struct pair_order {
-       struct diff_filepair *pair;
-       int orig_order;
-       int order;
-};
-
 static int match_order(const char *path)
 {
        int i;
@@ -73,7 +67,7 @@ static int match_order(const char *path)
                strbuf_addstr(&p, path);
                while (p.buf[0]) {
                        char *cp;
-                       if (!fnmatch(order[i], p.buf, 0))
+                       if (!wildmatch(order[i], p.buf, 0, NULL))
                                return i;
                        cp = strrchr(p.buf, '/');
                        if (!cp)
@@ -84,35 +78,54 @@ static int match_order(const char *path)
        return order_cnt;
 }
 
-static int compare_pair_order(const void *a_, const void *b_)
+static int compare_objs_order(const void *a_, const void *b_)
 {
-       struct pair_order const *a, *b;
-       a = (struct pair_order const *)a_;
-       b = (struct pair_order const *)b_;
+       struct obj_order const *a, *b;
+       a = (struct obj_order const *)a_;
+       b = (struct obj_order const *)b_;
        if (a->order != b->order)
                return a->order - b->order;
        return a->orig_order - b->orig_order;
 }
 
+void order_objects(const char *orderfile, obj_path_fn_t obj_path,
+                  struct obj_order *objs, int nr)
+{
+       int i;
+
+       if (!nr)
+               return;
+
+       prepare_order(orderfile);
+       for (i = 0; i < nr; i++) {
+               objs[i].orig_order = i;
+               objs[i].order = match_order(obj_path(objs[i].obj));
+       }
+       qsort(objs, nr, sizeof(*objs), compare_objs_order);
+}
+
+static const char *pair_pathtwo(void *obj)
+{
+       struct diff_filepair *pair = (struct diff_filepair *)obj;
+
+       return pair->two->path;
+}
+
 void diffcore_order(const char *orderfile)
 {
        struct diff_queue_struct *q = &diff_queued_diff;
-       struct pair_order *o;
+       struct obj_order *o;
        int i;
 
        if (!q->nr)
                return;
 
        o = xmalloc(sizeof(*o) * q->nr);
-       prepare_order(orderfile);
-       for (i = 0; i < q->nr; i++) {
-               o[i].pair = q->queue[i];
-               o[i].orig_order = i;
-               o[i].order = match_order(o[i].pair->two->path);
-       }
-       qsort(o, q->nr, sizeof(*o), compare_pair_order);
        for (i = 0; i < q->nr; i++)
-               q->queue[i] = o[i].pair;
+               o[i].obj = q->queue[i];
+       order_objects(orderfile, pair_pathtwo, o, q->nr);
+       for (i = 0; i < q->nr; i++)
+               q->queue[i] = o[i].obj;
        free(o);
        return;
 }
index 9b4f068eb390d9b9d53bdd91f8983432f6ec4563..749a35d2c2ab3271c6503a19271a5be6a6e97b4d 100644 (file)
@@ -38,11 +38,7 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
        if (!insert_ok)
                return NULL;
        /* insert to make it at "first" */
-       if (rename_dst_alloc <= rename_dst_nr) {
-               rename_dst_alloc = alloc_nr(rename_dst_alloc);
-               rename_dst = xrealloc(rename_dst,
-                                     rename_dst_alloc * sizeof(*rename_dst));
-       }
+       ALLOC_GROW(rename_dst, rename_dst_nr + 1, rename_dst_alloc);
        rename_dst_nr++;
        if (first < rename_dst_nr)
                memmove(rename_dst + first + 1, rename_dst + first,
@@ -82,11 +78,7 @@ static struct diff_rename_src *register_rename_src(struct diff_filepair *p)
        }
 
        /* insert to make it at "first" */
-       if (rename_src_alloc <= rename_src_nr) {
-               rename_src_alloc = alloc_nr(rename_src_alloc);
-               rename_src = xrealloc(rename_src,
-                                     rename_src_alloc * sizeof(*rename_src));
-       }
+       ALLOC_GROW(rename_src, rename_src_nr + 1, rename_src_alloc);
        rename_src_nr++;
        if (first < rename_src_nr)
                memmove(rename_src + first + 1, rename_src + first,
@@ -522,7 +514,7 @@ void diffcore_rename(struct diff_options *options)
 
        if (options->show_rename_progress) {
                progress = start_progress_delay(
-                               "Performing inexact rename detection",
+                               _("Performing inexact rename detection"),
                                rename_dst_nr * rename_src_nr, 50, 1);
        }
 
index 1315cfd4ef0fbe0aeb0cae9a14bf09fd53212124..c876dac71a585abb1e138444eb28258e3bf6d7e8 100644 (file)
@@ -46,7 +46,7 @@ struct diff_filespec {
        unsigned is_stdin : 1;
        unsigned has_more_entries : 1; /* only appear in combined diff */
        /* data should be considered "binary"; -1 means "don't know yet" */
-       int is_binary : 2;
+       signed int is_binary : 2;
        struct userdiff_driver *driver;
 };
 
@@ -111,6 +111,20 @@ extern void diffcore_merge_broken(void);
 extern void diffcore_pickaxe(struct diff_options *);
 extern void diffcore_order(const char *orderfile);
 
+/* low-level interface to diffcore_order */
+struct obj_order {
+       void *obj;      /* setup by caller */
+
+       /* setup/used by order_objects() */
+       int orig_order;
+       int order;
+};
+
+typedef const char *(*obj_path_fn_t)(void *obj);
+
+void order_objects(const char *orderfile, obj_path_fn_t obj_path,
+                  struct obj_order *objs, int nr);
+
 #define DIFF_DEBUG 0
 #if DIFF_DEBUG
 void diff_debug_filespec(struct diff_filespec *, int, const char *);
diff --git a/dir.c b/dir.c
index 98bb50fbabb69d25443df8ca4d29e11dea746a60..99f53033ba174301437c65b1dfa8f8cceb74f517 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -49,7 +49,9 @@ int strncmp_icase(const char *a, const char *b, size_t count)
 
 int fnmatch_icase(const char *pattern, const char *string, int flags)
 {
-       return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
+       return wildmatch(pattern, string,
+                        flags | (ignore_case ? WM_CASEFOLD : 0),
+                        NULL);
 }
 
 inline int git_fnmatch(const struct pathspec_item *item,
@@ -58,7 +60,7 @@ inline int git_fnmatch(const struct pathspec_item *item,
 {
        if (prefix > 0) {
                if (ps_strncmp(item, pattern, string, prefix))
-                       return FNM_NOMATCH;
+                       return WM_NOMATCH;
                pattern += prefix;
                string += prefix;
        }
@@ -76,8 +78,9 @@ inline int git_fnmatch(const struct pathspec_item *item,
                                 NULL);
        else
                /* wildmatch has not learned no FNM_PATHNAME mode yet */
-               return fnmatch(pattern, string,
-                              item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
+               return wildmatch(pattern, string,
+                                item->magic & PATHSPEC_ICASE ? WM_CASEFOLD : 0,
+                                NULL);
 }
 
 static int fnmatch_icase_mem(const char *pattern, int patternlen,
@@ -503,6 +506,25 @@ void clear_exclude_list(struct exclude_list *el)
        el->filebuf = NULL;
 }
 
+static void trim_trailing_spaces(char *buf)
+{
+       int i, last_space = -1, nr_spaces, len = strlen(buf);
+       for (i = 0; i < len; i++)
+               if (buf[i] == '\\')
+                       i++;
+               else if (buf[i] == ' ') {
+                       if (last_space == -1) {
+                               last_space = i;
+                               nr_spaces = 1;
+                       } else
+                               nr_spaces++;
+               } else
+                       last_space = -1;
+
+       if (last_space != -1 && last_space + nr_spaces == len)
+               buf[last_space] = '\0';
+}
+
 int add_excludes_from_file_to_list(const char *fname,
                                   const char *base,
                                   int baselen,
@@ -554,6 +576,7 @@ int add_excludes_from_file_to_list(const char *fname,
                if (buf[i] == '\n') {
                        if (entry != buf + i && entry[0] != '#') {
                                buf[i - (i && buf[i-1] == '\r')] = 0;
+                               trim_trailing_spaces(entry);
                                add_exclude(entry, base, baselen, el, lineno);
                        }
                        lineno++;
@@ -1341,10 +1364,7 @@ static struct path_simplify *create_simplify(const char **pathspec)
 
        for (nr = 0 ; ; nr++) {
                const char *match;
-               if (nr >= alloc) {
-                       alloc = alloc_nr(alloc);
-                       simplify = xrealloc(simplify, alloc * sizeof(*simplify));
-               }
+               ALLOC_GROW(simplify, nr + 1, alloc);
                match = *pathspec++;
                if (!match)
                        break;
index 4a3437d8a61256029655f25c76256f27a6189248..c3c860603da817b75d73bc446d03944e1963e874 100644 (file)
@@ -45,7 +45,7 @@ const char *editor_program;
 const char *askpass_program;
 const char *excludes_file;
 enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
-int read_replace_refs = 1; /* NEEDSWORK: rename to use_replace_refs */
+int check_replace_refs = 1;
 enum eol core_eol = EOL_UNSET;
 enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
@@ -147,7 +147,7 @@ static void setup_git_env(void)
        if (!git_graft_file)
                git_graft_file = git_pathdup("info/grafts");
        if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
-               read_replace_refs = 0;
+               check_replace_refs = 0;
        namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
        namespace_len = strlen(namespace);
        shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
diff --git a/fsck.c b/fsck.c
index 99c049767484288f273f036b57683df04c1ef0df..64bf279fd7e42da1921a65d725007c52c7ddc5fb 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -245,6 +245,8 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
 
 static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
 {
+       char *end;
+
        if (**ident == '<')
                return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
        *ident += strcspn(*ident, "<>\n");
@@ -264,10 +266,11 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
        (*ident)++;
        if (**ident == '0' && (*ident)[1] != ' ')
                return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
-       *ident += strspn(*ident, "0123456789");
-       if (**ident != ' ')
+       if (date_overflows(strtoul(*ident, &end, 10)))
+               return error_func(obj, FSCK_ERROR, "invalid author/committer line - date causes integer overflow");
+       if (end == *ident || *end != ' ')
                return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
-       (*ident)++;
+       *ident = end + 1;
        if ((**ident != '+' && **ident != '-') ||
            !isdigit((*ident)[1]) ||
            !isdigit((*ident)[2]) ||
@@ -287,9 +290,6 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
        int parents = 0;
        int err;
 
-       if (commit->date == ULONG_MAX)
-               return error_func(&commit->object, FSCK_ERROR, "invalid author/committer line");
-
        if (memcmp(buffer, "tree ", 5))
                return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line");
        if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
index 24bb1ab9929d2cbf117051ed0e4edeb37b0efaea..d3bca1261110014b2b969f6d2fc1d73dca424204 100755 (executable)
@@ -58,6 +58,9 @@
                Term::ReadKey->import;
                $use_readkey = 1;
        };
+       if (!$use_readkey) {
+               print STDERR "missing Term::ReadKey, disabling interactive.singlekey\n";
+       }
        eval {
                require Term::Cap;
                my $termcap = Term::Cap->Tgetent;
index 73b4c14d4f631b811a20392684a87c6b97daedc7..af4d04c3be87423d3c9ef6078766fff679411766 100755 (executable)
@@ -365,7 +365,7 @@ bisect_reset() {
        }
        case "$#" in
        0) branch=$(cat "$GIT_DIR/BISECT_START") ;;
-       1) git rev-parse --quiet --verify "$1^{commit}" > /dev/null || {
+       1) git rev-parse --quiet --verify "$1^{commit}" >/dev/null || {
                        invalid="$1"
                        die "$(eval_gettext "'\$invalid' is not a valid commit")"
                }
@@ -458,13 +458,13 @@ exit code \$res from '\$command' is < 0 or >= 128" >&2
                fi
 
                # We have to use a subshell because "bisect_state" can exit.
-               ( bisect_state $state > "$GIT_DIR/BISECT_RUN" )
+               ( bisect_state $state >"$GIT_DIR/BISECT_RUN" )
                res=$?
 
                cat "$GIT_DIR/BISECT_RUN"
 
                if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \
-                       > /dev/null
+                       >/dev/null
                then
                        gettextln "bisect run cannot continue any more" >&2
                        exit $res
@@ -477,7 +477,7 @@ exit code \$res from '\$command' is < 0 or >= 128" >&2
                        exit $res
                fi
 
-               if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null
+               if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" >/dev/null
                then
                        gettextln "bisect run success"
                        exit 0;
index 614a5e95bd298097111efa54bbf190056c701c57..585ef8a79bd9fa66a34a840eae30658894a213f1 100644 (file)
 #include <sys/time.h>
 #include <time.h>
 #include <signal.h>
-#ifndef USE_WILDMATCH
-#include <fnmatch.h>
-#endif
 #include <assert.h>
 #include <regex.h>
 #include <utime.h>
@@ -304,16 +301,7 @@ extern char *gitbasename(char *);
 
 #include "compat/bswap.h"
 
-#ifdef USE_WILDMATCH
 #include "wildmatch.h"
-#define FNM_PATHNAME WM_PATHNAME
-#define FNM_CASEFOLD WM_CASEFOLD
-#define FNM_NOMATCH  WM_NOMATCH
-static inline int fnmatch(const char *pattern, const char *string, int flags)
-{
-       return wildmatch(pattern, string, flags, NULL);
-}
-#endif
 
 /* General helper functions */
 extern void vreportf(const char *prefix, const char *err, va_list params);
@@ -351,9 +339,7 @@ extern void set_error_routine(void (*routine)(const char *err, va_list params));
 extern void set_die_is_recursing_routine(int (*routine)(void));
 
 extern int starts_with(const char *str, const char *prefix);
-extern int prefixcmp(const char *str, const char *prefix);
 extern int ends_with(const char *str, const char *suffix);
-extern int suffixcmp(const char *str, const char *suffix);
 
 static inline const char *skip_prefix(const char *str, const char *prefix)
 {
index e57d3d1295a5ba0a9c02c19df512c909a0631baa..18ca61e8d0493bde9c21ed337043bc72fa5c73a7 100755 (executable)
@@ -39,24 +39,10 @@ sub usage
 
 sub find_worktree
 {
-       my ($repo) = @_;
-
        # Git->repository->wc_path() does not honor changes to the working
        # tree location made by $ENV{GIT_WORK_TREE} or the 'core.worktree'
        # config variable.
-       my $worktree;
-       my $env_worktree = $ENV{GIT_WORK_TREE};
-       my $core_worktree = Git::config('core.worktree');
-
-       if (defined($env_worktree) and (length($env_worktree) > 0)) {
-               $worktree = $env_worktree;
-       } elsif (defined($core_worktree) and (length($core_worktree) > 0)) {
-               $worktree = $core_worktree;
-       } else {
-               $worktree = $repo->wc_path();
-       }
-
-       return $worktree;
+       return Git::command_oneline('rev-parse', '--show-toplevel');
 }
 
 sub print_tool_help
@@ -418,7 +404,7 @@ sub dir_diff
        my $rc;
        my $error = 0;
        my $repo = Git->repository();
-       my $workdir = find_worktree($repo);
+       my $workdir = find_worktree();
        my ($a, $b, $tmpdir, @worktree) =
                setup_dir_diff($repo, $workdir, $symlinks);
 
index 6d2f282d32212b605a1237bae224ecbba05cacd1..1c006a0518e247d58759df98602f6dae3935caf6 100755 (executable)
@@ -15,6 +15,8 @@ test -z "$refspec" && prefix="refs"
 
 export GIT_DIR="$url/.git"
 
+force=
+
 mkdir -p "$dir"
 
 if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS"
@@ -39,6 +41,7 @@ do
                fi
                test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags"
                test -n "$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE" && echo "no-private-update"
+               echo 'option'
                echo
                ;;
        list)
@@ -93,6 +96,7 @@ do
                before=$(git for-each-ref --format=' %(refname) %(objectname) ')
 
                git fast-import \
+                       ${force:+--force} \
                        ${testgitmarks:+"--import-marks=$testgitmarks"} \
                        ${testgitmarks:+"--export-marks=$testgitmarks"} \
                        --quiet
@@ -115,6 +119,20 @@ do
 
                echo
                ;;
+       option\ *)
+               read cmd opt val <<-EOF
+               $line
+               EOF
+               case $opt in
+               force)
+                       test $val = "true" && force="true" || force=
+                       echo "ok"
+                       ;;
+               *)
+                       echo "unsupported"
+                       ;;
+               esac
+               ;;
        '')
                exit
                ;;
index a33f68d27c0e1d482562373e6fd299da5dd9361a..6135cfa9127c1da094df59236f926c01721ae58b 100755 (executable)
@@ -9,7 +9,7 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
    or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
-   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
diff --git a/git.c b/git.c
index 7cf2953eff47ca91b9a134e2e810fea1fc53e386..9efd1a3ec1f2af63fe575f9c755dff685d9b1e51 100644 (file)
--- a/git.c
+++ b/git.c
@@ -78,7 +78,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        if (envchanged)
                                *envchanged = 1;
                } else if (!strcmp(cmd, "--no-replace-objects")) {
-                       read_replace_refs = 0;
+                       check_replace_refs = 0;
                        setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1);
                        if (envchanged)
                                *envchanged = 1;
index 3bc0f0b5ca0995910e0e517b545b5fb9af626a8b..79057b7d0e4f6c76a9d9853be14bbef60fa9c1c0 100755 (executable)
@@ -7094,7 +7094,7 @@ sub git_blob {
        git_print_page_path($file_name, "blob", $hash_base);
        print "<div class=\"page_body\">\n";
        if ($mimetype =~ m!^image/!) {
-               print qq!<img type="!.esc_attr($mimetype).qq!"!;
+               print qq!<img class="blob" type="!.esc_attr($mimetype).qq!"!;
                if ($file_name) {
                        print qq! alt="!.esc_attr($file_name).qq!" title="!.esc_attr($file_name).qq!"!;
                }
index 3b4d83382306772ac0b62743b0e23094f3d9f257..3212601032622fef063f06066bd7131061de36d9 100644 (file)
@@ -32,6 +32,11 @@ img.avatar {
        vertical-align: middle;
 }
 
+img.blob {
+       max-height: 100%;
+       max-width: 100%;
+}
+
 a.list img.avatar {
        border-style: none;
 }
diff --git a/help.c b/help.c
index df7d16d7ce52ce9b9f274db92b24aa64bac56ebf..b266b09320c067221eb4fffa56e4778d5f8b3a9e 100644 (file)
--- a/help.c
+++ b/help.c
@@ -78,8 +78,7 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
        cmds->cnt = cj;
 }
 
-static void pretty_print_string_list(struct cmdnames *cmds,
-                                    unsigned int colopts)
+static void pretty_print_cmdnames(struct cmdnames *cmds, unsigned int colopts)
 {
        struct string_list list = STRING_LIST_INIT_NODUP;
        struct column_options copts;
@@ -209,14 +208,14 @@ void list_commands(unsigned int colopts,
                const char *exec_path = git_exec_path();
                printf_ln(_("available git commands in '%s'"), exec_path);
                putchar('\n');
-               pretty_print_string_list(main_cmds, colopts);
+               pretty_print_cmdnames(main_cmds, colopts);
                putchar('\n');
        }
 
        if (other_cmds->cnt) {
                printf_ln(_("git commands available from elsewhere on your $PATH"));
                putchar('\n');
-               pretty_print_string_list(other_cmds, colopts);
+               pretty_print_cmdnames(other_cmds, colopts);
                putchar('\n');
        }
 }
diff --git a/http.c b/http.c
index 70eaa26e88cbcfa62e7d5e967b4e519432319210..94e1afdee7890825dfda0946b999f524265603fc 100644 (file)
--- a/http.c
+++ b/http.c
@@ -880,6 +880,20 @@ int handle_curl_result(struct slot_results *results)
        }
 }
 
+int run_one_slot(struct active_request_slot *slot,
+                struct slot_results *results)
+{
+       slot->results = results;
+       if (!start_active_slot(slot)) {
+               snprintf(curl_errorstr, sizeof(curl_errorstr),
+                        "failed to start HTTP request");
+               return HTTP_START_FAILED;
+       }
+
+       run_active_slot(slot);
+       return handle_curl_result(results);
+}
+
 static CURLcode curlinfo_strbuf(CURL *curl, CURLINFO info, struct strbuf *buf)
 {
        char *ptr;
@@ -907,7 +921,6 @@ static int http_request(const char *url,
        int ret;
 
        slot = get_active_slot();
-       slot->results = &results;
        curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
 
        if (result == NULL) {
@@ -942,14 +955,7 @@ static int http_request(const char *url,
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
-       if (start_active_slot(slot)) {
-               run_active_slot(slot);
-               ret = handle_curl_result(&results);
-       } else {
-               snprintf(curl_errorstr, sizeof(curl_errorstr),
-                        "failed to start HTTP request");
-               ret = HTTP_START_FAILED;
-       }
+       ret = run_one_slot(slot, &results);
 
        if (options && options->content_type)
                curlinfo_strbuf(slot->curl, CURLINFO_CONTENT_TYPE,
@@ -1384,7 +1390,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
        unsigned char *sha1)
 {
        char *hex = sha1_to_hex(sha1);
-       char *filename;
+       const char *filename;
        char prevfile[PATH_MAX];
        int prevlocal;
        char prev_buf[PREV_BUF_SIZE];
diff --git a/http.h b/http.h
index cd37d5881cb0e63e52bd33d0b49bed49645340f5..a82888445e9f04acfe27e36b1f274ffb9659cddf 100644 (file)
--- a/http.h
+++ b/http.h
@@ -90,6 +90,15 @@ extern void finish_active_slot(struct active_request_slot *slot);
 extern void finish_all_active_slots(void);
 extern int handle_curl_result(struct slot_results *results);
 
+/*
+ * This will run one slot to completion in a blocking manner, similar to how
+ * curl_easy_perform would work (but we don't want to use that, because
+ * we do not want to intermingle calls to curl_multi and curl_easy).
+ *
+ */
+int run_one_slot(struct active_request_slot *slot,
+                struct slot_results *results);
+
 #ifdef USE_CURL_MULTI
 extern void fill_active_slots(void);
 extern void add_fill_function(void *data, int (*fill)(void *));
index 08970bf46e49f6447ada24e81e5792ea9f92f419..5ce217d5eba33a54419ac8b29223cc16aa1f905e 100644 (file)
@@ -100,7 +100,7 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
 
        if (starts_with(refname, "refs/replace/")) {
                unsigned char original_sha1[20];
-               if (!read_replace_refs)
+               if (!check_replace_refs)
                        return 0;
                if (get_sha1_hex(refname + 13, original_sha1)) {
                        warning("invalid replace ref %s", refname);
index 2975dcd581024cd483953b47636466b79c95bafe..4aa7023903374aa3ccea23d5fc9ae82c9c67bca7 100644 (file)
@@ -75,7 +75,7 @@ static int notes_rewrite_config(const char *k, const char *v, void *cb)
                return 0;
        } else if (!c->mode_from_env && !strcmp(k, "notes.rewritemode")) {
                if (!v)
-                       config_error_nonbool(k);
+                       return config_error_nonbool(k);
                c->combine = parse_combine_notes_fn(v);
                if (!c->combine) {
                        error(_("Bad notes.rewriteMode value: '%s'"), v);
index 584f7acb36b68d17678b3fd6251105241794ea48..57a0890a87b66ea493337409606e57fd44d29f90 100644 (file)
--- a/object.c
+++ b/object.c
@@ -43,14 +43,32 @@ int type_from_string(const char *str)
        die("invalid object type \"%s\"", str);
 }
 
+/*
+ * Return a numerical hash value between 0 and n-1 for the object with
+ * the specified sha1.  n must be a power of 2.  Please note that the
+ * return value is *not* consistent across computer architectures.
+ */
 static unsigned int hash_obj(const unsigned char *sha1, unsigned int n)
 {
        unsigned int hash;
+
+       /*
+        * Since the sha1 is essentially random, we just take the
+        * required number of bits directly from the first
+        * sizeof(unsigned int) bytes of sha1.  First we have to copy
+        * the bytes into a properly aligned integer.  If we cared
+        * about getting consistent results across architectures, we
+        * would have to call ntohl() here, too.
+        */
        memcpy(&hash, sha1, sizeof(unsigned int));
-       /* Assumes power-of-2 hash sizes in grow_object_hash */
        return hash & (n - 1);
 }
 
+/*
+ * Insert obj into the hash table hash, which has length size (which
+ * must be a power of 2).  On collisions, simply overflow to the next
+ * empty bucket.
+ */
 static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
 {
        unsigned int j = hash_obj(obj->sha1, size);
@@ -63,6 +81,10 @@ static void insert_obj_hash(struct object *obj, struct object **hash, unsigned i
        hash[j] = obj;
 }
 
+/*
+ * Look up the record for the given sha1 in the hash map stored in
+ * obj_hash.  Return NULL if it was not found.
+ */
 struct object *lookup_object(const unsigned char *sha1)
 {
        unsigned int i, first;
@@ -92,6 +114,11 @@ struct object *lookup_object(const unsigned char *sha1)
        return obj;
 }
 
+/*
+ * Increase the size of the hash map stored in obj_hash to the next
+ * power of 2 (but at least 32).  Copy the existing values to the new
+ * hash map.
+ */
 static void grow_object_hash(void)
 {
        int i;
index dc5df8ce1d9579a28477f91300aa7a49f37ad4e4..732bf4d7e7012ce56045ec52404ac92b077305a6 100644 (file)
--- a/object.h
+++ b/object.h
@@ -42,7 +42,14 @@ struct object {
 extern const char *typename(unsigned int type);
 extern int type_from_string(const char *str);
 
+/*
+ * Return the current number of buckets in the object hashmap.
+ */
 extern unsigned int get_max_object_index(void);
+
+/*
+ * Return the object from the specified bucket in the object hashmap.
+ */
 extern struct object *get_indexed_object(unsigned int);
 
 /*
index bc8a28fdd71ae1476002d26adec64f54841f5cba..bf81b923610fe2473655560cd111adb3061673d9 100644 (file)
@@ -83,10 +83,7 @@ static struct patch_id *add_commit(struct commit *commit,
        ent = &bucket->bucket[bucket->nr++];
        hashcpy(ent->patch_id, sha1);
 
-       if (ids->alloc <= ids->nr) {
-               ids->alloc = alloc_nr(ids->nr);
-               ids->table = xrealloc(ids->table, sizeof(ent) * ids->alloc);
-       }
+       ALLOC_GROW(ids->table, ids->nr + 1, ids->alloc);
        if (pos < ids->nr)
                memmove(ids->table + pos + 1, ids->table + pos,
                        sizeof(ent) * (ids->nr - pos));
index e10263f2b2ce90f08ed082022ef16d13f1c7770a..0b9d59e8fa43dca6b580d9436712a7d09f27472b 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -1075,7 +1075,7 @@ msgstr "Votre branche est basée sur '%s', mais la branche amont a disparu.\n"
 
 #: remote.c:1875
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
-msgstr "  (utilisez \"git branch -unset-upstream\" pour corriger)\n"
+msgstr "  (utilisez \"git branch --unset-upstream\" pour corriger)\n"
 
 #: remote.c:1878
 #, c-format
@@ -3266,7 +3266,7 @@ msgstr "    git branch -d %s\n"
 #: builtin/branch.c:1027
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
-msgstr "    git branch -set-upstream-to %s\n"
+msgstr "    git branch --set-upstream-to %s\n"
 
 #: builtin/bundle.c:47
 #, c-format
index 87db08bd749e74fef0b2372ab71ea98baf57b322..6e266ddf2749ab1b2388f72e3a1101e98fa656cc 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -397,12 +397,18 @@ static const char *show_ident_date(const struct ident_split *ident,
                                   enum date_mode mode)
 {
        unsigned long date = 0;
-       int tz = 0;
+       long tz = 0;
 
        if (ident->date_begin && ident->date_end)
                date = strtoul(ident->date_begin, NULL, 10);
-       if (ident->tz_begin && ident->tz_end)
-               tz = strtol(ident->tz_begin, NULL, 10);
+       if (date_overflows(date))
+               date = 0;
+       else {
+               if (ident->tz_begin && ident->tz_end)
+                       tz = strtol(ident->tz_begin, NULL, 10);
+               if (tz >= INT_MAX || tz <= INT_MIN)
+                       tz = 0;
+       }
        return show_date(date, tz, mode);
 }
 
index 10652b174d1ccfb941b3d4122a882f1af3323084..261314ef3cd60662300129df98afff7ea2a1673c 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "git-compat-util.h"
+#include "gettext.h"
 #include "progress.h"
 #include "strbuf.h"
 
@@ -220,7 +221,7 @@ struct progress *start_progress(const char *title, unsigned total)
 
 void stop_progress(struct progress **p_progress)
 {
-       stop_progress_msg(p_progress, "done");
+       stop_progress_msg(p_progress, _("done"));
 }
 
 void stop_progress_msg(struct progress **p_progress, const char *msg)
index fb440b4d9d1aa002ebc760e4fa4e0f0d028fd868..ba13353b377d4f27b9ff6cf1b85811fcca61e224 100644 (file)
@@ -990,11 +990,7 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
        }
 
        /* Make sure the array is big enough .. */
-       if (istate->cache_nr == istate->cache_alloc) {
-               istate->cache_alloc = alloc_nr(istate->cache_alloc);
-               istate->cache = xrealloc(istate->cache,
-                                       istate->cache_alloc * sizeof(*istate->cache));
-       }
+       ALLOC_GROW(istate->cache, istate->cache_nr + 1, istate->cache_alloc);
 
        /* Add it in.. */
        istate->cache_nr++;
@@ -1220,6 +1216,42 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
 
 #define INDEX_FORMAT_DEFAULT 3
 
+static int index_format_config(const char *var, const char *value, void *cb)
+{
+       unsigned int *version = cb;
+       if (!strcmp(var, "index.version")) {
+               *version = git_config_int(var, value);
+               return 0;
+       }
+       return 1;
+}
+
+static unsigned int get_index_format_default(void)
+{
+       char *envversion = getenv("GIT_INDEX_VERSION");
+       char *endp;
+       unsigned int version = INDEX_FORMAT_DEFAULT;
+
+       if (!envversion) {
+               git_config(index_format_config, &version);
+               if (version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
+                       warning(_("index.version set, but the value is invalid.\n"
+                                 "Using version %i"), INDEX_FORMAT_DEFAULT);
+                       return INDEX_FORMAT_DEFAULT;
+               }
+               return version;
+       }
+
+       version = strtoul(envversion, &endp, 10);
+       if (*endp ||
+           version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
+               warning(_("GIT_INDEX_VERSION set, but the value is invalid.\n"
+                         "Using version %i"), INDEX_FORMAT_DEFAULT);
+               version = INDEX_FORMAT_DEFAULT;
+       }
+       return version;
+}
+
 /*
  * dev/ino/uid/gid/size are also just tracked to the low 32 bits
  * Again - this is just a (very strong in practice) heuristic that
@@ -1776,7 +1808,7 @@ int write_index(struct index_state *istate, int newfd)
        }
 
        if (!istate->version)
-               istate->version = INDEX_FORMAT_DEFAULT;
+               istate->version = get_index_format_default();
 
        /* demote version 3 to version 2 when the latter suffices */
        if (istate->version == 3 || istate->version == 2)
index b2fbdb2392f80a531d5f9a21630a036d45c0a827..2899729a8cbec4766182a1562c0c96d643de3a71 100644 (file)
@@ -26,11 +26,7 @@ static int read_one_reflog(unsigned char *osha1, unsigned char *nsha1,
        struct complete_reflogs *array = cb_data;
        struct reflog_info *item;
 
-       if (array->nr >= array->alloc) {
-               array->alloc = alloc_nr(array->nr + 1);
-               array->items = xrealloc(array->items, array->alloc *
-                       sizeof(struct reflog_info));
-       }
+       ALLOC_GROW(array->items, array->nr + 1, array->alloc);
        item = array->items + array->nr;
        memcpy(item->osha1, osha1, 20);
        memcpy(item->nsha1, nsha1, 20);
@@ -114,11 +110,7 @@ static void add_commit_info(struct commit *commit, void *util,
                struct commit_info_lifo *lifo)
 {
        struct commit_info *info;
-       if (lifo->nr >= lifo->alloc) {
-               lifo->alloc = alloc_nr(lifo->nr + 1);
-               lifo->items = xrealloc(lifo->items,
-                       lifo->alloc * sizeof(struct commit_info));
-       }
+       ALLOC_GROW(lifo->items, lifo->nr + 1, lifo->alloc);
        info = lifo->items + lifo->nr;
        info->commit = commit;
        info->util = util;
diff --git a/refs.c b/refs.c
index 89228e23732ef7e2e83a2e84e82ffb5bd7afec3f..f89d589182fcfc595ff1d60f01ffe25e1ea81579 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1477,7 +1477,7 @@ static int filter_refs(const char *refname, const unsigned char *sha1, int flags
                       void *data)
 {
        struct ref_filter *filter = (struct ref_filter *)data;
-       if (fnmatch(filter->pattern, refname, 0))
+       if (wildmatch(filter->pattern, refname, 0, NULL))
                return 0;
        return filter->fn(refname, sha1, flags, filter->cb_data);
 }
index 10cb0114eafdfd9760b3fdb3c0217d801195ba13..52c2d96ce6183ca8b3498794304fa8dc98f8f42a 100644 (file)
@@ -423,11 +423,8 @@ static int run_slot(struct active_request_slot *slot,
        if (!results)
                results = &results_buf;
 
-       slot->results = results;
-       slot->curl_result = curl_easy_perform(slot->curl);
-       finish_active_slot(slot);
+       err = run_one_slot(slot, results);
 
-       err = handle_curl_result(results);
        if (err != HTTP_OK && err != HTTP_REAUTH) {
                error("RPC failed; result=%d, HTTP code = %ld",
                      results->curl_result, results->http_code);
index e41251ee77af1426dd26d4b13ee61a39cffccdeb..5f63d55056e7f1087766374a20a23e794bf3530a 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -49,6 +49,7 @@ static int branches_nr;
 
 static struct branch *current_branch;
 static const char *default_remote_name;
+static const char *branch_pushremote_name;
 static const char *pushremote_name;
 static int explicit_default_remote_name;
 
@@ -352,7 +353,7 @@ static int handle_config(const char *key, const char *value, void *cb)
                        }
                } else if (!strcmp(subkey, ".pushremote")) {
                        if (branch == current_branch)
-                               if (git_config_string(&pushremote_name, key, value))
+                               if (git_config_string(&branch_pushremote_name, key, value))
                                        return -1;
                } else if (!strcmp(subkey, ".merge")) {
                        if (!value)
@@ -492,6 +493,10 @@ static void read_config(void)
                        make_branch(head_ref + strlen("refs/heads/"), 0);
        }
        git_config(handle_config, NULL);
+       if (branch_pushremote_name) {
+               free((char *)pushremote_name);
+               pushremote_name = branch_pushremote_name;
+       }
        alias_all_urls();
 }
 
index cdcaf8cbe2f4e6c7a5b334fc2c43da6855df4654..0ab2dc137487259d50b69258e967792aa6c43619 100644 (file)
@@ -3,8 +3,13 @@
 #include "refs.h"
 #include "commit.h"
 
+/*
+ * An array of replacements.  The array is kept sorted by the original
+ * sha1.
+ */
 static struct replace_object {
-       unsigned char sha1[2][20];
+       unsigned char original[20];
+       unsigned char replacement[20];
 } **replace_object;
 
 static int replace_object_alloc, replace_object_nr;
@@ -12,7 +17,7 @@ static int replace_object_alloc, replace_object_nr;
 static const unsigned char *replace_sha1_access(size_t index, void *table)
 {
        struct replace_object **replace = table;
-       return replace[index]->sha1[0];
+       return replace[index]->original;
 }
 
 static int replace_object_pos(const unsigned char *sha1)
@@ -24,7 +29,7 @@ static int replace_object_pos(const unsigned char *sha1)
 static int register_replace_object(struct replace_object *replace,
                                   int ignore_dups)
 {
-       int pos = replace_object_pos(replace->sha1[0]);
+       int pos = replace_object_pos(replace->original);
 
        if (0 <= pos) {
                if (ignore_dups)
@@ -36,12 +41,8 @@ static int register_replace_object(struct replace_object *replace,
                return 1;
        }
        pos = -pos - 1;
-       if (replace_object_alloc <= ++replace_object_nr) {
-               replace_object_alloc = alloc_nr(replace_object_alloc);
-               replace_object = xrealloc(replace_object,
-                                         sizeof(*replace_object) *
-                                         replace_object_alloc);
-       }
+       ALLOC_GROW(replace_object, replace_object_nr + 1, replace_object_alloc);
+       replace_object_nr++;
        if (pos < replace_object_nr)
                memmove(replace_object + pos + 1,
                        replace_object + pos,
@@ -60,14 +61,14 @@ static int register_replace_ref(const char *refname,
        const char *hash = slash ? slash + 1 : refname;
        struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
 
-       if (strlen(hash) != 40 || get_sha1_hex(hash, repl_obj->sha1[0])) {
+       if (strlen(hash) != 40 || get_sha1_hex(hash, repl_obj->original)) {
                free(repl_obj);
                warning("bad replace ref name: %s", refname);
                return 0;
        }
 
        /* Copy sha1 from the read ref */
-       hashcpy(repl_obj->sha1[1], sha1);
+       hashcpy(repl_obj->replacement, sha1);
 
        /* Register new object */
        if (register_replace_object(repl_obj, 1))
@@ -86,12 +87,19 @@ static void prepare_replace_object(void)
        for_each_replace_ref(register_replace_ref, NULL);
        replace_object_prepared = 1;
        if (!replace_object_nr)
-               read_replace_refs = 0;
+               check_replace_refs = 0;
 }
 
 /* We allow "recursive" replacement. Only within reason, though */
 #define MAXREPLACEDEPTH 5
 
+/*
+ * If a replacement for object sha1 has been set up, return the
+ * replacement object's name (replaced recursively, if necessary).
+ * The return value is either sha1 or a pointer to a
+ * permanently-allocated value.  This function always respects replace
+ * references, regardless of the value of check_replace_refs.
+ */
 const unsigned char *do_lookup_replace_object(const unsigned char *sha1)
 {
        int pos, depth = MAXREPLACEDEPTH;
@@ -107,7 +115,7 @@ const unsigned char *do_lookup_replace_object(const unsigned char *sha1)
 
                pos = replace_object_pos(cur);
                if (0 <= pos)
-                       cur = replace_object[pos]->sha1[1];
+                       cur = replace_object[pos]->replacement;
        } while (0 <= pos);
 
        return cur;
index bd027bc0152a59ac0c4584ab752ff70bee5abbfa..78b5c3ac0b2d7d436b35a69a3cf6c1b023c96dd5 100644 (file)
@@ -1186,7 +1186,7 @@ int ref_excluded(struct string_list *ref_excludes, const char *path)
        if (!ref_excludes)
                return 0;
        for_each_string_list_item(item, ref_excludes) {
-               if (!fnmatch(item->string, path, 0))
+               if (!wildmatch(item->string, path, 0, NULL))
                        return 1;
        }
        return 0;
diff --git a/setup.c b/setup.c
index cffb6d605e7893a3f9ff83f427732f6b7f3443ff..613e3b3c13b3f09bce07c54dc440d03c0b5beb0c 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -841,3 +841,27 @@ void sanitize_stdfds(void)
        if (fd > 2)
                close(fd);
 }
+
+int daemonize(void)
+{
+#ifdef NO_POSIX_GOODIES
+       errno = ENOSYS;
+       return -1;
+#else
+       switch (fork()) {
+               case 0:
+                       break;
+               case -1:
+                       die_errno("fork failed");
+               default:
+                       exit(0);
+       }
+       if (setsid() == -1)
+               die_errno("setsid failed");
+       close(0);
+       close(1);
+       close(2);
+       sanitize_stdfds();
+       return 0;
+#endif
+}
index 019628add50f4957c21f32abb99c06fc6e5f5d2c..400aa463a47c504feec3ca508e7340c6d5dc8268 100644 (file)
@@ -60,6 +60,12 @@ static struct cached_object empty_tree = {
        0
 };
 
+/*
+ * A pointer to the last packed_git in which an object was found.
+ * When an object is sought, we look in this packfile first, because
+ * objects that are looked up at similar times are often in the same
+ * packfile as one another.
+ */
 static struct packed_git *last_found_pack;
 
 static struct cached_object *find_cached_object(const unsigned char *sha1)
@@ -178,17 +184,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
        }
 }
 
-/*
- * NOTE! This returns a statically allocated buffer, so you have to be
- * careful about using it. Do an "xstrdup()" if you need to save the
- * filename.
- *
- * Also note that this returns the location for creating.  Reading
- * SHA1 file can happen from any alternate directory listed in the
- * DB_ENVIRONMENT environment variable if it is not found in
- * the primary object database.
- */
-char *sha1_file_name(const unsigned char *sha1)
+const char *sha1_file_name(const unsigned char *sha1)
 {
        static char buf[PATH_MAX];
        const char *objdir;
@@ -208,6 +204,11 @@ char *sha1_file_name(const unsigned char *sha1)
        return buf;
 }
 
+/*
+ * Return the name of the pack or index file with the specified sha1
+ * in its filename.  *base and *name are scratch space that must be
+ * provided by the caller.  which should be "pack" or "idx".
+ */
 static char *sha1_get_pack_name(const unsigned char *sha1,
                                char **name, char **base, const char *which)
 {
@@ -436,8 +437,7 @@ void prepare_alt_odb(void)
 
 static int has_loose_object_local(const unsigned char *sha1)
 {
-       char *name = sha1_file_name(sha1);
-       return !access(name, F_OK);
+       return !access(sha1_file_name(sha1), F_OK);
 }
 
 int has_loose_object_nonlocal(const unsigned char *sha1)
@@ -489,7 +489,12 @@ void pack_report(void)
                sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped));
 }
 
-static int check_packed_git_idx(const char *path,  struct packed_git *p)
+/*
+ * Open and mmap the index file at path, perform a couple of
+ * consistency checks, then record its information to p.  Return 0 on
+ * success.
+ */
+static int check_packed_git_idx(const char *path, struct packed_git *p)
 {
        void *idx_map;
        struct pack_idx_header *hdr;
@@ -1412,17 +1417,15 @@ int git_open_noatime(const char *name)
 
 static int stat_sha1_file(const unsigned char *sha1, struct stat *st)
 {
-       char *name = sha1_file_name(sha1);
        struct alternate_object_database *alt;
 
-       if (!lstat(name, st))
+       if (!lstat(sha1_file_name(sha1), st))
                return 0;
 
        prepare_alt_odb();
        errno = ENOENT;
        for (alt = alt_odb_list; alt; alt = alt->next) {
-               name = alt->name;
-               fill_sha1_path(name, sha1);
+               fill_sha1_path(alt->name, sha1);
                if (!lstat(alt->base, st))
                        return 0;
        }
@@ -1433,18 +1436,16 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st)
 static int open_sha1_file(const unsigned char *sha1)
 {
        int fd;
-       char *name = sha1_file_name(sha1);
        struct alternate_object_database *alt;
 
-       fd = git_open_noatime(name);
+       fd = git_open_noatime(sha1_file_name(sha1));
        if (fd >= 0)
                return fd;
 
        prepare_alt_odb();
        errno = ENOENT;
        for (alt = alt_odb_list; alt; alt = alt->next) {
-               name = alt->name;
-               fill_sha1_path(name, sha1);
+               fill_sha1_path(alt->name, sha1);
                fd = git_open_noatime(alt->base);
                if (fd >= 0)
                        return fd;
@@ -2287,6 +2288,10 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
        *final_size = size;
 
        unuse_pack(&w_curs);
+
+       if (delta_stack != small_delta_stack)
+               free(delta_stack);
+
        return data;
 }
 
@@ -2446,6 +2451,10 @@ static int fill_pack_entry(const unsigned char *sha1,
        return 1;
 }
 
+/*
+ * Iff a pack file contains the object named by sha1, return true and
+ * store its location to e.
+ */
 static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 {
        struct packed_git *p;
@@ -2458,11 +2467,13 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
                return 1;
 
        for (p = packed_git; p; p = p->next) {
-               if (p == last_found_pack || !fill_pack_entry(sha1, e, p))
-                       continue;
+               if (p == last_found_pack)
+                       continue; /* we already checked this one */
 
-               last_found_pack = p;
-               return 1;
+               if (fill_pack_entry(sha1, e, p)) {
+                       last_found_pack = p;
+                       return 1;
+               }
        }
        return 0;
 }
@@ -2624,12 +2635,7 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
        hash_sha1_file(buf, len, typename(type), sha1);
        if (has_sha1_file(sha1) || find_cached_object(sha1))
                return 0;
-       if (cached_object_alloc <= cached_object_nr) {
-               cached_object_alloc = alloc_nr(cached_object_alloc);
-               cached_objects = xrealloc(cached_objects,
-                                         sizeof(*cached_objects) *
-                                         cached_object_alloc);
-       }
+       ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc);
        co = &cached_objects[cached_object_nr++];
        co->size = len;
        co->type = type;
@@ -2677,7 +2683,6 @@ void *read_sha1_file_extended(const unsigned char *sha1,
                              unsigned flag)
 {
        void *data;
-       char *path;
        const struct packed_git *p;
        const unsigned char *repl = lookup_replace_object_extended(sha1, flag);
 
@@ -2695,7 +2700,8 @@ void *read_sha1_file_extended(const unsigned char *sha1,
                    sha1_to_hex(repl), sha1_to_hex(sha1));
 
        if (has_loose_object(repl)) {
-               path = sha1_file_name(sha1);
+               const char *path = sha1_file_name(sha1);
+
                die("loose object %s (stored in %s) is corrupt",
                    sha1_to_hex(repl), path);
        }
@@ -2893,10 +2899,9 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
        git_zstream stream;
        git_SHA_CTX c;
        unsigned char parano_sha1[20];
-       char *filename;
        static char tmp_file[PATH_MAX];
+       const char *filename = sha1_file_name(sha1);
 
-       filename = sha1_file_name(sha1);
        fd = create_tmpfile(tmp_file, sizeof(tmp_file), filename);
        if (fd < 0) {
                if (errno == EACCES)
index 83caf4a9147e6788107fb5fd23e6d9e1d6f6267f..ee96dcfb816625436582833d812a7156513d5d39 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -10,15 +10,6 @@ int starts_with(const char *str, const char *prefix)
                        return 0;
 }
 
-int prefixcmp(const char *str, const char *prefix)
-{
-       for (; ; str++, prefix++)
-               if (!*prefix)
-                       return 0;
-               else if (*str != *prefix)
-                       return (unsigned char)*prefix - (unsigned char)*str;
-}
-
 int ends_with(const char *str, const char *suffix)
 {
        int len = strlen(str), suflen = strlen(suffix);
@@ -28,15 +19,6 @@ int ends_with(const char *str, const char *suffix)
                return !strcmp(str + len - suflen, suffix);
 }
 
-int suffixcmp(const char *str, const char *suffix)
-{
-       int len = strlen(str), suflen = strlen(suffix);
-       if (len < suflen)
-               return -1;
-       else
-               return strcmp(str + len - suflen, suffix);
-}
-
 /*
  * Used as the default ->buf value, so that people can always assume
  * buf is non NULL and ->buf is NUL terminated even for a freshly
index 73e80cea69b5e2965cf4ce8c36444f45aae8e19c..39c14cfa384c5154abd96899a7c02417295f8555 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -17,20 +17,23 @@ extern void strbuf_init(struct strbuf *, size_t);
 extern void strbuf_release(struct strbuf *);
 extern char *strbuf_detach(struct strbuf *, size_t *);
 extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
-static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) {
+static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
+{
        struct strbuf tmp = *a;
        *a = *b;
        *b = tmp;
 }
 
 /*----- strbuf size related -----*/
-static inline size_t strbuf_avail(const struct strbuf *sb) {
+static inline size_t strbuf_avail(const struct strbuf *sb)
+{
        return sb->alloc ? sb->alloc - sb->len - 1 : 0;
 }
 
 extern void strbuf_grow(struct strbuf *, size_t);
 
-static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
+static inline void strbuf_setlen(struct strbuf *sb, size_t len)
+{
        if (len > (sb->alloc ? sb->alloc - 1 : 0))
                die("BUG: strbuf_setlen() beyond buffer");
        sb->len = len;
@@ -97,7 +100,8 @@ static inline struct strbuf **strbuf_split(const struct strbuf *sb,
 extern void strbuf_list_free(struct strbuf **);
 
 /*----- add data in your buffer -----*/
-static inline void strbuf_addch(struct strbuf *sb, int c) {
+static inline void strbuf_addch(struct strbuf *sb, int c)
+{
        strbuf_grow(sb, 1);
        sb->buf[sb->len++] = c;
        sb->buf[sb->len] = '\0';
@@ -113,10 +117,12 @@ extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
 extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
 
 extern void strbuf_add(struct strbuf *, const void *, size_t);
-static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
+static inline void strbuf_addstr(struct strbuf *sb, const char *s)
+{
        strbuf_add(sb, s, strlen(s));
 }
-static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2) {
+static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
+{
        strbuf_grow(sb, sb2->len);
        strbuf_add(sb, sb2->buf, sb2->len);
 }
index d7c9f32f0ce98112ddd4d4a8499b227b181e09e6..2ff036a0fa6c8e7b013d061d16baf33045305950 100644 (file)
@@ -152,8 +152,10 @@ struct git_istream *open_istream(const unsigned char *sha1,
        if (filter) {
                /* Add "&& !is_null_stream_filter(filter)" for performance */
                struct git_istream *nst = attach_stream_filter(st, filter);
-               if (!nst)
+               if (!nst) {
                        close_istream(st);
+                       return NULL;
+               }
                st = nst;
        }
 
index 1f22de260a2d456ee73d29f29b049fd5771e8ecc..bc4b3412fbca1f545ebdcaf23d3ef83d124ddc71 100644 (file)
 #      stop_git_daemon
 #      test_done
 
-if test -z "$GIT_TEST_GIT_DAEMON"
+test_tristate GIT_TEST_GIT_DAEMON
+if test "$GIT_TEST_GIT_DAEMON" = false
 then
-       skip_all="git-daemon testing disabled (define GIT_TEST_GIT_DAEMON to enable)"
+       skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)"
        test_done
 fi
 
@@ -58,7 +59,8 @@ start_git_daemon() {
                kill "$GIT_DAEMON_PID"
                wait "$GIT_DAEMON_PID"
                trap 'die' EXIT
-               error "git daemon failed to start"
+               test_skip_or_die $GIT_TEST_GIT_DAEMON \
+                       "git daemon failed to start"
        fi
 }
 
index b43162ea2a932deb521381863900279c8d87f2b1..252cbf163bcff90aabe39a48219e00565f577ffe 100644 (file)
 # Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at>
 #
 
-if test -z "$GIT_TEST_HTTPD"
+test_tristate GIT_TEST_HTTPD
+if test "$GIT_TEST_HTTPD" = false
 then
-       skip_all="Network testing disabled (define GIT_TEST_HTTPD to enable)"
+       skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)"
        test_done
 fi
 
@@ -76,8 +77,7 @@ GIT_VALGRIND_OPTIONS=$GIT_VALGRIND_OPTIONS; export GIT_VALGRIND_OPTIONS
 
 if ! test -x "$LIB_HTTPD_PATH"
 then
-       skip_all="skipping test, no web server found at '$LIB_HTTPD_PATH'"
-       test_done
+       test_skip_or_die $GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'"
 fi
 
 HTTPD_VERSION=`$LIB_HTTPD_PATH -v | \
@@ -89,19 +89,20 @@ then
        then
                if ! test $HTTPD_VERSION -ge 2
                then
-                       skip_all="skipping test, at least Apache version 2 is required"
-                       test_done
+                       test_skip_or_die $GIT_TEST_HTTPD \
+                               "at least Apache version 2 is required"
                fi
                if ! test -d "$DEFAULT_HTTPD_MODULE_PATH"
                then
-                       skip_all="Apache module directory not found.  Skipping tests."
-                       test_done
+                       test_skip_or_die $GIT_TEST_HTTPD \
+                               "Apache module directory not found"
                fi
 
                LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH"
        fi
 else
-       error "Could not identify web server at '$LIB_HTTPD_PATH'"
+       test_skip_or_die $GIT_TEST_HTTPD \
+               "Could not identify web server at '$LIB_HTTPD_PATH'"
 fi
 
 prepare_httpd() {
@@ -155,9 +156,8 @@ start_httpd() {
                >&3 2>&4
        if test $? -ne 0
        then
-               skip_all="skipping test, web server setup failed"
                trap 'die' EXIT
-               test_done
+               test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
        fi
 }
 
index b9d79476e20b4ddf0f9e85c672df2061fb910f9d..f0fbb425545019a6275a347a5826f6ba2977d394 100755 (executable)
@@ -243,40 +243,58 @@ EOF
        test_line_count = 0 err
 '
 
+test_expect_success 'using --git-dir and --work-tree' '
+       mkdir unreal real &&
+       git init real &&
+       echo "file test=in-real" >real/.gitattributes &&
+       (
+               cd unreal &&
+               attr_check file in-real "--git-dir ../real/.git --work-tree ../real"
+       )
+'
+
 test_expect_success 'setup bare' '
-       git clone --bare . bare.git &&
-       cd bare.git
+       git clone --bare . bare.git
 '
 
 test_expect_success 'bare repository: check that .gitattribute is ignored' '
        (
-               echo "f test=f"
-               echo "a/i test=a/i"
-       ) >.gitattributes &&
-       attr_check f unspecified &&
-       attr_check a/f unspecified &&
-       attr_check a/c/f unspecified &&
-       attr_check a/i unspecified &&
-       attr_check subdir/a/i unspecified
+               cd bare.git &&
+               (
+                       echo "f test=f"
+                       echo "a/i test=a/i"
+               ) >.gitattributes &&
+               attr_check f unspecified &&
+               attr_check a/f unspecified &&
+               attr_check a/c/f unspecified &&
+               attr_check a/i unspecified &&
+               attr_check subdir/a/i unspecified
+       )
 '
 
 test_expect_success 'bare repository: check that --cached honors index' '
-       GIT_INDEX_FILE=../.git/index \
-       git check-attr --cached --stdin --all <../stdin-all |
-       sort >actual &&
-       test_cmp ../specified-all actual
+       (
+               cd bare.git &&
+               GIT_INDEX_FILE=../.git/index \
+               git check-attr --cached --stdin --all <../stdin-all |
+               sort >actual &&
+               test_cmp ../specified-all actual
+       )
 '
 
 test_expect_success 'bare repository: test info/attributes' '
        (
-               echo "f test=f"
-               echo "a/i test=a/i"
-       ) >info/attributes &&
-       attr_check f f &&
-       attr_check a/f f &&
-       attr_check a/c/f f &&
-       attr_check a/i a/i &&
-       attr_check subdir/a/i unspecified
+               cd bare.git &&
+               (
+                       echo "f test=f"
+                       echo "a/i test=a/i"
+               ) >info/attributes &&
+               attr_check f f &&
+               attr_check a/f f &&
+               attr_check a/c/f f &&
+               attr_check a/i a/i &&
+               attr_check subdir/a/i unspecified
+       )
 '
 
 test_done
index b4d98e602f7422009599e58f0a7ae943476b1c7e..63beb99828cc17d2ec8218a6470b62c02a78806b 100755 (executable)
@@ -775,4 +775,35 @@ test_expect_success PIPE 'streaming support for --stdin' '
        echo "$response" | grep "^::    two"
 '
 
+############################################################################
+#
+# test whitespace handling
+
+test_expect_success 'trailing whitespace is ignored' '
+       mkdir whitespace &&
+       >whitespace/trailing &&
+       >whitespace/untracked &&
+       echo "whitespace/trailing   " >ignore &&
+       cat >expect <<EOF &&
+whitespace/untracked
+EOF
+       : >err.expect &&
+       git ls-files -o -X ignore whitespace >actual 2>err &&
+       test_cmp expect actual &&
+       test_cmp err.expect err
+'
+
+test_expect_success !MINGW 'quoting allows trailing whitespace' '
+       rm -rf whitespace &&
+       mkdir whitespace &&
+       >"whitespace/trailing  " &&
+       >whitespace/untracked &&
+       echo "whitespace/trailing\\ \\ " >ignore &&
+       echo whitespace/untracked >expect &&
+       : >err.expect &&
+       git ls-files -o -X ignore whitespace >actual 2>err &&
+       test_cmp expect actual &&
+       test_cmp err.expect err
+'
+
 test_done
index 967359344dab8118dfd55816ef08f4809a9f33ad..c9c426c273e556302338f7a30fc46de64b856eb2 100755 (executable)
@@ -475,15 +475,28 @@ ein.bahn=strasse
 EOF
 
 test_expect_success 'alternative GIT_CONFIG' '
-       GIT_CONFIG=other-config git config -l >output &&
+       GIT_CONFIG=other-config git config --list >output &&
        test_cmp expect output
 '
 
 test_expect_success 'alternative GIT_CONFIG (--file)' '
-       git config --file other-config -l > output &&
+       git config --file other-config --list >output &&
        test_cmp expect output
 '
 
+test_expect_success 'alternative GIT_CONFIG (--file=-)' '
+       git config --file - --list <other-config >output &&
+       test_cmp expect output
+'
+
+test_expect_success 'setting a value in stdin is an error' '
+       test_must_fail git config --file - some.value foo
+'
+
+test_expect_success 'editing stdin is an error' '
+       test_must_fail git config --file - --edit
+'
+
 test_expect_success 'refer config from subdirectory' '
        mkdir x &&
        (
index a70707620f146d3fce69f77e08cae3a47253f157..9ba2ba11c3cac88154dbb2d522b43adf98a8dee7 100755 (executable)
@@ -113,7 +113,7 @@ test_expect_success 'missing include files are ignored' '
 test_expect_success 'absolute includes from command line work' '
        echo "[test]one = 1" >one &&
        echo 1 >expect &&
-       git -c include.path="$PWD/one" config test.one >actual &&
+       git -c include.path="$(pwd)/one" config test.one >actual &&
        test_cmp expect actual
 '
 
@@ -122,6 +122,36 @@ test_expect_success 'relative includes from command line fail' '
        test_must_fail git -c include.path=one config test.one
 '
 
+test_expect_success 'absolute includes from blobs work' '
+       echo "[test]one = 1" >one &&
+       echo "[include]path=$(pwd)/one" >blob &&
+       blob=$(git hash-object -w blob) &&
+       echo 1 >expect &&
+       git config --blob=$blob test.one >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'relative includes from blobs fail' '
+       echo "[test]one = 1" >one &&
+       echo "[include]path=one" >blob &&
+       blob=$(git hash-object -w blob) &&
+       test_must_fail git config --blob=$blob test.one
+'
+
+test_expect_success 'absolute includes from stdin work' '
+       echo "[test]one = 1" >one &&
+       echo 1 >expect &&
+       echo "[include]path=\"$(pwd)/one\"" |
+       git config --file - test.one >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'relative includes from stdin line fail' '
+       echo "[test]one = 1" >one &&
+       echo "[include]path=one" |
+       test_must_fail git config --file - test.one
+'
+
 test_expect_success 'include cycles are detected' '
        cat >.gitconfig <<-\EOF &&
        [test]value = gitconfig
index d730734fde8e4de69fdf2662915bc67342198fc8..8c739c96135fe942d7e76236eb34429be93937a8 100755 (executable)
@@ -142,6 +142,20 @@ test_expect_success '> in name is reported' '
        grep "error in commit $new" out
 '
 
+# date is 2^64 + 1
+test_expect_success 'integer overflow in timestamps is reported' '
+       git cat-file commit HEAD >basis &&
+       sed "s/^\\(author .*>\\) [0-9]*/\\1 18446744073709551617/" \
+               <basis >bad-timestamp &&
+       new=$(git hash-object -t commit -w --stdin <bad-timestamp) &&
+       test_when_finished "remove_object $new" &&
+       git update-ref refs/heads/bogus "$new" &&
+       test_when_finished "git update-ref -d refs/heads/bogus" &&
+       git fsck 2>out &&
+       cat out &&
+       grep "error in commit $new.*integer overflow" out
+'
+
 test_expect_success 'tag pointing to nonexistent' '
        cat >invalid-tag <<-\EOF &&
        object ffffffffffffffffffffffffffffffffffffffff
diff --git a/t/t1600-index.sh b/t/t1600-index.sh
new file mode 100755 (executable)
index 0000000..079d241
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+test_description='index file specific tests'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       echo 1 >a
+'
+
+test_expect_success 'bogus GIT_INDEX_VERSION issues warning' '
+       (
+               rm -f .git/index &&
+               GIT_INDEX_VERSION=2bogus &&
+               export GIT_INDEX_VERSION &&
+               git add a 2>&1 | sed "s/[0-9]//" >actual.err &&
+               sed -e "s/ Z$/ /" <<-\EOF >expect.err &&
+                       warning: GIT_INDEX_VERSION set, but the value is invalid.
+                       Using version Z
+               EOF
+               test_i18ncmp expect.err actual.err
+       )
+'
+
+test_expect_success 'out of bounds GIT_INDEX_VERSION issues warning' '
+       (
+               rm -f .git/index &&
+               GIT_INDEX_VERSION=1 &&
+               export GIT_INDEX_VERSION &&
+               git add a 2>&1 | sed "s/[0-9]//" >actual.err &&
+               sed -e "s/ Z$/ /" <<-\EOF >expect.err &&
+                       warning: GIT_INDEX_VERSION set, but the value is invalid.
+                       Using version Z
+               EOF
+               test_i18ncmp expect.err actual.err
+       )
+'
+
+test_expect_success 'no warning with bogus GIT_INDEX_VERSION and existing index' '
+       (
+               GIT_INDEX_VERSION=1 &&
+               export GIT_INDEX_VERSION &&
+               git add a 2>actual.err &&
+               >expect.err &&
+               test_i18ncmp expect.err actual.err
+       )
+'
+
+test_expect_success 'out of bounds index.version issues warning' '
+       (
+               sane_unset GIT_INDEX_VERSION &&
+               rm -f .git/index &&
+               git config --add index.version 1 &&
+               git add a 2>&1 | sed "s/[0-9]//" >actual.err &&
+               sed -e "s/ Z$/ /" <<-\EOF >expect.err &&
+                       warning: index.version set, but the value is invalid.
+                       Using version Z
+               EOF
+               test_i18ncmp expect.err actual.err
+       )
+'
+
+test_expect_success 'GIT_INDEX_VERSION takes precedence over config' '
+       (
+               rm -f .git/index &&
+               GIT_INDEX_VERSION=4 &&
+               export GIT_INDEX_VERSION &&
+               git config --add index.version 2 &&
+               git add a 2>&1 &&
+               echo 4 >expect &&
+               test-index-version <.git/index >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_done
index 1d0879be0687267372eac27bec3ea313557e79ee..29c1fb10cad93818d467780b799ff874e8fdcab0 100755 (executable)
@@ -7,6 +7,8 @@ test_description='skip-worktree bit test'
 
 . ./test-lib.sh
 
+test_set_index_version 3
+
 cat >expect.full <<EOF
 H 1
 H 2
index 9bf2bdffd24b773a2eec636efdd534269f45e74b..e16b15d3e5784eb3c6423318142cb91fe3a58601 100755 (executable)
@@ -80,18 +80,13 @@ test_expect_success 'change gets noticed' '
 
 '
 
-# Note that this is scheduled to change in Git 2.0, when
-# "git add -u" will become full-tree by default.
-test_expect_success 'non-limited update in subdir leaves root alone' '
+test_expect_success 'non-qualified update in subdir updates from the root' '
        (
                cd dir1 &&
                echo even more >>sub2 &&
                git add -u
        ) &&
-       cat >expect <<-\EOF &&
-       check
-       top
-       EOF
+       : >expect &&
        git diff-files --name-only >actual &&
        test_cmp expect actual
 '
index 38446a0e872e90fb008d6d42784a1892bab214e9..ef509df351600f1238eab243ec353ab73ec8518f 100755 (executable)
@@ -14,19 +14,6 @@ match() {
            ! test-wildmatch wildmatch '$3' '$4'
        "
     fi
-    if [ $2 = 1 ]; then
-       test_expect_success "fnmatch:       match '$3' '$4'" "
-           test-wildmatch fnmatch '$3' '$4'
-       "
-    elif [ $2 = 0 ]; then
-       test_expect_success "fnmatch:    no match '$3' '$4'" "
-           ! test-wildmatch fnmatch '$3' '$4'
-       "
-#    else
-#      test_expect_success BROKEN_FNMATCH "fnmatch:       '$3' '$4'" "
-#          ! test-wildmatch fnmatch '$3' '$4'
-#      "
-    fi
 }
 
 imatch() {
index 16de05aff941c73b3e5f5371bd4739959f679efa..3bb79a47af5e2f619753c61436ec577ec025a8ae 100755 (executable)
@@ -812,6 +812,33 @@ test_expect_success 'create note from non-existing note with "git notes add -C"
        test_must_fail git notes list HEAD
 '
 
+test_expect_success 'create note from non-blob with "git notes add -C" fails' '
+       commit=$(git rev-parse --verify HEAD) &&
+       tree=$(git rev-parse --verify HEAD:) &&
+       test_must_fail git notes add -C $commit &&
+       test_must_fail git notes add -C $tree &&
+       test_must_fail git notes list HEAD
+'
+
+cat > expect << EOF
+commit 80d796defacd5db327b7a4e50099663902fbdc5c
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:20:13 2005 -0700
+
+    8th
+
+Notes (other):
+    This is a blob object
+EOF
+
+test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
+       blob=$(echo "This is a blob object" | git hash-object -w --stdin) &&
+       git notes add -C $blob &&
+       git log -1 > actual &&
+       test_cmp expect actual &&
+       test "$(git notes list HEAD)" = "$blob"
+'
+
 cat > expect << EOF
 commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b
 Author: A U Thor <author@example.com>
index bcae35ac1c93aaf79032db5ee09fd2d3400101f5..044620186d135fe5caeb9376665305af1c8acbe5 100755 (executable)
@@ -226,12 +226,13 @@ keep_only_cr () {
 }
 
 test_expect_success 'external diff with autocrlf = true' '
-       git config core.autocrlf true &&
+       test_config core.autocrlf true &&
        GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
        test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
 '
 
 test_expect_success 'diff --cached' '
+       test_config core.autocrlf true &&
        git add file &&
        git update-index --assume-unchanged file &&
        echo second >file &&
@@ -239,4 +240,31 @@ test_expect_success 'diff --cached' '
        test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
 '
 
+test_expect_success 'clean up crlf leftovers' '
+       git update-index --no-assume-unchanged file &&
+       rm -f file* &&
+       git reset --hard
+'
+
+test_expect_success 'submodule diff' '
+       git init sub &&
+       ( cd sub && test_commit sub1 ) &&
+       git add sub &&
+       test_tick &&
+       git commit -m "add submodule" &&
+       ( cd sub && test_commit sub2 ) &&
+       write_script gather_pre_post.sh <<-\EOF &&
+       echo "$1 $4" # path, mode
+       cat "$2" # old file
+       cat "$5" # new file
+       EOF
+       GIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual &&
+       cat >expected <<-EOF &&
+       sub 160000
+       Subproject commit $(git rev-parse HEAD:sub)
+       Subproject commit $(cd sub && git rev-parse HEAD)
+       EOF
+       test_cmp expected actual
+'
+
 test_done
index 9e2b29ede508e3d0822f5eb607db2ae4896611e6..c0460bb0e59c42de179fc6cbe0f3702a3b538a8e 100755 (executable)
@@ -97,4 +97,25 @@ do
        '
 done
 
+test_expect_success 'setup for testing combine-diff order' '
+       git checkout -b tmp HEAD~ &&
+       create_files 3 &&
+       git checkout master &&
+       git merge --no-commit -s ours tmp &&
+       create_files 5
+'
+
+test_expect_success "combine-diff: no order (=tree object order)" '
+       git diff --name-only HEAD HEAD^ HEAD^2 >actual &&
+       test_cmp expect_none actual
+'
+
+for i in 1 2
+do
+       test_expect_success "combine-diff: orderfile using option ($i)" '
+               git diff -Oorder_file_$i --name-only HEAD HEAD^ HEAD^2 >actual &&
+               test_cmp expect_$i actual
+       '
+done
+
 test_done
diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh
new file mode 100755 (executable)
index 0000000..097e632
--- /dev/null
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+test_description='combined diff show only paths that are different to all parents'
+
+. ./test-lib.sh
+
+# verify that diffc.expect matches output of
+# `git diff -c --name-only HEAD HEAD^ HEAD^2`
+diffc_verify () {
+       git diff -c --name-only HEAD HEAD^ HEAD^2 >diffc.actual &&
+       test_cmp diffc.expect diffc.actual
+}
+
+test_expect_success 'trivial merge - combine-diff empty' '
+       for i in $(test_seq 1 9)
+       do
+               echo $i >$i.txt &&
+               git add $i.txt
+       done &&
+       git commit -m "init" &&
+       git checkout -b side &&
+       for i in $(test_seq 2 9)
+       do
+               echo $i/2 >>$i.txt
+       done &&
+       git commit -a -m "side 2-9" &&
+       git checkout master &&
+       echo 1/2 >1.txt &&
+       git commit -a -m "master 1" &&
+       git merge side &&
+       >diffc.expect &&
+       diffc_verify
+'
+
+
+test_expect_success 'only one trully conflicting path' '
+       git checkout side &&
+       for i in $(test_seq 2 9)
+       do
+               echo $i/3 >>$i.txt
+       done &&
+       echo "4side" >>4.txt &&
+       git commit -a -m "side 2-9 +4" &&
+       git checkout master &&
+       for i in $(test_seq 1 9)
+       do
+               echo $i/3 >>$i.txt
+       done &&
+       echo "4master" >>4.txt &&
+       git commit -a -m "master 1-9 +4" &&
+       test_must_fail git merge side &&
+       cat <<-\EOF >4.txt &&
+       4
+       4/2
+       4/3
+       4master
+       4side
+       EOF
+       git add 4.txt &&
+       git commit -m "merge side (2)" &&
+       echo 4.txt >diffc.expect &&
+       diffc_verify
+'
+
+test_expect_success 'merge introduces new file' '
+       git checkout side &&
+       for i in $(test_seq 5 9)
+       do
+               echo $i/4 >>$i.txt
+       done &&
+       git commit -a -m "side 5-9" &&
+       git checkout master &&
+       for i in $(test_seq 1 3)
+       do
+               echo $i/4 >>$i.txt
+       done &&
+       git commit -a -m "master 1-3 +4hello" &&
+       git merge side &&
+       echo "Hello World" >4hello.txt &&
+       git add 4hello.txt &&
+       git commit --amend &&
+       echo 4hello.txt >diffc.expect &&
+       diffc_verify
+'
+
+test_expect_success 'merge removed a file' '
+       git checkout side &&
+       for i in $(test_seq 5 9)
+       do
+               echo $i/5 >>$i.txt
+       done &&
+       git commit -a -m "side 5-9" &&
+       git checkout master &&
+       for i in $(test_seq 1 3)
+       do
+               echo $i/4 >>$i.txt
+       done &&
+       git commit -a -m "master 1-3" &&
+       git merge side &&
+       git rm 4.txt &&
+       git commit --amend &&
+       echo 4.txt >diffc.expect &&
+       diffc_verify
+'
+
+test_done
index 93c7c366cfeffa46cc72665f6ce676bd37c3c2fe..3fa171541a161e0a5549c316b7c85608eb2d93d6 100755 (executable)
@@ -44,4 +44,49 @@ test_expect_success 'git log --format with broken author email' '
        test_cmp expect.err actual.err
 '
 
+munge_author_date () {
+       git cat-file commit "$1" >commit.orig &&
+       sed "s/^\(author .*>\) [0-9]*/\1 $2/" <commit.orig >commit.munge &&
+       git hash-object -w -t commit commit.munge
+}
+
+test_expect_success 'unparsable dates produce sentinel value' '
+       commit=$(munge_author_date HEAD totally_bogus) &&
+       echo "Date:   Thu Jan 1 00:00:00 1970 +0000" >expect &&
+       git log -1 $commit >actual.full &&
+       grep Date <actual.full >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'unparsable dates produce sentinel value (%ad)' '
+       commit=$(munge_author_date HEAD totally_bogus) &&
+       echo >expect &&
+       git log -1 --format=%ad $commit >actual
+       test_cmp expect actual
+'
+
+# date is 2^64 + 1
+test_expect_success 'date parser recognizes integer overflow' '
+       commit=$(munge_author_date HEAD 18446744073709551617) &&
+       echo "Thu Jan 1 00:00:00 1970 +0000" >expect &&
+       git log -1 --format=%ad $commit >actual &&
+       test_cmp expect actual
+'
+
+# date is 2^64 - 2
+test_expect_success 'date parser recognizes time_t overflow' '
+       commit=$(munge_author_date HEAD 18446744073709551614) &&
+       echo "Thu Jan 1 00:00:00 1970 +0000" >expect &&
+       git log -1 --format=%ad $commit >actual &&
+       test_cmp expect actual
+'
+
+# date is within 2^63-1, but enough to choke glibc's gmtime
+test_expect_success 'absurdly far-in-future dates produce sentinel' '
+       commit=$(munge_author_date HEAD 999999999999999999) &&
+       echo "Thu Jan 1 00:00:00 1970 +0000" >expect &&
+       git log -1 --format=%ad $commit >actual &&
+       test_cmp expect actual
+'
+
 test_done
index 05f011d38eeaf16e2be8caace5bca697b7a9daf3..1cf0a4e10301fe1bbfb3acced0c010da7b8df7f8 100755 (executable)
@@ -213,6 +213,15 @@ test_expect_success 'clients cannot access unreachable commits' '
        test_must_fail git archive --remote=. $sha1 >remote.tar
 '
 
+test_expect_success 'upload-archive can allow unreachable commits' '
+       test_commit unreachable1 &&
+       sha1=`git rev-parse HEAD` &&
+       git reset --hard HEAD^ &&
+       git archive $sha1 >remote.tar &&
+       test_config uploadarchive.allowUnreachable true &&
+       git archive --remote=. $sha1 >remote.tar
+'
+
 test_expect_success 'setup tar filters' '
        git config tar.tar.foo.command "tr ab ba" &&
        git config tar.bar.command "tr ab ba" &&
index 129fc88bd28e8ea85e81310aec860df808949447..0736bcbcd52a76ef3400c046e7d3558dd1a866c7 100755 (executable)
@@ -164,6 +164,7 @@ test_expect_success 'receive-pack runs auto-gc in remote repo' '
            # Set the child to auto-pack if more than one pack exists
            cd child &&
            git config gc.autopacklimit 1 &&
+           git config gc.autodetach false &&
            git branch test_auto_gc &&
            # And create a file that follows the temporary object naming
            # convention for the auto-gc to remove
index 926e7f6b979d4d1c69ecc9d280cd6de365627012..67e0ab346204b437c8e3585d948c2c61858e1928 100755 (executable)
@@ -536,6 +536,19 @@ test_expect_success 'push with config branch.*.pushremote' '
        check_push_result down_repo $the_commit heads/master
 '
 
+test_expect_success 'branch.*.pushremote config order is irrelevant' '
+       mk_test one_repo heads/master &&
+       mk_test two_repo heads/master &&
+       test_config remote.one.url one_repo &&
+       test_config remote.two.url two_repo &&
+       test_config branch.master.pushremote two_repo &&
+       test_config remote.pushdefault one_repo &&
+       test_config push.default matching &&
+       git push &&
+       check_push_result one_repo $the_first_commit heads/master &&
+       check_push_result two_repo $the_commit heads/master
+'
+
 test_expect_success 'push with dry-run' '
 
        mk_test testrepo heads/master &&
index 613f69a254bab23e1f09126b4a7f3dca8692deaa..c33cc25805d2a913725355a183118a0dd5547800 100755 (executable)
@@ -94,6 +94,19 @@ test_expect_failure 'push new branch with old:new refspec' '
        compare_refs local HEAD server refs/heads/new-refspec
 '
 
+test_expect_success 'forced push' '
+       (cd local &&
+       git checkout -b force-test &&
+       echo content >> file &&
+       git commit -a -m eight &&
+       git push origin force-test &&
+       echo content >> file &&
+       git commit -a --amend -m eight-modified &&
+       git push --force origin force-test
+       ) &&
+       compare_refs local refs/heads/force-test server refs/heads/force-test
+'
+
 test_expect_success 'cloning without refspec' '
        GIT_REMOTE_TESTGIT_REFSPEC="" \
        git clone "testgit::${PWD}/server" local2 2>error &&
index bc0846f4356e548cc72d3cf0c18ef00c21ede87d..450529404c686469ed5ba5ad465cf8b3ef651ef9 100755 (executable)
@@ -550,4 +550,15 @@ test_expect_success 'reset -N keeps removed files as intent-to-add' '
        test_cmp expect actual
 '
 
+test_expect_success 'reset --mixed sets up work tree' '
+       git init mixed_worktree &&
+       (
+               cd mixed_worktree &&
+               test_commit dummy
+       ) &&
+       : >expect &&
+       git --git-dir=mixed_worktree/.git --work-tree=mixed_worktree reset >actual &&
+       test_cmp expect actual
+'
+
 test_done
index 710be90489b2fd5d6ca1a98201c1ec635efcae9f..74de814aec1465848ba316e867106a18635139f6 100755 (executable)
@@ -511,4 +511,20 @@ test_expect_success SANITY 'git clean -d with an unreadable empty directory' '
        ! test -d foo
 '
 
+test_expect_success 'git clean -d respects pathspecs (dir is prefix of pathspec)' '
+       mkdir -p foo &&
+       mkdir -p foobar &&
+       git clean -df foobar &&
+       test_path_is_dir foo &&
+       test_path_is_missing foobar
+'
+
+test_expect_success 'git clean -d respects pathspecs (pathspec is prefix of dir)' '
+       mkdir -p foo &&
+       mkdir -p foobar &&
+       git clean -df foo &&
+       test_path_is_missing foo &&
+       test_path_is_dir foobar
+'
+
 test_done
index 2418528487624bf5497af71c9958a84e0a50328f..5a193c500d282cc2b13e8de6e128229585897a16 100755 (executable)
@@ -434,4 +434,18 @@ test_expect_success PERL 'difftool --no-symlinks detects conflict ' '
        )
 '
 
+test_expect_success PERL 'difftool properly honors gitlink and core.worktree' '
+       git submodule add ./. submod/ule &&
+       (
+               cd submod/ule &&
+               test_config diff.tool checktrees &&
+               test_config difftool.checktrees.cmd '\''
+                       test -d "$LOCAL" && test -d "$REMOTE" && echo good
+               '\'' &&
+               echo good >expect &&
+               git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
+               test_cmp expect actual
+       )
+'
+
 test_done
index aeae3ca7699b4c828f8ebe50624b5179fb5098b8..158e10a67e5878bb9031af2f28439b099b65fd50 100644 (file)
@@ -32,6 +32,11 @@ test_set_editor () {
        export EDITOR
 }
 
+test_set_index_version () {
+    GIT_INDEX_VERSION="$1"
+    export GIT_INDEX_VERSION
+}
+
 test_decode_color () {
        awk '
                function name(n) {
@@ -716,6 +721,64 @@ perl () {
        command "$PERL_PATH" "$@"
 }
 
+# Is the value one of the various ways to spell a boolean true/false?
+test_normalize_bool () {
+       git -c magic.variable="$1" config --bool magic.variable 2>/dev/null
+}
+
+# Given a variable $1, normalize the value of it to one of "true",
+# "false", or "auto" and store the result to it.
+#
+#     test_tristate GIT_TEST_HTTPD
+#
+# A variable set to an empty string is set to 'false'.
+# A variable set to 'false' or 'auto' keeps its value.
+# Anything else is set to 'true'.
+# An unset variable defaults to 'auto'.
+#
+# The last rule is to allow people to set the variable to an empty
+# string and export it to decline testing the particular feature
+# for versions both before and after this change.  We used to treat
+# both unset and empty variable as a signal for "do not test" and
+# took any non-empty string as "please test".
+
+test_tristate () {
+       if eval "test x\"\${$1+isset}\" = xisset"
+       then
+               # explicitly set
+               eval "
+                       case \"\$$1\" in
+                       '')     $1=false ;;
+                       auto)   ;;
+                       *)      $1=\$(test_normalize_bool \$$1 || echo true) ;;
+                       esac
+               "
+       else
+               eval "$1=auto"
+       fi
+}
+
+# Exit the test suite, either by skipping all remaining tests or by
+# exiting with an error. If "$1" is "auto", we then we assume we were
+# opportunistically trying to set up some tests and we skip. If it is
+# "true", then we report a failure.
+#
+# The error/skip message should be given by $2.
+#
+test_skip_or_die () {
+       case "$1" in
+       auto)
+               skip_all=$2
+               test_done
+               ;;
+       true)
+               error "$2"
+               ;;
+       *)
+               error "BUG: test tristate is '$1' (real error: $2)"
+       esac
+}
+
 # The following mingw_* functions obey POSIX shell syntax, but are actually
 # bash scripts, and are meant to be used only with bash on Windows.
 
index 1531c241c08f0fad1a8e0789dbed2675b0fe5e56..569b52dc0fa32f48f37dc0d29771118cc624c5e7 100644 (file)
@@ -108,6 +108,12 @@ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 export EDITOR
 
+if test -n "${TEST_GIT_INDEX_VERSION:+isset}"
+then
+       GIT_INDEX_VERSION="$TEST_GIT_INDEX_VERSION"
+       export GIT_INDEX_VERSION
+fi
+
 # Add libc MALLOC and MALLOC_PERTURB test
 # only if we are not executing the test with valgrind
 if expr " $GIT_TEST_OPTS " : ".* --valgrind " >/dev/null ||
index a3e2643fbc5022cabb671054db7950bc991652b9..578b164fe603f11dfe67e25be36a6ab38aa6d645 100644 (file)
@@ -1,85 +1,8 @@
-#ifdef USE_WILDMATCH
-#undef USE_WILDMATCH  /* We need real fnmatch implementation here */
-#endif
 #include "cache.h"
-#include "wildmatch.h"
-
-static int perf(int ac, char **av)
-{
-       struct timeval tv1, tv2;
-       struct stat st;
-       int fd, i, n, flags1 = 0, flags2 = 0;
-       char *buffer, *p;
-       uint32_t usec1, usec2;
-       const char *lang;
-       const char *file = av[0];
-       const char *pattern = av[1];
-
-       lang = getenv("LANG");
-       if (lang && strcmp(lang, "C"))
-               die("Please test it on C locale.");
-
-       if ((fd = open(file, O_RDONLY)) == -1 || fstat(fd, &st))
-               die_errno("file open");
-
-       buffer = xmalloc(st.st_size + 2);
-       if (read(fd, buffer, st.st_size) != st.st_size)
-               die_errno("read");
-
-       buffer[st.st_size] = '\0';
-       buffer[st.st_size + 1] = '\0';
-       for (i = 0; i < st.st_size; i++)
-               if (buffer[i] == '\n')
-                       buffer[i] = '\0';
-
-       n = atoi(av[2]);
-       if (av[3] && !strcmp(av[3], "pathname")) {
-               flags1 = WM_PATHNAME;
-               flags2 = FNM_PATHNAME;
-       }
-
-       gettimeofday(&tv1, NULL);
-       for (i = 0; i < n; i++) {
-               for (p = buffer; *p; p += strlen(p) + 1)
-                       wildmatch(pattern, p, flags1, NULL);
-       }
-       gettimeofday(&tv2, NULL);
-
-       usec1 = (uint32_t)tv2.tv_sec * 1000000 + tv2.tv_usec;
-       usec1 -= (uint32_t)tv1.tv_sec * 1000000 + tv1.tv_usec;
-       printf("wildmatch %ds %dus\n",
-              (int)(usec1 / 1000000),
-              (int)(usec1 % 1000000));
-
-       gettimeofday(&tv1, NULL);
-       for (i = 0; i < n; i++) {
-               for (p = buffer; *p; p += strlen(p) + 1)
-                       fnmatch(pattern, p, flags2);
-       }
-       gettimeofday(&tv2, NULL);
-
-       usec2 = (uint32_t)tv2.tv_sec * 1000000 + tv2.tv_usec;
-       usec2 -= (uint32_t)tv1.tv_sec * 1000000 + tv1.tv_usec;
-       if (usec2 > usec1)
-               printf("fnmatch   %ds %dus or %.2f%% slower\n",
-                      (int)((usec2 - usec1) / 1000000),
-                      (int)((usec2 - usec1) % 1000000),
-                      (float)(usec2 - usec1) / usec1 * 100);
-       else
-               printf("fnmatch   %ds %dus or %.2f%% faster\n",
-                      (int)((usec1 - usec2) / 1000000),
-                      (int)((usec1 - usec2) % 1000000),
-                      (float)(usec1 - usec2) / usec1 * 100);
-       return 0;
-}
 
 int main(int argc, char **argv)
 {
        int i;
-
-       if (!strcmp(argv[1], "perf"))
-               return perf(argc - 2, argv + 2);
-
        for (i = 2; i < argc; i++) {
                if (argv[i][0] == '/')
                        die("Forward slash is not allowed at the beginning of the\n"
@@ -93,8 +16,6 @@ int main(int argc, char **argv)
                return !!wildmatch(argv[3], argv[2], WM_PATHNAME | WM_CASEFOLD, NULL);
        else if (!strcmp(argv[1], "pathmatch"))
                return !!wildmatch(argv[3], argv[2], 0, NULL);
-       else if (!strcmp(argv[1], "fnmatch"))
-               return !!fnmatch(argv[3], argv[2], FNM_PATHNAME);
        else
                return 1;
 }
index ad72fbd53cb7bfc7fc037d98288b0cc831ea949a..86e1679c1e0e1e58ebe5297f4c5f48ca1a1f6418 100644 (file)
@@ -650,7 +650,7 @@ static int push_update_ref_status(struct strbuf *buf,
                                   struct ref *remote_refs)
 {
        char *refname, *msg;
-       int status;
+       int status, forced = 0;
 
        if (starts_with(buf->buf, "ok ")) {
                status = REF_STATUS_OK;
@@ -708,6 +708,11 @@ static int push_update_ref_status(struct strbuf *buf,
                        free(msg);
                        msg = NULL;
                }
+               else if (!strcmp(msg, "forced update")) {
+                       forced = 1;
+                       free(msg);
+                       msg = NULL;
+               }
        }
 
        if (*ref)
@@ -729,12 +734,14 @@ static int push_update_ref_status(struct strbuf *buf,
        }
 
        (*ref)->status = status;
+       (*ref)->forced_update |= forced;
        (*ref)->remote_status = msg;
        return !(status == REF_STATUS_OK);
 }
 
 static void push_update_refs_status(struct helper_data *data,
-                                   struct ref *remote_refs)
+                                   struct ref *remote_refs,
+                                   int flags)
 {
        struct strbuf buf = STRBUF_INIT;
        struct ref *ref = remote_refs;
@@ -748,7 +755,7 @@ static void push_update_refs_status(struct helper_data *data,
                if (push_update_ref_status(&buf, &ref, remote_refs))
                        continue;
 
-               if (!data->refspecs || data->no_private_update)
+               if (flags & TRANSPORT_PUSH_DRY_RUN || !data->refspecs || data->no_private_update)
                        continue;
 
                /* propagate back the update to the remote namespace */
@@ -839,7 +846,7 @@ static int push_refs_with_push(struct transport *transport,
        sendline(data, &buf);
        strbuf_release(&buf);
 
-       push_update_refs_status(data, remote_refs);
+       push_update_refs_status(data, remote_refs, flags);
        return 0;
 }
 
@@ -860,6 +867,11 @@ static int push_refs_with_export(struct transport *transport,
                        die("helper %s does not support dry-run", data->name);
        }
 
+       if (flags & TRANSPORT_PUSH_FORCE) {
+               if (set_helper_option(transport, "force", "true") != 0)
+                       warning("helper %s does not support 'force'", data->name);
+       }
+
        helper = get_helper(transport);
 
        write_constant(helper->in, "export\n");
@@ -881,9 +893,6 @@ static int push_refs_with_export(struct transport *transport,
                }
                free(private);
 
-               if (ref->deletion)
-                       die("remote-helpers do not support ref deletion");
-
                if (ref->peer_ref) {
                        if (strcmp(ref->peer_ref->name, ref->name))
                                die("remote-helpers do not support old:new syntax");
@@ -896,7 +905,7 @@ static int push_refs_with_export(struct transport *transport,
 
        if (finish_command(&exporter))
                die("Error while running fast-export");
-       push_update_refs_status(data, remote_refs);
+       push_update_refs_status(data, remote_refs, flags);
        return 0;
 }
 
index 0692ebe16e62fa4b31a20ec9c28cabb041236709..97fc9954672f2c374541cad827bb5c459abebcdc 100644 (file)
@@ -203,7 +203,7 @@ static int check_updates(struct unpack_trees_options *o)
                                total++;
                }
 
-               progress = start_progress_delay("Checking out files",
+               progress = start_progress_delay(_("Checking out files"),
                                                total, 50, 1);
                cnt = 0;
        }
index 0c44f6b292563e7c87bce0b7b5d9b8a4ccd32ec3..9314c250ffd72ef44dd6b675e0f3592e3e283a04 100644 (file)
@@ -796,7 +796,7 @@ int main(int argc, char **argv)
 
        packet_trace_identity("upload-pack");
        git_extract_argv0_path(argv[0]);
-       read_replace_refs = 0;
+       check_replace_refs = 0;
 
        for (i = 1; i < argc; i++) {
                char *arg = argv[i];
diff --git a/utf8.c b/utf8.c
index 0d20e0acb2b6fb2dd1d63abed676a036b2b7ec2f..a831d5089908df61574119b01a29a1991196f63a 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -5,8 +5,8 @@
 /* This code is originally from http://www.cl.cam.ac.uk/~mgk25/ucs/ */
 
 struct interval {
-  int first;
-  int last;
+       ucs_char_t first;
+       ucs_char_t last;
 };
 
 size_t display_mode_esc_sequence_len(const char *s)
@@ -529,7 +529,7 @@ char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv, int *outs
        while (1) {
                size_t cnt = iconv(conv, &cp, &insz, &outpos, &outsz);
 
-               if (cnt == -1) {
+               if (cnt == (size_t) -1) {
                        size_t sofar;
                        if (errno != E2BIG) {
                                free(out);