Merge branch 'ab/push-example-in-doc'
authorJunio C Hamano <gitster@pobox.com>
Sat, 1 Dec 2018 12:41:44 +0000 (21:41 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sat, 1 Dec 2018 12:41:44 +0000 (21:41 +0900)
An error message that sugggests how to give correct arguments to
"git push" has been updated.

* ab/push-example-in-doc:
push: change needlessly ambiguous example in error

134 files changed:
.gitattributes
.mailmap
.travis.yml
Documentation/Makefile
Documentation/RelNotes/2.19.2.txt [new file with mode: 0644]
Documentation/RelNotes/2.20.0.txt
Documentation/config.txt
Documentation/config/index.txt
Documentation/config/rebase.txt
Documentation/git-format-patch.txt
Documentation/git-range-diff.txt
Documentation/git-reset.txt
Documentation/gitrepository-layout.txt
Documentation/technical/api-parse-options.txt
Documentation/technical/repository-version.txt
GIT-VERSION-GEN
Makefile
apply.c
archive-tar.c
attr.c
builtin/am.c
builtin/blame.c
builtin/cat-file.c
builtin/checkout-index.c
builtin/clean.c
builtin/commit.c
builtin/fast-export.c
builtin/fetch.c
builtin/grep.c
builtin/index-pack.c
builtin/init-db.c
builtin/interpret-trailers.c
builtin/log.c
builtin/ls-files.c
builtin/ls-tree.c
builtin/merge-file.c
builtin/merge.c
builtin/notes.c
builtin/pack-objects.c
builtin/pull.c
builtin/read-tree.c
builtin/rebase.c
builtin/replace.c
builtin/show-branch.c
builtin/show-ref.c
builtin/tag.c
builtin/update-index.c
bundle.c
ci/lib-travisci.sh
commit.c
commit.h
compat/mingw.c
compat/win32/pthread.c
compat/win32/pthread.h
config.c
config.h
config.mak.uname
configure.ac
contrib/coccinelle/README
diff.c
entry.c
fast-import.c
gettext.c
gettext.h
git-compat-util.h
git-legacy-rebase.sh
git-sh-i18n.sh
grep.c
grep.h
http-push.c
http.c
log-tree.c
midx.c
name-hash.c
object.h
pack-objects.h
parse-options-cb.c
parse-options.h
po/README
preload-index.c
prio-queue.c
prio-queue.h
range-diff.c
range-diff.h
read-cache.c
ref-filter.c
refs.c
refs/files-backend.c
remote-curl.c
revision.c
revision.h
run-command.c
run-command.h
send-pack.c
sequencer.c
sha1-file.c
t/README
t/helper/test-parse-options.c
t/helper/test-prio-queue.c
t/lib-gettext.sh
t/lib-git-daemon.sh
t/lib-gpg/keyring.gpg
t/perf/p3400-rebase.sh
t/t0000-basic.sh
t/t0009-prio-queue.sh
t/t0040-parse-options.sh
t/t0205-gettext-poison.sh
t/t1700-split-index.sh
t/t3206-range-diff.sh
t/t3406-rebase-message.sh
t/t3420-rebase-autostash.sh
t/t3430-rebase-merges.sh
t/t4052-stat-output.sh
t/t4136-apply-check.sh
t/t5512-ls-remote.sh
t/t5562-http-backend-content-length.sh
t/t5562/invoke-with-content-length.pl [changed mode: 0755->0644]
t/t5573-pull-verify-signatures.sh
t/t5601-clone.sh
t/t5607-clone-bundle.sh
t/t6012-rev-list-simplify.sh
t/t6018-rev-list-glob.sh
t/t6050-replace.sh
t/t6600-test-reach.sh
t/t7201-co.sh
t/t7510-signed-commit.sh
t/t7612-merge-verify-signatures.sh
t/t9902-completion.sh
t/test-lib-functions.sh
t/test-lib.sh
thread-utils.c
thread-utils.h
transport-helper.c
wt-status.c
index 49b30516419c8dfe8c039ef368a3af984439ebcc..acf853e0299463a12212e9ed5f35d7f4a9d289af 100644 (file)
@@ -5,7 +5,7 @@
 *.pl eof=lf diff=perl
 *.pm eol=lf diff=perl
 *.py eol=lf diff=python
-/Documentation/git-*.txt eol=lf
+/Documentation/**/*.txt eol=lf
 /command-list.txt eol=lf
 /GIT-VERSION-GEN eol=lf
 /mergetools/* eol=lf
index bef3352b0d3c6e84a33304b2fe44f6a68f6044a3..eb7b5fc7b97f33999eced124943728854bc2e983 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -21,6 +21,8 @@ Anders Kaseorg <andersk@MIT.EDU> <andersk@mit.edu>
 Aneesh Kumar K.V <aneesh.kumar@gmail.com>
 Amos Waterland <apw@debian.org> <apw@rossby.metr.ou.edu>
 Amos Waterland <apw@debian.org> <apw@us.ibm.com>
+Ben Peart <benpeart@microsoft.com> <Ben.Peart@microsoft.com>
+Ben Peart <benpeart@microsoft.com> <peartben@gmail.com>
 Ben Walton <bdwalton@gmail.com> <bwalton@artsci.utoronto.ca>
 Benoit Sigoure <tsunanet@gmail.com> <tsuna@lrde.epita.fr>
 Bernt Hansen <bernt@norang.ca> <bernt@alumni.uwaterloo.ca>
@@ -32,6 +34,7 @@ Bryan Larsen <bryan@larsen.st> <bryanlarsen@yahoo.com>
 Cheng Renquan <crquan@gmail.com>
 Chris Shoemaker <c.shoemaker@cox.net>
 Chris Wright <chrisw@sous-sol.org> <chrisw@osdl.org>
+Christian Ludwig <chrissicool@gmail.com> <chrissicool@googlemail.com>
 Cord Seele <cowose@gmail.com> <cowose@googlemail.com>
 Christian Couder <chriscool@tuxfamily.org> <christian.couder@gmail.com>
 Christian Stimming <stimming@tuhh.de> <chs@ckiste.goetheallee>
@@ -51,6 +54,7 @@ David Reiss <dreiss@facebook.com> <dreiss@dreiss-vmware.(none)>
 David S. Miller <davem@davemloft.net>
 David Turner <novalis@novalis.org> <dturner@twopensource.com>
 David Turner <novalis@novalis.org> <dturner@twosigma.com>
+Derrick Stolee <dstolee@microsoft.com> <stolee@gmail.com>
 Deskin Miller <deskinm@umich.edu>
 Dirk Süsserott <newsletter@dirk.my1.cc>
 Eric Blake <eblake@redhat.com> <ebb9@byu.net>
@@ -98,6 +102,7 @@ Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com>
 Jens Lindström <jl@opera.com> Jens Lindstrom <jl@opera.com>
 Jim Meyering <jim@meyering.net> <meyering@redhat.com>
 Joachim Berdal Haga <cjhaga@fys.uio.no>
+Joachim Jablon <joachim.jablon@people-doc.com> <ewjoachim@gmail.com>
 Johannes Schindelin <Johannes.Schindelin@gmx.de> <johannes.schindelin@gmx.de>
 Johannes Sixt <j6t@kdbg.org> <J.Sixt@eudaptics.com>
 Johannes Sixt <j6t@kdbg.org> <j.sixt@viscovery.net>
@@ -150,6 +155,7 @@ Mark Levedahl <mdl123@verizon.net> <mlevedahl@gmail.com>
 Mark Rada <marada@uwaterloo.ca>
 Martin Langhoff <martin@laptop.org> <martin@catalyst.net.nz>
 Martin von Zweigbergk <martinvonz@gmail.com> <martin.von.zweigbergk@gmail.com>
+Masaya Suzuki <masayasuzuki@google.com> <draftcode@gmail.com>
 Matt Draisey <matt@draisey.ca> <mattdraisey@sympatico.ca>
 Matt Kraai <kraai@ftbfs.org> <matt.kraai@amo.abbott.com>
 Matt McCutchen <matt@mattmccutchen.net> <hashproduct@gmail.com>
@@ -157,6 +163,7 @@ Matthias Kestenholz <matthias@spinlock.ch> <mk@spinlock.ch>
 Matthias Rüster <matthias.ruester@gmail.com> Matthias Ruester
 Matthias Urlichs <matthias@urlichs.de> <smurf@kiste.(none)>
 Matthias Urlichs <matthias@urlichs.de> <smurf@smurf.noris.de>
+Matthieu Moy <git@matthieu-moy.fr> <Matthieu.Moy@imag.fr>
 Michael Coleman <tutufan@gmail.com>
 Michael J Gruber <git@grubix.eu> <michaeljgruber+gmane@fastmail.fm>
 Michael J Gruber <git@grubix.eu> <git@drmicha.warpmail.net>
@@ -180,7 +187,11 @@ Nick Stokoe <nick@noodlefactory.co.uk> Nick Woolley <nick@noodlefactory.co.uk>
 Nick Stokoe <nick@noodlefactory.co.uk> Nick Woolley <nickwoolley@yahoo.co.uk>
 Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nicolas.morey@free.fr>
 Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nmorey@kalray.eu>
+Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nicolas@morey-chaisemartin.com>
+Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <NMoreyChaisemartin@suse.com>
+Nicolas Morey-Chaisemartin <devel-git@morey-chaisemartin.com> <nmoreychaisemartin@suse.com>
 Nicolas Sebrecht <nicolas.s.dev@gmx.fr> <ni.s@laposte.net>
+Orgad Shaneh <orgads@gmail.com> <orgad.shaneh@audiocodes.com>
 Paolo Bonzini <bonzini@gnu.org> <paolo.bonzini@lu.unisi.ch>
 Pascal Obry <pascal@obry.net> <pascal.obry@gmail.com>
 Pascal Obry <pascal@obry.net> <pascal.obry@wanadoo.fr>
@@ -200,6 +211,7 @@ Philipp A. Hartmann <pah@qo.cx> <ph@sorgh.de>
 Philippe Bruhat <book@cpan.org>
 Ralf Thielow <ralf.thielow@gmail.com> <ralf.thielow@googlemail.com>
 Ramsay Jones <ramsay@ramsayjones.plus.com> <ramsay@ramsay1.demon.co.uk>
+Randall S. Becker <randall.becker@nexbridge.ca> <rsbecker@nexbridge.com>
 René Scharfe <l.s.r@web.de> <rene.scharfe@lsrfire.ath.cx>
 René Scharfe <l.s.r@web.de> Rene Scharfe
 Richard Hansen <rhansen@rhansen.org> <hansenr@google.com>
@@ -238,6 +250,7 @@ Steven Walter <stevenrwalter@gmail.com> <swalter@lpdev.prtdev.lexmark.com>
 Sven Verdoolaege <skimo@kotnet.org> <Sven.Verdoolaege@cs.kuleuven.ac.be>
 Sven Verdoolaege <skimo@kotnet.org> <skimo@liacs.nl>
 SZEDER Gábor <szeder.dev@gmail.com> <szeder@ira.uka.de>
+Tao Qingyun <taoqy@ls-a.me> <845767657@qq.com>
 Tay Ray Chuan <rctay89@gmail.com>
 Ted Percival <ted@midg3t.net> <ted.percival@quest.com>
 Theodore Ts'o <tytso@mit.edu>
index a5a82d6832563d48d8e7895e9a9656cea43b97b2..03c8e4c613015476fffe3f1e071c0c9d6609df0e 100644 (file)
@@ -14,7 +14,7 @@ compiler:
 
 matrix:
   include:
-    - env: jobname=GETTEXT_POISON
+    - env: jobname=GIT_TEST_GETTEXT_POISON
       os: linux
       compiler:
       addons:
index 48d261dc2ce29aca61112ee944522a20043d6827..d5d936e6a7a3dd8839901a0dd606cdc813249c1c 100644 (file)
@@ -73,6 +73,7 @@ TECH_DOCS += technical/hash-function-transition
 TECH_DOCS += technical/http-protocol
 TECH_DOCS += technical/index-format
 TECH_DOCS += technical/long-running-process-protocol
+TECH_DOCS += technical/multi-pack-index
 TECH_DOCS += technical/pack-format
 TECH_DOCS += technical/pack-heuristics
 TECH_DOCS += technical/pack-protocol
diff --git a/Documentation/RelNotes/2.19.2.txt b/Documentation/RelNotes/2.19.2.txt
new file mode 100644 (file)
index 0000000..759e6ca
--- /dev/null
@@ -0,0 +1,108 @@
+Git v2.19.2 Release Notes
+=========================
+
+Fixes since v2.19.1
+-------------------
+
+ * "git interpret-trailers" and its underlying machinery had a buggy
+   code that attempted to ignore patch text after commit log message,
+   which triggered in various codepaths that will always get the log
+   message alone and never get such an input.
+
+ * "git rebase -i" did not clear the state files correctly when a run
+   of "squash/fixup" is aborted and then the user manually amended the
+   commit instead, which has been corrected.
+
+ * When fsmonitor is in use, after operation on submodules updates
+   .gitmodules, we lost track of the fact that we did so and relied on
+   stale fsmonitor data.
+
+ * Fix for a long-standing bug that leaves the index file corrupt when
+   it shrinks during a partial commit.
+
+ * Further fix for O_APPEND emulation on Windows
+
+ * A corner case bugfix in "git rerere" code.
+
+ * "git add ':(attr:foo)'" is not supported and is supposed to be
+   rejected while the command line arguments are parsed, but we fail
+   to reject such a command line upfront.
+
+ * "git rebase" etc. in Git 2.19 fails to abort when given an empty
+   commit log message as result of editing, which has been corrected.
+
+ * The code to backfill objects in lazily cloned repository did not
+   work correctly, which has been corrected.
+
+ * Update error messages given by "git remote" and make them consistent.
+
+ * "git update-ref" learned to make both "--no-deref" and "--stdin"
+   work at the same time.
+
+ * Recently added "range-diff" had a corner-case bug to cause it
+   segfault, which has been corrected.
+
+ * The recently introduced commit-graph auxiliary data is incompatible
+   with mechanisms such as replace & grafts that "breaks" immutable
+   nature of the object reference relationship.  Disable optimizations
+   based on its use (and updating existing commit-graph) when these
+   incompatible features are in use in the repository.
+
+ * The mailmap file update.
+
+ * The code in "git status" sometimes hit an assertion failure.  This
+   was caused by a structure that was reused without cleaning the data
+   used for the first run, which has been corrected.
+
+ * A corner-case bugfix.
+
+ * A partial clone that is configured to lazily fetch missing objects
+   will on-demand issue a "git fetch" request to the originating
+   repository to fill not-yet-obtained objects.  The request has been
+   optimized for requesting a tree object (and not the leaf blob
+   objects contained in it) by telling the originating repository that
+   no blobs are needed.
+
+ * The codepath to support the experimental split-index mode had
+   remaining "racily clean" issues fixed.
+
+ * "git log --graph" showing an octopus merge sometimes miscounted the
+   number of display columns it is consuming to show the merge and its
+   parent commits, which has been corrected.
+
+ * The implementation of run_command() API on the UNIX platforms had a
+   bug that caused a command not on $PATH to be found in the current
+   directory.
+
+ * A mutex used in "git pack-objects" were not correctly initialized
+   and this caused "git repack" to dump core on Windows.
+
+ * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
+   Windows would strip initial parts from the paths because they
+   were not recognized as absolute, which has been corrected.
+
+ * The receive.denyCurrentBranch=updateInstead codepath kicked in even
+   when the push should have been rejected due to other reasons, such
+   as it does not fast-forward or the update-hook rejects it, which
+   has been corrected.
+
+ * "git repack" in a shallow clone did not correctly update the
+   shallow points in the repository, leading to a repository that
+   does not pass fsck.
+
+ * Operations on promisor objects make sense in the context of only a
+   small subset of the commands that internally use the revisions
+   machinery, but the "--exclude-promisor-objects" option were taken
+   and led to nonsense results by commands like "log", to which it
+   didn't make much sense.  This has been corrected.
+
+ * The "container" mode of TravisCI is going away.  Our .travis.yml
+   file is getting prepared for the transition.
+
+ * Our test scripts can now take the '-V' option as a synonym for the
+   '--verbose-log' option.
+
+ * A regression in Git 2.12 era made "git fsck" fall into an infinite
+   loop while processing truncated loose objects.
+
+Also contains various documentation updates and code clean-ups.
index 519c89407cf3f2e155042f52bebfe0a68f949714..8e266647f0c4b3a514e1e4e035eb1a760c9f38f9 100644 (file)
@@ -1,5 +1,5 @@
-Git Release Notes
-=================
+Git 2.20 Release Notes
+======================
 
 Backward Compatibility Notes
 ----------------------------
@@ -173,6 +173,15 @@ UI, Workflows & Features
    each other.
    (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).
 
+ * The "--no-patch" option, which can be used to get a high-level
+   overview without the actual line-by-line patch difference shown, of
+   the "range-diff" command was earlier broken, which has been
+   corrected.
+
+ * The recently merged "rebase in C" has an escape hatch to use the
+   scripted version when necessary, but it hasn't been documented,
+   which has been corrected.
+
 
 Performance, Internal Implementation, Development Support etc.
 
@@ -249,8 +258,8 @@ Performance, Internal Implementation, Development Support etc.
    used during tests are getting renamed for consistency.
    (merge 4231d1ba99 bp/rename-test-env-var later to maint).
 
- * A new extension to the index file has been introduced, which allows
-   the index file to be read in parallel for performance.
+ * A pair of new extensions to the index file have been introduced.
+   They allow the index file to be read in parallel for performance.
 
  * The oidset API was built on top of the oidmap API which in turn is
    on the hashmap API.  Replace the implementation to build on top of
@@ -332,6 +341,52 @@ Performance, Internal Implementation, Development Support etc.
  * The support for format-patch (and send-email) by the command-line
    completion script (in contrib/) has been simplified a bit.
 
+ * The revision walker machinery learned to take advantage of the
+   commit generation numbers stored in the commit-graph file.
+
+ * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".
+
+ * The way -lcurl library gets linked has been simplified by taking
+   advantage of the fact that we can just ask curl-config command how.
+
+ * Various functions have been audited for "-Wunused-parameter" warnings
+   and bugs in them got fixed.
+
+ * A sanity check for start-up sequence has been added in the config
+   API codepath.
+
+ * The build procedure to link for fuzzing test has been made
+   customizable with a new Makefile variable.
+
+ * The way "git rebase" parses and forwards the command line options
+   meant for underlying "git am" has been revamped, which fixed for
+   options with parameters that were not passed correctly.
+
+ * Our testing framework uses a special i18n "poisoned localization"
+   feature to find messages that ought to stay constant but are
+   incorrectly marked to be translated.  This feature has been made
+   into a runtime option (it used to be a compile-time option).
+
+ * "git push" used to check ambiguities between object-names and
+   refnames while processing the list of refs' old and new values,
+   which was unnecessary (as it knew that it is feeding raw object
+   names).  This has been optimized out.
+
+ * The xcurl_off_t() helper function is used to cast size_t to
+   curl_off_t, but some compilers gave warnings against the code to
+   ensure the casting is done without wraparound, when size_t is
+   narrower than curl_off_t.  This warning has been squelched.
+
+ * Code preparation to replace ulong vars with size_t vars where
+   appropriate continues.
+
+ * The "test installed Git" mode of our test suite has been updated to
+   work better.
+
+ * A coding convention around the Coccinelle semantic patches to have
+   two classes to ease code migration process has been proposed and
+   its support has been added to the Makefile.
+
 
 Fixes since v2.19
 -----------------
@@ -544,6 +599,46 @@ Fixes since v2.19
    pathspec elements were involved, which has been fixed.
    (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).
 
+ * "git merge" and "git pull" that merges into an unborn branch used
+   to completely ignore "--verify-signatures", which has been
+   corrected.
+   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).
+
+ * "git rebase --autostash" did not correctly re-attach the HEAD at times.
+
+ * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
+   quite work, which has been corrected.
+   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).
+
+ * When editing a patch in a "git add -i" session, a hunk could be
+   made to no-op.  The "git apply" program used to reject a patch with
+   such a no-op hunk to catch user mistakes, but it is now updated to
+   explicitly allow a no-op hunk in an edited patch.
+   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).
+
+ * The URL to an MSDN page in a comment has been updated.
+   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).
+
+ * "git ls-remote --sort=<thing>" can feed an object that is not yet
+   available into the comparison machinery and segfault, which has
+   been corrected to check such a request upfront and reject it.
+
+ * When "git bundle" aborts due to an empty commit ranges
+   (i.e. resulting in an empty pack), it left a file descriptor to an
+   lockfile open, which resulted in leftover lockfile on Windows where
+   you cannot remove a file with an open file descriptor.  This has
+   been corrected.
+   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).
+
+ * "git format-patch --stat=<width>" can be used to specify the width
+   used by the diffstat (shown in the cover letter).
+   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).
+
+ * The way .git/index and .git/sharedindex* files were initially
+   created gave these files different perm bits until they were
+   adjusted for shared repository settings.  This was made consistent.
+   (merge c9d6c78870 cc/shared-index-permbits later to maint).
+
  * Code cleanup, docfix, build fix, etc.
    (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
    (merge b9b07efdb2 tg/conflict-marker-size later to maint).
@@ -583,3 +678,4 @@ Fixes since v2.19
    (merge 3063477445 tb/char-may-be-unsigned later to maint).
    (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
    (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
+   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).
index 3e735f1a9a092eef091aaa4c7536aecff1f2807f..d87846faa6c3ffad7cba97fe7348ef97e0112899 100644 (file)
@@ -292,13 +292,6 @@ include::config/advice.txt[]
 
 include::config/core.txt[]
 
-extensions.worktreeConfig::
-       If set, by default "git config" reads from both "config" and
-       "config.worktree" file from GIT_DIR in that order. In
-       multiple working directory mode, "config" file is shared while
-       "config.worktree" is per-working directory (i.e., it's in
-       GIT_COMMON_DIR/worktrees/<id>/config.worktree)
-
 include::config/add.txt[]
 
 include::config/alias.txt[]
index 4b94b6bedc03071109998ee7d27cf50c53e4194b..f18150304106891ad388a7620594937b43e7615e 100644 (file)
@@ -1,3 +1,19 @@
+index.recordEndOfIndexEntries::
+       Specifies whether the index file should include an "End Of Index
+       Entry" section. This reduces index load time on multiprocessor
+       machines but produces a message "ignoring EOIE extension" when
+       reading the index using Git versions before 2.20. Defaults to
+       'true' if index.threads has been explicitly enabled, 'false'
+       otherwise.
+
+index.recordOffsetTable::
+       Specifies whether the index file should include an "Index Entry
+       Offset Table" section. This reduces index load time on
+       multiprocessor machines but produces a message "ignoring IEOT
+       extension" when reading the index using Git versions before 2.20.
+       Defaults to 'true' if index.threads has been explicitly enabled,
+       'false' otherwise.
+
 index.threads::
        Specifies the number of threads to spawn when loading the index.
        This is meant to reduce index load time on multiprocessor machines.
index 42e1ba757564e3ccff6da48895a06a65e03fa524..f079bf6b7e5d88e012074a223a785f8de5949f78 100644 (file)
@@ -1,3 +1,17 @@
+rebase.useBuiltin::
+       Set to `false` to use the legacy shellscript implementation of
+       linkgit:git-rebase[1]. Is `true` by default, which means use
+       the built-in rewrite of it in C.
++
+The C rewrite is first included with Git version 2.20. This option
+serves an an escape hatch to re-enable the legacy version in case any
+bugs are found in the rewrite. This option and the shellscript version
+of linkgit:git-rebase[1] will be removed in some future release.
++
+If you find some reason to set this option to `false` other than
+one-off testing you should report the behavior difference as a bug in
+git.
+
 rebase.stat::
        Whether to show a diffstat of what changed upstream since the last
        rebase. False by default.
index aba4c5febeb7ef4248d50a638d0a8bd58f7d553b..27304428a12ce9d0ee46e10e3c63069b4677838a 100644 (file)
@@ -250,6 +250,11 @@ feeding the result to `git send-email`.
        feature/v2`), or a revision range if the two versions of the series are
        disjoint (for example `git format-patch --cover-letter
        --range-diff=feature/v1~3..feature/v1 -3 feature/v2`).
++
+Note that diff options passed to the command affect how the primary
+product of `format-patch` is generated, and they are not passed to
+the underlying `range-diff` machinery used to generate the cover-letter
+material (this may change in the future).
 
 --creation-factor=<percent>::
        Used with `--range-diff`, tweak the heuristic which matches up commits
index f693930fdb502ac85cf99eae4d206c3d4962b247..8a6ea2c6c5c7a39a9f34d6b93388f3343c1e3026 100644 (file)
@@ -78,6 +78,23 @@ between patches", i.e. to compare the author, commit message and diff of
 corresponding old/new commits. There is currently no means to tweak the
 diff options passed to `git log` when generating those patches.
 
+OUTPUT STABILITY
+----------------
+
+The output of the `range-diff` command is subject to change. It is
+intended to be human-readable porcelain output, not something that can
+be used across versions of Git to get a textually stable `range-diff`
+(as opposed to something like the `--stable` option to
+linkgit:git-patch-id[1]). There's also no equivalent of
+linkgit:git-apply[1] for `range-diff`, the output is not intended to
+be machine-readable.
+
+This is particularly true when passing in diff options. Currently some
+options like `--stat` can, as an emergent effect, produce output
+that's quite useless in the context of `range-diff`. Future versions
+of `range-diff` may learn to interpret such options in a manner
+specific to `range-diff` (e.g. for `--stat` producing human-readable
+output which summarizes how the diffstat changed).
 
 CONFIGURATION
 -------------
index 2dac95c71a510b2cead5f39fd0dc5f03816ae5c4..9f69ae8b693a15184f26f65a44e552fb31a0bd32 100644 (file)
@@ -14,14 +14,14 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-In the first and second form, copy entries from <tree-ish> to the index.
-In the third form, set the current branch head (HEAD) to <commit>, optionally
-modifying index and working tree to match.  The <tree-ish>/<commit> defaults
-to HEAD in all forms.
+In the first and second form, copy entries from `<tree-ish>` to the index.
+In the third form, set the current branch head (`HEAD`) to `<commit>`,
+optionally modifying index and working tree to match.
+The `<tree-ish>`/`<commit>` defaults to `HEAD` in all forms.
 
 'git reset' [-q] [<tree-ish>] [--] <paths>...::
-       This form resets the index entries for all <paths> to their
-       state at <tree-ish>.  (It does not affect the working tree or
+       This form resets the index entries for all `<paths>` to their
+       state at `<tree-ish>`.  (It does not affect the working tree or
        the current branch.)
 +
 This means that `git reset <paths>` is the opposite of `git add
@@ -36,7 +36,7 @@ working tree in one go.
 
 'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...]::
        Interactively select hunks in the difference between the index
-       and <tree-ish> (defaults to HEAD).  The chosen hunks are applied
+       and `<tree-ish>` (defaults to `HEAD`).  The chosen hunks are applied
        in reverse to the index.
 +
 This means that `git reset -p` is the opposite of `git add -p`, i.e.
@@ -44,16 +44,16 @@ you can use it to selectively reset hunks. See the ``Interactive Mode''
 section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 
 'git reset' [<mode>] [<commit>]::
-       This form resets the current branch head to <commit> and
-       possibly updates the index (resetting it to the tree of <commit>) and
-       the working tree depending on <mode>. If <mode> is omitted,
-       defaults to "--mixed". The <mode> must be one of the following:
+       This form resets the current branch head to `<commit>` and
+       possibly updates the index (resetting it to the tree of `<commit>`) and
+       the working tree depending on `<mode>`. If `<mode>` is omitted,
+       defaults to `--mixed`. The `<mode>` must be one of the following:
 +
 --
 --soft::
        Does not touch the index file or the working tree at all (but
-       resets the head to <commit>, just like all modes do). This leaves
-       all your changed files "Changes to be committed", as 'git status'
+       resets the head to `<commit>`, just like all modes do). This leaves
+       all your changed files "Changes to be committed", as `git status`
        would put it.
 
 --mixed::
@@ -66,24 +66,24 @@ linkgit:git-add[1]).
 
 --hard::
        Resets the index and working tree. Any changes to tracked files in the
-       working tree since <commit> are discarded.
+       working tree since `<commit>` are discarded.
 
 --merge::
        Resets the index and updates the files in the working tree that are
-       different between <commit> and HEAD, but keeps those which are
+       different between `<commit>` and `HEAD`, but keeps those which are
        different between the index and working tree (i.e. which have changes
        which have not been added).
-       If a file that is different between <commit> and the index has unstaged
-       changes, reset is aborted.
+       If a file that is different between `<commit>` and the index has
+       unstaged changes, reset is aborted.
 +
-In other words, --merge does something like a 'git read-tree -u -m <commit>',
+In other words, `--merge` does something like a `git read-tree -u -m <commit>`,
 but carries forward unmerged index entries.
 
 --keep::
        Resets index entries and updates files in the working tree that are
-       different between <commit> and HEAD.
-       If a file that is different between <commit> and HEAD has local changes,
-       reset is aborted.
+       different between `<commit>` and `HEAD`.
+       If a file that is different between `<commit>` and `HEAD` has local
+       changes, reset is aborted.
 --
 
 If you want to undo a commit other than the latest on a branch,
@@ -116,15 +116,15 @@ $ git pull git://info.example.com/ nitfol  <4>
 +
 <1> You are happily working on something, and find the changes
 in these files are in good order.  You do not want to see them
-when you run "git diff", because you plan to work on other files
+when you run `git diff`, because you plan to work on other files
 and changes with these files are distracting.
 <2> Somebody asks you to pull, and the changes sound worthy of merging.
 <3> However, you already dirtied the index (i.e. your index does
-not match the HEAD commit).  But you know the pull you are going
-to make does not affect frotz.c or filfre.c, so you revert the
+not match the `HEAD` commit).  But you know the pull you are going
+to make does not affect `frotz.c` or `filfre.c`, so you revert the
 index changes for these two files.  Your changes in working tree
 remain there.
-<4> Then you can pull and merge, leaving frotz.c and filfre.c
+<4> Then you can pull and merge, leaving `frotz.c` and `filfre.c`
 changes still in the working tree.
 
 Undo a commit and redo::
@@ -140,11 +140,11 @@ $ git commit -a -c ORIG_HEAD  <3>
 just committed is incomplete, or you misspelled your commit
 message, or both.  Leaves working tree as it was before "reset".
 <2> Make corrections to working tree files.
-<3> "reset" copies the old head to .git/ORIG_HEAD; redo the
+<3> "reset" copies the old head to `.git/ORIG_HEAD`; redo the
 commit by starting with its log message.  If you do not need to
-edit the message further, you can give -C option instead.
+edit the message further, you can give `-C` option instead.
 +
-See also the --amend option to linkgit:git-commit[1].
+See also the `--amend` option to linkgit:git-commit[1].
 
 Undo a commit, making it a topic branch::
 +
@@ -155,11 +155,11 @@ $ git checkout topic/wip   <3>
 ------------
 +
 <1> You have made some commits, but realize they were premature
-to be in the "master" branch.  You want to continue polishing
-them in a topic branch, so create "topic/wip" branch off of the
-current HEAD.
+to be in the `master` branch.  You want to continue polishing
+them in a topic branch, so create `topic/wip` branch off of the
+current `HEAD`.
 <2> Rewind the master branch to get rid of those three commits.
-<3> Switch to "topic/wip" branch and keep working.
+<3> Switch to `topic/wip` branch and keep working.
 
 Undo commits permanently::
 +
@@ -168,7 +168,7 @@ $ git commit ...
 $ git reset --hard HEAD~3   <1>
 ------------
 +
-<1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad
+<1> The last three commits (`HEAD`, `HEAD^`, and `HEAD~2`) were bad
 and you do not want to ever see them again.  Do *not* do this if
 you have already given these commits to somebody else.  (See the
 "RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for
@@ -191,14 +191,14 @@ $ git reset --hard ORIG_HEAD       <4>
 <1> Try to update from the upstream resulted in a lot of
 conflicts; you were not ready to spend a lot of time merging
 right now, so you decide to do that later.
-<2> "pull" has not made merge commit, so "git reset --hard"
-which is a synonym for "git reset --hard HEAD" clears the mess
+<2> "pull" has not made merge commit, so `git reset --hard`
+which is a synonym for `git reset --hard HEAD` clears the mess
 from the index file and the working tree.
 <3> Merge a topic branch into the current branch, which resulted
 in a fast-forward.
 <4> But you decided that the topic branch is not ready for public
 consumption yet.  "pull" or "merge" always leaves the original
-tip of the current branch in ORIG_HEAD, so resetting hard to it
+tip of the current branch in `ORIG_HEAD`, so resetting hard to it
 brings your index file and the working tree back to that state,
 and resets the tip of the branch to that commit.
 
@@ -214,14 +214,14 @@ $ git reset --merge ORIG_HEAD      <2>
 ------------
 +
 <1> Even if you may have local modifications in your
-working tree, you can safely say "git pull" when you know
+working tree, you can safely say `git pull` when you know
 that the change in the other branch does not overlap with
 them.
 <2> After inspecting the result of the merge, you may find
 that the change in the other branch is unsatisfactory.  Running
-"git reset --hard ORIG_HEAD" will let you go back to where you
+`git reset --hard ORIG_HEAD` will let you go back to where you
 were, but it will discard your local changes, which you do not
-want.  "git reset --merge" keeps your local changes.
+want.  `git reset --merge` keeps your local changes.
 
 
 Interrupted workflow::
@@ -287,13 +287,13 @@ $ git checkout -b branch2                   <2>
 $ git reset --keep start                    <3>
 ------------
 +
-<1> This commits your first edits in branch1.
+<1> This commits your first edits in `branch1`.
 <2> In the ideal world, you could have realized that the earlier
     commit did not belong to the new topic when you created and switched
-    to branch2 (i.e. "git checkout -b branch2 start"), but nobody is
+    to `branch2` (i.e. `git checkout -b branch2 start`), but nobody is
     perfect.
-<3> But you can use "reset --keep" to remove the unwanted commit after
-    you switched to "branch2".
+<3> But you can use `reset --keep` to remove the unwanted commit after
+    you switched to `branch2`.
 
 Split a commit apart into a sequence of commits::
 +
@@ -317,26 +317,27 @@ $ git commit ...                            <8>
 +
 <1> First, reset the history back one commit so that we remove the original
     commit, but leave the working tree with all the changes. The -N ensures
-    that any new files added with HEAD are still marked so that git add -p
+    that any new files added with `HEAD` are still marked so that `git add -p`
     will find them.
-<2> Next, we interactively select diff hunks to add using the git add -p
+<2> Next, we interactively select diff hunks to add using the `git add -p`
     facility. This will ask you about each diff hunk in sequence and you can
     use simple commands such as "yes, include this", "No don't include this"
     or even the very powerful "edit" facility.
 <3> Once satisfied with the hunks you want to include, you should verify what
-    has been prepared for the first commit by using git diff --cached. This
+    has been prepared for the first commit by using `git diff --cached`. This
     shows all the changes that have been moved into the index and are about
     to be committed.
-<4> Next, commit the changes stored in the index. The -c option specifies to
+<4> Next, commit the changes stored in the index. The `-c` option specifies to
     pre-populate the commit message from the original message that you started
-    with in the first commit. This is helpful to avoid retyping it. The HEAD@{1}
-    is a special notation for the commit that HEAD used to be at prior to the
-    original reset commit (1 change ago). See linkgit:git-reflog[1] for more
-    details. You may also use any other valid commit reference.
+    with in the first commit. This is helpful to avoid retyping it. The
+    `HEAD@{1}` is a special notation for the commit that `HEAD` used to be at
+    prior to the original reset commit (1 change ago).
+    See linkgit:git-reflog[1] for more details. You may also use any other
+    valid commit reference.
 <5> You can repeat steps 2-4 multiple times to break the original code into
     any number of commits.
 <6> Now you've split out many of the changes into their own commits, and might
-    no longer use the patch mode of git add, in order to select all remaining
+    no longer use the patch mode of `git add`, in order to select all remaining
     uncommitted changes.
 <7> Once again, check to verify that you've included what you want to. You may
     also wish to verify that git diff doesn't show any remaining changes to be
@@ -353,104 +354,120 @@ The tables below show what happens when running:
 git reset --option target
 ----------
 
-to reset the HEAD to another commit (`target`) with the different
+to reset the `HEAD` to another commit (`target`) with the different
 reset options depending on the state of the files.
 
-In these tables, A, B, C and D are some different states of a
+In these tables, `A`, `B`, `C` and `D` are some different states of a
 file. For example, the first line of the first table means that if a
-file is in state A in the working tree, in state B in the index, in
-state C in HEAD and in state D in the target, then "git reset --soft
-target" will leave the file in the working tree in state A and in the
-index in state B.  It resets (i.e. moves) the HEAD (i.e. the tip of
-the current branch, if you are on one) to "target" (which has the file
-in state D).
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       A       B     C    D     --soft   A       B     D
-                               --mixed  A       D     D
-                               --hard   D       D     D
-                               --merge (disallowed)
-                               --keep  (disallowed)
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       A       B     C    C     --soft   A       B     C
-                               --mixed  A       C     C
-                               --hard   C       C     C
-                               --merge (disallowed)
-                               --keep   A       C     C
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       B     C    D     --soft   B       B     D
-                               --mixed  B       D     D
-                               --hard   D       D     D
-                               --merge  D       D     D
-                               --keep  (disallowed)
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       B     C    C     --soft   B       B     C
-                               --mixed  B       C     C
-                               --hard   C       C     C
-                               --merge  C       C     C
-                               --keep   B       C     C
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       C     C    D     --soft   B       C     D
-                               --mixed  B       D     D
-                               --hard   D       D     D
-                               --merge (disallowed)
-                               --keep  (disallowed)
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       B       C     C    C     --soft   B       C     C
-                               --mixed  B       C     C
-                               --hard   C       C     C
-                               --merge  B       C     C
-                               --keep   B       C     C
-
-"reset --merge" is meant to be used when resetting out of a conflicted
+file is in state `A` in the working tree, in state `B` in the index, in
+state `C` in `HEAD` and in state `D` in the target, then `git reset --soft
+target` will leave the file in the working tree in state `A` and in the
+index in state `B`.  It resets (i.e. moves) the `HEAD` (i.e. the tip of
+the current branch, if you are on one) to `target` (which has the file
+in state `D`).
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ A       B     C    D     --soft   A       B     D
+                         --mixed  A       D     D
+                         --hard   D       D     D
+                         --merge (disallowed)
+                         --keep  (disallowed)
+....
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ A       B     C    C     --soft   A       B     C
+                         --mixed  A       C     C
+                         --hard   C       C     C
+                         --merge (disallowed)
+                         --keep   A       C     C
+....
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       B     C    D     --soft   B       B     D
+                         --mixed  B       D     D
+                         --hard   D       D     D
+                         --merge  D       D     D
+                         --keep  (disallowed)
+....
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       B     C    C     --soft   B       B     C
+                         --mixed  B       C     C
+                         --hard   C       C     C
+                         --merge  C       C     C
+                         --keep   B       C     C
+....
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       C     C    D     --soft   B       C     D
+                         --mixed  B       D     D
+                         --hard   D       D     D
+                         --merge (disallowed)
+                         --keep  (disallowed)
+....
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ B       C     C    C     --soft   B       C     C
+                         --mixed  B       C     C
+                         --hard   C       C     C
+                         --merge  B       C     C
+                         --keep   B       C     C
+....
+
+`reset --merge` is meant to be used when resetting out of a conflicted
 merge. Any mergy operation guarantees that the working tree file that is
 involved in the merge does not have local change wrt the index before
 it starts, and that it writes the result out to the working tree. So if
 we see some difference between the index and the target and also
 between the index and the working tree, then it means that we are not
 resetting out from a state that a mergy operation left after failing
-with a conflict. That is why we disallow --merge option in this case.
+with a conflict. That is why we disallow `--merge` option in this case.
 
-"reset --keep" is meant to be used when removing some of the last
+`reset --keep` is meant to be used when removing some of the last
 commits in the current branch while keeping changes in the working
 tree. If there could be conflicts between the changes in the commit we
 want to remove and the changes in the working tree we want to keep,
 the reset is disallowed. That's why it is disallowed if there are both
-changes between the working tree and HEAD, and between HEAD and the
+changes between the working tree and `HEAD`, and between `HEAD` and the
 target. To be safe, it is also disallowed when there are unmerged
 entries.
 
 The following tables show what happens when there are unmerged
 entries:
 
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       X       U     A    B     --soft  (disallowed)
-                               --mixed  X       B     B
-                               --hard   B       B     B
-                               --merge  B       B     B
-                               --keep  (disallowed)
-
-      working index HEAD target         working index HEAD
-      ----------------------------------------------------
-       X       U     A    A     --soft  (disallowed)
-                               --mixed  X       A     A
-                               --hard   A       A     A
-                               --merge  A       A     A
-                               --keep  (disallowed)
-
-X means any state and U means an unmerged index.
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ X       U     A    B     --soft  (disallowed)
+                         --mixed  X       B     B
+                         --hard   B       B     B
+                         --merge  B       B     B
+                         --keep  (disallowed)
+....
+
+....
+working index HEAD target         working index HEAD
+----------------------------------------------------
+ X       U     A    A     --soft  (disallowed)
+                         --mixed  X       A     A
+                         --hard   A       A     A
+                         --merge  A       A     A
+                         --keep  (disallowed)
+....
+
+`X` means any state and `U` means an unmerged index.
 
 GIT
 ---
index d501af9d776edc6890aeea51e3581a3f9bb22049..366dee238c22486a5a934c4184eaafb1723db4e2 100644 (file)
@@ -290,6 +290,8 @@ worktrees/<id>/locked::
 worktrees/<id>/config.worktree::
        Working directory specific configuration file.
 
+include::technical/repository-version.txt[]
+
 SEE ALSO
 --------
 linkgit:git-init[1],
index 829b5581105468d4d3b457e60b10cdbdf317fbbc..2b036d7838ef906153a29cf0e17d57a1dbe93109 100644 (file)
@@ -183,10 +183,6 @@ There are some macros to easily define options:
        scale the provided value by 1024, 1024^2 or 1024^3 respectively.
        The scaled value is put into `unsigned_long_var`.
 
-`OPT_DATE(short, long, &timestamp_t_var, description)`::
-       Introduce an option with date argument, see `approxidate()`.
-       The timestamp is put into `timestamp_t_var`.
-
 `OPT_EXPIRY_DATE(short, long, &timestamp_t_var, description)`::
        Introduce an option with expiry date argument, see `parse_expiry_date()`.
        The timestamp is put into `timestamp_t_var`.
index e03eaccebc9c28acf29408060b2f76d7161db0d6..7844ef30ffdefd9158ae49ddd5d03d6a5c4edd4c 100644 (file)
@@ -1,5 +1,4 @@
-Git Repository Format Versions
-==============================
+== Git Repository Format Versions
 
 Every git repository is marked with a numeric version in the
 `core.repositoryformatversion` key of its `config` file. This version
@@ -40,16 +39,14 @@ format by default.
 
 The currently defined format versions are:
 
-Version `0`
------------
+=== Version `0`
 
 This is the format defined by the initial version of git, including but
 not limited to the format of the repository directory, the repository
 configuration file, and the object and ref storage. Specifying the
 complete behavior of git is beyond the scope of this document.
 
-Version `1`
------------
+=== Version `1`
 
 This format is identical to version `0`, with the following exceptions:
 
@@ -74,21 +71,18 @@ it here, in order to claim the name.
 
 The defined extensions are:
 
-`noop`
-~~~~~~
+==== `noop`
 
 This extension does not change git's behavior at all. It is useful only
 for testing format-1 compatibility.
 
-`preciousObjects`
-~~~~~~~~~~~~~~~~~
+==== `preciousObjects`
 
 When the config key `extensions.preciousObjects` is set to `true`,
 objects in the repository MUST NOT be deleted (e.g., by `git-prune` or
 `git repack -d`).
 
-`partialclone`
-~~~~~~~~~~~~~~
+==== `partialclone`
 
 When the config key `extensions.partialclone` is set, it indicates
 that the repo was created with a partial clone (or later performed
@@ -98,3 +92,11 @@ and it promises that all such omitted objects can be fetched from it
 in the future.
 
 The value of this key is the name of the promisor remote.
+
+==== `worktreeConfig`
+
+If set, by default "git config" reads from both "config" and
+"config.worktree" file from GIT_DIR in that order. In
+multiple working directory mode, "config" file is shared while
+"config.worktree" is per-working directory (i.e., it's in
+GIT_COMMON_DIR/worktrees/<id>/config.worktree)
index 498fce8b64af4af730bfe736b43c0ce311fc85a3..bc158744221facf88b0d8f4b34d86168036fee65 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.19.GIT
+DEF_VER=v2.20.0-rc1
 
 LF='
 '
index 016fdcdb817c00b2bced052a92c8a421bfef0e73..1a44c811aa56330327172cf693c61f9a221e4e16 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,13 @@ all::
 # Define CURL_CONFIG to curl's configuration program that prints information
 # about the library (e.g., its version number).  The default is 'curl-config'.
 #
+# Define CURL_LDFLAGS to specify flags that you need to link when using libcurl,
+# if you do not want to rely on the libraries provided by CURL_CONFIG.  The
+# default value is a result of `curl-config --libs`.  An example value for
+# CURL_LDFLAGS is as follows:
+#
+#     CURL_LDFLAGS=-lcurl
+#
 # Define NO_EXPAT if you do not have expat installed.  git-http-push is
 # not built, and you cannot push using http:// and https:// transports (dumb).
 #
@@ -183,10 +190,6 @@ all::
 #
 # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
 #
-# Define NEEDS_SSL_WITH_CURL if you need -lssl with -lcurl (Minix).
-#
-# Define NEEDS_IDN_WITH_CURL if you need -lidn when using -lcurl (Minix).
-#
 # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
 #
 # Define NEEDS_LIBINTL_BEFORE_LIBICONV if you need libintl before libiconv.
@@ -207,10 +210,12 @@ all::
 # Define MMAP_PREVENTS_DELETE if a file that is currently mmapped cannot be
 # deleted or cannot be replaced using rename().
 #
+# Define NO_POLL_H if you don't have poll.h.
+#
 # Define NO_SYS_POLL_H if you don't have sys/poll.h.
 #
 # Define NO_POLL if you do not have or don't want to use poll().
-# This also implies NO_SYS_POLL_H.
+# This also implies NO_POLL_H and NO_SYS_POLL_H.
 #
 # Define NEEDS_SYS_PARAM_H if you need to include sys/param.h to compile,
 # *PLEASE* REPORT to git@vger.kernel.org if your platform needs this;
@@ -362,11 +367,6 @@ all::
 # Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
 # user.
 #
-# Define GETTEXT_POISON if you are debugging the choice of strings marked
-# for translation.  In a GETTEXT_POISON build, you can turn all strings marked
-# for translation into gibberish by setting the GIT_GETTEXT_POISON variable
-# (to any value) in your environment.
-#
 # Define JSMIN to point to JavaScript minifier that functions as
 # a filter to have gitweb.js minified.
 #
@@ -993,6 +993,7 @@ LIB_OBJS += sub-process.o
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
 LIB_OBJS += tempfile.o
+LIB_OBJS += thread-utils.o
 LIB_OBJS += tmp-objdir.o
 LIB_OBJS += trace.o
 LIB_OBJS += trailer.o
@@ -1308,20 +1309,17 @@ else
        ifdef CURLDIR
                # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case.
                BASIC_CFLAGS += -I$(CURLDIR)/include
-               CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl
+               CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib)
        else
-               CURL_LIBCURL = -lcurl
-       endif
-       ifdef NEEDS_SSL_WITH_CURL
-               CURL_LIBCURL += -lssl
-               ifdef NEEDS_CRYPTO_WITH_SSL
-                       CURL_LIBCURL += -lcrypto
-               endif
-       endif
-       ifdef NEEDS_IDN_WITH_CURL
-               CURL_LIBCURL += -lidn
+               CURL_LIBCURL =
        endif
 
+ifdef CURL_LDFLAGS
+       CURL_LIBCURL += $(CURL_LDFLAGS)
+else
+       CURL_LIBCURL += $(shell $(CURL_CONFIG) --libs)
+endif
+
        REMOTE_CURL_PRIMARY = git-remote-http$X
        REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X
        REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES)
@@ -1453,13 +1451,14 @@ ifdef NO_SYMLINK_HEAD
        BASIC_CFLAGS += -DNO_SYMLINK_HEAD
 endif
 ifdef GETTEXT_POISON
-       BASIC_CFLAGS += -DGETTEXT_POISON
+$(warning The GETTEXT_POISON option has been removed in favor of runtime GIT_TEST_GETTEXT_POISON. See t/README!)
 endif
 ifdef NO_GETTEXT
        BASIC_CFLAGS += -DNO_GETTEXT
        USE_GETTEXT_SCHEME ?= fallthrough
 endif
 ifdef NO_POLL
+       NO_POLL_H = YesPlease
        NO_SYS_POLL_H = YesPlease
        COMPAT_CFLAGS += -DNO_POLL -Icompat/poll
        COMPAT_OBJS += compat/poll/poll.o
@@ -1498,6 +1497,9 @@ endif
 ifdef NO_SYS_SELECT_H
        BASIC_CFLAGS += -DNO_SYS_SELECT_H
 endif
+ifdef NO_POLL_H
+       BASIC_CFLAGS += -DNO_POLL_H
+endif
 ifdef NO_SYS_POLL_H
        BASIC_CFLAGS += -DNO_SYS_POLL_H
 endif
@@ -1677,7 +1679,6 @@ ifdef NO_PTHREADS
 else
        BASIC_CFLAGS += $(PTHREAD_CFLAGS)
        EXTLIBS += $(PTHREAD_LIBS)
-       LIB_OBJS += thread-utils.o
 endif
 
 ifdef HAVE_PATHS_H
@@ -2111,7 +2112,7 @@ $(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES
        $(QUIET_GEN)$(cmd_munge_script) && \
        mv $@+ $@
 
-git.res: git.rc GIT-VERSION-FILE
+git.res: git.rc GIT-VERSION-FILE GIT-PREFIX
        $(QUIET_RC)$(RC) \
          $(join -DMAJOR= -DMINOR= -DMICRO= -DPATCHLEVEL=, $(wordlist 1, 4, \
            $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \
@@ -2591,6 +2592,7 @@ GIT-BUILD-OPTIONS: FORCE
        @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
        @echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
        @echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
+       @echo X=\'$(X)\' >>$@+
 ifdef TEST_OUTPUT_DIRECTORY
        @echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
 endif
@@ -2604,7 +2606,6 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
        @echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+
 endif
        @echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
-       @echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@+
 ifdef GIT_PERF_REPEAT_COUNT
        @echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+
 endif
@@ -2741,9 +2742,12 @@ endif
        then \
                echo '    ' SPATCH result: $@; \
        fi
-coccicheck: $(addsuffix .patch,$(wildcard contrib/coccinelle/*.cocci))
+coccicheck: $(addsuffix .patch,$(filter-out %.pending.cocci,$(wildcard contrib/coccinelle/*.cocci)))
+
+# See contrib/coccinelle/README
+coccicheck-pending: $(addsuffix .patch,$(wildcard contrib/coccinelle/*.pending.cocci))
 
-.PHONY: coccicheck
+.PHONY: coccicheck coccicheck-pending
 
 ### Installation rules
 
@@ -3099,14 +3103,16 @@ cover_db_html: cover_db
 # An example command to build against libFuzzer from LLVM 4.0.0:
 #
 # make CC=clang CXX=clang++ \
-#      CFLAGS="-fsanitize-coverage=trace-pc-guard -fsanitize=address" \
+#      FUZZ_CXXFLAGS="-fsanitize-coverage=trace-pc-guard -fsanitize=address" \
 #      LIB_FUZZING_ENGINE=/usr/lib/llvm-4.0/lib/libFuzzer.a \
 #      fuzz-all
 #
+FUZZ_CXXFLAGS ?= $(CFLAGS)
+
 .PHONY: fuzz-all
 
 $(FUZZ_PROGRAMS): all
-       $(QUIET_LINK)$(CXX) $(CFLAGS) $(LIB_OBJS) $(BUILTIN_OBJS) \
+       $(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) $(LIB_OBJS) $(BUILTIN_OBJS) \
                $(XDIFF_OBJS) $(EXTLIBS) git.o $@.o $(LIB_FUZZING_ENGINE) -o $@
 
 fuzz-all: $(FUZZ_PROGRAMS)
diff --git a/apply.c b/apply.c
index 073d5f04512ac6febc2949040f53ef273433f3c0..01793d612620246b14fa57f6ce3ed6c33df65d0f 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -1748,7 +1748,7 @@ static int parse_fragment(struct apply_state *state,
        }
        if (oldlines || newlines)
                return -1;
-       if (!deleted && !added)
+       if (!patch->recount && !deleted && !added)
                return -1;
 
        fragment->leading = leading;
@@ -4772,6 +4772,9 @@ static int apply_option_parse_exclude(const struct option *opt,
                                      const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        add_name_limit(state, arg, 1);
        return 0;
 }
@@ -4780,6 +4783,9 @@ static int apply_option_parse_include(const struct option *opt,
                                      const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        add_name_limit(state, arg, 0);
        state->has_include = 1;
        return 0;
@@ -4790,6 +4796,9 @@ static int apply_option_parse_p(const struct option *opt,
                                int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        state->p_value = atoi(arg);
        state->p_value_known = 1;
        return 0;
@@ -4799,6 +4808,9 @@ static int apply_option_parse_space_change(const struct option *opt,
                                           const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_ARG(arg);
+
        if (unset)
                state->ws_ignore_action = ignore_ws_none;
        else
@@ -4810,9 +4822,12 @@ static int apply_option_parse_whitespace(const struct option *opt,
                                         const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        state->whitespace_option = arg;
        if (parse_whitespace_option(state, arg))
-               exit(1);
+               return -1;
        return 0;
 }
 
@@ -4820,6 +4835,9 @@ static int apply_option_parse_directory(const struct option *opt,
                                        const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        strbuf_reset(&state->root);
        strbuf_addstr(&state->root, arg);
        strbuf_complete(&state->root, '/');
@@ -4939,10 +4957,10 @@ int apply_parse_options(int argc, const char **argv,
        struct option builtin_apply_options[] = {
                { OPTION_CALLBACK, 0, "exclude", state, N_("path"),
                        N_("don't apply changes matching the given path"),
-                       0, apply_option_parse_exclude },
+                       PARSE_OPT_NONEG, apply_option_parse_exclude },
                { OPTION_CALLBACK, 0, "include", state, N_("path"),
                        N_("apply changes matching the given path"),
-                       0, apply_option_parse_include },
+                       PARSE_OPT_NONEG, apply_option_parse_include },
                { OPTION_CALLBACK, 'p', NULL, state, N_("num"),
                        N_("remove <num> leading slashes from traditional diff paths"),
                        0, apply_option_parse_p },
index 7a535cba24a2a0535b412f1cfb3531ddde155c1e..a58e1a8ebf874afc856b03f2203ee32d79183b31 100644 (file)
@@ -202,7 +202,7 @@ static void prepare_header(struct archiver_args *args,
                           unsigned int mode, unsigned long size)
 {
        xsnprintf(header->mode, sizeof(header->mode), "%07o", mode & 07777);
-       xsnprintf(header->size, sizeof(header->size), "%011lo", S_ISREG(mode) ? size : 0);
+       xsnprintf(header->size, sizeof(header->size), "%011"PRIoMAX , S_ISREG(mode) ? (uintmax_t)size : (uintmax_t)0);
        xsnprintf(header->mtime, sizeof(header->mtime), "%011lo", (unsigned long) args->time);
 
        xsnprintf(header->uid, sizeof(header->uid), "%07o", 0);
diff --git a/attr.c b/attr.c
index 60d284796de728f59b839865eb035e1289a1a060..eaece6658d64b2129332ffab39e30485730f3306 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -41,23 +41,17 @@ const char *git_attr_name(const struct git_attr *attr)
 
 struct attr_hashmap {
        struct hashmap map;
-#ifndef NO_PTHREADS
        pthread_mutex_t mutex;
-#endif
 };
 
 static inline void hashmap_lock(struct attr_hashmap *map)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_lock(&map->mutex);
-#endif
 }
 
 static inline void hashmap_unlock(struct attr_hashmap *map)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_unlock(&map->mutex);
-#endif
 }
 
 /*
@@ -498,23 +492,17 @@ static struct check_vector {
        size_t nr;
        size_t alloc;
        struct attr_check **checks;
-#ifndef NO_PTHREADS
        pthread_mutex_t mutex;
-#endif
 } check_vector;
 
 static inline void vector_lock(void)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_lock(&check_vector.mutex);
-#endif
 }
 
 static inline void vector_unlock(void)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_unlock(&check_vector.mutex);
-#endif
 }
 
 static void check_vector_add(struct attr_check *c)
@@ -1181,8 +1169,6 @@ void git_all_attrs(const struct index_state *istate,
 
 void attr_start(void)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_init(&g_attr_hashmap.mutex, NULL);
        pthread_mutex_init(&check_vector.mutex, NULL);
-#endif
 }
index dc576a33728f5c2264acf66fcbe3243284144781..8f27f3375b1e92f2ef026e0a1530ca8b6b3235bf 100644 (file)
@@ -2113,7 +2113,9 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
 {
        int *opt_value = opt->value;
 
-       if (!strcmp(arg, "mbox"))
+       if (unset)
+               *opt_value = PATCH_FORMAT_UNKNOWN;
+       else if (!strcmp(arg, "mbox"))
                *opt_value = PATCH_FORMAT_MBOX;
        else if (!strcmp(arg, "stgit"))
                *opt_value = PATCH_FORMAT_STGIT;
index a443af9ee9dad5ec20de7e75640947c221e7aa6a..06a7163ffe269cd43dc783c81ca6ac71b91b3614 100644 (file)
@@ -732,6 +732,8 @@ static int blame_copy_callback(const struct option *option, const char *arg, int
 {
        int *opt = option->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        /*
         * -C enables copy from removed files;
         * -C -C enables copy from existing files, but only
@@ -754,6 +756,8 @@ static int blame_move_callback(const struct option *option, const char *arg, int
 {
        int *opt = option->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        *opt |= PICKAXE_BLAME_MOVE;
 
        if (arg)
index 0d403eb77d37d3b409d7d8ef030c12b91fe63da6..2ca56fd086bf6bef7595ad008d9eda2c64901cf5 100644 (file)
@@ -99,7 +99,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                oi.sizep = &size;
                if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
                        die("git cat-file: could not get object info");
-               printf("%lu\n", size);
+               printf("%"PRIuMAX"\n", (uintmax_t)size);
                return 0;
 
        case 'e':
@@ -245,7 +245,7 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
                if (data->mark_query)
                        data->info.sizep = &data->size;
                else
-                       strbuf_addf(sb, "%lu", data->size);
+                       strbuf_addf(sb, "%"PRIuMAX , (uintmax_t)data->size);
        } else if (is_atom("objectsize:disk", atom, len)) {
                if (data->mark_query)
                        data->info.disk_sizep = &data->disk_size;
@@ -603,8 +603,10 @@ static int batch_option_callback(const struct option *opt,
 {
        struct batch_options *bo = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (bo->enabled) {
-               return 1;
+               return error(_("only one batch option may be specified"));
        }
 
        bo->enabled = 1;
@@ -639,10 +641,12 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
                { OPTION_CALLBACK, 0, "batch", &batch, "format",
                        N_("show info and content of objects fed from the standard input"),
-                       PARSE_OPT_OPTARG, batch_option_callback },
+                       PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
+                       batch_option_callback },
                { OPTION_CALLBACK, 0, "batch-check", &batch, "format",
                        N_("show info about objects fed from the standard input"),
-                       PARSE_OPT_OPTARG, batch_option_callback },
+                       PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
+                       batch_option_callback },
                OPT_BOOL(0, "follow-symlinks", &batch.follow_symlinks,
                         N_("follow in-tree symlinks (used with --batch or --batch-check)")),
                OPT_BOOL(0, "batch-all-objects", &batch.all_objects,
index 88b86c8d9f5a0ea9c49b42e891082203b80a977f..eb74774cbc9d6bd6acf1b7fe2f31b8e80e461a12 100644 (file)
@@ -132,6 +132,8 @@ static const char * const builtin_checkout_index_usage[] = {
 static int option_parse_stage(const struct option *opt,
                              const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+
        if (!strcmp(arg, "all")) {
                to_tempfile = 1;
                checkout_stage = CHECKOUT_ALL;
index 8d9a7dc20647079bc5f35b446bbbab5479abb32d..bbcdeb2d9e7f275309609a2a21a5dd4baf1cf1bd 100644 (file)
@@ -140,6 +140,7 @@ static void clean_print_color(enum color_clean ix)
 static int exclude_cb(const struct option *opt, const char *arg, int unset)
 {
        struct string_list *exclude_list = opt->value;
+       BUG_ON_OPT_NEG(unset);
        string_list_append(exclude_list, arg);
        return 0;
 }
index 96d336ec3d8044918fb260d6cf8c03296cf32ed1..c021b119bb9df106ab7a860e032ea5dd35529401 100644 (file)
@@ -161,6 +161,9 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
 static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset)
 {
        const char **value = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        if (arg != NULL && *arg == '=')
                arg = arg + 1;
 
@@ -1335,7 +1338,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
                { OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg,
                  N_("n"), N_("detect renames, optionally set similarity index"),
-                 PARSE_OPT_OPTARG, opt_parse_rename_score },
+                 PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_rename_score },
                OPT_END(),
        };
 
index 456797c12a41a468a0b6dd25153403f6cfd7bb2f..5790f0d554b0aed2ea36a38c289cc6ce2c3c0faf 100644 (file)
@@ -253,7 +253,7 @@ static void export_blob(const struct object_id *oid)
 
        mark_next_object(object);
 
-       printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
+       printf("blob\nmark :%"PRIu32"\ndata %"PRIuMAX"\n", last_idnum, (uintmax_t)size);
        if (size && fwrite(buf, size, 1, stdout) != 1)
                die_errno("could not write blob '%s'", oid_to_hex(oid));
        printf("\n");
index 6ec7c07d1dc111e6370dad498bf7453b5cd2c92e..e0140327aab23654c69e7388c23a07b98b8ff913 100644 (file)
@@ -98,6 +98,8 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
 
 static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+
        /*
         * "git fetch --refmap='' origin foo"
         * can be used to tell the command not to store anywhere
index 56e4a110526379d1df69615a0ade611c2a82c17d..71df52a333cbc756b057e93bf3d2affca8157860 100644 (file)
@@ -34,7 +34,6 @@ static int recurse_submodules;
 #define GREP_NUM_THREADS_DEFAULT 8
 static int num_threads;
 
-#ifndef NO_PTHREADS
 static pthread_t *threads;
 
 /* We use one producer thread and THREADS consumer
@@ -70,13 +69,11 @@ static pthread_mutex_t grep_mutex;
 
 static inline void grep_lock(void)
 {
-       assert(num_threads);
        pthread_mutex_lock(&grep_mutex);
 }
 
 static inline void grep_unlock(void)
 {
-       assert(num_threads);
        pthread_mutex_unlock(&grep_mutex);
 }
 
@@ -234,6 +231,9 @@ static int wait_all(void)
        int hit = 0;
        int i;
 
+       if (!HAVE_THREADS)
+               BUG("Never call this function unless you have started threads");
+
        grep_lock();
        all_work_added = 1;
 
@@ -265,13 +265,6 @@ static int wait_all(void)
 
        return hit;
 }
-#else /* !NO_PTHREADS */
-
-static int wait_all(void)
-{
-       return 0;
-}
-#endif
 
 static int grep_cmd_config(const char *var, const char *value, void *cb)
 {
@@ -284,17 +277,15 @@ static int grep_cmd_config(const char *var, const char *value, void *cb)
                if (num_threads < 0)
                        die(_("invalid number of threads specified (%d) for %s"),
                            num_threads, var);
-#ifdef NO_PTHREADS
-               else if (num_threads && num_threads != 1) {
+               else if (!HAVE_THREADS && num_threads > 1) {
                        /*
                         * TRANSLATORS: %s is the configuration
                         * variable for tweaking threads, currently
                         * grep.threads
                         */
                        warning(_("no threads support, ignoring %s"), var);
-                       num_threads = 0;
+                       num_threads = 1;
                }
-#endif
        }
 
        if (!strcmp(var, "submodule.recurse"))
@@ -330,17 +321,14 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
        grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid);
        strbuf_release(&pathbuf);
 
-#ifndef NO_PTHREADS
-       if (num_threads) {
+       if (num_threads > 1) {
                /*
                 * add_work() copies gs and thus assumes ownership of
                 * its fields, so do not call grep_source_clear()
                 */
                add_work(opt, &gs);
                return 0;
-       } else
-#endif
-       {
+       } else {
                int hit;
 
                hit = grep_source(opt, &gs);
@@ -363,17 +351,14 @@ static int grep_file(struct grep_opt *opt, const char *filename)
        grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
        strbuf_release(&buf);
 
-#ifndef NO_PTHREADS
-       if (num_threads) {
+       if (num_threads > 1) {
                /*
                 * add_work() copies gs and thus assumes ownership of
                 * its fields, so do not call grep_source_clear()
                 */
                add_work(opt, &gs);
                return 0;
-       } else
-#endif
-       {
+       } else {
                int hit;
 
                hit = grep_source(opt, &gs);
@@ -723,11 +708,14 @@ static int context_callback(const struct option *opt, const char *arg,
 static int file_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
-       int from_stdin = !strcmp(arg, "-");
+       int from_stdin;
        FILE *patterns;
        int lno = 0;
        struct strbuf sb = STRBUF_INIT;
 
+       BUG_ON_OPT_NEG(unset);
+
+       from_stdin = !strcmp(arg, "-");
        patterns = from_stdin ? stdin : fopen(arg, "r");
        if (!patterns)
                die_errno(_("cannot open '%s'"), arg);
@@ -748,6 +736,8 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
 static int not_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT);
        return 0;
 }
@@ -755,6 +745,8 @@ static int not_callback(const struct option *opt, const char *arg, int unset)
 static int and_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND);
        return 0;
 }
@@ -762,6 +754,8 @@ static int and_callback(const struct option *opt, const char *arg, int unset)
 static int open_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN);
        return 0;
 }
@@ -769,6 +763,8 @@ static int open_callback(const struct option *opt, const char *arg, int unset)
 static int close_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN);
        return 0;
 }
@@ -777,6 +773,7 @@ static int pattern_callback(const struct option *opt, const char *arg,
                            int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
        append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN);
        return 0;
 }
@@ -1049,39 +1046,35 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        pathspec.recursive = 1;
        pathspec.recurse_submodules = !!recurse_submodules;
 
-#ifndef NO_PTHREADS
-       if (list.nr || cached || show_in_pager)
-               num_threads = 0;
-       else if (num_threads == 0)
-               num_threads = GREP_NUM_THREADS_DEFAULT;
-       else if (num_threads < 0)
-               die(_("invalid number of threads specified (%d)"), num_threads);
-       if (num_threads == 1)
-               num_threads = 0;
-#else
-       if (num_threads)
+       if (list.nr || cached || show_in_pager) {
+               if (num_threads > 1)
+                       warning(_("invalid option combination, ignoring --threads"));
+               num_threads = 1;
+       } else if (!HAVE_THREADS && num_threads > 1) {
                warning(_("no threads support, ignoring --threads"));
-       num_threads = 0;
-#endif
+               num_threads = 1;
+       } else if (num_threads < 0)
+               die(_("invalid number of threads specified (%d)"), num_threads);
+       else if (num_threads == 0)
+               num_threads = HAVE_THREADS ? GREP_NUM_THREADS_DEFAULT : 1;
 
-       if (!num_threads)
+       if (num_threads > 1) {
+               if (!HAVE_THREADS)
+                       BUG("Somebody got num_threads calculation wrong!");
+               if (!(opt.name_only || opt.unmatch_name_only || opt.count)
+                   && (opt.pre_context || opt.post_context ||
+                       opt.file_break || opt.funcbody))
+                       skip_first_line = 1;
+               start_threads(&opt);
+       } else {
                /*
                 * The compiled patterns on the main path are only
                 * used when not using threading. Otherwise
-                * start_threads() below calls compile_grep_patterns()
+                * start_threads() above calls compile_grep_patterns()
                 * for each thread.
                 */
                compile_grep_patterns(&opt);
-
-#ifndef NO_PTHREADS
-       if (num_threads) {
-               if (!(opt.name_only || opt.unmatch_name_only || opt.count)
-                   && (opt.pre_context || opt.post_context ||
-                       opt.file_break || opt.funcbody))
-                       skip_first_line = 1;
-               start_threads(&opt);
        }
-#endif
 
        if (show_in_pager && (cached || list.nr))
                die(_("--open-files-in-pager only works on the worktree"));
@@ -1132,7 +1125,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                hit = grep_objects(&opt, &pathspec, &list);
        }
 
-       if (num_threads)
+       if (num_threads > 1)
                hit |= wait_all();
        if (hit && show_in_pager)
                run_pager(&opt, prefix);
index 2004e25da230c7d9f0b1e951d8a59dca2d9d08b8..ac1f4ea9a782508e89f269bb1bf000a4a805c793 100644 (file)
@@ -42,9 +42,7 @@ struct base_data {
 };
 
 struct thread_local {
-#ifndef NO_PTHREADS
        pthread_t thread;
-#endif
        struct base_data *base_cache;
        size_t base_cache_used;
        int pack_fd;
@@ -98,8 +96,6 @@ static uint32_t input_crc32;
 static int input_fd, output_fd;
 static const char *curr_pack;
 
-#ifndef NO_PTHREADS
-
 static struct thread_local *thread_data;
 static int nr_dispatched;
 static int threads_active;
@@ -179,26 +175,6 @@ static void cleanup_thread(void)
        free(thread_data);
 }
 
-#else
-
-#define read_lock()
-#define read_unlock()
-
-#define counter_lock()
-#define counter_unlock()
-
-#define work_lock()
-#define work_unlock()
-
-#define deepest_delta_lock()
-#define deepest_delta_unlock()
-
-#define type_cas_lock()
-#define type_cas_unlock()
-
-#endif
-
-
 static int mark_link(struct object *obj, int type, void *data, struct fsck_options *options)
 {
        if (!obj)
@@ -364,22 +340,20 @@ static NORETURN void bad_object(off_t offset, const char *format, ...)
 
 static inline struct thread_local *get_thread_data(void)
 {
-#ifndef NO_PTHREADS
-       if (threads_active)
-               return pthread_getspecific(key);
-       assert(!threads_active &&
-              "This should only be reached when all threads are gone");
-#endif
+       if (HAVE_THREADS) {
+               if (threads_active)
+                       return pthread_getspecific(key);
+               assert(!threads_active &&
+                      "This should only be reached when all threads are gone");
+       }
        return &nothread_data;
 }
 
-#ifndef NO_PTHREADS
 static void set_thread_data(struct thread_local *data)
 {
        if (threads_active)
                pthread_setspecific(key, data);
 }
-#endif
 
 static struct base_data *alloc_base_data(void)
 {
@@ -450,7 +424,8 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
        int hdrlen;
 
        if (!is_delta_type(type)) {
-               hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), size) + 1;
+               hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX,
+                                  type_name(type),(uintmax_t)size) + 1;
                the_hash_algo->init_fn(&c);
                the_hash_algo->update_fn(&c, hdr, hdrlen);
        } else
@@ -1092,7 +1067,6 @@ static void resolve_base(struct object_entry *obj)
        find_unresolved_deltas(base_obj);
 }
 
-#ifndef NO_PTHREADS
 static void *threaded_second_pass(void *data)
 {
        set_thread_data(data);
@@ -1116,7 +1090,6 @@ static void *threaded_second_pass(void *data)
        }
        return NULL;
 }
-#endif
 
 /*
  * First pass:
@@ -1213,7 +1186,6 @@ static void resolve_deltas(void)
                progress = start_progress(_("Resolving deltas"),
                                          nr_ref_deltas + nr_ofs_deltas);
 
-#ifndef NO_PTHREADS
        nr_dispatched = 0;
        if (nr_threads > 1 || getenv("GIT_FORCE_THREADS")) {
                init_thread();
@@ -1229,7 +1201,6 @@ static void resolve_deltas(void)
                cleanup_thread();
                return;
        }
-#endif
 
        for (i = 0; i < nr_objects; i++) {
                struct object_entry *obj = &objects[i];
@@ -1531,11 +1502,10 @@ static int git_index_pack_config(const char *k, const char *v, void *cb)
                if (nr_threads < 0)
                        die(_("invalid number of threads specified (%d)"),
                            nr_threads);
-#ifdef NO_PTHREADS
-               if (nr_threads != 1)
+               if (!HAVE_THREADS && nr_threads != 1) {
                        warning(_("no threads support, ignoring %s"), k);
-               nr_threads = 1;
-#endif
+                       nr_threads = 1;
+               }
                return 0;
        }
        return git_default_config(k, v, cb);
@@ -1628,10 +1598,10 @@ static void show_pack_info(int stat_only)
                        chain_histogram[obj_stat[i].delta_depth - 1]++;
                if (stat_only)
                        continue;
-               printf("%s %-6s %lu %lu %"PRIuMAX,
+               printf("%s %-6s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX,
                       oid_to_hex(&obj->idx.oid),
-                      type_name(obj->real_type), obj->size,
-                      (unsigned long)(obj[1].idx.offset - obj->idx.offset),
+                      type_name(obj->real_type), (uintmax_t)obj->size,
+                      (uintmax_t)(obj[1].idx.offset - obj->idx.offset),
                       (uintmax_t)obj->idx.offset);
                if (is_delta_type(obj->type)) {
                        struct object_entry *bobj = &objects[obj_stat[i].base_object_no];
@@ -1723,12 +1693,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                                nr_threads = strtoul(arg+10, &end, 0);
                                if (!arg[10] || *end || nr_threads < 0)
                                        usage(index_pack_usage);
-#ifdef NO_PTHREADS
-                               if (nr_threads != 1)
-                                       warning(_("no threads support, "
-                                                 "ignoring %s"), arg);
-                               nr_threads = 1;
-#endif
+                               if (!HAVE_THREADS && nr_threads != 1) {
+                                       warning(_("no threads support, ignoring %s"), arg);
+                                       nr_threads = 1;
+                               }
                        } else if (starts_with(arg, "--pack_header=")) {
                                struct pack_header *hdr;
                                char *c;
@@ -1791,14 +1759,12 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        if (strict)
                opts.flags |= WRITE_IDX_STRICT;
 
-#ifndef NO_PTHREADS
-       if (!nr_threads) {
+       if (HAVE_THREADS && !nr_threads) {
                nr_threads = online_cpus();
                /* An experiment showed that more threads does not mean faster */
                if (nr_threads > 3)
                        nr_threads = 3;
        }
-#endif
 
        curr_pack = open_pack_file(pack_name);
        parse_pack_header();
index 12ddda7e7bac51f74b2f7ca8a2b64ffe90fd8683..41faffd28db8850fb97daa52c6d481375b380504 100644 (file)
@@ -451,6 +451,7 @@ static int guess_repository_type(const char *git_dir)
 
 static int shared_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        *((int *) opt->value) = (arg) ? git_config_perm("arg", arg) : PERM_GROUP;
        return 0;
 }
index 4b87e0dd2e8854bf940e92e3020c5e4f66e8a6bd..8ae40dec4746571cf80d2f76bbad067c33a972fa 100644 (file)
@@ -80,6 +80,8 @@ static int parse_opt_parse(const struct option *opt, const char *arg,
        v->only_trailers = 1;
        v->only_input = 1;
        v->unfold = 1;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return 0;
 }
 
index 061d4fd864f3fb479e2877e3bbf25928ad1fb9d3..5ac18e28486b61b91239d859c445bc620c51c5ad 100644 (file)
@@ -107,6 +107,8 @@ static int log_line_range_callback(const struct option *option, const char *arg,
 {
        struct line_opt_callback_data *data = option->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
 
@@ -1009,8 +1011,6 @@ static void show_diffstat(struct rev_info *rev,
 
        memcpy(&opts, &rev->diffopt, sizeof(opts));
        opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
-       opts.stat_width = MAIL_DEFAULT_WRAP;
-
        diff_setup_done(&opts);
 
        diff_tree_oid(get_commit_tree_oid(origin),
@@ -1096,7 +1096,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
        if (rev->rdiff1) {
                fprintf_ln(rev->diffopt.file, "%s", rev->rdiff_title);
                show_range_diff(rev->rdiff1, rev->rdiff2,
-                               rev->creation_factor, 1, &rev->diffopt);
+                               rev->creation_factor, 1, NULL);
        }
 }
 
@@ -1151,6 +1151,8 @@ static int keep_subject = 0;
 
 static int keep_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        ((struct rev_info *)opt->value)->total = -1;
        keep_subject = 1;
        return 0;
@@ -1161,6 +1163,7 @@ static int subject_prefix = 0;
 static int subject_prefix_callback(const struct option *opt, const char *arg,
                            int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        subject_prefix = 1;
        ((struct rev_info *)opt->value)->subject_prefix = arg;
        return 0;
@@ -1168,6 +1171,8 @@ static int subject_prefix_callback(const struct option *opt, const char *arg,
 
 static int rfc_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return subject_prefix_callback(opt, "RFC PATCH", unset);
 }
 
@@ -1176,6 +1181,7 @@ static int numbered_cmdline_opt = 0;
 static int numbered_callback(const struct option *opt, const char *arg,
                             int unset)
 {
+       BUG_ON_OPT_ARG(arg);
        *(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
        if (unset)
                auto_number =  0;
@@ -1185,6 +1191,7 @@ static int numbered_callback(const struct option *opt, const char *arg,
 static int no_numbered_callback(const struct option *opt, const char *arg,
                                int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        return numbered_callback(opt, arg, 1);
 }
 
@@ -1192,6 +1199,7 @@ static int output_directory_callback(const struct option *opt, const char *arg,
                              int unset)
 {
        const char **dir = (const char **)opt->value;
+       BUG_ON_OPT_NEG(unset);
        if (*dir)
                die(_("Two output directories?"));
        *dir = arg;
@@ -1508,7 +1516,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                            PARSE_OPT_NOARG, numbered_callback },
                { OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
                            N_("use [PATCH] even with multiple patches"),
-                           PARSE_OPT_NOARG, no_numbered_callback },
+                           PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback },
                OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")),
                OPT_BOOL(0, "stdout", &use_stdout,
                            N_("print patches to standard out")),
index 7f9919a36234f603ffe76d7324fafc7f5872d404..c70a9c71588a76b2ef04689fc6cd805cee4ae0b8 100644 (file)
@@ -475,6 +475,8 @@ static int option_parse_exclude(const struct option *opt,
 {
        struct string_list *exclude_list = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        exc_given = 1;
        string_list_append(exclude_list, arg);
 
@@ -486,6 +488,8 @@ static int option_parse_exclude_from(const struct option *opt,
 {
        struct dir_struct *dir = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        exc_given = 1;
        add_excludes_from_file(dir, arg);
 
@@ -497,6 +501,9 @@ static int option_parse_exclude_standard(const struct option *opt,
 {
        struct dir_struct *dir = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
+
        exc_given = 1;
        setup_standard_excludes(dir);
 
@@ -548,15 +555,16 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
                            N_("show resolve-undo information")),
                { OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"),
                        N_("skip files matching pattern"),
-                       0, option_parse_exclude },
+                       PARSE_OPT_NONEG, option_parse_exclude },
                { OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"),
                        N_("exclude patterns are read from <file>"),
-                       0, option_parse_exclude_from },
+                       PARSE_OPT_NONEG, option_parse_exclude_from },
                OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"),
                        N_("read additional per-directory exclude patterns in <file>")),
                { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
                        N_("add the standard git exclusions"),
-                       PARSE_OPT_NOARG, option_parse_exclude_standard },
+                       PARSE_OPT_NOARG | PARSE_OPT_NONEG,
+                       option_parse_exclude_standard },
                OPT_SET_INT_F(0, "full-name", &prefix_len,
                              N_("make the output relative to the project top directory"),
                              0, PARSE_OPT_NONEG),
index fe3b952cb3007d12c2e94a08b10486ed301c4769..7d581d6463dc534606d27b1998c27991a800d6f1 100644 (file)
@@ -100,7 +100,7 @@ static int show_tree(const struct object_id *oid, struct strbuf *base,
                                                  "BAD");
                                else
                                        xsnprintf(size_text, sizeof(size_text),
-                                                 "%lu", size);
+                                                 "%"PRIuMAX, (uintmax_t)size);
                        } else
                                xsnprintf(size_text, sizeof(size_text), "-");
                        printf("%06o %s %s %7s\t", mode, type,
index b08803e61119a569e2ca5a33402666d8978d9ff0..06a2f90c4875f2a8ff82a927071ac584ad929f8b 100644 (file)
@@ -15,6 +15,8 @@ static int label_cb(const struct option *opt, const char *arg, int unset)
        static int label_count = 0;
        const char **names = (const char **)opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (label_count >= 3)
                return error("too many labels on the command line");
        names[label_count++] = arg;
index 4aa60715980f2f226d752e9d7fe0df4ecdcc369d..c3c976d471ce78268e673a5135a4c37ebc6d0f6d 100644 (file)
@@ -224,6 +224,7 @@ static int option_parse_x(const struct option *opt,
 static int option_parse_n(const struct option *opt,
                          const char *arg, int unset)
 {
+       BUG_ON_OPT_ARG(arg);
        show_diffstat = unset;
        return 0;
 }
@@ -1336,6 +1337,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        die(_("%s - not something we can merge"), argv[0]);
                if (remoteheads->next)
                        die(_("Can merge only exactly one commit into empty head"));
+
+               if (verify_signatures)
+                       verify_merge_signature(remoteheads->item, verbosity);
+
                remote_head_oid = &remoteheads->item->object.oid;
                read_empty(remote_head_oid, 0);
                update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0,
@@ -1357,31 +1362,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
        if (verify_signatures) {
                for (p = remoteheads; p; p = p->next) {
-                       struct commit *commit = p->item;
-                       char hex[GIT_MAX_HEXSZ + 1];
-                       struct signature_check signature_check;
-                       memset(&signature_check, 0, sizeof(signature_check));
-
-                       check_commit_signature(commit, &signature_check);
-
-                       find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
-                       switch (signature_check.result) {
-                       case 'G':
-                               break;
-                       case 'U':
-                               die(_("Commit %s has an untrusted GPG signature, "
-                                     "allegedly by %s."), hex, signature_check.signer);
-                       case 'B':
-                               die(_("Commit %s has a bad GPG signature "
-                                     "allegedly by %s."), hex, signature_check.signer);
-                       default: /* 'N' */
-                               die(_("Commit %s does not have a GPG signature."), hex);
-                       }
-                       if (verbosity >= 0 && signature_check.result == 'G')
-                               printf(_("Commit %s has a good GPG signature by %s\n"),
-                                      hex, signature_check.signer);
-
-                       signature_check_clear(&signature_check);
+                       verify_merge_signature(p->item, verbosity);
                }
        }
 
index c05cd004abcbdcd1e4c3d140f3cf4251c416df36..c78b7a0c5b7fbea81320ae9873553c437d82e73e 100644 (file)
@@ -215,6 +215,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
 {
        struct note_data *d = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        strbuf_grow(&d->buf, strlen(arg) + 2);
        if (d->buf.len)
                strbuf_addch(&d->buf, '\n');
@@ -229,6 +231,8 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset)
 {
        struct note_data *d = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (d->buf.len)
                strbuf_addch(&d->buf, '\n');
        if (!strcmp(arg, "-")) {
@@ -250,15 +254,15 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
        enum object_type type;
        unsigned long len;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (d->buf.len)
                strbuf_addch(&d->buf, '\n');
 
        if (get_oid(arg, &object))
                die(_("failed to resolve '%s' as a valid ref."), arg);
-       if (!(buf = read_object_file(&object, &type, &len))) {
-               free(buf);
+       if (!(buf = read_object_file(&object, &type, &len)))
                die(_("failed to read object '%s'."), arg);
-       }
        if (type != OBJ_BLOB) {
                free(buf);
                die(_("cannot read note data from non-blob object '%s'."), arg);
@@ -273,6 +277,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
 static int parse_reedit_arg(const struct option *opt, const char *arg, int unset)
 {
        struct note_data *d = opt->value;
+       BUG_ON_OPT_NEG(unset);
        d->use_editor = 1;
        return parse_reuse_arg(opt, arg, unset);
 }
index c99ee79c31a84a3f67735cb44e85c156f63ad966..411aefd6875b2d35ee4a12d1a043ba50027021b3 100644 (file)
@@ -1953,8 +1953,6 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size,
        return 0;
 }
 
-#ifndef NO_PTHREADS
-
 /* Protect access to object database */
 static pthread_mutex_t read_mutex;
 #define read_lock()            pthread_mutex_lock(&read_mutex)
@@ -1979,16 +1977,6 @@ static pthread_mutex_t progress_mutex;
  * ahead in the list because they can be stolen and would need
  * progress_mutex for protection.
  */
-#else
-
-#define read_lock()            (void)0
-#define read_unlock()          (void)0
-#define cache_lock()           (void)0
-#define cache_unlock()         (void)0
-#define progress_lock()                (void)0
-#define progress_unlock()      (void)0
-
-#endif
 
 /*
  * Return the size of the object without doing any delta
@@ -2095,9 +2083,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
                        die(_("object %s cannot be read"),
                            oid_to_hex(&trg_entry->idx.oid));
                if (sz != trg_size)
-                       die(_("object %s inconsistent object length (%lu vs %lu)"),
-                           oid_to_hex(&trg_entry->idx.oid), sz,
-                           trg_size);
+                       die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"),
+                           oid_to_hex(&trg_entry->idx.oid), (uintmax_t)sz,
+                           (uintmax_t)trg_size);
                *mem_usage += sz;
        }
        if (!src->data) {
@@ -2122,9 +2110,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
                            oid_to_hex(&src_entry->idx.oid));
                }
                if (sz != src_size)
-                       die(_("object %s inconsistent object length (%lu vs %lu)"),
-                           oid_to_hex(&src_entry->idx.oid), sz,
-                           src_size);
+                       die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"),
+                           oid_to_hex(&src_entry->idx.oid), (uintmax_t)sz,
+                           (uintmax_t)src_size);
                *mem_usage += sz;
        }
        if (!src->index) {
@@ -2347,8 +2335,6 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
        free(array);
 }
 
-#ifndef NO_PTHREADS
-
 static void try_to_free_from_threads(size_t size)
 {
        read_lock();
@@ -2577,10 +2563,6 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
        free(p);
 }
 
-#else
-#define ll_find_deltas(l, s, w, d, p)  find_deltas(l, &s, w, d, p)
-#endif
-
 static void add_tag_chain(const struct object_id *oid)
 {
        struct tag *tag;
@@ -2733,12 +2715,10 @@ static int git_pack_config(const char *k, const char *v, void *cb)
                if (delta_search_threads < 0)
                        die(_("invalid number of threads specified (%d)"),
                            delta_search_threads);
-#ifdef NO_PTHREADS
-               if (delta_search_threads != 1) {
+               if (!HAVE_THREADS && delta_search_threads != 1) {
                        warning(_("no threads support, ignoring %s"), k);
                        delta_search_threads = 0;
                }
-#endif
                return 0;
        }
        if (!strcmp(k, "pack.indexversion")) {
@@ -2806,9 +2786,11 @@ static void show_object(struct object *obj, const char *name, void *data)
 
        if (use_delta_islands) {
                const char *p;
-               unsigned depth = 0;
+               unsigned depth;
                struct object_entry *ent;
 
+               /* the empty string is a root tree, which is depth 0 */
+               depth = *name ? 1 : 0;
                for (p = strchr(name, '/'); p; p = strchr(p + 1, '/'))
                        depth++;
 
@@ -3104,6 +3086,7 @@ static void get_object_list(int ac, const char **av)
        struct rev_info revs;
        char line[1000];
        int flags = 0;
+       int save_warning;
 
        repo_init_revisions(the_repository, &revs, NULL);
        save_commit_buffer = 0;
@@ -3113,6 +3096,9 @@ static void get_object_list(int ac, const char **av)
        /* make sure shallows are read */
        is_repository_shallow(the_repository);
 
+       save_warning = warn_on_object_refname_ambiguity;
+       warn_on_object_refname_ambiguity = 0;
+
        while (fgets(line, sizeof(line), stdin) != NULL) {
                int len = strlen(line);
                if (len && line[len - 1] == '\n')
@@ -3139,6 +3125,8 @@ static void get_object_list(int ac, const char **av)
                        die(_("bad revision '%s'"), line);
        }
 
+       warn_on_object_refname_ambiguity = save_warning;
+
        if (use_bitmap_index && !get_object_list_from_bitmap(&revs))
                return;
 
@@ -3207,6 +3195,9 @@ static int option_parse_index_version(const struct option *opt,
 {
        char *c;
        const char *val = arg;
+
+       BUG_ON_OPT_NEG(unset);
+
        pack_idx_opts.version = strtoul(val, &c, 10);
        if (pack_idx_opts.version > 2)
                die(_("unsupported index version %s"), val);
@@ -3253,7 +3244,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                         N_("similar to --all-progress when progress meter is shown")),
                { OPTION_CALLBACK, 0, "index-version", NULL, N_("<version>[,<offset>]"),
                  N_("write the pack index file in the specified idx format version"),
-                 0, option_parse_index_version },
+                 PARSE_OPT_NONEG, option_parse_index_version },
                OPT_MAGNITUDE(0, "max-pack-size", &pack_size_limit,
                              N_("maximum size of each output pack file")),
                OPT_BOOL(0, "local", &local,
@@ -3402,10 +3393,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (!delta_search_threads)      /* --threads=0 means autodetect */
                delta_search_threads = online_cpus();
 
-#ifdef NO_PTHREADS
-       if (delta_search_threads != 1)
+       if (!HAVE_THREADS && delta_search_threads != 1)
                warning(_("no threads support, ignoring --threads"));
-#endif
        if (!pack_to_stdout && !pack_size_limit)
                pack_size_limit = pack_size_limit_cfg;
        if (pack_to_stdout && pack_size_limit)
index c21aa276f1e93ef2593397d5304e72d59e6914b0..1b90622b1311187612ef8b33995c92a6802eb343 100644 (file)
@@ -557,6 +557,17 @@ static int run_fetch(const char *repo, const char **refspecs)
 static int pull_into_void(const struct object_id *merge_head,
                const struct object_id *curr_head)
 {
+       if (opt_verify_signatures) {
+               struct commit *commit;
+
+               commit = lookup_commit(the_repository, merge_head);
+               if (!commit)
+                       die(_("unable to access commit %s"),
+                           oid_to_hex(merge_head));
+
+               verify_merge_signature(commit, opt_verbosity);
+       }
+
        /*
         * Two-way merge: we treat the index as based on an empty tree,
         * and try to fast-forward to HEAD. This ensures we will not lose
index fbbc98e5161f011a25743a528e6bb3f85e415f51..183ee8c1e5d4de53d10e9ed00c624f615baf3fc9 100644 (file)
@@ -44,6 +44,7 @@ static const char * const read_tree_usage[] = {
 static int index_output_cb(const struct option *opt, const char *arg,
                                 int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        set_alternate_index_output(arg);
        return 0;
 }
@@ -54,6 +55,8 @@ static int exclude_per_directory_cb(const struct option *opt, const char *arg,
        struct dir_struct *dir;
        struct unpack_trees_options *opts;
 
+       BUG_ON_OPT_NEG(unset);
+
        opts = (struct unpack_trees_options *)opt->value;
 
        if (opts->dir)
index 0ee06aa3631ee89761d570b433994cc77302742e..b5c99ec10c200a5fccb293c0acadae80642f2808 100644 (file)
@@ -23,6 +23,7 @@
 #include "revision.h"
 #include "commit-reach.h"
 #include "rerere.h"
+#include "branch.h"
 
 static char const * const builtin_rebase_usage[] = {
        N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
@@ -48,7 +49,10 @@ static int use_builtin_rebase(void)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
        struct strbuf out = STRBUF_INIT;
-       int ret;
+       int ret, env = git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1);
+
+       if (env != -1)
+               return env;
 
        argv_array_pushl(&cp.args,
                         "config", "--bool", "rebase.usebuiltin", NULL);
@@ -87,7 +91,7 @@ struct rebase_options {
                REBASE_FORCE = 1<<3,
                REBASE_INTERACTIVE_EXPLICIT = 1<<4,
        } flags;
-       struct strbuf git_am_opt;
+       struct argv_array git_am_opts;
        const char *action;
        int signoff;
        int allow_rerere_autoupdate;
@@ -339,7 +343,7 @@ N_("Resolve all conflicts manually, mark them as resolved with\n"
 static int run_specific_rebase(struct rebase_options *opts)
 {
        const char *argv[] = { NULL, NULL };
-       struct strbuf script_snippet = STRBUF_INIT;
+       struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
        int status;
        const char *backend, *backend_func;
 
@@ -433,7 +437,9 @@ static int run_specific_rebase(struct rebase_options *opts)
                oid_to_hex(&opts->restrict_revision->object.oid) : NULL);
        add_var(&script_snippet, "GIT_QUIET",
                opts->flags & REBASE_NO_QUIET ? "" : "t");
-       add_var(&script_snippet, "git_am_opt", opts->git_am_opt.buf);
+       sq_quote_argv_pretty(&buf, opts->git_am_opts.argv);
+       add_var(&script_snippet, "git_am_opt", buf.buf);
+       strbuf_release(&buf);
        add_var(&script_snippet, "verbose",
                opts->flags & REBASE_VERBOSE ? "t" : "");
        add_var(&script_snippet, "diffstat",
@@ -522,12 +528,17 @@ static int run_specific_rebase(struct rebase_options *opts)
 
 #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
 
+#define RESET_HEAD_DETACH (1<<0)
+#define RESET_HEAD_HARD (1<<1)
+
 static int reset_head(struct object_id *oid, const char *action,
-                     const char *switch_to_branch, int detach_head,
+                     const char *switch_to_branch, unsigned flags,
                      const char *reflog_orig_head, const char *reflog_head)
 {
+       unsigned detach_head = flags & RESET_HEAD_DETACH;
+       unsigned reset_hard = flags & RESET_HEAD_HARD;
        struct object_id head_oid;
-       struct tree_desc desc;
+       struct tree_desc desc[2] = { { NULL }, { NULL } };
        struct lock_file lock = LOCK_INIT;
        struct unpack_trees_options unpack_tree_opts;
        struct tree *tree;
@@ -536,60 +547,63 @@ static int reset_head(struct object_id *oid, const char *action,
        size_t prefix_len;
        struct object_id *orig = NULL, oid_orig,
                *old_orig = NULL, oid_old_orig;
-       int ret = 0;
+       int ret = 0, nr = 0;
 
        if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
                BUG("Not a fully qualified branch: '%s'", switch_to_branch);
 
-       if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
-               return -1;
+       if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) {
+               ret = -1;
+               goto leave_reset_head;
+       }
 
-       if (!oid) {
-               if (get_oid("HEAD", &head_oid)) {
-                       rollback_lock_file(&lock);
-                       return error(_("could not determine HEAD revision"));
-               }
-               oid = &head_oid;
+       if ((!oid || !reset_hard) && get_oid("HEAD", &head_oid)) {
+               ret = error(_("could not determine HEAD revision"));
+               goto leave_reset_head;
        }
 
+       if (!oid)
+               oid = &head_oid;
+
        memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
        setup_unpack_trees_porcelain(&unpack_tree_opts, action);
        unpack_tree_opts.head_idx = 1;
        unpack_tree_opts.src_index = the_repository->index;
        unpack_tree_opts.dst_index = the_repository->index;
-       unpack_tree_opts.fn = oneway_merge;
+       unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
        unpack_tree_opts.update = 1;
        unpack_tree_opts.merge = 1;
        if (!detach_head)
                unpack_tree_opts.reset = 1;
 
        if (read_index_unmerged(the_repository->index) < 0) {
-               rollback_lock_file(&lock);
-               return error(_("could not read index"));
+               ret = error(_("could not read index"));
+               goto leave_reset_head;
        }
 
-       if (!fill_tree_descriptor(&desc, oid)) {
-               error(_("failed to find tree of %s"), oid_to_hex(oid));
-               rollback_lock_file(&lock);
-               free((void *)desc.buffer);
-               return -1;
+       if (!reset_hard && !fill_tree_descriptor(&desc[nr++], &head_oid)) {
+               ret = error(_("failed to find tree of %s"),
+                           oid_to_hex(&head_oid));
+               goto leave_reset_head;
        }
 
-       if (unpack_trees(1, &desc, &unpack_tree_opts)) {
-               rollback_lock_file(&lock);
-               free((void *)desc.buffer);
-               return -1;
+       if (!fill_tree_descriptor(&desc[nr++], oid)) {
+               ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
+               goto leave_reset_head;
+       }
+
+       if (unpack_trees(nr, desc, &unpack_tree_opts)) {
+               ret = -1;
+               goto leave_reset_head;
        }
 
        tree = parse_tree_indirect(oid);
        prime_cache_tree(the_repository->index, tree);
 
-       if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0)
+       if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) {
                ret = error(_("could not write index"));
-       free((void *)desc.buffer);
-
-       if (ret)
-               return ret;
+               goto leave_reset_head;
+       }
 
        reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
        strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : "rebase");
@@ -613,7 +627,8 @@ static int reset_head(struct object_id *oid, const char *action,
                reflog_head = msg.buf;
        }
        if (!switch_to_branch)
-               ret = update_ref(reflog_head, "HEAD", oid, orig, REF_NO_DEREF,
+               ret = update_ref(reflog_head, "HEAD", oid, orig,
+                                detach_head ? REF_NO_DEREF : 0,
                                 UPDATE_REFS_MSG_ON_ERR);
        else {
                ret = create_symref("HEAD", switch_to_branch, msg.buf);
@@ -622,7 +637,11 @@ static int reset_head(struct object_id *oid, const char *action,
                                         UPDATE_REFS_MSG_ON_ERR);
        }
 
+leave_reset_head:
        strbuf_release(&msg);
+       rollback_lock_file(&lock);
+       while (nr)
+               free((void *)desc[--nr].buffer);
        return ret;
 }
 
@@ -703,6 +722,9 @@ static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
 {
        struct rebase_options *opts = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
+
        if (!is_interactive(opts))
                opts->type = REBASE_MERGE;
 
@@ -715,6 +737,9 @@ static int parse_opt_interactive(const struct option *opt, const char *arg,
 {
        struct rebase_options *opts = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
+
        opts->type = REBASE_INTERACTIVE;
        opts->flags |= REBASE_INTERACTIVE_EXPLICIT;
 
@@ -751,12 +776,29 @@ static void NORETURN error_on_missing_default_upstream(void)
        exit(1);
 }
 
+static void set_reflog_action(struct rebase_options *options)
+{
+       const char *env;
+       struct strbuf buf = STRBUF_INIT;
+
+       if (!is_interactive(options))
+               return;
+
+       env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
+       if (env && strcmp("rebase", env))
+               return; /* only override it if it is "rebase" */
+
+       strbuf_addf(&buf, "rebase -i (%s)", options->action);
+       setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
+       strbuf_release(&buf);
+}
+
 int cmd_rebase(int argc, const char **argv, const char *prefix)
 {
        struct rebase_options options = {
                .type = REBASE_UNSPECIFIED,
                .flags = REBASE_NO_QUIET,
-               .git_am_opt = STRBUF_INIT,
+               .git_am_opts = ARGV_ARRAY_INIT,
                .allow_rerere_autoupdate  = -1,
                .allow_empty_message = 1,
                .git_format_patch_opt = STRBUF_INIT,
@@ -777,12 +819,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                ACTION_EDIT_TODO,
                ACTION_SHOW_CURRENT_PATCH,
        } action = NO_ACTION;
-       int committer_date_is_author_date = 0;
-       int ignore_date = 0;
-       int ignore_whitespace = 0;
        const char *gpg_sign = NULL;
-       int opt_c = -1;
-       struct string_list whitespace = STRING_LIST_INIT_NODUP;
        struct string_list exec = STRING_LIST_INIT_NODUP;
        const char *rebase_merges = NULL;
        int fork_point = -1;
@@ -804,15 +841,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                {OPTION_NEGBIT, 'n', "no-stat", &options.flags, NULL,
                        N_("do not show diffstat of what changed upstream"),
                        PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
-               OPT_BOOL(0, "ignore-whitespace", &ignore_whitespace,
-                        N_("passed to 'git apply'")),
                OPT_BOOL(0, "signoff", &options.signoff,
                         N_("add a Signed-off-by: line to each commit")),
-               OPT_BOOL(0, "committer-date-is-author-date",
-                        &committer_date_is_author_date,
-                        N_("passed to 'git am'")),
-               OPT_BOOL(0, "ignore-date", &ignore_date,
-                        N_("passed to 'git am'")),
+               OPT_PASSTHRU_ARGV(0, "ignore-whitespace", &options.git_am_opts,
+                                 NULL, N_("passed to 'git am'"),
+                                 PARSE_OPT_NOARG),
+               OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date",
+                                 &options.git_am_opts, NULL,
+                                 N_("passed to 'git am'"), PARSE_OPT_NOARG),
+               OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts, NULL,
+                                 N_("passed to 'git am'"), PARSE_OPT_NOARG),
+               OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"),
+                                 N_("passed to 'git apply'"), 0),
+               OPT_PASSTHRU_ARGV(0, "whitespace", &options.git_am_opts,
+                                 N_("action"), N_("passed to 'git apply'"), 0),
                OPT_BIT('f', "force-rebase", &options.flags,
                        N_("cherry-pick all commits, even if unchanged"),
                        REBASE_FORCE),
@@ -846,7 +888,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                               "them"), REBASE_PRESERVE_MERGES),
                OPT_BOOL(0, "rerere-autoupdate",
                         &options.allow_rerere_autoupdate,
-                        N_("allow rerere to update index  with resolved "
+                        N_("allow rerere to update index with resolved "
                            "conflict")),
                OPT_BOOL('k', "keep-empty", &options.keep_empty,
                         N_("preserve empty commits during rebase")),
@@ -856,10 +898,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
                        N_("GPG-sign commits"),
                        PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
-               OPT_STRING_LIST(0, "whitespace", &whitespace,
-                               N_("whitespace"), N_("passed to 'git apply'")),
-               OPT_SET_INT('C', NULL, &opt_c, N_("passed to 'git apply'"),
-                           REBASE_AM),
                OPT_BOOL(0, "autostash", &options.autostash,
                         N_("automatically stash/stash pop before and after")),
                OPT_STRING_LIST('x', "exec", &exec, N_("exec"),
@@ -884,6 +922,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                         N_("rebase all reachable commits up to the root(s)")),
                OPT_END(),
        };
+       int i;
 
        /*
         * NEEDSWORK: Once the builtin rebase has been tested enough
@@ -956,6 +995,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 
        if (action != NO_ACTION && !in_progress)
                die(_("No rebase in progress?"));
+       setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
 
        if (action == ACTION_EDIT_TODO && !is_interactive(&options))
                die(_("The --edit-todo action can only be used during "
@@ -968,6 +1008,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                int fd;
 
                options.action = "continue";
+               set_reflog_action(&options);
 
                /* Sanity check */
                if (get_oid("HEAD", &head))
@@ -996,12 +1037,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                struct string_list merge_rr = STRING_LIST_INIT_DUP;
 
                options.action = "skip";
+               set_reflog_action(&options);
 
                rerere_clear(&merge_rr);
                string_list_clear(&merge_rr, 1);
 
-               if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0)
+               if (reset_head(NULL, "reset", NULL, RESET_HEAD_HARD,
+                              NULL, NULL) < 0)
                        die(_("could not discard worktree changes"));
+               remove_branch_state();
                if (read_basic_state(&options))
                        exit(1);
                goto run_rebase;
@@ -1009,6 +1053,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
        case ACTION_ABORT: {
                struct string_list merge_rr = STRING_LIST_INIT_DUP;
                options.action = "abort";
+               set_reflog_action(&options);
 
                rerere_clear(&merge_rr);
                string_list_clear(&merge_rr, 1);
@@ -1016,9 +1061,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                if (read_basic_state(&options))
                        exit(1);
                if (reset_head(&options.orig_head, "reset",
-                              options.head_name, 0, NULL, NULL) < 0)
+                              options.head_name, RESET_HEAD_HARD,
+                              NULL, NULL) < 0)
                        die(_("could not move back to %s"),
                            oid_to_hex(&options.orig_head));
+               remove_branch_state();
                ret = finish_rebase(&options);
                goto cleanup;
        }
@@ -1064,22 +1111,27 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                    state_dir_base, cmd_live_rebase, buf.buf);
        }
 
-       if (!(options.flags & REBASE_NO_QUIET))
-               strbuf_addstr(&options.git_am_opt, " -q");
-
-       if (committer_date_is_author_date) {
-               strbuf_addstr(&options.git_am_opt,
-                             " --committer-date-is-author-date");
-               options.flags |= REBASE_FORCE;
+       for (i = 0; i < options.git_am_opts.argc; i++) {
+               const char *option = options.git_am_opts.argv[i], *p;
+               if (!strcmp(option, "--committer-date-is-author-date") ||
+                   !strcmp(option, "--ignore-date") ||
+                   !strcmp(option, "--whitespace=fix") ||
+                   !strcmp(option, "--whitespace=strip"))
+                       options.flags |= REBASE_FORCE;
+               else if (skip_prefix(option, "-C", &p)) {
+                       while (*p)
+                               if (!isdigit(*(p++)))
+                                       die(_("switch `C' expects a "
+                                             "numerical value"));
+               } else if (skip_prefix(option, "--whitespace=", &p)) {
+                       if (*p && strcmp(p, "warn") && strcmp(p, "nowarn") &&
+                           strcmp(p, "error") && strcmp(p, "error-all"))
+                               die("Invalid whitespace option: '%s'", p);
+               }
        }
 
-       if (ignore_whitespace)
-               strbuf_addstr(&options.git_am_opt, " --ignore-whitespace");
-
-       if (ignore_date) {
-               strbuf_addstr(&options.git_am_opt, " --ignore-date");
-               options.flags |= REBASE_FORCE;
-       }
+       if (!(options.flags & REBASE_NO_QUIET))
+               argv_array_push(&options.git_am_opts, "-q");
 
        if (options.keep_empty)
                imply_interactive(&options, "--keep-empty");
@@ -1089,23 +1141,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign);
        }
 
-       if (opt_c >= 0)
-               strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
-
-       if (whitespace.nr) {
-               int i;
-
-               for (i = 0; i < whitespace.nr; i++) {
-                       const char *item = whitespace.items[i].string;
-
-                       strbuf_addf(&options.git_am_opt, " --whitespace=%s",
-                                   item);
-
-                       if ((!strcmp(item, "fix")) || (!strcmp(item, "strip")))
-                               options.flags |= REBASE_FORCE;
-               }
-       }
-
        if (exec.nr) {
                int i;
 
@@ -1181,23 +1216,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                break;
        }
 
-       if (options.git_am_opt.len) {
-               const char *p;
-
+       if (options.git_am_opts.argc) {
                /* all am options except -q are compatible only with --am */
-               strbuf_reset(&buf);
-               strbuf_addbuf(&buf, &options.git_am_opt);
-               strbuf_addch(&buf, ' ');
-               while ((p = strstr(buf.buf, " -q ")))
-                       strbuf_splice(&buf, p - buf.buf, 4, " ", 1);
-               strbuf_trim(&buf);
+               for (i = options.git_am_opts.argc - 1; i >= 0; i--)
+                       if (strcmp(options.git_am_opts.argv[i], "-q"))
+                               break;
 
-               if (is_interactive(&options) && buf.len)
+               if (is_interactive(&options) && i >= 0)
                        die(_("error: cannot combine interactive options "
                              "(--interactive, --exec, --rebase-merges, "
                              "--preserve-merges, --keep-empty, --root + "
                              "--onto) with am options (%s)"), buf.buf);
-               if (options.type == REBASE_MERGE && buf.len)
+               if (options.type == REBASE_MERGE && i >= 0)
                        die(_("error: cannot combine merge options (--merge, "
                              "--strategy, --strategy-option) with am options "
                              "(%s)"), buf.buf);
@@ -1207,7 +1237,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                if (options.type == REBASE_PRESERVE_MERGES)
                        die("cannot combine '--signoff' with "
                            "'--preserve-merges'");
-               strbuf_addstr(&options.git_am_opt, " --signoff");
+               argv_array_push(&options.git_am_opts, "--signoff");
                options.flags |= REBASE_FORCE;
        }
 
@@ -1380,7 +1410,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                        write_file(autostash, "%s", oid_to_hex(&oid));
                        printf(_("Created autostash: %s\n"), buf.buf);
                        if (reset_head(&head->object.oid, "reset --hard",
-                                      NULL, 0, NULL, NULL) < 0)
+                                      NULL, RESET_HEAD_HARD, NULL, NULL) < 0)
                                die(_("could not reset --hard"));
                        printf(_("HEAD is now at %s"),
                               find_unique_abbrev(&head->object.oid,
@@ -1431,11 +1461,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                                }
 
                                strbuf_reset(&buf);
-                               strbuf_addf(&buf, "rebase: checkout %s",
+                               strbuf_addf(&buf, "%s: checkout %s",
+                                           getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
                                            options.switch_to);
                                if (reset_head(&oid, "checkout",
                                               options.head_name, 0,
-                                              NULL, NULL) < 0) {
+                                              NULL, buf.buf) < 0) {
                                        ret = !!error(_("could not switch to "
                                                        "%s"),
                                                      options.switch_to);
@@ -1472,10 +1503,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
        if (options.flags & REBASE_DIFFSTAT) {
                struct diff_options opts;
 
-               if (options.flags & REBASE_VERBOSE)
-                       printf(_("Changes from %s to %s:\n"),
-                               oid_to_hex(&merge_base),
-                               oid_to_hex(&options.onto->object.oid));
+               if (options.flags & REBASE_VERBOSE) {
+                       if (is_null_oid(&merge_base))
+                               printf(_("Changes to %s:\n"),
+                                      oid_to_hex(&options.onto->object.oid));
+                       else
+                               printf(_("Changes from %s to %s:\n"),
+                                      oid_to_hex(&merge_base),
+                                      oid_to_hex(&options.onto->object.oid));
+               }
 
                /* We want color (if set), but no pager */
                diff_setup(&opts);
@@ -1485,8 +1521,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                        DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
                opts.detect_rename = DIFF_DETECT_RENAME;
                diff_setup_done(&opts);
-               diff_tree_oid(&merge_base, &options.onto->object.oid,
-                             "", &opts);
+               diff_tree_oid(is_null_oid(&merge_base) ?
+                             the_hash_algo->empty_tree : &merge_base,
+                             &options.onto->object.oid, "", &opts);
                diffcore_std(&opts);
                diff_flush(&opts);
        }
@@ -1499,9 +1536,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                printf(_("First, rewinding head to replay your work on top of "
                         "it...\n"));
 
-       strbuf_addf(&msg, "rebase: checkout %s", options.onto_name);
-       if (reset_head(&options.onto->object.oid, "checkout", NULL, 1,
-           NULL, msg.buf))
+       strbuf_addf(&msg, "%s: checkout %s",
+                   getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
+       if (reset_head(&options.onto->object.oid, "checkout", NULL,
+                      RESET_HEAD_DETACH, NULL, msg.buf))
                die(_("Could not detach HEAD"));
        strbuf_release(&msg);
 
@@ -1511,7 +1549,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
         */
        strbuf_reset(&msg);
        if (!oidcmp(&merge_base, &options.orig_head)) {
-               printf(_("Fast-forwarded %s to %s. \n"),
+               printf(_("Fast-forwarded %s to %s.\n"),
                        branch_name, options.onto_name);
                strbuf_addf(&msg, "rebase finished: %s onto %s",
                        options.head_name ? options.head_name : "detached HEAD",
index a58b9c6d130568602ac7928bd1da4a83724ff4f1..affcdfb4169899c2affee51593f0453d5d9b9add 100644 (file)
@@ -495,6 +495,7 @@ static int convert_graft_file(int force)
        if (!fp)
                return -1;
 
+       advice_graft_file_deprecated = 0;
        while (strbuf_getline(&buf, fp) != EOF) {
                if (*buf.buf == '#')
                        continue;
index 65f4a4c83c42ec33d5ffe3f1d83d7b5465c0796d..934e5149448783e32acc8b605f202384af7d96ee 100644 (file)
@@ -604,6 +604,7 @@ static int parse_reflog_param(const struct option *opt, const char *arg,
 {
        char *ep;
        const char **base = (const char **)opt->value;
+       BUG_ON_OPT_NEG(unset);
        if (!arg)
                arg = "";
        reflog = strtoul(arg, &ep, 10);
@@ -674,7 +675,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                { OPTION_CALLBACK, 'g', "reflog", &reflog_base, N_("<n>[,<base>]"),
                            N_("show <n> most recent ref-log entries starting at "
                               "base"),
-                           PARSE_OPT_OPTARG,
+                           PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
                            parse_reflog_param },
                OPT_END()
        };
index 2f13f1316fadc2fc860fac75a161b47f7d11e391..ed888ffa48ce1d5ef80859b8f5b3bf1720e49abd 100644 (file)
@@ -151,6 +151,7 @@ static int hash_callback(const struct option *opt, const char *arg, int unset)
 static int exclude_existing_callback(const struct option *opt, const char *arg,
                                     int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        exclude_arg = 1;
        *(const char **)opt->value = arg;
        return 0;
index f6236321865773cb60907bfe8b56d96bbaf3e83a..02f6bd1279d9c360f97d04ebba0b1f88ff2f27e1 100644 (file)
@@ -338,6 +338,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
 {
        struct msg_arg *msg = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
        if (msg->buf.len)
@@ -390,8 +392,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                OPT_GROUP(N_("Tag creation options")),
                OPT_BOOL('a', "annotate", &annotate,
                                        N_("annotated tag, needs a message")),
-               OPT_CALLBACK('m', "message", &msg, N_("message"),
-                            N_("tag message"), parse_msg_arg),
+               { OPTION_CALLBACK, 'm', "message", &msg, N_("message"),
+                 N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg },
                OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
                OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")),
                OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
index 0e1dcf0438f7b2ec37b404d3f2acb7bd70650b67..31e7cce3013a3b3f358834f24848fc73b67f8e8b 100644 (file)
@@ -790,12 +790,16 @@ static int refresh(struct refresh_params *o, unsigned int flag)
 static int refresh_callback(const struct option *opt,
                                const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return refresh(opt->value, 0);
 }
 
 static int really_refresh_callback(const struct option *opt,
                                const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return refresh(opt->value, REFRESH_REALLY);
 }
 
@@ -803,6 +807,7 @@ static int chmod_callback(const struct option *opt,
                                const char *arg, int unset)
 {
        char *flip = opt->value;
+       BUG_ON_OPT_NEG(unset);
        if ((arg[0] != '-' && arg[0] != '+') || arg[1] != 'x' || arg[2])
                return error("option 'chmod' expects \"+x\" or \"-x\"");
        *flip = arg[0];
@@ -812,6 +817,8 @@ static int chmod_callback(const struct option *opt,
 static int resolve_undo_clear_callback(const struct option *opt,
                                const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        resolve_undo_clear();
        return 0;
 }
@@ -847,6 +854,8 @@ static int cacheinfo_callback(struct parse_opt_ctx_t *ctx,
        unsigned int mode;
        const char *path;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {
                if (add_cacheinfo(mode, &oid, path, 0))
                        die("git update-index: --cacheinfo cannot add %s", path);
@@ -869,6 +878,8 @@ static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx,
 {
        int *nul_term_line = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (ctx->argc != 1)
                return error("option '%s' must be the last argument", opt->long_name);
        allow_add = allow_replace = allow_remove = 1;
@@ -881,6 +892,8 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx,
 {
        int *read_from_stdin = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (ctx->argc != 1)
                return error("option '%s' must be the last argument", opt->long_name);
        *read_from_stdin = 1;
@@ -888,11 +901,13 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx,
 }
 
 static int unresolve_callback(struct parse_opt_ctx_t *ctx,
-                               const struct option *opt, int flags)
+                               const struct option *opt, int unset)
 {
        int *has_errors = opt->value;
        const char *prefix = startup_info->prefix;
 
+       BUG_ON_OPT_NEG(unset);
+
        /* consume remaining arguments. */
        *has_errors = do_unresolve(ctx->argc, ctx->argv,
                                prefix, prefix ? strlen(prefix) : 0);
@@ -905,11 +920,13 @@ static int unresolve_callback(struct parse_opt_ctx_t *ctx,
 }
 
 static int reupdate_callback(struct parse_opt_ctx_t *ctx,
-                               const struct option *opt, int flags)
+                               const struct option *opt, int unset)
 {
        int *has_errors = opt->value;
        const char *prefix = startup_info->prefix;
 
+       BUG_ON_OPT_NEG(unset);
+
        /* consume remaining arguments. */
        setup_work_tree();
        *has_errors = do_reupdate(ctx->argc, ctx->argv,
index 1ef584b93b87491dca873429f1fbbbadf19622d4..88c3e16d86162518ddde771703a3d2b0fc622f3b 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -243,7 +243,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
 }
 
 
-/* Write the pack data to bundle_fd, then close it if it is > 1. */
+/* Write the pack data to bundle_fd */
 static int write_pack_data(int bundle_fd, struct rev_info *revs)
 {
        struct child_process pack_objects = CHILD_PROCESS_INIT;
@@ -256,6 +256,20 @@ static int write_pack_data(int bundle_fd, struct rev_info *revs)
        pack_objects.in = -1;
        pack_objects.out = bundle_fd;
        pack_objects.git_cmd = 1;
+
+       /*
+        * start_command() will close our descriptor if it's >1. Duplicate it
+        * to avoid surprising the caller.
+        */
+       if (pack_objects.out > 1) {
+               pack_objects.out = dup(pack_objects.out);
+               if (pack_objects.out < 0) {
+                       error_errno(_("unable to dup bundle descriptor"));
+                       child_process_clear(&pack_objects);
+                       return -1;
+               }
+       }
+
        if (start_command(&pack_objects))
                return error(_("Could not spawn pack-objects"));
 
@@ -421,21 +435,10 @@ int create_bundle(struct bundle_header *header, const char *path,
        bundle_to_stdout = !strcmp(path, "-");
        if (bundle_to_stdout)
                bundle_fd = 1;
-       else {
+       else
                bundle_fd = hold_lock_file_for_update(&lock, path,
                                                      LOCK_DIE_ON_ERROR);
 
-               /*
-                * write_pack_data() will close the fd passed to it,
-                * but commit_lock_file() will also try to close the
-                * lockfile's fd. So make a copy of the file
-                * descriptor to avoid trying to close it twice.
-                */
-               bundle_fd = dup(bundle_fd);
-               if (bundle_fd < 0)
-                       die_errno("unable to dup file descriptor");
-       }
-
        /* write signature */
        write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
 
@@ -463,10 +466,8 @@ int create_bundle(struct bundle_header *header, const char *path,
                goto err;
 
        /* write pack */
-       if (write_pack_data(bundle_fd, &revs)) {
-               bundle_fd = -1; /* already closed by the above call */
+       if (write_pack_data(bundle_fd, &revs))
                goto err;
-       }
 
        if (!bundle_to_stdout) {
                if (commit_lock_file(&lock))
@@ -474,11 +475,7 @@ int create_bundle(struct bundle_header *header, const char *path,
        }
        return 0;
 err:
-       if (!bundle_to_stdout) {
-               if (0 <= bundle_fd)
-                       close(bundle_fd);
-               rollback_lock_file(&lock);
-       }
+       rollback_lock_file(&lock);
        return -1;
 }
 
index 06970f72134fae6f6fd6df9afd93a7c7f064f495..69dff4d1ecb4b21c32f8127d78a87a925e9390c5 100755 (executable)
@@ -123,7 +123,7 @@ osx-clang|osx-gcc)
        # Travis CI OS X
        export GIT_SKIP_TESTS="t9810 t9816"
        ;;
-GETTEXT_POISON)
-       export GETTEXT_POISON=YesPlease
+GIT_TEST_GETTEXT_POISON)
+       export GIT_TEST_GETTEXT_POISON=YesPlease
        ;;
 esac
index d566d7e45c17cfa53493f228dbe46f2f92713ac9..d13a7bc3746406bdaf0bda0975c25b40111afe47 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -657,11 +657,10 @@ struct commit *pop_commit(struct commit_list **stack)
 /* count number of children that have not been emitted */
 define_commit_slab(indegree_slab, int);
 
-/* record author-date for each commit object */
 define_commit_slab(author_date_slab, timestamp_t);
 
-static void record_author_date(struct author_date_slab *author_date,
-                              struct commit *commit)
+void record_author_date(struct author_date_slab *author_date,
+                       struct commit *commit)
 {
        const char *buffer = get_commit_buffer(commit, NULL);
        struct ident_split ident;
@@ -686,8 +685,8 @@ static void record_author_date(struct author_date_slab *author_date,
        unuse_commit_buffer(commit, buffer);
 }
 
-static int compare_commits_by_author_date(const void *a_, const void *b_,
-                                         void *cb_data)
+int compare_commits_by_author_date(const void *a_, const void *b_,
+                                  void *cb_data)
 {
        const struct commit *a = a_, *b = b_;
        struct author_date_slab *author_date = cb_data;
@@ -1100,7 +1099,33 @@ int check_commit_signature(const struct commit *commit, struct signature_check *
        return ret;
 }
 
+void verify_merge_signature(struct commit *commit, int verbosity)
+{
+       char hex[GIT_MAX_HEXSZ + 1];
+       struct signature_check signature_check;
+       memset(&signature_check, 0, sizeof(signature_check));
+
+       check_commit_signature(commit, &signature_check);
+
+       find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
+       switch (signature_check.result) {
+       case 'G':
+               break;
+       case 'U':
+               die(_("Commit %s has an untrusted GPG signature, "
+                     "allegedly by %s."), hex, signature_check.signer);
+       case 'B':
+               die(_("Commit %s has a bad GPG signature "
+                     "allegedly by %s."), hex, signature_check.signer);
+       default: /* 'N' */
+               die(_("Commit %s does not have a GPG signature."), hex);
+       }
+       if (verbosity >= 0 && signature_check.result == 'G')
+               printf(_("Commit %s has a good GPG signature by %s\n"),
+                      hex, signature_check.signer);
 
+       signature_check_clear(&signature_check);
+}
 
 void append_merge_tag_headers(struct commit_list *parents,
                              struct commit_extra_header ***tail)
index 8f15cfd43b602f0b85eda82fb9af90eef7996b6c..98664536cb82c65f04a1742c3e5c1e269afc9493 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -8,6 +8,7 @@
 #include "gpg-interface.h"
 #include "string-list.h"
 #include "pretty.h"
+#include "commit-slab.h"
 
 #define COMMIT_NOT_FROM_GRAPH 0xFFFFFFFF
 #define GENERATION_NUMBER_INFINITY 0xFFFFFFFF
@@ -333,6 +334,20 @@ extern int remove_signature(struct strbuf *buf);
  */
 extern int check_commit_signature(const struct commit *commit, struct signature_check *sigc);
 
+/* record author-date for each commit object */
+struct author_date_slab;
+void record_author_date(struct author_date_slab *author_date,
+                       struct commit *commit);
+
+int compare_commits_by_author_date(const void *a_, const void *b_, void *unused);
+
+/*
+ * Verify a single commit with check_commit_signature() and die() if it is not
+ * a good signature. This isn't really suitable for general use, but is a
+ * helper to implement consistent logic for pull/merge --verify-signatures.
+ */
+void verify_merge_signature(struct commit *commit, int verbose);
+
 int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);
 int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused);
 
index d2f4fabb44b898ea6049b8b3fecadc26ddbb6253..34b3880b29d57eee6d6ae0afbb786d7980e7fa3e 100644 (file)
@@ -1028,8 +1028,8 @@ char *mingw_getcwd(char *pointer, int len)
 }
 
 /*
- * See http://msdn2.microsoft.com/en-us/library/17w5ykft(vs.71).aspx
- * (Parsing C++ Command-Line Arguments)
+ * See "Parsing C++ Command-Line Arguments" at Microsoft's Docs:
+ * https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments
  */
 static const char *quote_arg(const char *arg)
 {
@@ -2211,24 +2211,12 @@ int mingw_raise(int sig)
 
 int link(const char *oldpath, const char *newpath)
 {
-       typedef BOOL (WINAPI *T)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
-       static T create_hard_link = NULL;
        wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
        if (xutftowcs_path(woldpath, oldpath) < 0 ||
                xutftowcs_path(wnewpath, newpath) < 0)
                return -1;
 
-       if (!create_hard_link) {
-               create_hard_link = (T) GetProcAddress(
-                       GetModuleHandle("kernel32.dll"), "CreateHardLinkW");
-               if (!create_hard_link)
-                       create_hard_link = (T)-1;
-       }
-       if (create_hard_link == (T)-1) {
-               errno = ENOSYS;
-               return -1;
-       }
-       if (!create_hard_link(wnewpath, woldpath, NULL)) {
+       if (!CreateHardLinkW(wnewpath, woldpath, NULL)) {
                errno = err_win_to_posix(GetLastError());
                return -1;
        }
index e18f5c6e2e55a4b42f178e3042301cd77a654d80..2e7eead42cb008980c7a3b4de63050897c2996da 100644 (file)
@@ -56,141 +56,3 @@ pthread_t pthread_self(void)
        t.tid = GetCurrentThreadId();
        return t;
 }
-
-int pthread_cond_init(pthread_cond_t *cond, const void *unused)
-{
-       cond->waiters = 0;
-       cond->was_broadcast = 0;
-       InitializeCriticalSection(&cond->waiters_lock);
-
-       cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
-       if (!cond->sema)
-               die("CreateSemaphore() failed");
-
-       cond->continue_broadcast = CreateEvent(NULL,    /* security */
-                               FALSE,                  /* auto-reset */
-                               FALSE,                  /* not signaled */
-                               NULL);                  /* name */
-       if (!cond->continue_broadcast)
-               die("CreateEvent() failed");
-
-       return 0;
-}
-
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
-       CloseHandle(cond->sema);
-       CloseHandle(cond->continue_broadcast);
-       DeleteCriticalSection(&cond->waiters_lock);
-       return 0;
-}
-
-int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)
-{
-       int last_waiter;
-
-       EnterCriticalSection(&cond->waiters_lock);
-       cond->waiters++;
-       LeaveCriticalSection(&cond->waiters_lock);
-
-       /*
-        * Unlock external mutex and wait for signal.
-        * NOTE: we've held mutex locked long enough to increment
-        * waiters count above, so there's no problem with
-        * leaving mutex unlocked before we wait on semaphore.
-        */
-       LeaveCriticalSection(mutex);
-
-       /* let's wait - ignore return value */
-       WaitForSingleObject(cond->sema, INFINITE);
-
-       /*
-        * Decrease waiters count. If we are the last waiter, then we must
-        * notify the broadcasting thread that it can continue.
-        * But if we continued due to cond_signal, we do not have to do that
-        * because the signaling thread knows that only one waiter continued.
-        */
-       EnterCriticalSection(&cond->waiters_lock);
-       cond->waiters--;
-       last_waiter = cond->was_broadcast && cond->waiters == 0;
-       LeaveCriticalSection(&cond->waiters_lock);
-
-       if (last_waiter) {
-               /*
-                * cond_broadcast was issued while mutex was held. This means
-                * that all other waiters have continued, but are contending
-                * for the mutex at the end of this function because the
-                * broadcasting thread did not leave cond_broadcast, yet.
-                * (This is so that it can be sure that each waiter has
-                * consumed exactly one slice of the semaphor.)
-                * The last waiter must tell the broadcasting thread that it
-                * can go on.
-                */
-               SetEvent(cond->continue_broadcast);
-               /*
-                * Now we go on to contend with all other waiters for
-                * the mutex. Auf in den Kampf!
-                */
-       }
-       /* lock external mutex again */
-       EnterCriticalSection(mutex);
-
-       return 0;
-}
-
-/*
- * IMPORTANT: This implementation requires that pthread_cond_signal
- * is called while the mutex is held that is used in the corresponding
- * pthread_cond_wait calls!
- */
-int pthread_cond_signal(pthread_cond_t *cond)
-{
-       int have_waiters;
-
-       EnterCriticalSection(&cond->waiters_lock);
-       have_waiters = cond->waiters > 0;
-       LeaveCriticalSection(&cond->waiters_lock);
-
-       /*
-        * Signal only when there are waiters
-        */
-       if (have_waiters)
-               return ReleaseSemaphore(cond->sema, 1, NULL) ?
-                       0 : err_win_to_posix(GetLastError());
-       else
-               return 0;
-}
-
-/*
- * DOUBLY IMPORTANT: This implementation requires that pthread_cond_broadcast
- * is called while the mutex is held that is used in the corresponding
- * pthread_cond_wait calls!
- */
-int pthread_cond_broadcast(pthread_cond_t *cond)
-{
-       EnterCriticalSection(&cond->waiters_lock);
-
-       if ((cond->was_broadcast = cond->waiters > 0)) {
-               /* wake up all waiters */
-               ReleaseSemaphore(cond->sema, cond->waiters, NULL);
-               LeaveCriticalSection(&cond->waiters_lock);
-               /*
-                * At this point all waiters continue. Each one takes its
-                * slice of the semaphor. Now it's our turn to wait: Since
-                * the external mutex is held, no thread can leave cond_wait,
-                * yet. For this reason, we can be sure that no thread gets
-                * a chance to eat *more* than one slice. OTOH, it means
-                * that the last waiter must send us a wake-up.
-                */
-               WaitForSingleObject(cond->continue_broadcast, INFINITE);
-               /*
-                * Since the external mutex is held, no thread can enter
-                * cond_wait, and, hence, it is safe to reset this flag
-                * without cond->waiters_lock held.
-                */
-               cond->was_broadcast = 0;
-       } else {
-               LeaveCriticalSection(&cond->waiters_lock);
-       }
-       return 0;
-}
index 1c164088fbb64d2f0143f536f3186f481d876d28..c6cb8dd2190062b3c3db2ac93a996c859a2e1145 100644 (file)
@@ -32,27 +32,13 @@ typedef int pthread_mutexattr_t;
 #define pthread_mutexattr_settype(a, t) 0
 #define PTHREAD_MUTEX_RECURSIVE 0
 
-/*
- * Implement simple condition variable for Windows threads, based on ACE
- * implementation.
- *
- * See original implementation: http://bit.ly/1vkDjo
- * ACE homepage: http://www.cse.wustl.edu/~schmidt/ACE.html
- * See also: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
- */
-typedef struct {
-       LONG waiters;
-       int was_broadcast;
-       CRITICAL_SECTION waiters_lock;
-       HANDLE sema;
-       HANDLE continue_broadcast;
-} pthread_cond_t;
-
-extern int pthread_cond_init(pthread_cond_t *cond, const void *unused);
-extern int pthread_cond_destroy(pthread_cond_t *cond);
-extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);
-extern int pthread_cond_signal(pthread_cond_t *cond);
-extern int pthread_cond_broadcast(pthread_cond_t *cond);
+#define pthread_cond_t CONDITION_VARIABLE
+
+#define pthread_cond_init(a,b) InitializeConditionVariable((a))
+#define pthread_cond_destroy(a) do {} while (0)
+#define pthread_cond_wait(a,b) return_0(SleepConditionVariableCS((a), (b), INFINITE))
+#define pthread_cond_signal WakeConditionVariable
+#define pthread_cond_broadcast WakeAllConditionVariable
 
 /*
  * Simple thread creation implementation using pthread API
index 2ffd39c22006beaf8c4b0941d82183dd3b756955..ff521eb27ad243b27c7bd95f3ad7a1b777a4ae00 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1668,6 +1668,8 @@ static int do_git_config_sequence(const struct config_options *opts,
 
        if (opts->commondir)
                repo_config = mkpathdup("%s/config", opts->commondir);
+       else if (opts->git_dir)
+               BUG("git_dir without commondir");
        else
                repo_config = NULL;
 
@@ -2292,22 +2294,25 @@ int git_config_get_fsmonitor(void)
        return 0;
 }
 
-int git_config_get_index_threads(void)
+int git_config_get_index_threads(int *dest)
 {
-       int is_bool, val = 0;
+       int is_bool, val;
 
        val = git_env_ulong("GIT_TEST_INDEX_THREADS", 0);
-       if (val)
-               return val;
+       if (val) {
+               *dest = val;
+               return 0;
+       }
 
        if (!git_config_get_bool_or_int("index.threads", &is_bool, &val)) {
                if (is_bool)
-                       return val ? 0 : 1;
+                       *dest = val ? 0 : 1;
                else
-                       return val;
+                       *dest = val;
+               return 0;
        }
 
-       return 0; /* auto */
+       return 1;
 }
 
 NORETURN
index a06027e69b9d453c6e4277968622aa9bd6ae92b1..ee5d3fa7b4264f24e8b36c2e1154546ae626c191 100644 (file)
--- a/config.h
+++ b/config.h
@@ -246,11 +246,11 @@ extern int git_config_get_bool(const char *key, int *dest);
 extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
 extern int git_config_get_maybe_bool(const char *key, int *dest);
 extern int git_config_get_pathname(const char *key, const char **dest);
+extern int git_config_get_index_threads(int *dest);
 extern int git_config_get_untracked_cache(void);
 extern int git_config_get_split_index(void);
 extern int git_config_get_max_percent_split_change(void);
 extern int git_config_get_fsmonitor(void);
-extern int git_config_get_index_threads(void);
 
 /* This dies if the configured or default date is in the future */
 extern int git_config_get_expiry(const char *key, const char **output);
index f179d7a1dc98d091f915dcca9ceb05dda5491549..3ee7da0e230c4c33e79ae2f3cf498a5cd7cc4881 100644 (file)
@@ -430,8 +430,6 @@ ifeq ($(uname_S),Minix)
        NO_NSEC = YesPlease
        NEEDS_LIBGEN =
        NEEDS_CRYPTO_WITH_SSL = YesPlease
-       NEEDS_IDN_WITH_CURL = YesPlease
-       NEEDS_SSL_WITH_CURL = YesPlease
        NEEDS_RESOLV =
        NO_HSTRERROR = YesPlease
        NO_MMAP = YesPlease
@@ -457,7 +455,6 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
        # Missdetected, hence commented out, see below.
        #NO_CURL = YesPlease
        # Added manually, see above.
-       NEEDS_SSL_WITH_CURL = YesPlease
        HAVE_LIBCHARSET_H = YesPlease
        HAVE_STRINGS_H = YesPlease
        NEEDS_LIBICONV = YesPlease
index e11b7976ab1c93d8ccec2e499d0093db42551059..e0d0da3c0c9bccb0b6b1b1a5a3db0097f4f10757 100644 (file)
@@ -600,17 +600,14 @@ AC_CHECK_PROG([CURL_CONFIG], [curl-config],
 
 if test $CURL_CONFIG != no; then
     GIT_CONF_SUBST([CURL_CONFIG])
-    if test -z "${NO_OPENSSL}"; then
-      AC_MSG_CHECKING([if Curl supports SSL])
-      if test $(curl-config --features|grep SSL) = SSL; then
-         NEEDS_SSL_WITH_CURL=YesPlease
-         AC_MSG_RESULT([yes])
-      else
-         NEEDS_SSL_WITH_CURL=
-         AC_MSG_RESULT([no])
-      fi
-      GIT_CONF_SUBST([NEEDS_SSL_WITH_CURL])
+
+    if test -z "$CURL_CONFIG_OPTS"; then
+        CURL_CONFIG_OPTS="--libs"
     fi
+
+    CURL_LDFLAGS=$($CURL_CONFIG $CURL_CONFIG_OPTS)
+    AC_MSG_NOTICE([Setting CURL_LDFLAGS to '$CURL_LDFLAGS'])
+    GIT_CONF_SUBST([CURL_LDFLAGS], [$CURL_LDFLAGS])
 fi
 
 fi
@@ -792,6 +789,12 @@ AC_CHECK_HEADER([sys/select.h],
 [NO_SYS_SELECT_H=UnfortunatelyYes])
 GIT_CONF_SUBST([NO_SYS_SELECT_H])
 #
+# Define NO_POLL_H if you don't have poll.h
+AC_CHECK_HEADER([poll.h],
+[NO_POLL_H=],
+[NO_POLL_H=UnfortunatelyYes])
+GIT_CONF_SUBST([NO_POLL_H])
+#
 # Define NO_SYS_POLL_H if you don't have sys/poll.h
 AC_CHECK_HEADER([sys/poll.h],
 [NO_SYS_POLL_H=],
index 9c2f8879c2efd40a1a7f10980b0603aaeaae6228..f0e80bd7f037731530e7099dc2b27985dd880be3 100644 (file)
@@ -1,2 +1,43 @@
 This directory provides examples of Coccinelle (http://coccinelle.lip6.fr/)
 semantic patches that might be useful to developers.
+
+There are two types of semantic patches:
+
+ * Using the semantic transformation to check for bad patterns in the code;
+   The target 'make coccicheck' is designed to check for these patterns and
+   it is expected that any resulting patch indicates a regression.
+   The patches resulting from 'make coccicheck' are small and infrequent,
+   so once they are found, they can be sent to the mailing list as per usual.
+
+   Example for introducing new patterns:
+   67947c34ae (convert "hashcmp() != 0" to "!hasheq()", 2018-08-28)
+   b84c783882 (fsck: s/++i > 1/i++/, 2018-10-24)
+
+   Example of fixes using this approach:
+   248f66ed8e (run-command: use strbuf_addstr() for adding a string to
+               a strbuf, 2018-03-25)
+   f919ffebed (Use MOVE_ARRAY, 2018-01-22)
+
+   These types of semantic patches are usually part of testing, c.f.
+   0860a7641b (travis-ci: fail if Coccinelle static analysis found something
+               to transform, 2018-07-23)
+
+ * Using semantic transformations in large scale refactorings throughout
+   the code base.
+
+   When applying the semantic patch into a real patch, sending it to the
+   mailing list in the usual way, such a patch would be expected to have a
+   lot of textual and semantic conflicts as such large scale refactorings
+   change function signatures that are used widely in the code base.
+   A textual conflict would arise if surrounding code near any call of such
+   function changes. A semantic conflict arises when other patch series in
+   flight introduce calls to such functions.
+
+   So to aid these large scale refactorings, semantic patches can be used.
+   However we do not want to store them in the same place as the checks for
+   bad patterns, as then automated builds would fail.
+   That is why semantic patches 'contrib/coccinelle/*.pending.cocci'
+   are ignored for checks, and can be applied using 'make coccicheck-pending'.
+
+   This allows to expose plans of pending large scale refactorings without
+   impacting the bad pattern checks.
diff --git a/diff.c b/diff.c
index e38d1ecaf45d1b79eeab093ba86e34fe3bbd931a..dc9965e836cd49c46a01293ef1d678a619b8f997 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3228,7 +3228,7 @@ static void emit_binary_diff_body(struct diff_options *o,
        }
 
        if (delta && delta_size < deflate_size) {
-               char *s = xstrfmt("%lu", orig_size);
+               char *s = xstrfmt("%"PRIuMAX , (uintmax_t)orig_size);
                emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER_DELTA,
                                 s, strlen(s), 0);
                free(s);
diff --git a/entry.c b/entry.c
index 5d136c5d55e0811b70fdb10f59ea506ceb1b273b..0a3c451f5f0f08deabe20b4ca1858825f2b29f3f 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -404,7 +404,7 @@ static void mark_colliding_entries(const struct checkout *state,
 {
        int i, trust_ino = check_stat;
 
-#if defined(GIT_WINDOWS_NATIVE)
+#if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__)
        trust_ino = 0;
 #endif
 
@@ -419,7 +419,7 @@ static void mark_colliding_entries(const struct checkout *state,
                if (dup->ce_flags & (CE_MATCHED | CE_VALID | CE_SKIP_WORKTREE))
                        continue;
 
-               if ((trust_ino && dup->ce_stat_data.sd_ino == st->st_ino) ||
+               if ((trust_ino && !match_stat_data(&dup->ce_stat_data, st)) ||
                    (!trust_ino && !fspathcmp(ce->name, dup->name))) {
                        dup->ce_flags |= CE_MATCHED;
                        break;
index 95600c78e048f9d3d28672737d4bc2a941073abc..69886687ce95fd7dfe5363d0c776e21241b6b830 100644 (file)
@@ -2955,8 +2955,8 @@ static void cat_blob(struct object_entry *oe, struct object_id *oid)
                die("Object %s is a %s but a blob was expected.",
                    oid_to_hex(oid), type_name(type));
        strbuf_reset(&line);
-       strbuf_addf(&line, "%s %s %lu\n", oid_to_hex(oid),
-                                               type_name(type), size);
+       strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),
+                   type_name(type), (uintmax_t)size);
        cat_blob_write(line.buf, line.len);
        strbuf_release(&line);
        cat_blob_write(buf, size);
index 7272771c8e445da194ea608443d8bc9c891b6b33..d4021d690c07237edefb0cf2869eb6795d227a54 100644 (file)
--- a/gettext.c
+++ b/gettext.c
@@ -7,6 +7,7 @@
 #include "gettext.h"
 #include "strbuf.h"
 #include "utf8.h"
+#include "config.h"
 
 #ifndef NO_GETTEXT
 #      include <locale.h>
@@ -46,15 +47,15 @@ const char *get_preferred_languages(void)
        return NULL;
 }
 
-#ifdef GETTEXT_POISON
 int use_gettext_poison(void)
 {
        static int poison_requested = -1;
-       if (poison_requested == -1)
-               poison_requested = getenv("GIT_GETTEXT_POISON") ? 1 : 0;
+       if (poison_requested == -1) {
+               const char *v = getenv("GIT_TEST_GETTEXT_POISON");
+               poison_requested = v && strlen(v) ? 1 : 0;
+       }
        return poison_requested;
 }
-#endif
 
 #ifndef NO_GETTEXT
 static int test_vsnprintf(const char *fmt, ...)
@@ -164,6 +165,8 @@ void git_setup_gettext(void)
        if (!podir)
                podir = p = system_path(GIT_LOCALE_PATH);
 
+       use_gettext_poison(); /* getenv() reentrancy paranoia */
+
        if (!is_directory(podir)) {
                free(p);
                return;
index 7eee64a34fa0a5e922606e6351b29d08cb26fe6b..71255e503eeb70e691e03ac1be0e2a249244a096 100644 (file)
--- a/gettext.h
+++ b/gettext.h
 
 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
 
+extern int use_gettext_poison(void);
+
 #ifndef NO_GETTEXT
 extern void git_setup_gettext(void);
 extern int gettext_width(const char *s);
 #else
 static inline void git_setup_gettext(void)
 {
+       use_gettext_poison(); /* getenv() reentrancy paranoia */
 }
 static inline int gettext_width(const char *s)
 {
@@ -41,12 +44,6 @@ static inline int gettext_width(const char *s)
 }
 #endif
 
-#ifdef GETTEXT_POISON
-extern int use_gettext_poison(void);
-#else
-#define use_gettext_poison() 0
-#endif
-
 static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
        if (!*msgid)
index 3a08d9916fb49b5a1578c74a5ae2949d98a8e699..09b0102cae8c8c0e39dc239003ca599a896730cf 100644 (file)
 #include <regex.h>
 #include <utime.h>
 #include <syslog.h>
-#ifndef NO_SYS_POLL_H
+#if !defined(NO_POLL_H)
+#include <poll.h>
+#elif !defined(NO_SYS_POLL_H)
 #include <sys/poll.h>
 #else
+/* Pull the compat stuff */
 #include <poll.h>
 #endif
 #ifdef HAVE_BSD_SYSCTL
@@ -858,6 +861,7 @@ extern FILE *fopen_or_warn(const char *path, const char *mode);
 #define FREE_AND_NULL(p) do { free(p); (p) = NULL; } while (0)
 
 #define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
+#define CALLOC_ARRAY(x, alloc) (x) = xcalloc((alloc), sizeof(*(x)));
 #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
 
 #define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \
index 75a08b2683e76e6832475bc91e4d4f38b3d3bc3c..b4c7dbfa575d3b5c664677c22b8613284d2e33fb 100755 (executable)
@@ -337,6 +337,11 @@ do
                fix|strip)
                        force_rebase=t
                        ;;
+               warn|nowarn|error|error-all)
+                       ;; # okay, known whitespace option
+               *)
+                       die "fatal: Invalid whitespace option: '${1#*=}'"
+                       ;;
                esac
                ;;
        --ignore-whitespace)
@@ -352,6 +357,9 @@ do
                git_am_opt="$git_am_opt $1"
                force_rebase=t
                ;;
+       -C*[!0-9]*)
+               die "fatal: switch \`C' expects a numerical value"
+               ;;
        -C*)
                git_am_opt="$git_am_opt $1"
                ;;
@@ -710,10 +718,16 @@ if test -n "$diffstat"
 then
        if test -n "$verbose"
        then
-               echo "$(eval_gettext "Changes from \$mb to \$onto:")"
+               if test -z "$mb"
+               then
+                       echo "$(eval_gettext "Changes to \$onto:")"
+               else
+                       echo "$(eval_gettext "Changes from \$mb to \$onto:")"
+               fi
        fi
+       mb_tree="${mb:-$(git hash-object -t tree /dev/null)}"
        # We want color (if set), but no pager
-       GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
+       GIT_PAGER='' git diff --stat --summary "$mb_tree" "$onto"
 fi
 
 test -n "$interactive_rebase" && run_specific_rebase
index 9d065fb4bf9a308e64fa2d4aa5dff294b116f1a9..e1d917fd2796d1f2d952c509cb79d8cafe0cf89e 100644 (file)
@@ -17,7 +17,7 @@ export TEXTDOMAINDIR
 
 # First decide what scheme to use...
 GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
-if test -n "$GIT_GETTEXT_POISON"
+if test -n "$GIT_TEST_GETTEXT_POISON"
 then
        GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
 elif test -n "@@USE_GETTEXT_SCHEME@@"
diff --git a/grep.c b/grep.c
index f6bd89e40b7f7a8442a6e0a302a1e6080df5afbd..4db1510d167c9fc3cc7b129c90aa874a4c7c2b0f 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -1513,7 +1513,6 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
        }
 }
 
-#ifndef NO_PTHREADS
 int grep_use_locks;
 
 /*
@@ -1539,11 +1538,6 @@ static inline void grep_attr_unlock(void)
  */
 pthread_mutex_t grep_read_mutex;
 
-#else
-#define grep_attr_lock()
-#define grep_attr_unlock()
-#endif
-
 static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bol, char *eol)
 {
        xdemitconf_t *xecfg = opt->priv;
diff --git a/grep.h b/grep.h
index 1a57d12b906fb07a9041f52b109dcdb4c7478bfa..fb0489372169d7f1563a09e050c8715542ce5963 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -229,7 +229,6 @@ int grep_source(struct grep_opt *opt, struct grep_source *gs);
 extern struct grep_opt *grep_opt_dup(const struct grep_opt *opt);
 extern int grep_threads_ok(const struct grep_opt *opt);
 
-#ifndef NO_PTHREADS
 /*
  * Mutex used around access to the attributes machinery if
  * opt->use_threads.  Must be initialized/destroyed by callers!
@@ -250,9 +249,4 @@ static inline void grep_read_unlock(void)
                pthread_mutex_unlock(&grep_read_mutex);
 }
 
-#else
-#define grep_read_lock()
-#define grep_read_unlock()
-#endif
-
 #endif
index d1f52cbdf698ef3ac48d3c599d28d6ba7dfa13aa..cd485909127a79afcbb58ef18cd28977b65efb79 100644 (file)
@@ -365,7 +365,7 @@ static void start_put(struct transfer_request *request)
        git_zstream stream;
 
        unpacked = read_object_file(&request->obj->oid, &type, &len);
-       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
+       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
 
        /* Set it up */
        git_deflate_init(&stream, zlib_compression_level);
diff --git a/http.c b/http.c
index 3dc8c560d65e7acebb22f63e797406e38afc6422..eacc2a75ef2e41da9d5f5741defcf1952e6c01a3 100644 (file)
--- a/http.c
+++ b/http.c
@@ -834,7 +834,7 @@ static CURL *get_curl_handle(void)
 #if LIBCURL_VERSION_NUM >= 0x072c00
                curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
 #else
-               warning(_("CURLSSLOPT_NO_REVOKE not suported with cURL < 7.44.0"));
+               warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"));
 #endif
        }
 
index 7a83e99250c5245bbbbd43908f3c116567f39b62..b243779a0b7dc15200689febe68549a85ce5c6a7 100644 (file)
@@ -762,7 +762,7 @@ void show_log(struct rev_info *opt)
                next_commentary_block(opt, NULL);
                fprintf_ln(opt->diffopt.file, "%s", opt->rdiff_title);
                show_range_diff(opt->rdiff1, opt->rdiff2,
-                               opt->creation_factor, 1, &opt->diffopt);
+                               opt->creation_factor, 1, NULL);
 
                memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));
        }
diff --git a/midx.c b/midx.c
index a50b117b777d2659a6d930997ced4f43fbbc3e46..2a6a24fcd7eff1a074c37e6c556f2143ef134c19 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -202,7 +202,7 @@ int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
        struct strbuf pack_name = STRBUF_INIT;
 
        if (pack_int_id >= m->num_packs)
-               die(_("bad pack-int-id: %u (%u total packs"),
+               die(_("bad pack-int-id: %u (%u total packs)"),
                    pack_int_id, m->num_packs);
 
        if (m->packs[pack_int_id])
@@ -721,12 +721,18 @@ static size_t write_midx_object_offsets(struct hashfile *f, int large_offset_nee
 static size_t write_midx_large_offsets(struct hashfile *f, uint32_t nr_large_offset,
                                       struct pack_midx_entry *objects, uint32_t nr_objects)
 {
-       struct pack_midx_entry *list = objects;
+       struct pack_midx_entry *list = objects, *end = objects + nr_objects;
        size_t written = 0;
 
        while (nr_large_offset) {
-               struct pack_midx_entry *obj = list++;
-               uint64_t offset = obj->offset;
+               struct pack_midx_entry *obj;
+               uint64_t offset;
+
+               if (list >= end)
+                       BUG("too many large-offset objects");
+
+               obj = list++;
+               offset = obj->offset;
 
                if (!(offset >> 31))
                        continue;
index 1fcda73cb396e305a75aa8dc5869aaf85011761e..623ca6923a9ec78b9bb7d7cc899af72057d101d3 100644 (file)
@@ -7,6 +7,7 @@
  */
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
+#include "thread-utils.h"
 
 struct dir_entry {
        struct hashmap_entry ent;
@@ -131,22 +132,6 @@ static int cache_entry_cmp(const void *unused_cmp_data,
 static int lazy_try_threaded = 1;
 static int lazy_nr_dir_threads;
 
-#ifdef NO_PTHREADS
-
-static inline int lookup_lazy_params(struct index_state *istate)
-{
-       return 0;
-}
-
-static inline void threaded_lazy_init_name_hash(
-       struct index_state *istate)
-{
-}
-
-#else
-
-#include "thread-utils.h"
-
 /*
  * Set a minimum number of cache_entries that we will handle per
  * thread and use that to decide how many threads to run (upto
@@ -509,6 +494,7 @@ static inline void lazy_update_dir_ref_counts(
 static void threaded_lazy_init_name_hash(
        struct index_state *istate)
 {
+       int err;
        int nr_each;
        int k_start;
        int t;
@@ -516,6 +502,9 @@ static void threaded_lazy_init_name_hash(
        struct lazy_dir_thread_data *td_dir;
        struct lazy_name_thread_data *td_name;
 
+       if (!HAVE_THREADS)
+               return;
+
        k_start = 0;
        nr_each = DIV_ROUND_UP(istate->cache_nr, lazy_nr_dir_threads);
 
@@ -538,8 +527,9 @@ static void threaded_lazy_init_name_hash(
                if (k_start > istate->cache_nr)
                        k_start = istate->cache_nr;
                td_dir_t->k_end = k_start;
-               if (pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t))
-                       die("unable to create lazy_dir_thread");
+               err = pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t);
+               if (err)
+                       die(_("unable to create lazy_dir thread: %s"), strerror(err));
        }
        for (t = 0; t < lazy_nr_dir_threads; t++) {
                struct lazy_dir_thread_data *td_dir_t = td_dir + t;
@@ -559,13 +549,15 @@ static void threaded_lazy_init_name_hash(
         */
        td_name->istate = istate;
        td_name->lazy_entries = lazy_entries;
-       if (pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name))
-               die("unable to create lazy_name_thread");
+       err = pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name);
+       if (err)
+               die(_("unable to create lazy_name thread: %s"), strerror(err));
 
        lazy_update_dir_ref_counts(istate, lazy_entries);
 
-       if (pthread_join(td_name->pthread, NULL))
-               die("unable to join lazy_name_thread");
+       err = pthread_join(td_name->pthread, NULL);
+       if (err)
+               die(_("unable to join lazy_name thread: %s"), strerror(err));
 
        cleanup_dir_mutex();
 
@@ -574,8 +566,6 @@ static void threaded_lazy_init_name_hash(
        free(lazy_entries);
 }
 
-#endif
-
 static void lazy_init_name_hash(struct index_state *istate)
 {
 
index 0feb90ae613be04d56ac091307c9b2be88724e42..796792cb32a7ae86b253df05671e1ed4736e4d15 100644 (file)
--- a/object.h
+++ b/object.h
@@ -59,7 +59,7 @@ struct object_array {
 
 /*
  * object flag allocation:
- * revision.h:               0---------10                              2526
+ * revision.h:               0---------10                              25----28
  * fetch-pack.c:             01
  * negotiator/default.c:       2--5
  * walker.c:                 0-2
@@ -78,7 +78,7 @@ struct object_array {
  * builtin/show-branch.c:    0-------------------------------------------26
  * builtin/unpack-objects.c:                                 2021
  */
-#define FLAG_BITS  27
+#define FLAG_BITS  29
 
 /*
  * The object type is stored in 3 bits.
index 86ee93feb4f7d14518ed1ffe9cac8d8a7cd817fe..dc869f26c2b753593a875f275d896933b7723b31 100644 (file)
@@ -145,9 +145,7 @@ struct packing_data {
        struct packed_git **in_pack_by_idx;
        struct packed_git **in_pack;
 
-#ifndef NO_PTHREADS
        pthread_mutex_t lock;
-#endif
 
        /*
         * This list contains entries for bases which we know the other side
@@ -169,15 +167,11 @@ void prepare_packing_data(struct packing_data *pdata);
 
 static inline void packing_data_lock(struct packing_data *pdata)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_lock(&pdata->lock);
-#endif
 }
 static inline void packing_data_unlock(struct packing_data *pdata)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_unlock(&pdata->lock);
-#endif
 }
 
 struct object_entry *packlist_alloc(struct packing_data *pdata,
@@ -418,7 +412,7 @@ static inline void oe_set_tree_depth(struct packing_data *pack,
                                     unsigned int tree_depth)
 {
        if (!pack->tree_depth)
-               ALLOC_ARRAY(pack->tree_depth, pack->nr_objects);
+               CALLOC_ARRAY(pack->tree_depth, pack->nr_alloc);
        pack->tree_depth[e - pack->objects] = tree_depth;
 }
 
@@ -435,7 +429,7 @@ static inline void oe_set_layer(struct packing_data *pack,
                                unsigned char layer)
 {
        if (!pack->layer)
-               ALLOC_ARRAY(pack->layer, pack->nr_objects);
+               CALLOC_ARRAY(pack->layer, pack->nr_alloc);
        pack->layer[e - pack->objects] = layer;
 }
 
index e8236534ac8aa00fde2a5a9ae27e85c72d062f3a..8c9edce52f63bcb1085b119b3a2264a97b1fb374 100644 (file)
@@ -28,13 +28,6 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
-int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
-                            int unset)
-{
-       *(timestamp_t *)(opt->value) = approxidate(arg);
-       return 0;
-}
-
 int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
                             int unset)
 {
@@ -65,6 +58,8 @@ int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
 {
        int *target = opt->value;
 
+       BUG_ON_OPT_ARG(arg);
+
        if (unset)
                /* --no-quiet, --no-verbose */
                *target = 0;
@@ -87,6 +82,8 @@ int parse_opt_commits(const struct option *opt, const char *arg, int unset)
        struct object_id oid;
        struct commit *commit;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
        if (get_oid(arg, &oid))
@@ -117,6 +114,9 @@ int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
 int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
 {
        int *target = opt->value;
+
+       BUG_ON_OPT_ARG(arg);
+
        *target = unset ? 2 : 1;
        return 0;
 }
index dd14911a297a5b10705ecb31243c55a7dc2f193c..6c4fe2016d65f1093400f8f5080085eb244f0026 100644 (file)
@@ -150,9 +150,6 @@ struct option {
                                      (h), 0, &parse_opt_string_list }
 #define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
                                      (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
-#define OPT_DATE(s, l, v, h) \
-       { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,    \
-         parse_opt_approxidate_cb }
 #define OPT_EXPIRY_DATE(s, l, v, h) \
        { OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0,     \
          parse_opt_expiry_date_cb }
@@ -194,6 +191,20 @@ extern int opterror(const struct option *opt, const char *reason, int flags);
 #define opterror(o,r,f) (opterror((o),(r),(f)), const_error())
 #endif
 
+/*
+ * Use these assertions for callbacks that expect to be called with NONEG and
+ * NOARG respectively, and do not otherwise handle the "unset" and "arg"
+ * parameters.
+ */
+#define BUG_ON_OPT_NEG(unset) do { \
+       if ((unset)) \
+               BUG("option callback does not expect negation"); \
+} while (0)
+#define BUG_ON_OPT_ARG(arg) do { \
+       if ((arg)) \
+               BUG("option callback does not expect an argument"); \
+} while (0)
+
 /*----- incremental advanced APIs -----*/
 
 enum {
@@ -232,7 +243,6 @@ extern struct option *parse_options_concat(struct option *a, struct option *b);
 
 /*----- some often used options -----*/
 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
-extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
 extern int parse_opt_expiry_date_cb(const struct option *, const char *, int);
 extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
 extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
index fef4c0f0b5ae15e98b8a5913afe60783a701f40a..aa704ffcb7f70af2c42494a2f26eeef17c5eed67 100644 (file)
--- a/po/README
+++ b/po/README
@@ -289,16 +289,11 @@ something in the test suite might still depend on the US English
 version of the strings, e.g. to grep some error message or other
 output.
 
-To smoke out issues like these Git can be compiled with gettext poison
-support, at the top-level:
+To smoke out issues like these, Git tested with a translation mode that
+emits gibberish on every call to gettext. To use it run the test suite
+with it, e.g.:
 
-    make GETTEXT_POISON=YesPlease
-
-That'll give you a git which emits gibberish on every call to
-gettext. It's obviously not meant to be installed, but you should run
-the test suite with it:
-
-    cd t && prove -j 9 ./t[0-9]*.sh
+    cd t && GIT_TEST_GETTEXT_POISON=YesPlease prove -j 9 ./t[0-9]*.sh
 
 If tests break with it you should inspect them manually and see if
 what you're translating is sane, i.e. that you're not translating
index 222792ccbc39b6166a75c702525c396b77c2299e..c7dc3f2b9f62a762efd7f590d6e8959fc1707479 100644 (file)
@@ -7,17 +7,7 @@
 #include "fsmonitor.h"
 #include "config.h"
 #include "progress.h"
-
-#ifdef NO_PTHREADS
-void preload_index(struct index_state *index,
-                         const struct pathspec *pathspec,
-                         unsigned int refresh_flags)
-{
-       ; /* nothing */
-}
-#else
-
-#include <pthread.h>
+#include "thread-utils.h"
 
 /*
  * Mostly randomly chosen maximum thread counts: we
@@ -108,7 +98,7 @@ void preload_index(struct index_state *index,
        struct thread_data data[MAX_PARALLEL];
        struct progress_data pd;
 
-       if (!core_preload_index)
+       if (!HAVE_THREADS || !core_preload_index)
                return;
 
        threads = index->cache_nr / THREAD_COST;
@@ -131,6 +121,8 @@ void preload_index(struct index_state *index,
 
        for (i = 0; i < threads; i++) {
                struct thread_data *p = data+i;
+               int err;
+
                p->index = index;
                if (pathspec)
                        copy_pathspec(&p->pathspec, pathspec);
@@ -139,8 +131,10 @@ void preload_index(struct index_state *index,
                if (pd.progress)
                        p->progress = &pd;
                offset += work;
-               if (pthread_create(&p->pthread, NULL, preload_thread, p))
-                       die("unable to create threaded lstat");
+               err = pthread_create(&p->pthread, NULL, preload_thread, p);
+
+               if (err)
+                       die(_("unable to create threaded lstat: %s"), strerror(err));
        }
        for (i = 0; i < threads; i++) {
                struct thread_data *p = data+i;
@@ -151,7 +145,6 @@ void preload_index(struct index_state *index,
 
        trace_performance_leave("preload index");
 }
-#endif
 
 int read_index_preload(struct index_state *index,
                       const struct pathspec *pathspec,
index a07845187233e429e00138cce7ade42e97a40d4b..d3f488cb05f29bc90e4e03810d9bf4b972d0834f 100644 (file)
@@ -85,3 +85,12 @@ void *prio_queue_get(struct prio_queue *queue)
        }
        return result;
 }
+
+void *prio_queue_peek(struct prio_queue *queue)
+{
+       if (!queue->nr)
+               return NULL;
+       if (!queue->compare)
+               return queue->array[queue->nr - 1].data;
+       return queue->array[0].data;
+}
index d030ec9dd6765447ad986a40945d1ed8bf9272a0..682e51867a3452bc1106bc63f44d6d6ba5f523b9 100644 (file)
@@ -46,6 +46,12 @@ extern void prio_queue_put(struct prio_queue *, void *thing);
  */
 extern void *prio_queue_get(struct prio_queue *);
 
+/*
+ * Gain access to the "thing" that would be returned by
+ * prio_queue_get, but do not remove it from the queue.
+ */
+extern void *prio_queue_peek(struct prio_queue *);
+
 extern void clear_prio_queue(struct prio_queue *);
 
 /* Reverse the LIFO elements */
index 3958720f004ebe9ba027cd6097a7cd3ce41e3d73..48b0e1b4ce0ff69b9c7a430174db25b1ca6494f8 100644 (file)
@@ -460,8 +460,13 @@ int show_range_diff(const char *range1, const char *range2,
                struct diff_options opts;
                struct strbuf indent = STRBUF_INIT;
 
-               memcpy(&opts, diffopt, sizeof(opts));
-               opts.output_format = DIFF_FORMAT_PATCH;
+               if (diffopt)
+                       memcpy(&opts, diffopt, sizeof(opts));
+               else
+                       diff_setup(&opts);
+
+               if (!opts.output_format)
+                       opts.output_format = DIFF_FORMAT_PATCH;
                opts.flags.suppress_diff_headers = 1;
                opts.flags.dual_color_diffed_diffs = dual_color;
                opts.output_prefix = output_prefix_cb;
index 190593f0c78151c99cc6e87161137b99c2615c80..08a50b6e98fc768f42e48b33c70ffbf17a7e8e4c 100644 (file)
@@ -5,6 +5,11 @@
 
 #define RANGE_DIFF_CREATION_FACTOR_DEFAULT 60
 
+/*
+ * Compare series of commmits in RANGE1 and RANGE2, and emit to the
+ * standard output.  NULL can be passed to DIFFOPT to use the built-in
+ * default.
+ */
 int show_range_diff(const char *range1, const char *range2,
                    int creation_factor, int dual_color,
                    struct diff_options *diffopt);
index 8c924506dd96037c1d7c0fa93e4223f9274a851f..bd45dc3e24d7dc28820d26cc6e6d377f92fda46d 100644 (file)
@@ -1752,7 +1752,7 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
        size_t len;
        const char *name;
        unsigned int flags;
-       size_t copy_len;
+       size_t copy_len = 0;
        /*
         * Adjacent cache entries tend to share the leading paths, so it makes
         * sense to only store the differences in later entries.  In the v4
@@ -1792,8 +1792,6 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
                                die(_("malformed name field in the index, near path '%s'"),
                                        previous_ce->name);
                        copy_len = previous_len - strip_len;
-               } else {
-                       copy_len = 0;
                }
                name = (const char *)cp;
        }
@@ -1926,19 +1924,15 @@ struct index_entry_offset_table
        struct index_entry_offset entries[FLEX_ARRAY];
 };
 
-#ifndef NO_PTHREADS
 static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset);
 static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_table *ieot);
-#endif
 
 static size_t read_eoie_extension(const char *mmap, size_t mmap_size);
 static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context, size_t offset);
 
 struct load_index_extensions
 {
-#ifndef NO_PTHREADS
        pthread_t pthread;
-#endif
        struct index_state *istate;
        const char *mmap;
        size_t mmap_size;
@@ -2016,8 +2010,6 @@ static unsigned long load_all_cache_entries(struct index_state *istate,
        return consumed;
 }
 
-#ifndef NO_PTHREADS
-
 /*
  * Mostly randomly chosen maximum thread counts: we
  * cap the parallelism to online_cpus() threads, and we want
@@ -2128,7 +2120,6 @@ static unsigned long load_cache_entries_threaded(struct index_state *istate, con
 
        return consumed;
 }
-#endif
 
 /* remember to discard_cache() before reading a different cache! */
 int do_read_index(struct index_state *istate, const char *path, int must_exist)
@@ -2141,10 +2132,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        size_t mmap_size;
        struct load_index_extensions p;
        size_t extension_offset = 0;
-#ifndef NO_PTHREADS
        int nr_threads, cpus;
        struct index_entry_offset_table *ieot = NULL;
-#endif
 
        if (istate->initialized)
                return istate->cache_nr;
@@ -2187,8 +2176,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
 
        src_offset = sizeof(*hdr);
 
-#ifndef NO_PTHREADS
-       nr_threads = git_config_get_index_threads();
+       if (git_config_get_index_threads(&nr_threads))
+               nr_threads = 1;
 
        /* TODO: does creating more threads than cores help? */
        if (!nr_threads) {
@@ -2198,6 +2187,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
                        nr_threads = cpus;
        }
 
+       if (!HAVE_THREADS)
+               nr_threads = 1;
+
        if (nr_threads > 1) {
                extension_offset = read_eoie_extension(mmap, mmap_size);
                if (extension_offset) {
@@ -2225,22 +2217,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        } else {
                src_offset += load_all_cache_entries(istate, mmap, mmap_size, src_offset);
        }
-#else
-       src_offset += load_all_cache_entries(istate, mmap, mmap_size, src_offset);
-#endif
 
        istate->timestamp.sec = st.st_mtime;
        istate->timestamp.nsec = ST_MTIME_NSEC(st);
 
        /* if we created a thread, join it otherwise load the extensions on the primary thread */
-#ifndef NO_PTHREADS
        if (extension_offset) {
                int ret = pthread_join(p.pthread, NULL);
                if (ret)
                        die(_("unable to join load_index_extensions thread: %s"), strerror(ret));
-       }
-#endif
-       if (!extension_offset) {
+       } else {
                p.src_offset = src_offset;
                load_index_extensions(&p);
        }
@@ -2704,6 +2690,36 @@ void update_index_if_able(struct index_state *istate, struct lock_file *lockfile
                rollback_lock_file(lockfile);
 }
 
+static int record_eoie(void)
+{
+       int val;
+
+       if (!git_config_get_bool("index.recordendofindexentries", &val))
+               return val;
+
+       /*
+        * As a convenience, the end of index entries extension
+        * used for threading is written by default if the user
+        * explicitly requested threaded index reads.
+        */
+       return !git_config_get_index_threads(&val) && val != 1;
+}
+
+static int record_ieot(void)
+{
+       int val;
+
+       if (!git_config_get_bool("index.recordoffsettable", &val))
+               return val;
+
+       /*
+        * As a convenience, the offset table used for threading is
+        * written by default if the user explicitly requested
+        * threaded index reads.
+        */
+       return !git_config_get_index_threads(&val) && val != 1;
+}
+
 /*
  * On success, `tempfile` is closed. If it is the temporary file
  * of a `struct lock_file`, we will therefore effectively perform
@@ -2762,9 +2778,10 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
        if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
                return -1;
 
-#ifndef NO_PTHREADS
-       nr_threads = git_config_get_index_threads();
-       if (nr_threads != 1) {
+       if (!HAVE_THREADS || git_config_get_index_threads(&nr_threads))
+               nr_threads = 1;
+
+       if (nr_threads != 1 && record_ieot()) {
                int ieot_blocks, cpus;
 
                /*
@@ -2793,7 +2810,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
                        ieot_entries = DIV_ROUND_UP(entries, ieot_blocks);
                }
        }
-#endif
 
        offset = lseek(newfd, 0, SEEK_CUR);
        if (offset < 0) {
@@ -2877,7 +2893,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
         * strip_extensions parameter as we need it when loading the shared
         * index.
         */
-#ifndef NO_PTHREADS
        if (ieot) {
                struct strbuf sb = STRBUF_INIT;
 
@@ -2889,7 +2904,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
                if (err)
                        return -1;
        }
-#endif
 
        if (!strip_extensions && istate->split_index) {
                struct strbuf sb = STRBUF_INIT;
@@ -2951,7 +2965,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
         * read.  Write it out regardless of the strip_extensions parameter as we need it
         * when loading the shared index.
         */
-       if (offset) {
+       if (offset && record_eoie()) {
                struct strbuf sb = STRBUF_INIT;
 
                write_eoie_extension(&sb, &eoie_c, offset);
@@ -3165,7 +3179,8 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
                struct tempfile *temp;
                int saved_errno;
 
-               temp = mks_tempfile(git_path("sharedindex_XXXXXX"));
+               /* Same initial permissions as the main .git/index file */
+               temp = mks_tempfile_sm(git_path("sharedindex_XXXXXX"), 0, 0666);
                if (!temp) {
                        oidclr(&si->base_oid);
                        ret = do_write_locked_index(istate, lock, flags);
@@ -3475,7 +3490,6 @@ static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context,
        strbuf_add(sb, hash, the_hash_algo->rawsz);
 }
 
-#ifndef NO_PTHREADS
 #define IEOT_VERSION   (1)
 
 static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset)
@@ -3548,4 +3562,3 @@ static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_ta
               strbuf_add(sb, &buffer, sizeof(uint32_t));
        }
 }
-#endif
index 0c45ed9d94a4bd4bfab6c9d441ca9bc7de7ebf31..5de616befe46e64b014ebe7c3feb5913bc8af2df 100644 (file)
@@ -534,6 +534,10 @@ static int parse_ref_filter_atom(const struct ref_format *format,
        if (ARRAY_SIZE(valid_atom) <= i)
                return strbuf_addf_ret(err, -1, _("unknown field name: %.*s"),
                                       (int)(ep-atom), atom);
+       if (valid_atom[i].source != SOURCE_NONE && !have_git_dir())
+               return strbuf_addf_ret(err, -1,
+                                      _("not a git repository, but the field '%.*s' requires access to object data"),
+                                      (int)(ep-atom), atom);
 
        /* Add it in, including the deref prefix */
        at = used_atom_cnt;
@@ -878,7 +882,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
                        v->s = xstrdup(type_name(oi->type));
                else if (!strcmp(name, "objectsize")) {
                        v->value = oi->size;
-                       v->s = xstrfmt("%lu", oi->size);
+                       v->s = xstrfmt("%"PRIuMAX , (uintmax_t)oi->size);
                }
                else if (deref)
                        grab_objectname(name, &oi->oid, v, &used_atom[i]);
@@ -2316,6 +2320,8 @@ int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset)
        struct object_id oid;
        int no_merged = starts_with(opt->long_name, "no");
 
+       BUG_ON_OPT_NEG(unset);
+
        if (rf->merge) {
                if (no_merged) {
                        return opterror(opt, "is incompatible with --merged", 0);
diff --git a/refs.c b/refs.c
index 17e4307f3171697ddd8c1e49710c16218e6774a8..f9936355cda6a1515f3192151f7fc14d0c2d7522 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -217,6 +217,7 @@ char *resolve_refdup(const char *refname, int resolve_flags,
 /* The argument to filter_refs */
 struct ref_filter {
        const char *pattern;
+       const char *prefix;
        each_ref_fn *fn;
        void *cb_data;
 };
@@ -296,6 +297,8 @@ static int filter_refs(const char *refname, const struct object_id *oid,
 
        if (wildmatch(filter->pattern, refname, 0))
                return 0;
+       if (filter->prefix)
+               skip_prefix(refname, filter->prefix, &refname);
        return filter->fn(refname, oid, flags, filter->cb_data);
 }
 
@@ -458,6 +461,7 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
        }
 
        filter.pattern = real_pattern.buf;
+       filter.prefix = prefix;
        filter.fn = fn;
        filter.cb_data = cb_data;
        ret = for_each_ref(filter_refs, &filter);
index 9183875dadb72c4b285b8a99ee7df7620a1e7eeb..dd8abe918508027ed46c3234bac1d91107c6ca94 100644 (file)
@@ -180,7 +180,8 @@ static void files_reflog_path(struct files_ref_store *refs,
                break;
        case REF_TYPE_OTHER_PSEUDOREF:
        case REF_TYPE_MAIN_PSEUDOREF:
-               return files_reflog_path_other_worktrees(refs, sb, refname);
+               files_reflog_path_other_worktrees(refs, sb, refname);
+               break;
        case REF_TYPE_NORMAL:
                strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
                break;
index 762a55a75f6d9d3c510bfbf9ff0d41bc0a1afb6e..1220dffcdc57a17476fb2021db5fb1605857ab80 100644 (file)
@@ -617,10 +617,11 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)
        return err;
 }
 
-static curl_off_t xcurl_off_t(ssize_t len) {
-       if (len > maximum_signed_value_of_type(curl_off_t))
+static curl_off_t xcurl_off_t(size_t len) {
+       uintmax_t size = len;
+       if (size > maximum_signed_value_of_type(curl_off_t))
                die("cannot handle pushes this big");
-       return (curl_off_t) len;
+       return (curl_off_t)size;
 }
 
 static int post_rpc(struct rpc_state *rpc)
index bdd3e7c9f193415d073b78c220366ac69afa5c20..13e0519c0241635c0c1fd14a7ff12e9478c70bd4 100644 (file)
@@ -25,6 +25,8 @@
 #include "worktree.h"
 #include "argv-array.h"
 #include "commit-reach.h"
+#include "commit-graph.h"
+#include "prio-queue.h"
 
 volatile show_early_output_fn_t show_early_output;
 
@@ -767,8 +769,8 @@ static void commit_list_insert_by_date_cached(struct commit *p, struct commit_li
                *cache = new_entry;
 }
 
-static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
-                   struct commit_list **list, struct commit_list **cache_ptr)
+static int process_parents(struct rev_info *revs, struct commit *commit,
+                          struct commit_list **list, struct commit_list **cache_ptr)
 {
        struct commit_list *parent = commit->parents;
        unsigned left_flag;
@@ -807,7 +809,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
                        if (p->object.flags & SEEN)
                                continue;
                        p->object.flags |= SEEN;
-                       commit_list_insert_by_date_cached(p, list, cached_base, cache_ptr);
+                       if (list)
+                               commit_list_insert_by_date_cached(p, list, cached_base, cache_ptr);
                }
                return 0;
        }
@@ -846,7 +849,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
                p->object.flags |= left_flag;
                if (!(p->object.flags & SEEN)) {
                        p->object.flags |= SEEN;
-                       commit_list_insert_by_date_cached(p, list, cached_base, cache_ptr);
+                       if (list)
+                               commit_list_insert_by_date_cached(p, list, cached_base, cache_ptr);
                }
                if (revs->first_parent_only)
                        break;
@@ -1090,7 +1094,7 @@ static int limit_list(struct rev_info *revs)
 
                if (revs->max_age != -1 && (commit->date < revs->max_age))
                        obj->flags |= UNINTERESTING;
-               if (add_parents_to_list(revs, commit, &list, NULL) < 0)
+               if (process_parents(revs, commit, &list, NULL) < 0)
                        return -1;
                if (obj->flags & UNINTERESTING) {
                        mark_parents_uninteresting(commit);
@@ -2468,7 +2472,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
        if (revs->diffopt.objfind)
                revs->simplify_history = 0;
 
-       if (revs->topo_order)
+       if (revs->topo_order && !generation_numbers_enabled(the_repository))
                revs->limited = 1;
 
        if (revs->prune_data.nr) {
@@ -2907,6 +2911,217 @@ static int mark_uninteresting(const struct object_id *oid,
        return 0;
 }
 
+define_commit_slab(indegree_slab, int);
+define_commit_slab(author_date_slab, timestamp_t);
+
+struct topo_walk_info {
+       uint32_t min_generation;
+       struct prio_queue explore_queue;
+       struct prio_queue indegree_queue;
+       struct prio_queue topo_queue;
+       struct indegree_slab indegree;
+       struct author_date_slab author_date;
+};
+
+static inline void test_flag_and_insert(struct prio_queue *q, struct commit *c, int flag)
+{
+       if (c->object.flags & flag)
+               return;
+
+       c->object.flags |= flag;
+       prio_queue_put(q, c);
+}
+
+static void explore_walk_step(struct rev_info *revs)
+{
+       struct topo_walk_info *info = revs->topo_walk_info;
+       struct commit_list *p;
+       struct commit *c = prio_queue_get(&info->explore_queue);
+
+       if (!c)
+               return;
+
+       if (parse_commit_gently(c, 1) < 0)
+               return;
+
+       if (revs->sort_order == REV_SORT_BY_AUTHOR_DATE)
+               record_author_date(&info->author_date, c);
+
+       if (revs->max_age != -1 && (c->date < revs->max_age))
+               c->object.flags |= UNINTERESTING;
+
+       if (process_parents(revs, c, NULL, NULL) < 0)
+               return;
+
+       if (c->object.flags & UNINTERESTING)
+               mark_parents_uninteresting(c);
+
+       for (p = c->parents; p; p = p->next)
+               test_flag_and_insert(&info->explore_queue, p->item, TOPO_WALK_EXPLORED);
+}
+
+static void explore_to_depth(struct rev_info *revs,
+                            uint32_t gen_cutoff)
+{
+       struct topo_walk_info *info = revs->topo_walk_info;
+       struct commit *c;
+       while ((c = prio_queue_peek(&info->explore_queue)) &&
+              c->generation >= gen_cutoff)
+               explore_walk_step(revs);
+}
+
+static void indegree_walk_step(struct rev_info *revs)
+{
+       struct commit_list *p;
+       struct topo_walk_info *info = revs->topo_walk_info;
+       struct commit *c = prio_queue_get(&info->indegree_queue);
+
+       if (!c)
+               return;
+
+       if (parse_commit_gently(c, 1) < 0)
+               return;
+
+       explore_to_depth(revs, c->generation);
+
+       for (p = c->parents; p; p = p->next) {
+               struct commit *parent = p->item;
+               int *pi = indegree_slab_at(&info->indegree, parent);
+
+               if (*pi)
+                       (*pi)++;
+               else
+                       *pi = 2;
+
+               test_flag_and_insert(&info->indegree_queue, parent, TOPO_WALK_INDEGREE);
+
+               if (revs->first_parent_only)
+                       return;
+       }
+}
+
+static void compute_indegrees_to_depth(struct rev_info *revs,
+                                      uint32_t gen_cutoff)
+{
+       struct topo_walk_info *info = revs->topo_walk_info;
+       struct commit *c;
+       while ((c = prio_queue_peek(&info->indegree_queue)) &&
+              c->generation >= gen_cutoff)
+               indegree_walk_step(revs);
+}
+
+static void init_topo_walk(struct rev_info *revs)
+{
+       struct topo_walk_info *info;
+       struct commit_list *list;
+       revs->topo_walk_info = xmalloc(sizeof(struct topo_walk_info));
+       info = revs->topo_walk_info;
+       memset(info, 0, sizeof(struct topo_walk_info));
+
+       init_indegree_slab(&info->indegree);
+       memset(&info->explore_queue, 0, sizeof(info->explore_queue));
+       memset(&info->indegree_queue, 0, sizeof(info->indegree_queue));
+       memset(&info->topo_queue, 0, sizeof(info->topo_queue));
+
+       switch (revs->sort_order) {
+       default: /* REV_SORT_IN_GRAPH_ORDER */
+               info->topo_queue.compare = NULL;
+               break;
+       case REV_SORT_BY_COMMIT_DATE:
+               info->topo_queue.compare = compare_commits_by_commit_date;
+               break;
+       case REV_SORT_BY_AUTHOR_DATE:
+               init_author_date_slab(&info->author_date);
+               info->topo_queue.compare = compare_commits_by_author_date;
+               info->topo_queue.cb_data = &info->author_date;
+               break;
+       }
+
+       info->explore_queue.compare = compare_commits_by_gen_then_commit_date;
+       info->indegree_queue.compare = compare_commits_by_gen_then_commit_date;
+
+       info->min_generation = GENERATION_NUMBER_INFINITY;
+       for (list = revs->commits; list; list = list->next) {
+               struct commit *c = list->item;
+
+               if (parse_commit_gently(c, 1))
+                       continue;
+
+               test_flag_and_insert(&info->explore_queue, c, TOPO_WALK_EXPLORED);
+               test_flag_and_insert(&info->indegree_queue, c, TOPO_WALK_INDEGREE);
+
+               if (c->generation < info->min_generation)
+                       info->min_generation = c->generation;
+
+               *(indegree_slab_at(&info->indegree, c)) = 1;
+
+               if (revs->sort_order == REV_SORT_BY_AUTHOR_DATE)
+                       record_author_date(&info->author_date, c);
+       }
+       compute_indegrees_to_depth(revs, info->min_generation);
+
+       for (list = revs->commits; list; list = list->next) {
+               struct commit *c = list->item;
+
+               if (*(indegree_slab_at(&info->indegree, c)) == 1)
+                       prio_queue_put(&info->topo_queue, c);
+       }
+
+       /*
+        * This is unfortunate; the initial tips need to be shown
+        * in the order given from the revision traversal machinery.
+        */
+       if (revs->sort_order == REV_SORT_IN_GRAPH_ORDER)
+               prio_queue_reverse(&info->topo_queue);
+}
+
+static struct commit *next_topo_commit(struct rev_info *revs)
+{
+       struct commit *c;
+       struct topo_walk_info *info = revs->topo_walk_info;
+
+       /* pop next off of topo_queue */
+       c = prio_queue_get(&info->topo_queue);
+
+       if (c)
+               *(indegree_slab_at(&info->indegree, c)) = 0;
+
+       return c;
+}
+
+static void expand_topo_walk(struct rev_info *revs, struct commit *commit)
+{
+       struct commit_list *p;
+       struct topo_walk_info *info = revs->topo_walk_info;
+       if (process_parents(revs, commit, NULL, NULL) < 0) {
+               if (!revs->ignore_missing_links)
+                       die("Failed to traverse parents of commit %s",
+                           oid_to_hex(&commit->object.oid));
+       }
+
+       for (p = commit->parents; p; p = p->next) {
+               struct commit *parent = p->item;
+               int *pi;
+
+               if (parse_commit_gently(parent, 1) < 0)
+                       continue;
+
+               if (parent->generation < info->min_generation) {
+                       info->min_generation = parent->generation;
+                       compute_indegrees_to_depth(revs, info->min_generation);
+               }
+
+               pi = indegree_slab_at(&info->indegree, parent);
+
+               (*pi)--;
+               if (*pi == 1)
+                       prio_queue_put(&info->topo_queue, parent);
+
+               if (revs->first_parent_only)
+                       return;
+       }
+}
+
 int prepare_revision_walk(struct rev_info *revs)
 {
        int i;
@@ -2943,11 +3158,13 @@ int prepare_revision_walk(struct rev_info *revs)
                commit_list_sort_by_date(&revs->commits);
        if (revs->no_walk)
                return 0;
-       if (revs->limited)
+       if (revs->limited) {
                if (limit_list(revs) < 0)
                        return -1;
-       if (revs->topo_order)
-               sort_in_topological_order(&revs->commits, revs->sort_order);
+               if (revs->topo_order)
+                       sort_in_topological_order(&revs->commits, revs->sort_order);
+       } else if (revs->topo_order)
+               init_topo_walk(revs);
        if (revs->line_level_traverse)
                line_log_filter(revs);
        if (revs->simplify_merges)
@@ -2964,7 +3181,7 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp
        for (;;) {
                struct commit *p = *pp;
                if (!revs->limited)
-                       if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0)
+                       if (process_parents(revs, p, &revs->commits, &cache) < 0)
                                return rewrite_one_error;
                if (p->object.flags & UNINTERESTING)
                        return rewrite_one_ok;
@@ -3272,6 +3489,8 @@ static struct commit *get_revision_1(struct rev_info *revs)
 
                if (revs->reflog_info)
                        commit = next_reflog_entry(revs->reflog_info);
+               else if (revs->topo_walk_info)
+                       commit = next_topo_commit(revs);
                else
                        commit = pop_commit(&revs->commits);
 
@@ -3293,7 +3512,9 @@ static struct commit *get_revision_1(struct rev_info *revs)
 
                        if (revs->reflog_info)
                                try_to_simplify_commit(revs, commit);
-                       else if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) {
+                       else if (revs->topo_walk_info)
+                               expand_topo_walk(revs, commit);
+                       else if (process_parents(revs, commit, &revs->commits, NULL) < 0) {
                                if (!revs->ignore_missing_links)
                                        die("Failed to traverse parents of commit %s",
                                                oid_to_hex(&commit->object.oid));
index 0d2abc2d36ec579c281135a2a3b866fb37911326..7987bfcd2e9bd6ee7bac4f1cbeb10af17ab40b50 100644 (file)
@@ -32,6 +32,9 @@
 #define TRACK_LINEAR   (1u<<26)
 #define ALL_REV_FLAGS  (((1u<<11)-1) | NOT_USER_GIVEN | TRACK_LINEAR)
 
+#define TOPO_WALK_EXPLORED     (1u<<27)
+#define TOPO_WALK_INDEGREE     (1u<<28)
+
 #define DECORATE_SHORT_REFS    1
 #define DECORATE_FULL_REFS     2
 
@@ -64,6 +67,8 @@ struct rev_cmdline_info {
 #define REVISION_WALK_NO_WALK_SORTED 1
 #define REVISION_WALK_NO_WALK_UNSORTED 2
 
+struct topo_walk_info;
+
 struct rev_info {
        /* Starting list */
        struct commit_list *commits;
@@ -270,6 +275,8 @@ struct rev_info {
        const char *break_bar;
 
        struct revision_sources *sources;
+
+       struct topo_walk_info *topo_walk_info;
 };
 
 int ref_excluded(struct string_list *, const char *path);
index d679cc267c39b9fb34f57078db5db12ed591b7e2..c11ff8067481f70c444198bcc7477ef744d99fd3 100644 (file)
@@ -1226,7 +1226,7 @@ int start_async(struct async *async)
        {
                int err = pthread_create(&async->tid, NULL, run_thread, async);
                if (err) {
-                       error_errno("cannot create thread");
+                       error(_("cannot create async thread: %s"), strerror(err));
                        goto error;
                }
        }
@@ -1259,6 +1259,15 @@ int finish_async(struct async *async)
 #endif
 }
 
+int async_with_fork(void)
+{
+#ifdef NO_PTHREADS
+       return 1;
+#else
+       return 0;
+#endif
+}
+
 const char *find_hook(const char *name)
 {
        static struct strbuf path = STRBUF_INIT;
index 3932420ec8a560479c9697e3626e9da15e952853..68f5369fc2d432e8b4b504e9625b541056814216 100644 (file)
@@ -1,9 +1,7 @@
 #ifndef RUN_COMMAND_H
 #define RUN_COMMAND_H
 
-#ifndef NO_PTHREADS
-#include <pthread.h>
-#endif
+#include "thread-utils.h"
 
 #include "argv-array.h"
 
@@ -143,6 +141,7 @@ struct async {
 int start_async(struct async *async);
 int finish_async(struct async *async);
 int in_async(void);
+int async_with_fork(void);
 void check_pipe(int err);
 
 /**
index e920ca57df4dd0b65d6694ed2532dead8ae83fb6..f692686770f69b49d44bf6dbabdb17886d85ea1a 100644 (file)
@@ -203,9 +203,8 @@ static int receive_status(int in, struct ref *refs)
 static int sideband_demux(int in, int out, void *data)
 {
        int *fd = data, ret;
-#ifdef NO_PTHREADS
-       close(fd[1]);
-#endif
+       if (async_with_fork())
+               close(fd[1]);
        ret = recv_sideband("send-pack", fd[0], out);
        close(out);
        return ret;
index 0d87b0739be5c5fdaf686063729aca02559638b8..e1a4dd15f1a826c7bd1bf4780c8f85c21117c43b 100644 (file)
@@ -3244,10 +3244,6 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
        }
 
        merge_commit = to_merge->item;
-       write_message(oid_to_hex(&merge_commit->object.oid), GIT_SHA1_HEXSZ,
-                     git_path_merge_head(the_repository), 0);
-       write_message("no-ff", 5, git_path_merge_mode(the_repository), 0);
-
        bases = get_merge_bases(head_commit, merge_commit);
        if (bases && oideq(&merge_commit->object.oid,
                           &bases->item->object.oid)) {
@@ -3256,6 +3252,10 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
                goto leave_merge;
        }
 
+       write_message(oid_to_hex(&merge_commit->object.oid), GIT_SHA1_HEXSZ,
+                     git_path_merge_head(the_repository), 0);
+       write_message("no-ff", 5, git_path_merge_mode(the_repository), 0);
+
        for (j = bases; j; j = j->next)
                commit_list_insert(j->item, &reversed);
        free_commit_list(bases);
@@ -3512,6 +3512,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                        unlink(rebase_path_author_script());
                        unlink(rebase_path_stopped_sha());
                        unlink(rebase_path_amend());
+                       unlink(git_path_merge_head(the_repository));
                        delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
 
                        if (item->command == TODO_BREAK)
@@ -3882,6 +3883,7 @@ static int commit_staged_changes(struct replay_opts *opts,
                           opts, flags))
                return error(_("could not commit staged changes."));
        unlink(rebase_path_amend());
+       unlink(git_path_merge_head(the_repository));
        if (final_fixup) {
                unlink(rebase_path_fixup_msg());
                unlink(rebase_path_squash_msg());
index 2daf7d9935d4aea4db13067f1134bc851c8ab166..5bd11c85bc563618b59dad3ff06e5ae5296c892b 100644 (file)
@@ -833,7 +833,7 @@ int check_object_signature(const struct object_id *oid, void *map,
                return -1;
 
        /* Generate the header */
-       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(obj_type), size) + 1;
+       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(obj_type), (uintmax_t)size) + 1;
 
        /* Sha1.. */
        the_hash_algo->init_fn(&c);
@@ -1492,7 +1492,7 @@ static void write_object_file_prepare(const void *buf, unsigned long len,
        git_hash_ctx c;
 
        /* Generate the header */
-       *hdrlen = xsnprintf(hdr, *hdrlen, "%s %lu", type, len)+1;
+       *hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
 
        /* Sha1.. */
        the_hash_algo->init_fn(&c);
@@ -1758,7 +1758,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
        buf = read_object(oid->hash, &type, &len);
        if (!buf)
                return error(_("cannot read sha1_file for %s"), oid_to_hex(oid));
-       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
+       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
        ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime);
        free(buf);
 
index 242497455f4f448335f7170e7444e5a2f2ff6b7d..28711cc508f9e5dfb2f2ef238be14926d56f9a12 100644 (file)
--- a/t/README
+++ b/t/README
@@ -302,6 +302,12 @@ that cannot be easily covered by a few specific test cases. These
 could be enabled by running the test suite with correct GIT_TEST_
 environment set.
 
+GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for
+translation into gibberish if non-empty (think "test -n"). Used for
+spotting those tests that need to be marked with a C_LOCALE_OUTPUT
+prerequisite when adding more strings for translation. See "Testing
+marked strings" in po/README for details.
+
 GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
 test suite. Accept any boolean values that are accepted by git-config.
 
@@ -339,6 +345,10 @@ for the index version specified.  Can be set to any valid version
 GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
 by overriding the minimum number of cache entries required per thread.
 
+GIT_TEST_REBASE_USE_BUILTIN=<boolean>, when false, disables the
+builtin version of git-rebase. See 'rebase.useBuiltin' in
+git-config(1).
+
 GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
 of the index for the whole test suite by bypassing the default number of
 cache entries and thread minimums. Setting this to 1 will make the
index 9cb8a0ea0f8ae7b3da8525b2a354bfa542db93c3..47fee660b86a6e6977735e2c940de79d4330d519 100644 (file)
@@ -36,6 +36,7 @@ static int length_callback(const struct option *opt, const char *arg, int unset)
 
 static int number_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        *(int *)opt->value = strtol(arg, NULL, 10);
        return 0;
 }
@@ -119,7 +120,6 @@ int cmd__parse_options(int argc, const char **argv)
                OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
                OPT_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"),
                OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
-               OPT_DATE('t', NULL, &timestamp, "get timestamp of <time>"),
                OPT_CALLBACK('L', "length", &integer, "str",
                        "get length of <str>", length_callback),
                OPT_FILENAME('F', "file", &file, "set file to <file>"),
index 9807b649b14c0002bee6d10b200c27bb89a54812..5bc9c46ea5603e22e6fb5aaa5c0276a12d2a031f 100644 (file)
@@ -22,14 +22,24 @@ int cmd__prio_queue(int argc, const char **argv)
        struct prio_queue pq = { intcmp };
 
        while (*++argv) {
-               if (!strcmp(*argv, "get"))
-                       show(prio_queue_get(&pq));
-               else if (!strcmp(*argv, "dump")) {
-                       int *v;
-                       while ((v = prio_queue_get(&pq)))
-                              show(v);
-               }
-               else {
+               if (!strcmp(*argv, "get")) {
+                       void *peek = prio_queue_peek(&pq);
+                       void *get = prio_queue_get(&pq);
+                       if (peek != get)
+                               BUG("peek and get results do not match");
+                       show(get);
+               } else if (!strcmp(*argv, "dump")) {
+                       void *peek;
+                       void *get;
+                       while ((peek = prio_queue_peek(&pq))) {
+                               get = prio_queue_get(&pq);
+                               if (peek != get)
+                                       BUG("peek and get results do not match");
+                               show(get);
+                       }
+               } else if (!strcmp(*argv, "stack")) {
+                       pq.compare = NULL;
+               } else {
                        int *v = malloc(sizeof(*v));
                        *v = atoi(*argv);
                        prio_queue_put(&pq, v);
index eec757f104708df3a00935cef89dd7dad537afb9..2139b427ca1ced9ba0342ef33d634c9b054ade5e 100644 (file)
@@ -10,9 +10,14 @@ GIT_TEXTDOMAINDIR="$GIT_BUILD_DIR/po/build/locale"
 GIT_PO_PATH="$GIT_BUILD_DIR/po"
 export GIT_TEXTDOMAINDIR GIT_PO_PATH
 
-. "$GIT_BUILD_DIR"/git-sh-i18n
+if test -n "$GIT_TEST_INSTALLED"
+then
+       . "$(git --exec-path)"/git-sh-i18n
+else
+       . "$GIT_BUILD_DIR"/git-sh-i18n
+fi
 
-if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
+if test_have_prereq GETTEXT && test_have_prereq C_LOCALE_OUTPUT
 then
        # is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
        is_IS_locale=$(locale -a 2>/dev/null |
index edbea2d986134f36b86e044f307abae1457f8165..f98de95c15b14aa4030c65d26e6270dc06088372 100644 (file)
@@ -92,7 +92,7 @@ stop_git_daemon() {
        kill "$GIT_DAEMON_PID"
        wait "$GIT_DAEMON_PID" >&3 2>&4
        ret=$?
-       if test_match_signal 15 $?
+       if ! test_match_signal 15 $ret
        then
                error "git daemon exited with status: $ret"
        fi
index d4754a1f19c7984b3286cfd9dfa9740a790800e0..918dfce332e183c9ab62ab2400f8a35598f1ad8c 100644 (file)
@@ -30,7 +30,6 @@ Cezx4Q2khACcCs+/LtE8Lb9hC+2cvr3uH5p82AI=
 =aEiU
 -----END PGP PRIVATE KEY BLOCK-----
 -----BEGIN PGP PRIVATE KEY BLOCK-----
-Version: GnuPG v1
 
 lQOYBFFMlkcBCADJi/xnAF8yI34PHilSCbM7VtOFO17oFMkpu4cgN2QpPuM5MVjy
 cvrzKSguZFvPCDLzeAFJW1uPxL4SHaHSkisCrFhijH7OJWcOPNPSFCwu+inAoAsv
@@ -83,11 +82,43 @@ fn1sY/IG5atoKK+ypmV/TlBlMZqFQzuPIJQT8VLbmxtLlDhJG04LbI6c8axIZxOO
 ZKLy5nTTSy16ztqEeS7eifHLPZg1UFFyEEIQ1XW0CNDAeuWKh90ERjyl4Cg7PnWS
 Z9Ei+zj6JD5Pcdi3BJhQo9WOLOVEJ0NHmewTYqk9QVXH/0v1Hdl4LMJtgcbdbDWk
 4UTkXbg9pn3umCgkNJ3Vs8fWnIWO9Izdr2/wrFY2JvUT7Yvl+wsNIWatvOEzGy7n
-BOW78WUxzhu0YJTLKy+iKCjg5HS5dx6OC+e4aEEgfhNPCMkbvDsJjtQ=
-=hieJ
+BOW78WUxzhu0YJTLKy+iKCjg5HS5dx6OC+e4aEEgfhNPCMkbvDsJjtSdA5gEW967
+3AEIAKjseT0sTQjyN39fOn0fzxWp89REMUUKgLigb01MKuuNI3cedBZsz3hpFOKV
+cii5rldw8uf3yS3Okht2DfHPSD4NrGzLGEzSTpQ10S8N2q0DUYwyLU6C0U8HnMZm
+/n+lCGBbUoxvnruohAvKAjpHO3rmJ8D4De9hlWg/fwdAxQQ0Sve0kN8Vwk2p1GuO
+OWQKV1SU9c+kBiou7dewQmbilPRanKmP5ZSU4emhpTOMlJFXF+kmYSODQk1cMvWW
+Ob3ttll2llX0Gul7Sjf+haq/FcRyRk7Tw5MHwZjr5aWiCny0/0+byvfF6SBIfzyE
+qlyWURQ2gHZUqSiG3QPMZiYr04cAEQEAAQAH/Am4rv/oQF6wodgz5y4zc6JJiTDA
+4+nKdIuR7OKqUxk1oo7eZjJML/xvMumygNyUvJ9nodl1SlMKilOhdAswfkKj9gJY
+BdDJLm1OufhW3pJwy6ahbjeqEgwJFVENtSPF0zkuyED9kElrpbD2ZTGfzwdM0e9D
+10ZDFWtODCw8rzOFcijujgI8oilLtxSNrkkTKW+25WJFRNPSHgIkMIm8UlPAG+rj
+3Yj9UqodeXTSvXwG2zceOxjFJadV77sOFJDgwWslN6J8El4+GcgwFVepJxoZEj7e
+cKkmVr0Dc9/Q04D5dWATc1FYcIhZbTu3oImCAh45ep4u9WYLUV5PGyeMviEEAMwo
+mJbYBxWuPjpNa722HQcbvMUiZWWDwHfLCib/SaP0AgfDahid8/PcZwxOPHPByBrm
+GDi0z7ibn/pgJr07kpp1Cic9ntfc2FvkI0QMzG0EuiekzQyPEnzjoDHF+V4nJIj2
+GWVjLYYqlZWEmhsfKt1CnlPXBunKoDJ30ABPcHJ/BADT0WxAIVKF4lO2HlrDVP44
+bufBEG9Ct7dl/G08Qve4Ag3VEZpT82vEFp0LzX0mTCDIUKJUYAYLxAIPhP7IvIfc
+EZXrwyDUxU7YSgKTHMKo9nFC6fIc1GeGPRalIF1gmTY32qlYJC6y5BTDhZNV5ydG
+u8QL2P/orP7XuRrJyeyK+QP/XTekr/DS6Jkct826MPA52ciIkWVgYLatH5fO4HCq
+ssDU8vz7FbbvGs0G1Xn7GA4m9dNYVOZtKwX++3nf2IEOpgPiZVTn/nP2u3HutpJb
+/HMLlcfZGiGdxS6n/vdz6wsEobJoi6STkHkA+VFNOSZmdsw6eKl3X911tpCTYfOG
+2U47/IkCbAQYAQgAIBYhBNS+IjEa0xMeXtoppGEJLoW3InGJBQJb3rvcAhsCAUAJ
+EGEJLoW3InGJwHQgBBkBCAAdFiEE+DZKWeB//p9NYwBaZaDuoC4wytcFAlveu9wA
+CgkQZaDuoC4wytcD9gf/WigtHl7lFyl8RaE/uqROFEelZyM00v1h55fd/IGRG88E
+tN0Lr4FaqBqPkMZjU/LN9UMBaTd+748vHlHaweZqljXJu99CO9Id7Y4w7WzF3C3Y
+yQsGZ92EGxthsPK0+rhHV0MbaINupI1oO9gATFglSxq17o83FJatGRjaXCZau8jr
+57/By1MGtjk+Iq1NkzGkrX778LdRQGLKDw2Qa7lsdHY8d3lUPAH8mbb97ELmIc9t
+PG2aM7ATJL7nBmFuTHo6hmEcIw32Ei9KK1zxM0ZylEYkjBjHAlklWmKb9MiayMC5
+uHW7Iyhjl+NbgbIEr2JTamW/9tL6UrIIxiDEdqaHNfCaB/9D+V31Upcohc9azwB4
+AF8diQwt5nfiVpnVeF/W8+eS1By2W6QrwLNthNRabYFnuSf9USHAY6atDWe+egId
+MLIv4ce0i3ykoczSu0oMoUCMxdl9kQrsNHZCqWX/OiDDLSb05u/P/3he900y6tSB
+15MbIPA6i5Bw/693nHguqxS1ASbBB/LiIu3vCXdFEs9RMvIJ+qkP3xQA96oImQiK
+R3U6OGv593eONKijUINNqHRq6+UxIyJ+OCAi+L2QTidAhJLRCp6EZD96u02cthYq
+8KA8j1+rx9BcbeacVVHepeG1JsgxsXX8BTJ7ZuS5VVndZOjag8URW/9nJMf01w/h
+el64
+=Iv7W
 -----END PGP PRIVATE KEY BLOCK-----
 -----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1
 
 mQGiBEZnyykRBACzCPjIpTYNL7Y2tQqlEGTTDlvZcWNLjF5f7ZzuyOqNOidLUgFD
 36qch1LZLSZkShdR3Gae+bsolyjxrlFuFP0eXRPMtqK20aLw7WZvPFpEV1ThMne+
@@ -137,6 +168,25 @@ bGPyBuWraCivsqZlf05QZTGahUM7jyCUE/FS25sbS5Q4SRtOC2yOnPGsSGcTjmSi
 8uZ000stes7ahHku3onxyz2YNVBRchBCENV1tAjQwHrliofdBEY8peAoOz51kmfR
 Ivs4+iQ+T3HYtwSYUKPVjizlRCdDR5nsE2KpPUFVx/9L9R3ZeCzCbYHG3Ww1pOFE
 5F24PaZ97pgoJDSd1bPH1pyFjvSM3a9v8KxWNib1E+2L5fsLDSFmrbzhMxsu5wTl
-u/FlMc4btGCUyysvoigo4OR0uXcejgvnuGhBIH4TTwjJG7w7CY7U
-=iYv/
+u/FlMc4btGCUyysvoigo4OR0uXcejgvnuGhBIH4TTwjJG7w7CY7UuQENBFveu9wB
+CACo7Hk9LE0I8jd/Xzp9H88VqfPURDFFCoC4oG9NTCrrjSN3HnQWbM94aRTilXIo
+ua5XcPLn98ktzpIbdg3xz0g+DaxsyxhM0k6UNdEvDdqtA1GMMi1OgtFPB5zGZv5/
+pQhgW1KMb567qIQLygI6Rzt65ifA+A3vYZVoP38HQMUENEr3tJDfFcJNqdRrjjlk
+CldUlPXPpAYqLu3XsEJm4pT0Wpypj+WUlOHpoaUzjJSRVxfpJmEjg0JNXDL1ljm9
+7bZZdpZV9Brpe0o3/oWqvxXEckZO08OTB8GY6+Wlogp8tP9Pm8r3xekgSH88hKpc
+llEUNoB2VKkoht0DzGYmK9OHABEBAAGJAmwEGAEIACAWIQTUviIxGtMTHl7aKaRh
+CS6FtyJxiQUCW9673AIbAgFACRBhCS6FtyJxicB0IAQZAQgAHRYhBPg2Slngf/6f
+TWMAWmWg7qAuMMrXBQJb3rvcAAoJEGWg7qAuMMrXA/YH/1ooLR5e5RcpfEWhP7qk
+ThRHpWcjNNL9YeeX3fyBkRvPBLTdC6+BWqgaj5DGY1PyzfVDAWk3fu+PLx5R2sHm
+apY1ybvfQjvSHe2OMO1sxdwt2MkLBmfdhBsbYbDytPq4R1dDG2iDbqSNaDvYAExY
+JUsate6PNxSWrRkY2lwmWrvI6+e/wctTBrY5PiKtTZMxpK1++/C3UUBiyg8NkGu5
+bHR2PHd5VDwB/Jm2/exC5iHPbTxtmjOwEyS+5wZhbkx6OoZhHCMN9hIvSitc8TNG
+cpRGJIwYxwJZJVpim/TImsjAubh1uyMoY5fjW4GyBK9iU2plv/bS+lKyCMYgxHam
+hzXwmgf/Q/ld9VKXKIXPWs8AeABfHYkMLeZ34laZ1Xhf1vPnktQctlukK8CzbYTU
+Wm2BZ7kn/VEhwGOmrQ1nvnoCHTCyL+HHtIt8pKHM0rtKDKFAjMXZfZEK7DR2Qqll
+/zogwy0m9Obvz/94XvdNMurUgdeTGyDwOouQcP+vd5x4LqsUtQEmwQfy4iLt7wl3
+RRLPUTLyCfqpD98UAPeqCJkIikd1Ojhr+fd3jjSoo1CDTah0auvlMSMifjggIvi9
+kE4nQISS0QqehGQ/ertNnLYWKvCgPI9fq8fQXG3mnFVR3qXhtSbIMbF1/AUye2bk
+uVVZ3WTo2oPFEVv/ZyTH9NcP4XpeuA==
+=KRyT
 -----END PGP PUBLIC KEY BLOCK-----
index ce271ca4c1a07f620f25c5f4dd6febe020308c64..d202aaed06fc6cba62a1955e790bbe324d365235 100755 (executable)
@@ -6,9 +6,9 @@ test_description='Tests rebase performance'
 test_perf_default_repo
 
 test_expect_success 'setup rebasing on top of a lot of changes' '
-       git checkout -f -b base &&
-       git checkout -b to-rebase &&
-       git checkout -b upstream &&
+       git checkout -f -B base &&
+       git checkout -B to-rebase &&
+       git checkout -B upstream &&
        for i in $(seq 100)
        do
                # simulate huge diffs
@@ -35,8 +35,8 @@ test_perf 'rebase on top of a lot of unrelated changes' '
 
 test_expect_success 'setup rebasing many changes without split-index' '
        git config core.splitIndex false &&
-       git checkout -b upstream2 to-rebase &&
-       git checkout -b to-rebase2 upstream
+       git checkout -B upstream2 to-rebase &&
+       git checkout -B to-rebase2 upstream
 '
 
 test_perf 'rebase a lot of unrelated changes without split-index' '
index 4d23373526945eea7bc4e875beac5fdc4451cac8..b6566003dd8704503305314767f84d516c170f7a 100755 (executable)
@@ -274,7 +274,7 @@ test_expect_success 'pretend we have a mix of all possible results' "
        EOF
 "
 
-test_expect_success 'test --verbose' '
+test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
        test_must_fail run_sub_test_lib_test \
                test-verbose "test verbose" --verbose <<-\EOF &&
        test_expect_success "passing test" true
index e56dfce6680298c133bc2b2de12d9492fda66b7a..3941ad25286562a57faa63d4ba37604d1fd708bd 100755 (executable)
@@ -47,4 +47,18 @@ test_expect_success 'notice empty queue' '
        test_cmp expect actual
 '
 
+cat >expect <<'EOF'
+3
+2
+6
+4
+5
+1
+8
+EOF
+test_expect_success 'stack order' '
+       test-tool prio-queue stack 8 1 5 4 6 2 3 dump >actual &&
+       test_cmp expect actual
+'
+
 test_done
index 17d0c18feb84e2c47167b9b54f71f192d78b0e9b..f5b10861c498e435155f6aec5dec6f27c82aa51b 100755 (executable)
@@ -23,7 +23,6 @@ usage: test-tool parse-options <options>
     -j <n>                get a integer, too
     -m, --magnitude <n>   get a magnitude
     --set23               set integer to 23
-    -t <time>             get timestamp of <time>
     -L, --length <str>    get length of <str>
     -F, --file <file>     set file to <file>
 
@@ -245,27 +244,6 @@ test_expect_success 'keep some options as arguments' '
        test-tool parse-options --expect="arg 00: --quux" --quux
 '
 
-cat >expect <<\EOF
-boolean: 0
-integer: 0
-magnitude: 0
-timestamp: 1
-string: (not set)
-abbrev: 7
-verbose: -1
-quiet: 1
-dry run: no
-file: (not set)
-arg 00: foo
-EOF
-
-test_expect_success 'OPT_DATE() works' '
-       test-tool parse-options -t "1970-01-01 00:00:01 +0000" \
-               foo -q >output 2>output.err &&
-       test_must_be_empty output.err &&
-       test_cmp expect output
-'
-
 cat >expect <<\EOF
 Callback: "four", 0
 boolean: 5
index 438e778d6afa086e8823b2ac3d38c2a26f171dbd..a06269f38ae555f952b83b6fbc38374a725293d1 100755 (executable)
@@ -5,13 +5,15 @@
 
 test_description='Gettext Shell poison'
 
+GIT_TEST_GETTEXT_POISON=YesPlease
+export GIT_TEST_GETTEXT_POISON
 . ./lib-gettext.sh
 
-test_expect_success GETTEXT_POISON 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
+test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
     test "$GIT_INTERNAL_GETTEXT_SH_SCHEME" = "poison"
 '
 
-test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison semantics' '
+test_expect_success 'gettext: our gettext() fallback has poison semantics' '
     printf "# GETTEXT POISON #" >expect &&
     gettext "test" >actual &&
     test_cmp expect actual &&
@@ -20,7 +22,7 @@ test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison s
     test_cmp expect actual
 '
 
-test_expect_success GETTEXT_POISON 'eval_gettext: our eval_gettext() fallback has poison semantics' '
+test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semantics' '
     printf "# GETTEXT POISON #" >expect &&
     eval_gettext "test" >actual &&
     test_cmp expect actual &&
index 2ac47aa0e4a7164cd06037496832a1744990a774..4667e1a1909a01e638b13b7264b9041805a438b6 100755 (executable)
@@ -25,14 +25,17 @@ test_expect_success 'enable split index' '
        git update-index --split-index &&
        test-tool dump-split-index .git/index >actual &&
        indexversion=$(test-tool index-version <.git/index) &&
+
+       # NEEDSWORK: Stop hard-coding checksums.
        if test "$indexversion" = "4"
        then
-               own=3527df833c6c100d3d1d921a9a782d62a8be4b58
-               base=746f7ab2ed44fb839efdfbffcf399d0b113fb4cb
+               own=432ef4b63f32193984f339431fd50ca796493569
+               base=508851a7f0dfa8691e9f69c7f055865389012491
        else
-               own=5e9b60117ece18da410ddecc8b8d43766a0e4204
-               base=4370042739b31cd17a5c5cd6043a77c9a00df113
+               own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
+               base=39d890139ee5356c7ef572216cebcd27aa41f9df
        fi &&
+
        cat >expect <<-EOF &&
        own $own
        base $base
@@ -381,6 +384,26 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"
        test $(ls .git/sharedindex.* | wc -l) -le 2
 '
 
+test_expect_success POSIXPERM 'same mode for index & split index' '
+       git init same-mode &&
+       (
+               cd same-mode &&
+               test_commit A &&
+               test_modebits .git/index >index_mode &&
+               test_must_fail git config core.sharedRepository &&
+               git -c core.splitIndex=true status &&
+               shared=$(ls .git/sharedindex.*) &&
+               case "$shared" in
+               *" "*)
+                       # we have more than one???
+                       false ;;
+               *)
+                       test_modebits "$shared" >split_index_mode &&
+                       test_cmp index_mode split_index_mode ;;
+               esac
+       )
+'
+
 while read -r mode modebits
 do
        test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
index 6aae36417122a8af5d010910fb2586aa9ec91815..e497c1358f8b2da6960d3d73db3cc75f9f7df85c 100755 (executable)
@@ -122,6 +122,36 @@ test_expect_success 'changed commit' '
        test_cmp expected actual
 '
 
+test_expect_success 'changed commit with --no-patch diff option' '
+       git range-diff --no-color --no-patch topic...changed >actual &&
+       cat >expected <<-EOF &&
+       1:  4de457d = 1:  a4b3333 s/5/A/
+       2:  fccce22 = 2:  f51d370 s/4/A/
+       3:  147e64e ! 3:  0559556 s/11/B/
+       4:  a63e992 ! 4:  d966c5c s/12/B/
+       EOF
+       test_cmp expected actual
+'
+
+test_expect_success 'changed commit with --stat diff option' '
+       git range-diff --no-color --stat topic...changed >actual &&
+       cat >expected <<-EOF &&
+       1:  4de457d = 1:  a4b3333 s/5/A/
+            a => b | 0
+            1 file changed, 0 insertions(+), 0 deletions(-)
+       2:  fccce22 = 2:  f51d370 s/4/A/
+            a => b | 0
+            1 file changed, 0 insertions(+), 0 deletions(-)
+       3:  147e64e ! 3:  0559556 s/11/B/
+            a => b | 0
+            1 file changed, 0 insertions(+), 0 deletions(-)
+       4:  a63e992 ! 4:  d966c5c s/12/B/
+            a => b | 0
+            1 file changed, 0 insertions(+), 0 deletions(-)
+       EOF
+       test_cmp expected actual
+'
+
 test_expect_success 'changed commit with sm config' '
        git range-diff --no-color --submodule=log topic...changed >actual &&
        cat >expected <<-EOF &&
index 0392e36d2364c8149f2a628a0901f113b7a5875f..f64b130cb805bbca8475f3c262693fa0faa2cafe 100755 (executable)
@@ -77,11 +77,54 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
 #     "Does not point to a valid commit: invalid-ref"
 #
 # NEEDSWORK: This "grep" is fine in real non-C locales, but
-# GETTEXT_POISON poisons the refname along with the enclosing
+# GIT_TEST_GETTEXT_POISON poisons the refname along with the enclosing
 # error message.
 test_expect_success 'rebase --onto outputs the invalid ref' '
        test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
        test_i18ngrep "invalid-ref" err
 '
 
+test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
+       test_must_fail git rebase -Cnot-a-number HEAD 2>err &&
+       test_i18ngrep "numerical value" err &&
+       test_must_fail git rebase --whitespace=bad HEAD 2>err &&
+       test_i18ngrep "Invalid whitespace option" err
+'
+
+test_expect_success 'GIT_REFLOG_ACTION' '
+       git checkout start &&
+       test_commit reflog-onto &&
+       git checkout -b reflog-topic start &&
+       test_commit reflog-to-rebase &&
+
+       git rebase reflog-onto &&
+       git log -g --format=%gs -3 >actual &&
+       cat >expect <<-\EOF &&
+       rebase finished: returning to refs/heads/reflog-topic
+       rebase: reflog-to-rebase
+       rebase: checkout reflog-onto
+       EOF
+       test_cmp expect actual &&
+
+       git checkout -b reflog-prefix reflog-to-rebase &&
+       GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&
+       git log -g --format=%gs -3 >actual &&
+       cat >expect <<-\EOF &&
+       rebase finished: returning to refs/heads/reflog-prefix
+       change-the-reflog: reflog-to-rebase
+       change-the-reflog: checkout reflog-onto
+       EOF
+       test_cmp expect actual
+'
+
+test_expect_success 'rebase -i onto unrelated history' '
+       git init unrelated &&
+       test_commit -C unrelated 1 &&
+       git -C unrelated remote add -f origin "$PWD" &&
+       git -C unrelated branch --set-upstream-to=origin/master &&
+       git -C unrelated -c core.editor=true rebase -i -v --stat >actual &&
+       test_i18ngrep "Changes to " actual &&
+       test_i18ngrep "5 files changed" actual
+'
+
 test_done
index f355c6825a4a5ff6adef656c432a4e2fdaf0fea9..4c7494cc8f77a3ff92373cb130974825c4418ada 100755 (executable)
@@ -361,4 +361,12 @@ test_expect_success 'autostash with dirty submodules' '
        git rebase -i --autostash HEAD
 '
 
+test_expect_success 'branch is left alone when possible' '
+       git checkout -b unchanged-branch &&
+       echo changed >file0 &&
+       git rebase --autostash unchanged-branch &&
+       test changed = "$(cat file0)" &&
+       test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
+'
+
 test_done
index aa7bfc88ece9de7f542f354c78b7be9ec6d2bdf7..cc5646836fce1aaaa01556450a9b017c7a853088 100755 (executable)
@@ -396,4 +396,20 @@ test_expect_success 'with --autosquash and --exec' '
        grep "G: +G" actual
 '
 
+test_expect_success '--continue after resolving conflicts after a merge' '
+       git checkout -b already-has-g E &&
+       git cherry-pick E..G &&
+       test_commit H2 &&
+
+       git checkout -b conflicts-in-merge H &&
+       test_commit H2 H2.t conflicts H2-conflict &&
+       test_must_fail git rebase -r already-has-g &&
+       grep conflicts H2.t &&
+       echo resolved >H2.t &&
+       git add -u &&
+       git rebase --continue &&
+       test_must_fail git rev-parse --verify HEAD^2 &&
+       test_path_is_missing .git/MERGE_HEAD
+'
+
 test_done
index 6e2cf933f761683781525b36330e38c758aaabd6..28c053849aafa8811a13131a8f705838f50ec97d 100755 (executable)
@@ -44,42 +44,50 @@ show --stat
 log -1 --stat
 EOF
 
-while read cmd args
+cat >expect.60 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+cat >expect.6030 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+cat >expect2.60 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+cat >expect2.6030 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+while read expect cmd args
 do
-       cat >expect <<-'EOF'
-        ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
-       EOF
        test_expect_success "$cmd --stat=width: a long name is given more room when the bar is short" '
                git $cmd $args --stat=40 >output &&
                grep " | " output >actual &&
-               test_cmp expect actual
+               test_cmp $expect.60 actual
        '
 
        test_expect_success "$cmd --stat-width=width with long name" '
                git $cmd $args --stat-width=40 >output &&
                grep " | " output >actual &&
-               test_cmp expect actual
+               test_cmp $expect.60 actual
        '
 
-       cat >expect <<-'EOF'
-        ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
-       EOF
        test_expect_success "$cmd --stat=...,name-width with long name" '
                git $cmd $args --stat=60,30 >output &&
                grep " | " output >actual &&
-               test_cmp expect actual
+               test_cmp $expect.6030 actual
        '
 
        test_expect_success "$cmd --stat-name-width with long name" '
                git $cmd $args --stat-name-width=30 >output &&
                grep " | " output >actual &&
-               test_cmp expect actual
+               test_cmp $expect.6030 actual
        '
 done <<\EOF
-format-patch -1 --stdout
-diff HEAD^ HEAD --stat
-show --stat
-log -1 --stat
+expect2 format-patch --cover-letter -1 --stdout
+expect diff HEAD^ HEAD --stat
+expect show --stat
+expect log -1 --stat
 EOF
 
 
@@ -95,6 +103,16 @@ test_expect_success 'preparation for big change tests' '
        git commit -m message abcd
 '
 
+cat >expect72 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success "format-patch --cover-letter ignores COLUMNS (big change)" '
+       COLUMNS=200 git format-patch -1 --stdout --cover-letter >output &&
+       grep " | " output >actual &&
+       test_cmp expect72 actual
+'
+
 cat >expect72 <<'EOF'
  abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 EOF
index 6d9287231826ece18873b531186907cd75ef7461..4c3f264a633b770445e116edfac83872b47916bf 100755 (executable)
@@ -29,6 +29,18 @@ test_expect_success 'apply exits non-zero with no-op patch' '
        test_must_fail git apply --check input
 '
 
+test_expect_success '`apply --recount` allows no-op patch' '
+       echo 1 >1 &&
+       git apply --recount --check <<-\EOF
+       diff --get a/1 b/1
+       index 6696ea4..606eddd 100644
+       --- a/1
+       +++ b/1
+       @@ -1,1 +1,1 @@
+        1
+       EOF
+'
+
 test_expect_success 'invalid combination: create and copy' '
        test_must_fail git apply --check - <<-\EOF
        diff --git a/1 b/2
index 91ee6841c150f5b7c03e2624231b5344a1fa47e9..32e722db2ed96f14b6ca4b0fe53636c719f57eb5 100755 (executable)
@@ -302,6 +302,12 @@ test_expect_success 'ls-remote works outside repository' '
        nongit git ls-remote dst.git
 '
 
+test_expect_success 'ls-remote --sort fails gracefully outside repository' '
+       # Use a sort key that requires access to the referenced objects.
+       nongit test_must_fail git ls-remote --sort=authordate "$TRASH_DIRECTORY" 2>err &&
+       test_i18ngrep "^fatal: not a git repository, but the field '\''authordate'\'' requires access to object data" err
+'
+
 test_expect_success 'ls-remote patterns work with all protocol versions' '
        git for-each-ref --format="%(objectname)        %(refname)" \
                refs/heads/master refs/remotes/origin/master >expect &&
index b24d8b05a498674612870a133e1a4fc4a37bd5d3..90d890d02fd8f5451d0d78d880f6698d11b22a3d 100755 (executable)
@@ -31,6 +31,7 @@ test_http_env() {
                PATH_TRANSLATED="$PWD/.git/git-$handler_type-pack" \
                GIT_HTTP_EXPORT_ALL=TRUE \
                REQUEST_METHOD=POST \
+               "$PERL_PATH" \
                "$TEST_DIRECTORY"/t5562/invoke-with-content-length.pl \
                    "$request_body" git http-backend >act.out 2>act.err
 }
old mode 100755 (executable)
new mode 100644 (file)
index 6c2aae7..0943474
@@ -1,4 +1,3 @@
-#!/usr/bin/perl
 use 5.008;
 use strict;
 use warnings;
index 747775c147612f3b09a599661fe3dc7d3b1d34bd..3e9876e1971348daad7fd87f8aa107ea5fd6aaff 100755 (executable)
@@ -78,4 +78,11 @@ test_expect_success GPG 'pull commit with bad signature with --no-verify-signatu
        git pull --ff-only --no-verify-signatures bad 2>pullerror
 '
 
+test_expect_success GPG 'pull unsigned commit into unborn branch' '
+       git init empty-repo &&
+       test_must_fail \
+               git -C empty-repo pull --verify-signatures ..  2>pullerror &&
+       test_i18ngrep "does not have a GPG signature" pullerror
+'
+
 test_done
index f1a49e94f5fe56a0c175b0e5354ce1d5300cb382..8bbc7068acbd1eab9f0499ff1151abd58a87079c 100755 (executable)
@@ -628,7 +628,7 @@ test_expect_success 'clone on case-insensitive fs' '
        )
 '
 
-test_expect_success !MINGW,!CYGWIN,CASE_INSENSITIVE_FS 'colliding file detection' '
+test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' '
        grep X icasefs/warning &&
        grep x icasefs/warning &&
        test_i18ngrep "the following paths have collided" icasefs/warning
index 348d9b3bc7ad3ea512f68b6200481c9f6b90d792..cf39e9e2437f06b4725b61ad2194dd65b4857f82 100755 (executable)
@@ -71,4 +71,10 @@ test_expect_success 'prerequisites with an empty commit message' '
        git bundle verify bundle
 '
 
+test_expect_success 'failed bundle creation does not leave cruft' '
+       # This fails because the bundle would be empty.
+       test_must_fail git bundle create fail.bundle master..master &&
+       test_path_is_missing fail.bundle.lock
+'
+
 test_done
index b5a1190ffe63b53d8b637b39a15d3d94b3efa6cd..a10f0df02b0ec8acdcaf7c90d02da4a9c20ffb1b 100755 (executable)
@@ -12,6 +12,22 @@ unnote () {
        git name-rev --tags --stdin | sed -e "s|$OID_REGEX (tags/\([^)]*\)) |\1 |g"
 }
 
+#
+# Create a test repo with interesting commit graph:
+#
+# A--B----------G--H--I--K--L
+#  \  \           /     /
+#   \  \         /     /
+#    C------E---F     J
+#        \_/
+#
+# The commits are laid out from left-to-right starting with
+# the root commit A and terminating at the tip commit L.
+#
+# There are a few places where we adjust the commit date or
+# author date to make the --topo-order, --date-order, and
+# --author-date-order flags produce different output.
+
 test_expect_success setup '
        echo "Hi there" >file &&
        echo "initial" >lost &&
@@ -21,10 +37,18 @@ test_expect_success setup '
 
        git branch other-branch &&
 
+       git symbolic-ref HEAD refs/heads/unrelated &&
+       git rm -f "*" &&
+       echo "Unrelated branch" >side &&
+       git add side &&
+       test_tick && git commit -m "Side root" &&
+       note J &&
+       git checkout master &&
+
        echo "Hello" >file &&
        echo "second" >lost &&
        git add file lost &&
-       test_tick && git commit -m "Modified file and lost" &&
+       test_tick && GIT_AUTHOR_DATE=$(($test_tick + 120)) git commit -m "Modified file and lost" &&
        note B &&
 
        git checkout other-branch &&
@@ -63,13 +87,6 @@ test_expect_success setup '
        test_tick && git commit -a -m "Final change" &&
        note I &&
 
-       git symbolic-ref HEAD refs/heads/unrelated &&
-       git rm -f "*" &&
-       echo "Unrelated branch" >side &&
-       git add side &&
-       test_tick && git commit -m "Side root" &&
-       note J &&
-
        git checkout master &&
        test_tick && git merge --allow-unrelated-histories -m "Coolest" unrelated &&
        note K &&
@@ -103,14 +120,24 @@ check_result () {
        check_outcome success "$@"
 }
 
-check_result 'L K J I H G F E D C B A' --full-history
+check_result 'L K J I H F E D C G B A' --full-history --topo-order
+check_result 'L K I H G F E D C B J A' --full-history
+check_result 'L K I H G F E D C B J A' --full-history --date-order
+check_result 'L K I H G F E D B C J A' --full-history --author-date-order
 check_result 'K I H E C B A' --full-history -- file
 check_result 'K I H E C B A' --full-history --topo-order -- file
 check_result 'K I H E C B A' --full-history --date-order -- file
+check_result 'K I H E B C A' --full-history --author-date-order -- file
 check_result 'I E C B A' --simplify-merges -- file
+check_result 'I E C B A' --simplify-merges --topo-order -- file
+check_result 'I E C B A' --simplify-merges --date-order -- file
+check_result 'I E B C A' --simplify-merges --author-date-order -- file
 check_result 'I B A' -- file
 check_result 'I B A' --topo-order -- file
+check_result 'I B A' --date-order -- file
+check_result 'I B A' --author-date-order -- file
 check_result 'H' --first-parent -- another-file
+check_result 'H' --first-parent --topo-order -- another-file
 
 check_result 'E C B A' --full-history E -- lost
 test_expect_success 'full history simplification without parent' '
index 270e579c2d3a30b2a08517bc63fe6edf5221af59..bb5aeac07f8341ed44bfe25aba6238a92e1fc9e7 100755 (executable)
@@ -36,7 +36,13 @@ test_expect_success 'setup' '
        git tag foo/bar master &&
        commit master3 &&
        git update-ref refs/remotes/foo/baz master &&
-       commit master4
+       commit master4 &&
+       git update-ref refs/remotes/upstream/one subspace/one &&
+       git update-ref refs/remotes/upstream/two subspace/two &&
+       git update-ref refs/remotes/upstream/x subspace-x &&
+       git tag qux/one subspace/one &&
+       git tag qux/two subspace/two &&
+       git tag qux/x subspace-x
 '
 
 test_expect_success 'rev-parse --glob=refs/heads/subspace/*' '
@@ -153,6 +159,54 @@ test_expect_success 'rev-parse --all clears --exclude' '
        compare rev-parse "--exclude=* --all --all" "--all"
 '
 
+test_expect_success 'rev-parse --exclude=glob with --branches=glob' '
+       compare rev-parse "--exclude=subspace-* --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-parse --exclude=glob with --tags=glob' '
+       compare rev-parse "--exclude=qux/? --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-parse --exclude=glob with --remotes=glob' '
+       compare rev-parse "--exclude=upstream/? --remotes=upstream/*" "upstream/one upstream/two"
+'
+
+test_expect_success 'rev-parse --exclude=ref with --branches=glob' '
+       compare rev-parse "--exclude=subspace-x --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-parse --exclude=ref with --tags=glob' '
+       compare rev-parse "--exclude=qux/x --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-parse --exclude=ref with --remotes=glob' '
+       compare rev-parse "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two"
+'
+
+test_expect_success 'rev-list --exclude=glob with --branches=glob' '
+       compare rev-list "--exclude=subspace-* --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-list --exclude=glob with --tags=glob' '
+       compare rev-list "--exclude=qux/? --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-list --exclude=glob with --remotes=glob' '
+       compare rev-list "--exclude=upstream/? --remotes=upstream/*" "upstream/one upstream/two"
+'
+
+test_expect_success 'rev-list --exclude=ref with --branches=glob' '
+       compare rev-list "--exclude=subspace-x --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-list --exclude=ref with --tags=glob' '
+       compare rev-list "--exclude=qux/x --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-list --exclude=ref with --remotes=glob' '
+       compare rev-list "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two"
+'
+
 test_expect_success 'rev-list --glob=refs/heads/subspace/*' '
 
        compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*"
@@ -245,7 +299,7 @@ test_expect_success 'rev-list --tags=foo' '
 
 test_expect_success 'rev-list --tags' '
 
-       compare rev-list "foo/bar" "--tags"
+       compare rev-list "foo/bar qux/x qux/two qux/one" "--tags"
 
 '
 
@@ -304,7 +358,7 @@ test_expect_success 'shortlog accepts --glob/--tags/--remotes' '
          "master other/three someref subspace-x subspace/one subspace/two" \
          "--glob=heads/*" &&
        compare shortlog foo/bar --tags=foo &&
-       compare shortlog foo/bar --tags &&
+       compare shortlog "foo/bar qux/one qux/two qux/x" --tags &&
        compare shortlog foo/baz --remotes=foo
 
 '
index 86374a9c52c0bd26a8ba7223526c9e1f128f468a..5d6d3184ac390f2cd476a322cf6d15e69a912494 100755 (executable)
@@ -461,7 +461,10 @@ test_expect_success '--convert-graft-file' '
        printf "%s\n%s %s\n\n# comment\n%s\n" \
                $(git rev-parse HEAD^^ HEAD^ HEAD^^ HEAD^2) \
                >.git/info/grafts &&
-       git replace --convert-graft-file &&
+       git status 2>stderr &&
+       test_i18ngrep "hint:.*grafts is deprecated" stderr &&
+       git replace --convert-graft-file 2>stderr &&
+       test_i18ngrep ! "hint:.*grafts is deprecated" stderr &&
        test_path_is_missing .git/info/grafts &&
 
        : verify that the history is now "grafted" &&
index a0c64e617a187fd4513a9c0fa3d281e29ab14fe8..b24d85003606bf2076902d944fb395bf55761d5a 100755 (executable)
@@ -56,18 +56,22 @@ test_expect_success 'setup' '
        git config core.commitGraph true
 '
 
-test_three_modes () {
+run_three_modes () {
        test_when_finished rm -rf .git/objects/info/commit-graph &&
-       test-tool reach $1 <input >actual &&
+       "$@" <input >actual &&
        test_cmp expect actual &&
        cp commit-graph-full .git/objects/info/commit-graph &&
-       test-tool reach $1 <input >actual &&
+       "$@" <input >actual &&
        test_cmp expect actual &&
        cp commit-graph-half .git/objects/info/commit-graph &&
-       test-tool reach $1 <input >actual &&
+       "$@" <input >actual &&
        test_cmp expect actual
 }
 
+test_three_modes () {
+       run_three_modes test-tool reach "$@"
+}
+
 test_expect_success 'ref_newer:miss' '
        cat >input <<-\EOF &&
        A:commit-5-7
@@ -265,6 +269,90 @@ test_expect_success 'commit_contains:miss' '
        test_three_modes commit_contains --tag
 '
 
+test_expect_success 'rev-list: basic topo-order' '
+       git rev-parse \
+               commit-6-6 commit-5-6 commit-4-6 commit-3-6 commit-2-6 commit-1-6 \
+               commit-6-5 commit-5-5 commit-4-5 commit-3-5 commit-2-5 commit-1-5 \
+               commit-6-4 commit-5-4 commit-4-4 commit-3-4 commit-2-4 commit-1-4 \
+               commit-6-3 commit-5-3 commit-4-3 commit-3-3 commit-2-3 commit-1-3 \
+               commit-6-2 commit-5-2 commit-4-2 commit-3-2 commit-2-2 commit-1-2 \
+               commit-6-1 commit-5-1 commit-4-1 commit-3-1 commit-2-1 commit-1-1 \
+       >expect &&
+       run_three_modes git rev-list --topo-order commit-6-6
+'
+
+test_expect_success 'rev-list: first-parent topo-order' '
+       git rev-parse \
+               commit-6-6 \
+               commit-6-5 \
+               commit-6-4 \
+               commit-6-3 \
+               commit-6-2 \
+               commit-6-1 commit-5-1 commit-4-1 commit-3-1 commit-2-1 commit-1-1 \
+       >expect &&
+       run_three_modes git rev-list --first-parent --topo-order commit-6-6
+'
+
+test_expect_success 'rev-list: range topo-order' '
+       git rev-parse \
+               commit-6-6 commit-5-6 commit-4-6 commit-3-6 commit-2-6 commit-1-6 \
+               commit-6-5 commit-5-5 commit-4-5 commit-3-5 commit-2-5 commit-1-5 \
+               commit-6-4 commit-5-4 commit-4-4 commit-3-4 commit-2-4 commit-1-4 \
+               commit-6-3 commit-5-3 commit-4-3 \
+               commit-6-2 commit-5-2 commit-4-2 \
+               commit-6-1 commit-5-1 commit-4-1 \
+       >expect &&
+       run_three_modes git rev-list --topo-order commit-3-3..commit-6-6
+'
+
+test_expect_success 'rev-list: range topo-order' '
+       git rev-parse \
+               commit-6-6 commit-5-6 commit-4-6 \
+               commit-6-5 commit-5-5 commit-4-5 \
+               commit-6-4 commit-5-4 commit-4-4 \
+               commit-6-3 commit-5-3 commit-4-3 \
+               commit-6-2 commit-5-2 commit-4-2 \
+               commit-6-1 commit-5-1 commit-4-1 \
+       >expect &&
+       run_three_modes git rev-list --topo-order commit-3-8..commit-6-6
+'
+
+test_expect_success 'rev-list: first-parent range topo-order' '
+       git rev-parse \
+               commit-6-6 \
+               commit-6-5 \
+               commit-6-4 \
+               commit-6-3 \
+               commit-6-2 \
+               commit-6-1 commit-5-1 commit-4-1 \
+       >expect &&
+       run_three_modes git rev-list --first-parent --topo-order commit-3-8..commit-6-6
+'
+
+test_expect_success 'rev-list: ancestry-path topo-order' '
+       git rev-parse \
+               commit-6-6 commit-5-6 commit-4-6 commit-3-6 \
+               commit-6-5 commit-5-5 commit-4-5 commit-3-5 \
+               commit-6-4 commit-5-4 commit-4-4 commit-3-4 \
+               commit-6-3 commit-5-3 commit-4-3 \
+       >expect &&
+       run_three_modes git rev-list --topo-order --ancestry-path commit-3-3..commit-6-6
+'
+
+test_expect_success 'rev-list: symmetric difference topo-order' '
+       git rev-parse \
+               commit-6-6 commit-5-6 commit-4-6 \
+               commit-6-5 commit-5-5 commit-4-5 \
+               commit-6-4 commit-5-4 commit-4-4 \
+               commit-6-3 commit-5-3 commit-4-3 \
+               commit-6-2 commit-5-2 commit-4-2 \
+               commit-6-1 commit-5-1 commit-4-1 \
+               commit-3-8 commit-2-8 commit-1-8 \
+               commit-3-7 commit-2-7 commit-1-7 \
+       >expect &&
+       run_three_modes git rev-list --topo-order commit-3-8...commit-6-6
+'
+
 test_expect_success 'get_reachable_subset:all' '
        cat >input <<-\EOF &&
        X:commit-9-1
index 826987ca804fbd74bc06467446c99b7b4a27ea3e..72b9b375baa6b26d0bca91c0c2d214cd4a9b8a42 100755 (executable)
@@ -254,9 +254,9 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
 test_expect_success 'checkout to detach HEAD' '
        git config advice.detachedHead true &&
        git checkout -f renamer && git clean -f &&
-       git checkout renamer^ 2>messages &&
-       test_i18ngrep "HEAD is now at 7329388" messages &&
-       (test_line_count -gt 1 messages || test -n "$GETTEXT_POISON") &&
+       GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
+       grep "HEAD is now at 7329388" messages &&
+       test_line_count -gt 1 messages &&
        H=$(git rev-parse --verify HEAD) &&
        M=$(git show-ref -s --verify refs/heads/master) &&
        test "z$H" = "z$M" &&
index 19ccae28699da7949af3203cde62ac648c7effb4..86d3f93fa22e45ba9dda24c49ec02df14e22ebc3 100755 (executable)
@@ -176,8 +176,9 @@ test_expect_success GPG 'show good signature with custom format' '
        13B6F51ECDDE430D
        C O Mitter <committer@example.com>
        73D758744BE721698EC54E8713B6F51ECDDE430D
+       73D758744BE721698EC54E8713B6F51ECDDE430D
        EOF
-       git log -1 --format="%G?%n%GK%n%GS%n%GF" sixth-signed >actual &&
+       git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
        test_cmp expect actual
 '
 
@@ -187,30 +188,33 @@ test_expect_success GPG 'show bad signature with custom format' '
        13B6F51ECDDE430D
        C O Mitter <committer@example.com>
 
+
        EOF
-       git log -1 --format="%G?%n%GK%n%GS%n%GF" $(cat forged1.commit) >actual &&
+       git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat forged1.commit) >actual &&
        test_cmp expect actual
 '
 
 test_expect_success GPG 'show untrusted signature with custom format' '
        cat >expect <<-\EOF &&
        U
-       61092E85B7227189
+       65A0EEA02E30CAD7
        Eris Discordia <discord@example.net>
+       F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
        D4BE22311AD3131E5EDA29A461092E85B7227189
        EOF
-       git log -1 --format="%G?%n%GK%n%GS%n%GF" eighth-signed-alt >actual &&
+       git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
        test_cmp expect actual
 '
 
 test_expect_success GPG 'show unknown signature with custom format' '
        cat >expect <<-\EOF &&
        E
-       61092E85B7227189
+       65A0EEA02E30CAD7
+
 
 
        EOF
-       GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS%n%GF" eighth-signed-alt >actual &&
+       GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
        test_cmp expect actual
 '
 
@@ -220,8 +224,9 @@ test_expect_success GPG 'show lack of signature with custom format' '
 
 
 
+
        EOF
-       git log -1 --format="%G?%n%GK%n%GS%n%GF" seventh-unsigned >actual &&
+       git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" seventh-unsigned >actual &&
        test_cmp expect actual
 '
 
@@ -261,8 +266,9 @@ test_expect_success GPG 'show double signature with custom format' '
 
 
 
+
        EOF
-       git log -1 --format="%G?%n%GK%n%GS%n%GF" $(cat double-commit.commit) >actual &&
+       git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat double-commit.commit) >actual &&
        test_cmp expect actual
 '
 
index e2b1df817a50a48132964124d359c7dc29a89e23..d99218a725c5956d75e32684b196bdc050a0e8b1 100755 (executable)
@@ -103,4 +103,11 @@ test_expect_success GPG 'merge commit with bad signature with merge.verifySignat
        git merge --no-verify-signatures $(cat forged.commit)
 '
 
+test_expect_success GPG 'merge unsigned commit into unborn branch' '
+       test_when_finished "git checkout initial" &&
+       git checkout --orphan unborn &&
+       test_must_fail git merge --verify-signatures side-unsigned 2>mergeerror &&
+       test_i18ngrep "does not have a GPG signature" mergeerror
+'
+
 test_done
index 175f83d7042a0fb9f093bc6f25e1d0b25ce548af..3c6b185b60891c164f56a638071873051420fdac 100755 (executable)
@@ -1697,7 +1697,8 @@ test_expect_success 'sourcing the completion script clears cached commands' '
        verbose test -z "$__git_all_commands"
 '
 
-test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
+test_expect_success 'sourcing the completion script clears cached merge strategies' '
+       GIT_TEST_GETTEXT_POISON= &&
        __git_compute_merge_strategies &&
        verbose test -n "$__git_merge_strategies" &&
        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
index d158c8d0bf704646b2ce764fe96a849fb0303c2f..b4e391526a2957fe2e578d226ef756321e51aef7 100644 (file)
@@ -778,16 +778,16 @@ test_cmp_bin() {
 
 # Use this instead of test_cmp to compare files that contain expected and
 # actual output from git commands that can be translated.  When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
 # results.
 test_i18ncmp () {
-       test -n "$GETTEXT_POISON" || test_cmp "$@"
+       ! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
 }
 
 # Use this instead of "grep expected-string actual" to see if the
 # output from a git command that can be translated either contains an
 # expected string, or does not contain an unwanted one.  When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
 # results.
 test_i18ngrep () {
        eval "last_arg=\${$#}"
@@ -802,7 +802,7 @@ test_i18ngrep () {
                error "bug in the test script: too few parameters to test_i18ngrep"
        fi
 
-       if test -n "$GETTEXT_POISON"
+       if test_have_prereq !C_LOCALE_OUTPUT
        then
                # pretend success
                return 0
@@ -923,7 +923,8 @@ test_create_repo () {
        mkdir -p "$repo"
        (
                cd "$repo" || error "Cannot setup test environment"
-               "$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
+               "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+                       "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
                error "cannot run git init -- have you built things yet?"
                mv .git/hooks .git/hooks-disabled
        ) || exit
index aba66cafa207765cb74d78e86c13faa619788c16..6c6c0af7a128ea7f35fb1753ed39c073208976ea 100644 (file)
@@ -49,18 +49,28 @@ export ASAN_OPTIONS
 : ${LSAN_OPTIONS=abort_on_error=1}
 export LSAN_OPTIONS
 
+if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+then
+       echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).'
+       exit 1
+fi
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH SHELL_PATH
+
 ################################################################
 # It appears that people try to run tests without building...
-"$GIT_BUILD_DIR/git" >/dev/null
+"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
 if test $? != 1
 then
-       echo >&2 'error: you do not seem to have built git yet.'
+       if test -n "$GIT_TEST_INSTALLED"
+       then
+               echo >&2 "error: there is no working Git at '$GIT_TEST_INSTALLED'"
+       else
+               echo >&2 'error: you do not seem to have built git yet.'
+       fi
        exit 1
 fi
 
-. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
-export PERL_PATH SHELL_PATH
-
 # if --tee was passed, write the output not only to the terminal, but
 # additionally to the file test-results/$BASENAME.out, too.
 case "$GIT_TEST_TEE_STARTED, $* " in
@@ -95,6 +105,16 @@ PAGER=cat
 TZ=UTC
 export LANG LC_ALL PAGER TZ
 EDITOR=:
+
+# GIT_TEST_GETTEXT_POISON should not influence git commands executed
+# during initialization of test-lib and the test repo. Back it up,
+# unset and then restore after initialization is finished.
+if test -n "$GIT_TEST_GETTEXT_POISON"
+then
+       GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
+       unset GIT_TEST_GETTEXT_POISON
+fi
+
 # A call to "unset" with no arguments causes at least Solaris 10
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
 # deriving from the command substitution clustered with the other
@@ -957,7 +977,7 @@ elif test -n "$GIT_TEST_INSTALLED"
 then
        GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
        error "Cannot run git from $GIT_TEST_INSTALLED."
-       PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
+       PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH
        GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
 else # normal case, use ../bin-wrappers only unless $with_dashes:
        git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
@@ -1104,13 +1124,15 @@ test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
 test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 
+if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
+then
+       GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
+       unset GIT_TEST_GETTEXT_POISON_ORIG
+fi
+
 # Can we rely on git's output in the C locale?
-if test -n "$GETTEXT_POISON"
+if test -z "$GIT_TEST_GETTEXT_POISON"
 then
-       GIT_GETTEXT_POISON=YesPlease
-       export GIT_GETTEXT_POISON
-       test_set_prereq GETTEXT_POISON
-else
        test_set_prereq C_LOCALE_OUTPUT
 fi
 
index a2135e0743ac60d8d4512210a81bac2102948fa1..532984569132de11f6f05b561f817817523a3468 100644 (file)
@@ -20,6 +20,9 @@
 
 int online_cpus(void)
 {
+#ifdef NO_PTHREADS
+       return 1;
+#else
 #ifdef _SC_NPROCESSORS_ONLN
        long ncpus;
 #endif
@@ -59,10 +62,12 @@ int online_cpus(void)
 #endif
 
        return 1;
+#endif
 }
 
 int init_recursive_mutex(pthread_mutex_t *m)
 {
+#ifndef NO_PTHREADS
        pthread_mutexattr_t a;
        int ret;
 
@@ -74,4 +79,47 @@ int init_recursive_mutex(pthread_mutex_t *m)
                pthread_mutexattr_destroy(&a);
        }
        return ret;
+#else
+       return 0;
+#endif
+}
+
+#ifdef NO_PTHREADS
+int dummy_pthread_create(pthread_t *pthread, const void *attr,
+                        void *(*fn)(void *), void *data)
+{
+       /*
+        * Do nothing.
+        *
+        * The main purpose of this function is to break compiler's
+        * flow analysis and avoid -Wunused-variable false warnings.
+        */
+       return ENOSYS;
+}
+
+int dummy_pthread_init(void *data)
+{
+       /*
+        * Do nothing.
+        *
+        * The main purpose of this function is to break compiler's
+        * flow analysis or it may realize that functions like
+        * pthread_mutex_init() is no-op, which means the (static)
+        * variable is not used/initialized at all and trigger
+        * -Wunused-variable
+        */
+       return ENOSYS;
 }
+
+int dummy_pthread_join(pthread_t pthread, void **retval)
+{
+       /*
+        * Do nothing.
+        *
+        * The main purpose of this function is to break compiler's
+        * flow analysis and avoid -Wunused-variable false warnings.
+        */
+       return ENOSYS;
+}
+
+#endif
index d9a769d19084587b397c50e9420843be38e89903..4961487ed914f4fea817df26904109bb05f2a2c5 100644 (file)
@@ -4,12 +4,54 @@
 #ifndef NO_PTHREADS
 #include <pthread.h>
 
-extern int online_cpus(void);
-extern int init_recursive_mutex(pthread_mutex_t*);
+#define HAVE_THREADS 1
 
 #else
 
-#define online_cpus() 1
+#define HAVE_THREADS 0
+
+/*
+ * macros instead of typedefs because pthread definitions may have
+ * been pulled in by some system dependencies even though the user
+ * wants to disable pthread.
+ */
+#define pthread_t int
+#define pthread_mutex_t int
+#define pthread_cond_t int
+#define pthread_key_t int
+
+#define pthread_mutex_init(mutex, attr) dummy_pthread_init(mutex)
+#define pthread_mutex_lock(mutex)
+#define pthread_mutex_unlock(mutex)
+#define pthread_mutex_destroy(mutex)
+
+#define pthread_cond_init(cond, attr) dummy_pthread_init(cond)
+#define pthread_cond_wait(cond, mutex)
+#define pthread_cond_signal(cond)
+#define pthread_cond_broadcast(cond)
+#define pthread_cond_destroy(cond)
+
+#define pthread_key_create(key, attr) dummy_pthread_init(key)
+#define pthread_key_delete(key)
+
+#define pthread_create(thread, attr, fn, data) \
+       dummy_pthread_create(thread, attr, fn, data)
+#define pthread_join(thread, retval) \
+       dummy_pthread_join(thread, retval)
+
+#define pthread_setspecific(key, data)
+#define pthread_getspecific(key) NULL
+
+int dummy_pthread_create(pthread_t *pthread, const void *attr,
+                        void *(*fn)(void *), void *data);
+int dummy_pthread_join(pthread_t pthread, void **retval);
+
+int dummy_pthread_init(void *);
 
 #endif
+
+int online_cpus(void);
+int init_recursive_mutex(pthread_mutex_t*);
+
+
 #endif /* THREAD_COMPAT_H */
index 7213fa0d320284e318c7895cc0915ef556ac4f6d..bf225c698fac81a9a94eff6d3371988ac4ff0bac 100644 (file)
@@ -573,7 +573,7 @@ static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
                        fprintf(stderr, "Debug: Falling back to dumb "
                                "transport.\n");
        } else {
-               die(_(_("unknown response to connect: %s")),
+               die(_("unknown response to connect: %s"),
                    cmdbuf->buf);
        }
 
index 187568a112a08c7d2ceda7cdc216b72ebcce6631..a24711374c41918bed46fbe5d5a3060312917fa6 100644 (file)
@@ -1559,6 +1559,7 @@ void wt_status_get_state(struct wt_status_state *state,
        struct object_id oid;
 
        if (!stat(git_path_merge_head(the_repository), &st)) {
+               wt_status_check_rebase(NULL, state);
                state->merge_in_progress = 1;
        } else if (wt_status_check_rebase(NULL, state)) {
                ;               /* all set */
@@ -1583,9 +1584,13 @@ static void wt_longstatus_print_state(struct wt_status *s)
        const char *state_color = color(WT_STATUS_HEADER, s);
        struct wt_status_state *state = &s->state;
 
-       if (state->merge_in_progress)
+       if (state->merge_in_progress) {
+               if (state->rebase_interactive_in_progress) {
+                       show_rebase_information(s, state_color);
+                       fputs("\n", s->fp);
+               }
                show_merge_in_progress(s, state_color);
-       else if (state->am_in_progress)
+       else if (state->am_in_progress)
                show_am_in_progress(s, state_color);
        else if (state->rebase_in_progress || state->rebase_interactive_in_progress)
                show_rebase_in_progress(s, state_color);