Merge branch 'sb/submodule-clone-retry'
authorJunio C Hamano <gitster@pobox.com>
Mon, 11 Jul 2016 17:31:04 +0000 (10:31 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 11 Jul 2016 17:31:04 +0000 (10:31 -0700)
"git submodule update" that drives many "git clone" could
eventually hit flaky servers/network conditions on one of the
submodules; the command learned to retry the attempt.

* sb/submodule-clone-retry:
  submodule update: continue when a clone fails
  submodule--helper: initial clone learns retry logic

213 files changed:
.mailmap
.travis.yml
Documentation/CodingGuidelines
Documentation/Makefile
Documentation/RelNotes/2.10.0.txt [new file with mode: 0644]
Documentation/RelNotes/2.8.4.txt
Documentation/RelNotes/2.9.0.txt
Documentation/RelNotes/2.9.1.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/date-formats.txt
Documentation/diff-config.txt
Documentation/diff-generate-patch.txt
Documentation/diff-options.txt
Documentation/fetch-options.txt
Documentation/git-am.txt
Documentation/git-bisect-lk2009.txt
Documentation/git-bisect.txt
Documentation/git-cherry-pick.txt
Documentation/git-clone.txt
Documentation/git-commit.txt
Documentation/git-config.txt
Documentation/git-daemon.txt
Documentation/git-fast-import.txt
Documentation/git-filter-branch.txt
Documentation/git-format-patch.txt
Documentation/git-gc.txt
Documentation/git-grep.txt
Documentation/git-help.txt
Documentation/git-http-backend.txt
Documentation/git-init.txt
Documentation/git-instaweb.txt
Documentation/git-log.txt
Documentation/git-mailsplit.txt
Documentation/git-notes.txt
Documentation/git-p4.txt
Documentation/git-push.txt
Documentation/git-quiltimport.txt
Documentation/git-repack.txt
Documentation/git-replace.txt
Documentation/git-send-email.txt
Documentation/git-sh-setup.txt
Documentation/git-svn.txt
Documentation/git-tag.txt
Documentation/git-upload-pack.txt
Documentation/git-verify-commit.txt
Documentation/git-web--browse.txt
Documentation/git-worktree.txt
Documentation/git.txt
Documentation/gitattributes.txt
Documentation/gitignore.txt
Documentation/gitremote-helpers.txt
Documentation/gitweb.conf.txt
Documentation/gitweb.txt
Documentation/merge-config.txt
Documentation/pretty-options.txt
Documentation/technical/signature-format.txt [new file with mode: 0644]
GIT-VERSION-GEN
Makefile
README.md
RelNotes
archive.c
bisect.c
builtin/add.c
builtin/am.c
builtin/apply.c
builtin/blame.c
builtin/cat-file.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/fetch.c
builtin/interpret-trailers.c
builtin/log.c
builtin/mailsplit.c
builtin/pack-objects.c
builtin/patch-id.c
builtin/pull.c
builtin/receive-pack.c
builtin/remote.c
builtin/repack.c
builtin/reset.c
builtin/rev-list.c
builtin/shortlog.c
builtin/submodule--helper.c
builtin/update-index.c
builtin/worktree.c
cache.h
combine-diff.c
commit.h
compat/mingw.c
compat/mingw.h
compat/regex/regcomp.c
compat/regex/regex.c
compat/winansi.c
config.c
config.mak.uname
contrib/completion/git-completion.bash
contrib/completion/git-prompt.sh
contrib/credential/gnome-keyring/Makefile
daemon.c
date.c
diff.c
fast-import.c
git-add--interactive.perl
git-p4.py
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh
git-send-email.perl
git-sh-setup.sh
git-submodule.sh
gpg-interface.c
graph.c
graph.h
grep.c
http.c
http.h
imap-send.c
line-log.c
log-tree.c
notes-merge.c
notes.c
parse-options-cb.c
pathspec.c
pathspec.h
perl/Git/SVN.pm
po/bg.po
po/de.po
po/fr.po
po/git.pot
po/ko.po
po/pt_PT.po
po/ru.po
po/sv.po
po/vi.po
po/zh_CN.po
pretty.c
read-cache.c
reflog-walk.c
refs.h
revision.c
run-command.c
run-command.h
send-pack.c
sequencer.c
sideband.c
sideband.h
strbuf.h
submodule.c
t/helper/test-config.c
t/helper/test-date.c
t/helper/test-parse-options.c
t/lib-httpd.sh
t/perf/perf-lib.sh
t/t0006-date.sh
t/t0008-ignores.sh
t/t1308-config-set.sh
t/t1401-symbolic-ref.sh
t/t1410-reflog.sh
t/t1500-rev-parse.sh
t/t2025-worktree-add.sh
t/t2300-cd-to-toplevel.sh
t/t3700-add.sh
t/t4014-format-patch.sh
t/t4018-diff-funcname.sh
t/t4018/css-brace-in-col-1 [new file with mode: 0644]
t/t4018/css-colon-eol [new file with mode: 0644]
t/t4018/css-colon-selector [new file with mode: 0644]
t/t4018/css-common [new file with mode: 0644]
t/t4018/css-long-selector-list [new file with mode: 0644]
t/t4018/css-prop-sans-indent [new file with mode: 0644]
t/t4018/css-short-selector-list [new file with mode: 0644]
t/t4018/css-trailing-space [new file with mode: 0644]
t/t4034-diff-words.sh
t/t4034/css/expect [new file with mode: 0644]
t/t4034/css/post [new file with mode: 0644]
t/t4034/css/pre [new file with mode: 0644]
t/t4051-diff-function-context.sh
t/t4051/appended1.c [new file with mode: 0644]
t/t4051/appended2.c [new file with mode: 0644]
t/t4051/dummy.c [new file with mode: 0644]
t/t4051/hello.c [new file with mode: 0644]
t/t4051/includes.c [new file with mode: 0644]
t/t4150-am.sh
t/t4204-patch-id.sh
t/t4205-log-pretty-formats.sh
t/t5100-mailinfo.sh
t/t5100/0001mboxrd [new file with mode: 0644]
t/t5100/0002mboxrd [new file with mode: 0644]
t/t5100/sample.mboxrd [new file with mode: 0644]
t/t5310-pack-bitmaps.sh
t/t5500-fetch-pack.sh
t/t5520-pull.sh
t/t5544-pack-objects-hook.sh [new file with mode: 0755]
t/t5614-clone-submodules.sh
t/t6006-rev-list-format.sh
t/t6044-merge-unrelated-index-changes.sh
t/t7004-tag.sh
t/t7403-submodule-sync.sh
t/t7701-repack-unpack-unreachable.sh
t/t7800-difftool.sh
t/t7810-grep.sh
t/t9300-fast-import.sh
t/t9302-fast-import-unpack-limit.sh [new file with mode: 0755]
t/test-lib-functions.sh
tree-diff.c
upload-pack.c
userdiff.c
worktree.c
write_or_die.c
wt-status.c
xdiff-interface.c
xdiff/xemit.c

index a9162c0..a714e69 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -46,6 +46,7 @@ David D. Kilzer <ddkilzer@kilzer.net>
 David Kågedal <davidk@lysator.liu.se>
 David Reiss <dreiss@facebook.com> <dreiss@dreiss-vmware.(none)>
 David S. Miller <davem@davemloft.net>
+David Turner <novalis@novalis.org> <dturner@twopensource.com>
 Deskin Miller <deskinm@umich.edu>
 Dirk Süsserott <newsletter@dirk.my1.cc>
 Eric Blake <eblake@redhat.com> <ebb9@byu.net>
index c20ec54..c2b76f9 100644 (file)
@@ -82,6 +82,8 @@ before_install:
       brew tap homebrew/binary --quiet
       brew_force_set_latest_binary_hash perforce
       brew_force_set_latest_binary_hash perforce-server
+      # Uncomment this if you want to run perf tests:
+      # brew install gnu-time
       brew install git-lfs perforce-server perforce gettext
       brew link --force gettext
       ;;
index 0ddd368..7f4769a 100644 (file)
@@ -526,12 +526,19 @@ Writing Documentation:
  modifying paragraphs or option/command explanations that contain options
  or commands:
 
- Literal examples (e.g. use of command-line options, command names, and
- configuration variables) are typeset in monospace, and if you can use
- `backticks around word phrases`, do so.
+ Literal examples (e.g. use of command-line options, command names,
+ configuration and environment variables) must be typeset in monospace (i.e.
+ wrapped with backticks):
    `--pretty=oneline`
    `git rev-list`
    `remote.pushDefault`
+   `GIT_DIR`
+
+ An environment variable must be prefixed with "$" only when referring to its
+ value and not when referring to the variable itself, in this case there is
+ nothing to add except the backticks:
+   `GIT_DIR` is specified
+   `$GIT_DIR/hooks/pre-receive`
 
  Word phrases enclosed in `backtick characters` are rendered literally
  and will not be further expanded. The use of `backticks` to achieve the
index f6e288b..b43d66e 100644 (file)
@@ -76,6 +76,7 @@ TECH_DOCS += technical/protocol-common
 TECH_DOCS += technical/racy-git
 TECH_DOCS += technical/send-pack-pipeline
 TECH_DOCS += technical/shallow
+TECH_DOCS += technical/signature-format
 TECH_DOCS += technical/trivial-merge
 SP_ARTICLES += $(TECH_DOCS)
 SP_ARTICLES += technical/api-index
@@ -146,7 +147,7 @@ else
        ASCIIDOC_EXTRA += -a git-asciidoc-no-roff
        endif
 endif
-ifdef MAN_BOLD_LITERAL
+ifndef NO_MAN_BOLD_LITERAL
 XMLTO_EXTRA += -m manpage-bold-literal.xsl
 endif
 ifdef DOCBOOK_SUPPRESS_SP
diff --git a/Documentation/RelNotes/2.10.0.txt b/Documentation/RelNotes/2.10.0.txt
new file mode 100644 (file)
index 0000000..3853b3d
--- /dev/null
@@ -0,0 +1,228 @@
+Git 2.10 Release Notes
+======================
+
+Backward compatibility notes
+----------------------------
+
+Updates since v2.9
+------------------
+
+UI, Workflows & Features
+
+ * "git pull --rebase --verify-signature" learned to warn the user
+   that "--verify-signature" is a no-op when rebasing.
+
+ * An upstream project can make a recommendation to shallowly clone
+   some submodules in the .gitmodules file it ships.
+
+ * "git worktree add" learned that '-' can be used as a short-hand for
+   "@{-1}", the previous branch.
+
+ * Update the funcname definition to support css files.
+
+ * The completion script (in contrib/) learned to complete "git
+   status" options.
+
+ * Messages that are generated by auto gc during "git push" on the
+   receiving end are now passed back to the sending end in such a way
+   that they are shown with "remote: " prefix to avoid confusing the
+   users.
+
+ * "git add -i/-p" learned to honor diff.compactionHeuristic
+   experimental knob, so that the user can work on the same hunk split
+   as "git diff" output.
+   (merge 46e3d17 jk/add-i-diff-compact-heuristics later to maint).
+
+ * "upload-pack" allows a custom "git pack-objects" replacement when
+   responding to "fetch/clone" via the uploadpack.packObjectsHook.
+   (merge 20b20a2 jk/upload-pack-hook later to maint).
+
+ * Teach format-patch and mailsplit (hence "am") how a line that
+   happens to begin with "From " in the e-mail message is quoted with
+   ">", so that these lines can be restored to their original shape.
+   (merge d9925d1 ew/mboxrd-format-am later to maint).
+
+ * "git repack" learned the "--keep-unreachable" option, which sends
+   loose unreachable objects to a pack instead of leaving them loose.
+   This helps heuristics based on the number of loose objects
+   (e.g. "gc --auto").
+   (merge e26a8c4 jk/repack-keep-unreachable later to maint).
+
+ * "log --graph --format=" learned that "%>|(N)" specifies the width
+   relative to the terminal's left edge, not relative to the area to
+   draw text that is to the right of the ancestry-graph section.  It
+   also now accepts negative N that means the column limit is relative
+   to the right border.
+   (merge 066790d nd/graph-width-padded later to maint).
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * "git fast-import" learned the same performance trick to avoid
+   creating too small a packfile as "git fetch" and "git push" have,
+   using *.unpackLimit configuration.
+
+ * When "git daemon" is run without --[init-]timeout specified, a
+   connection from a client that silently goes offline can hang around
+   for a long time, wasting resources.  The socket-level KEEPALIVE has
+   been enabled to allow the OS to notice such failed connections.
+   (merge a43b68a ew/daemon-socket-keepalive later to maint).
+
+ * "git upload-pack" command has been updated to use the parse-options
+   API.
+
+ * The "git apply" standalone program is being libified; this is the
+   first step to move many state variables into a structure that can
+   be explicitly (re)initialized to make the machinery callable more
+   than once.
+
+ * HTTP transport gained an option to produce more detailed debugging
+   trace.
+   (merge 73e57aa ep/http-curl-trace later to maint).
+
+ * Instead of taking advantage of a struct string_list that is
+   allocated with all NULs happens to be STRING_LIST_INIT_NODUP kind,
+   initialize them explicitly as such, to document their behaviour
+   better.
+   (merge 2721ce2 jk/string-list-static-init later to maint).
+
+ * HTTPd tests learned to show the server error log to help diagnosing
+   a failing tests.
+   (merge 44f243d nd/test-lib-httpd-show-error-log-in-verbose later to maint).
+
+ * The ownership rule for the piece of memory that hold references to
+   be fetched in "git fetch" was screwy, which has been cleaned up.
+   (merge b7410f6 km/fetch-do-not-free-remote-name later to maint).
+
+ * "git bisect" makes an internal call to "git diff-tree" when
+   bisection finds the culprit, but this call did not initialize the
+   data structure to pass to the diff-tree API correctly.
+   (merge 43ec550 jk/bisect-show-tree later to maint).
+
+ * Further preparatory clean-up for "worktree" feature continues.
+   (merge 0409e0b nd/worktree-cleanup-post-head-protection later to maint).
+
+ * Formats of the various data (and how to validate them) where we use
+   GPG signature have been documented.
+   (merge cc6ee97 mg/signature-doc later to maint).
+
+ * A new run-command API function pipe_command() is introduced to
+   sanely feed data to the standard input while capturing data from
+   the standard output and the standard error of an external process,
+   which is cumbersome to hand-roll correctly without deadlocking.
+
+   The codepath to sign data in a prepared buffer with GPG has been
+   updated to use this API to read from the status-fd to check for
+   errors (instead of relying on GPG's exit status).
+   (merge efee955 jk/gpg-interface-cleanup later to maint).
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v2.9
+----------------
+
+Unless otherwise noted, all the fixes since v2.8 in the maintenance
+track are contained in this release (see the maintenance releases'
+notes for details).
+
+ * The commands in `git log` family take %C(auto) in a custom format
+   string.  This unconditionally turned the color on, ignoring
+   --no-color or with --color=auto when the output is not connected to
+   a tty; this was corrected to make the format truly behave as
+   "auto".
+   (merge b15a3e0 et/pretty-format-c-auto later to maint).
+
+ * "git rev-list --count" whose walk-length is limited with "-n"
+   option did not work well with the counting optimized to look at the
+   bitmap index.
+   (merge fb85db8 jk/rev-list-count-with-bitmap later to maint).
+
+ * "git show -W" (extend hunks to cover the entire function, delimited
+   by lines that match the "funcname" pattern) used to show the entire
+   file when a change added an entire function at the end of the file,
+   which has been fixed.
+   (merge 6f8d9bc rs/xdiff-hunk-with-func-line later to maint).
+
+ * The documentation set has been updated so that literal commands,
+   configuration variables and environment variables are consistently
+   typeset in fixed-width font and bold in manpages.
+
+ * "git svn propset" subcommand that was added in 2.3 days is
+   documented now.
+
+ * The documentation tries to consistently spell "GPG"; when
+   referring to the specific program name, "gpg" is used.
+
+ * "git reflog" stopped upon seeing an entry that denotes a branch
+   creation event (aka "unborn"), which made it appear as if the
+   reflog was truncated.
+
+ * The git-prompt scriptlet (in contrib/) was not friendly with those
+   who uses "set -u", which has been fixed.
+
+ * compat/regex code did not cleanly compile.
+
+ * A codepath that used alloca(3) to place an unbounded amount of data
+   on the stack has been updated to avoid doing so.
+
+ * "git update-index --add --chmod=+x file" may be usable as an escape
+   hatch, but not a friendly thing to force for people who do need to
+   use it regularly.  "git add --chmod=+x file" can be used instead.
+
+ * Build improvements for gnome-keyring (in contrib/)
+
+ * "git status" used to say "working directory" when it meant "working
+   tree".
+
+ * Comments about misbehaving FreeBSD shells have been clarified with
+   the version number (9.x and before are broken, newer ones are OK).
+
+ * "git cherry-pick A" worked on an unborn branch, but "git
+   cherry-pick A..B" didn't.
+
+ * Fix an unintended regression in v2.9 that breaks "clone --depth"
+   that recurses down to submodules by forcing the submodules to also
+   be cloned shallowly, which many server instances that host upstream
+   of the submodules are not prepared for.
+   (merge 18a74a0 sb/clone-shallow-passthru later to maint).
+
+ * Fix unnecessarily waste in the idiomatic use of ': ${VAR=default}'
+   to set the default value, without enclosing it in double quotes.
+   (merge 01247e0 lc/shell-default-value-noexpand later to maint).
+
+ * Some platform-specific code had non-ANSI strict declarations of C
+   functions that do not take any parameters, which has been
+   corrected.
+   (merge 0767172 js/mingw-parameter-less-c-functions later to maint).
+
+ * The internal code used to show local timezone offset is not
+   prepared to handle timestamps beyond year 2100, and gave a
+   bogus offset value to the caller.  Use a more benign looking
+   +0000 instead and let "git log" going in such a case, instead
+   of aborting.
+   (merge bab7483 jk/tzoffset-fix later to maint).
+
+ * One among four invocations of readlink(1) in our test suite has
+   been rewritten so that the test can run on systems without the
+   command (others are in valgrind test framework and t9802).
+   (merge d2addc3 ak/t7800-wo-readlink later to maint).
+
+ * t/perf needs /usr/bin/time with GNU extension; the invocation of it
+   is updated to "gtime" on Darwin.
+   (merge e3efa94 js/perf-on-apple later to maint).
+
+ * A bug, which caused "git p4" while running under verbose mode to
+   report paths that are omitted due to branch prefix incorrectly, has
+   been fixed; the command said "Ignoring file outside of prefix" for
+   paths that are _inside_.
+   (merge 09667d0 ao/p4-has-branch-prefix-fix later to maint).
+
+ * Other minor clean-ups and documentation updates
+   (merge e51b0df pb/commit-editmsg-path later to maint).
+   (merge b333d0d jk/send-pack-stdio later to maint).
+   (merge fcf0fe9 lf/sideband-returns-void later to maint).
+   (merge 5819c2e sb/t5614-modernize later to maint).
+   (merge fe0537a cb/t7810-test-label-fix later to maint).
+   (merge 412b9a1 jc/t2300-setup later to maint).
index 6005548..f4e2552 100644 (file)
@@ -24,4 +24,46 @@ Fixes since v2.8.3
  * Many 'linkgit:<git documentation page>' references were broken,
    which are all fixed with this.
 
+ * "git describe --contains" often made a hard-to-justify choice of
+   tag to give name to a given commit, because it tried to come up
+   with a name with smallest number of hops from a tag, causing an old
+   commit whose close descendant that is recently tagged were not
+   described with respect to an old tag but with a newer tag.  It did
+   not help that its computation of "hop" count was further tweaked to
+   penalize being on a side branch of a merge.  The logic has been
+   updated to favor using the tag with the oldest tagger date, which
+   is a lot easier to explain to the end users: "We describe a commit
+   in terms of the (chronologically) oldest tag that contains the
+   commit."
+
+ * Running tests with '-x' option to trace the individual command
+   executions is a useful way to debug test scripts, but some tests
+   that capture the standard error stream and check what the command
+   said can be broken with the trace output mixed in.  When running
+   our tests under "bash", however, we can redirect the trace output
+   to another file descriptor to keep the standard error of programs
+   being tested intact.
+
+ * "http.cookieFile" configuration variable clearly wants a pathname,
+   but we forgot to treat it as such by e.g. applying tilde expansion.
+
+ * When de-initialising all submodules, "git submodule deinit" gave a
+   faulty recommendation to use "git submodule deinit .", which would
+   result in a strange error message in a pathological corner case.
+   This has been corrected to suggest "submodule deinit --all" instead.
+
+ * Many commands normalize command line arguments from NFD to NFC
+   variant of UTF-8 on OSX, but commands in the "diff" family did
+   not, causing "git diff $path" to complain that no such path is
+   known to Git.  They have been taught to do the normalization.
+
+ * A couple of bugs around core.autocrlf have been fixed.
+
+ * "git difftool" learned to handle unmerged paths correctly in
+   dir-diff mode.
+
+ * The "are we talking with TTY, doing an interactive session?"
+   detection has been updated to work better for "Git for Windows".
+
+
 Also contains other minor documentation updates and code clean-ups.
index a60e92e..b61d367 100644 (file)
@@ -1,12 +1,12 @@
 Git 2.9 Release Notes
 =====================
 
-Backward compatibility note
----------------------------
+Backward compatibility notes
+----------------------------
 
 The end-user facing Porcelain level commands in the "git diff" and
-"git log" by default enables the rename detection; you can still use
-"diff.renames" configuration variable to disable this.
+"git log" family by default enable the rename detection; you can still
+use "diff.renames" configuration variable to disable this.
 
 Merging two branches that have no common ancestor with "git merge" is
 by default forbidden now to prevent creating such an unusual merge by
@@ -30,8 +30,8 @@ UI, Workflows & Features
 
  * Comes with git-multimail 1.3.1 (in contrib/).
 
- * The end-user facing Porcelain level commands like "diff" and "log"
-   now enables the rename detection by default.
+ * The end-user facing commands like "git diff" and "git log"
+   now enable the rename detection by default.
 
  * The credential.helper configuration variable is cumulative and
    there is no good way to override it from the command line.  As
@@ -39,7 +39,7 @@ UI, Workflows & Features
    as the signal to clear the values specified in various files.
 
  * A new "interactive.diffFilter" configuration can be used to
-   customize the diff shown in "git add -i" session.
+   customize the diff shown in "git add -i" sessions.
 
  * "git p4" now allows P4 author names to be mapped to Git author
    names.
@@ -64,7 +64,7 @@ UI, Workflows & Features
    to be used in a rare event that merges histories of two projects
    that started their lives independently.
 
- * "git pull" has been taught to pass --allow-unrelated-histories
+ * "git pull" has been taught to pass the "--allow-unrelated-histories"
    option to underlying "git merge".
 
  * "git apply -v" learned to report paths in the patch that were
@@ -87,7 +87,7 @@ UI, Workflows & Features
 
  * When "git log" shows the log message indented by 4-spaces, the
    remainder of a line after a HT does not align in the way the author
-   originally intended.  The command now expands tabs by default in
+   originally intended.  The command now expands tabs by default to help
    such a case, and allows the users to override it with a new option,
    "--no-expand-tabs".
 
@@ -97,13 +97,12 @@ UI, Workflows & Features
  * "git rerere" can encounter two or more files with the same conflict
    signature that have to be resolved in different ways, but there was
    no way to record these separate resolutions.
-   (merge d9d501b068 jc/rerere-multi later to maint).
 
  * "git p4" learned to record P4 jobs in Git commit that imports from
    the history in Perforce.
 
  * "git describe --contains" often made a hard-to-justify choice of
-   tag to give name to a given commit, because it tried to come up
+   tag to name a given commit, because it tried to come up
    with a name with smallest number of hops from a tag, causing an old
    commit whose close descendant that is recently tagged were not
    described with respect to an old tag but with a newer tag.  It did
@@ -113,16 +112,17 @@ UI, Workflows & Features
    is a lot easier to explain to the end users: "We describe a commit
    in terms of the (chronologically) oldest tag that contains the
    commit."
-   (merge 7550424 js/name-rev-use-oldest-ref later to maint).
 
- * "git clone" learned "--shallow-submodules" option.
+ * "git clone" learned the "--shallow-submodules" option.
 
  * HTTP transport clients learned to throw extra HTTP headers at the
    server, specified via http.extraHeader configuration variable.
 
- * Patch output from "git diff" and friends has been tweaked to be
-   more readable by using a blank line as a strong hint that the
-   contents before and after it belong to a logically separate unit.
+ * The "--compaction-heuristic" option to "git diff" family of
+   commands enables a heuristic to make the patch output more readable
+   by using a blank line as a strong hint that the contents before and
+   after it belong to logically separate units.  It is still
+   experimental.
 
  * A new configuration variable core.hooksPath allows customizing
    where the hook directory is.
@@ -147,9 +147,20 @@ UI, Workflows & Features
    (public, well-known) commit the original series was built on in
    its output.
 
- * "git commit" learned to pay attention to "commit.verbose"
-   configuration variable and act as if "--verbose" option was
-   given from the command line.
+ * "git commit" learned to pay attention to the "commit.verbose"
+   configuration variable and act as if the "--verbose" option
+   was given from the command line.
+
+ * Updated documentation gives hints to GMail users with two-factor
+   auth enabled that they need app-specific-password when using
+   "git send-email".
+
+ * The manpage output of our documentation did not render well in
+   terminal; typeset literals in bold by default to make them stand
+   out more.
+
+ * The mark-up in the top-level README.md file has been updated to
+   typeset CLI command names differently from the body text.
 
 
 Performance, Internal Implementation, Development Support etc.
@@ -171,7 +182,8 @@ Performance, Internal Implementation, Development Support etc.
 
  * A major part of "git submodule update" has been ported to C to take
    advantage of the recently added framework to run download tasks in
-   parallel.
+   parallel.  Other updates to "git submodule" that move pieces of
+   logic to C continues.
 
  * Rename bunch of tests on "git clone" for better organization.
 
@@ -185,16 +197,15 @@ Performance, Internal Implementation, Development Support etc.
    do not attempt to look into refs/* when we know we do not have a
    Git repository.
 
- * Code restructuring around the "refs" area to prepare for pluggable
+ * Code restructuring around the "refs" API to prepare for pluggable
    refs backends.
 
- * Sources to many test helper binaries (and the generated helpers)
+ * Sources to many test helper binaries and the generated helpers
    have been moved to t/helper/ subdirectory to reduce clutter at the
    top level of the tree.
 
  * Unify internal logic between "git tag -v" and "git verify-tag"
    commands by making one directly call into the other.
-   (merge bef234b st/verify-tag later to maint).
 
  * "merge-recursive" strategy incorrectly checked if a path that is
    involved in its internal merge exists in the working tree.
@@ -206,9 +217,7 @@ Performance, Internal Implementation, Development Support etc.
  * As nobody maintains our in-tree git.spec.in and distros use their
    own spec file, we stopped pretending that we support "make rpm".
 
- * Move from unsigned char[20] to struct object_id continues.
-
- * Update of "git submodule" to move pieces of logic to C continues.
+ * Move from "unsigned char[20]" to "struct object_id" continues.
 
  * The code for warning_errno/die_errno has been refactored and a new
    error_errno() reporting helper is introduced.
@@ -221,24 +230,40 @@ Performance, Internal Implementation, Development Support etc.
    our tests under "bash", however, we can redirect the trace output
    to another file descriptor to keep the standard error of programs
    being tested intact.
-   (merge d88785e jk/test-send-sh-x-trace-elsewhere later to maint).
 
  * t0040 had too many unnecessary repetitions in its test data.  Teach
    test-parse-options program so that a caller can tell what it
    expects in its output, so that these repetitions can be cleaned up.
 
- * Add perf test for "rebase -i"
+ * Add perf test for "rebase -i".
 
  * Common mistakes when writing gitlink: in our documentation are
    found by "make check-docs".
 
  * t9xxx series has been updated primarily for readability, while
-   fixing small bugs in it.  A few scripted Porcelains have also been
-   updated to fix possible bugs around their use of "test -z" and
-   "test -n".
+   fixing small bugs in it.  A few scripted Porcelain commands have
+   also been updated to fix possible bugs around their use of
+   "test -z" and "test -n".
 
  * CI test was taught to run git-svn tests.
 
+ * "git cat-file --batch-all" has been sped up, by taking advantage
+   of the fact that it does not have to read a list of objects, in two
+   ways.
+
+ * test updates to make it more readable and maintainable.
+   (merge e6273f4 es/t1500-modernize later to maint).
+
+ * "make DEVELOPER=1" worked as expected; setting DEVELOPER=1 in
+   config.mak didn't.
+   (merge 51dd3e8 mm/makefile-developer-can-be-in-config-mak later to maint).
+
+ * The way how "submodule--helper list" signals unmatch error to its
+   callers has been updated.
+
+ * A bash-ism "local" has been removed from "git submodule" scripted
+   Porcelain.
+
 
 Also contains various documentation updates and code clean-ups.
 
@@ -326,11 +351,11 @@ notes for details).
  * Support for CRAM-MD5 authentication method in "git imap-send" did
    not work well.
 
- * Upcoming OpenSSL 1.1.0 will break compilation b updating a few APIs
-   we use in imap-send, which has been adjusted for the change.
+ * Upcoming OpenSSL 1.1.0 will break compilation by updating a few API
+   elements we use in imap-send, which has been adjusted for the change.
 
  * The socks5:// proxy support added back in 2.6.4 days was not aware
-   that socks5h:// proxies behave differently.
+   that socks5h:// proxies behave differently from socks5:// proxies.
 
  * "git config" had a codepath that tried to pass a NULL to
    printf("%s"), which nobody seems to have noticed.
@@ -351,12 +376,12 @@ notes for details).
  * When "git merge" notices that the merge can be resolved purely at
    the tree level (without having to merge blobs) and the resulting
    tree happens to already exist in the object store, it forgot to
-   update the index, which lead to an inconsistent state for later
-   operations.
+   update the index, which left an inconsistent state that would
+   break later operations.
 
  * "git submodule" reports the paths of submodules the command
-   recurses into, but this was incorrect when the command was not run
-   from the root level of the superproject.
+   recurses into, but these paths were incorrectly reported when
+   the command was not run from the root level of the superproject.
 
  * The "user.useConfigOnly" configuration variable makes it an error
    if users do not explicitly set user.name and user.email.  However,
@@ -388,7 +413,6 @@ notes for details).
  * "git rebase -m" could be asked to rebase an entire branch starting
    from the root, but failed by assuming that there always is a parent
    commit to the first commit on the branch.
-   (merge 79f4344 bw/rebase-merge-entire-branch later to maint).
 
  * Fix a broken "p4 lfs" test.
 
@@ -414,24 +438,19 @@ notes for details).
    the configuration variable.  This will stop requiring the users to
    sign commit objects used internally as an implementation detail of
    "git stash".
-   (merge 6694856 jc/commit-tree-ignore-commit-gpgsign later to maint).
 
  * "http.cookieFile" configuration variable clearly wants a pathname,
    but we forgot to treat it as such by e.g. applying tilde expansion.
-   (merge e5a39ad bn/http-cookiefile-config later to maint).
 
  * Consolidate description of tilde-expansion that is done to
    configuration variables that take pathname to a single place.
-   (merge dca83ab jc/config-pathname-type later to maint).
 
  * Correct faulty recommendation to use "git submodule deinit ." when
    de-initialising all submodules, which would result in a strange
    error message in a pathological corner case.
-   (merge f6a5279 sb/submodule-deinit-all later to maint).
 
  * Many 'linkgit:<git documentation page>' references were broken,
    which are all fixed with this.
-   (merge 1cca17d jc/linkgit-fix later to maint).
 
  * "git rerere" can get confused by conflict markers deliberately left
    by the inner merge step, because they are indistinguishable from
@@ -441,48 +460,53 @@ notes for details).
    (merge 0f9fd5c jc/ll-merge-internal later to maint).
 
  * CI test was taught to build documentation pages.
-   (merge b98712b ls/travis-build-doc later to maint).
 
  * "git fsck" learned to catch NUL byte in a commit object as
    potential error and warn.
-   (merge 6d2d780 jc/fsck-nul-in-commit later to maint).
 
  * Portability enhancement for "rebase -i" to help platforms whose
    shell does not like "for i in <empty>" (which is not POSIX-kosher).
-   (merge 8e98b35 jk/rebase-interative-eval-fix later to maint).
 
  * On Windows, .git and optionally any files whose name starts with a
    dot are now marked as hidden, with a core.hideDotFiles knob to
    customize this behaviour.
-   (merge ebf31e7 js/windows-dotgit later to maint).
 
  * Documentation for "git merge --verify-signatures" has been updated
    to clarify that the signature of only the commit at the tip is
    verified.  Also the phrasing used for signature and key validity is
    adjusted to align with that used by OpenPGP.
-   (merge 05a5869 kf/gpg-sig-verification-doc later to maint).
 
  * A couple of bugs around core.autocrlf have been fixed.
-   (merge caa47ad tb/core-eol-fix later to maint).
 
  * Many commands normalize command line arguments from NFD to NFC
    variant of UTF-8 on OSX, but commands in the "diff" family did
    not, causing "git diff $path" to complain that no such path is
    known to Git.  They have been taught to do the normalization.
-   (merge 90a78b8 ar/diff-args-osx-precompose later to maint).
 
  * "git difftool" learned to handle unmerged paths correctly in
    dir-diff mode.
-   (merge 366f9ce da/difftool later to maint).
+
+ * The "are we talking with TTY, doing an interactive session?"
+   detection has been updated to work better for "Git for Windows".
+
+ * We forgot to add "git log --decorate=auto" to documentation when we
+   added the feature back in v2.1.0 timeframe.
+   (merge 462cbb4 rj/log-decorate-auto later to maint).
+
+ * "git fast-import --export-marks" would overwrite the existing marks
+   file even when it makes a dump from its custom die routine.
+   Prevent it from doing so when we have an import-marks file but
+   haven't finished reading it.
+   (merge f4beed6 fc/fast-import-broken-marks-file later to maint).
+
+ * "git rebase -i", after it fails to auto-resolve the conflict, had
+   an unnecessary call to "git rerere" from its very early days, which
+   was spotted recently; the call has been removed.
+   (merge 7063693 js/rebase-i-dedup-call-to-rerere later to maint).
 
  * Other minor clean-ups and documentation updates
-   (merge 832c0e5 lp/typofixes later to maint).
-   (merge f5ee54a sb/z-is-gnutar-ism later to maint).
-   (merge 2e3926b va/i18n-misc-updates later to maint).
-   (merge f212dcc bn/config-doc-tt-varnames later to maint).
-   (merge f54bea4 nd/remote-plural-ours-plus-theirs later to maint).
-   (merge 2bb0518 ak/t4151-ls-files-could-be-empty later to maint).
-   (merge 4df4313 jc/test-seq later to maint).
-   (merge a75a308 tb/t5601-sed-fix later to maint).
-   (merge 6c1fbe1 va/i18n-remote-comment-to-align later to maint).
-   (merge dee2303 va/mailinfo-doc-typofix later to maint).
+   (merge cd82b7a pa/cherry-pick-doc-typo later to maint).
+   (merge 2bb73ae rs/patch-id-use-skip-prefix later to maint).
+   (merge aa20cbc rs/apply-name-terminate later to maint).
+   (merge fe17fc0 jc/t2300-setup later to maint).
+   (merge e256eec jk/shell-portability later to maint).
diff --git a/Documentation/RelNotes/2.9.1.txt b/Documentation/RelNotes/2.9.1.txt
new file mode 100644 (file)
index 0000000..369383b
--- /dev/null
@@ -0,0 +1,62 @@
+Git v2.9.1 Release Notes
+========================
+
+Fixes since v2.9
+----------------
+
+ * When "git daemon" is run without --[init-]timeout specified, a
+   connection from a client that silently goes offline can hang around
+   for a long time, wasting resources.  The socket-level KEEPALIVE has
+   been enabled to allow the OS to notice such failed connections.
+
+ * The commands in `git log` family take %C(auto) in a custom format
+   string.  This unconditionally turned the color on, ignoring
+   --no-color or with --color=auto when the output is not connected to
+   a tty; this was corrected to make the format truly behave as
+   "auto".
+
+ * "git rev-list --count" whose walk-length is limited with "-n"
+   option did not work well with the counting optimized to look at the
+   bitmap index.
+
+ * "git show -W" (extend hunks to cover the entire function, delimited
+   by lines that match the "funcname" pattern) used to show the entire
+   file when a change added an entire function at the end of the file,
+   which has been fixed.
+
+ * The documentation set has been updated so that literal commands,
+   configuration variables and environment variables are consistently
+   typeset in fixed-width font and bold in manpages.
+
+ * "git svn propset" subcommand that was added in 2.3 days is
+   documented now.
+
+ * The documentation tries to consistently spell "GPG"; when
+   referring to the specific program name, "gpg" is used.
+
+ * "git reflog" stopped upon seeing an entry that denotes a branch
+   creation event (aka "unborn"), which made it appear as if the
+   reflog was truncated.
+
+ * The git-prompt scriptlet (in contrib/) was not friendly with those
+   who uses "set -u", which has been fixed.
+
+ * A codepath that used alloca(3) to place an unbounded amount of data
+   on the stack has been updated to avoid doing so.
+
+ * "git update-index --add --chmod=+x file" may be usable as an escape
+   hatch, but not a friendly thing to force for people who do need to
+   use it regularly.  "git add --chmod=+x file" can be used instead.
+
+ * Build improvements for gnome-keyring (in contrib/)
+
+ * "git status" used to say "working directory" when it meant "working
+   tree".
+
+ * Comments about misbehaving FreeBSD shells have been clarified with
+   the version number (9.x and before are broken, newer ones are OK).
+
+ * "git cherry-pick A" worked on an unborn branch, but "git
+   cherry-pick A..B" didn't.
+
+Also contains minor documentation updates and code clean-ups.
index 53f00db..e208af1 100644 (file)
@@ -434,7 +434,7 @@ core.gitProxy::
        may be set multiple times and is matched in the given order;
        the first match wins.
 +
-Can be overridden by the 'GIT_PROXY_COMMAND' environment variable
+Can be overridden by the `GIT_PROXY_COMMAND` environment variable
 (which always applies universally, without the special "for"
 handling).
 +
@@ -478,9 +478,9 @@ false), while all other repositories are assumed to be bare (bare
 
 core.worktree::
        Set the path to the root of the working tree.
-       If GIT_COMMON_DIR environment variable is set, core.worktree
+       If `GIT_COMMON_DIR` environment variable is set, core.worktree
        is ignored and not used for determining the root of working tree.
-       This can be overridden by the GIT_WORK_TREE environment
+       This can be overridden by the `GIT_WORK_TREE` environment
        variable and the '--work-tree' command-line option.
        The value can be an absolute path or relative to the path to
        the .git directory, which is either specified by --git-dir
@@ -545,7 +545,7 @@ core.compression::
        -1 is the zlib default. 0 means no compression,
        and 1..9 are various speed/size tradeoffs, 9 being slowest.
        If set, this provides a default to other compression variables,
-       such as 'core.looseCompression' and 'pack.compression'.
+       such as `core.looseCompression` and `pack.compression`.
 
 core.looseCompression::
        An integer -1..9, indicating the compression level for objects that
@@ -619,9 +619,9 @@ core.excludesFile::
 core.askPass::
        Some commands (e.g. svn and http interfaces) that interactively
        ask for a password can be told to use an external program given
-       via the value of this variable. Can be overridden by the 'GIT_ASKPASS'
+       via the value of this variable. Can be overridden by the `GIT_ASKPASS`
        environment variable. If not set, fall back to the value of the
-       'SSH_ASKPASS' environment variable or, failing that, a simple password
+       `SSH_ASKPASS` environment variable or, failing that, a simple password
        prompt. The external program shall be given a suitable prompt as
        command-line argument and write the password on its STDOUT.
 
@@ -764,7 +764,7 @@ core.notesRef::
        notes should be printed.
 +
 This setting defaults to "refs/notes/commits", and it can be overridden by
-the 'GIT_NOTES_REF' environment variable.  See linkgit:git-notes[1].
+the `GIT_NOTES_REF` environment variable.  See linkgit:git-notes[1].
 
 core.sparseCheckout::
        Enable "sparse checkout" feature. See section "Sparse checkout" in
@@ -800,7 +800,7 @@ it will be treated as a shell command.  For example, defining
 "gitk --all --not ORIG_HEAD".  Note that shell commands will be
 executed from the top-level directory of a repository, which may
 not necessarily be the current directory.
-'GIT_PREFIX' is set as returned by running 'git rev-parse --show-prefix'
+`GIT_PREFIX` is set as returned by running 'git rev-parse --show-prefix'
 from the original current directory. See linkgit:git-rev-parse[1].
 
 am.keepcr::
@@ -1189,6 +1189,15 @@ difftool.<tool>.cmd::
 difftool.prompt::
        Prompt before each invocation of the diff tool.
 
+fastimport.unpackLimit::
+       If the number of objects imported by linkgit:git-fast-import[1]
+       is below this limit, then the objects will be unpacked into
+       loose object files.  However if the number of imported objects
+       equals or exceeds this limit then the pack will be stored as a
+       pack.  Storing the pack from a fast-import can make the import
+       operation complete faster, especially on slow filesystems.  If
+       not set, the value of `transfer.unpackLimit` is used instead.
+
 fetch.recurseSubmodules::
        This option can be either set to a boolean value or to 'on-demand'.
        Setting it to a boolean changes the behavior of fetch and pull to
@@ -1426,18 +1435,18 @@ gitcvs.usecrlfattr::
        treat it as text. If they suppress text conversion, the file
        will be set with '-kb' mode, which suppresses any newline munging
        the client might otherwise do. If the attributes do not allow
-       the file type to be determined, then 'gitcvs.allBinary' is
+       the file type to be determined, then `gitcvs.allBinary` is
        used. See linkgit:gitattributes[5].
 
 gitcvs.allBinary::
-       This is used if 'gitcvs.usecrlfattr' does not resolve
+       This is used if `gitcvs.usecrlfattr` does not resolve
        the correct '-kb' mode to use. If true, all
        unresolved files are sent to the client in
        mode '-kb'. This causes the client to treat them
        as binary files, which suppresses any newline munging it
        otherwise might do. Alternatively, if it is set to "guess",
        then the contents of the file are examined to decide if
-       it is binary, similar to 'core.autocrlf'.
+       it is binary, similar to `core.autocrlf`.
 
 gitcvs.dbName::
        Database used by git-cvsserver to cache revision information
@@ -1456,7 +1465,7 @@ gitcvs.dbDriver::
        See linkgit:git-cvsserver[1].
 
 gitcvs.dbUser, gitcvs.dbPass::
-       Database user and password. Only useful if setting 'gitcvs.dbDriver',
+       Database user and password. Only useful if setting `gitcvs.dbDriver`,
        since SQLite has no concept of database users and/or passwords.
        'gitcvs.dbUser' supports variable substitution (see
        linkgit:git-cvsserver[1] for details).
@@ -1468,8 +1477,8 @@ gitcvs.dbTableNamePrefix::
        linkgit:git-cvsserver[1] for details).  Any non-alphabetic
        characters will be replaced with underscores.
 
-All gitcvs variables except for 'gitcvs.usecrlfattr' and
-'gitcvs.allBinary' can also be specified as
+All gitcvs variables except for `gitcvs.usecrlfattr` and
+`gitcvs.allBinary` can also be specified as
 'gitcvs.<access_method>.<varname>' (where 'access_method'
 is one of "ext" and "pserver") to make them apply only for the given
 access method.
@@ -1502,7 +1511,7 @@ grep.patternType::
 
 grep.extendedRegexp::
        If set to true, enable '--extended-regexp' option by default. This
-       option is ignored when the 'grep.patternType' option is set to a value
+       option is ignored when the `grep.patternType` option is set to a value
        other than 'default'.
 
 grep.threads::
@@ -1587,7 +1596,7 @@ guitool.<name>.cmd::
        of the linkgit:git-gui[1] `Tools` menu is invoked. This option is
        mandatory for every tool. The command is executed from the root of
        the working directory, and in the environment it receives the name of
-       the tool as 'GIT_GUITOOL', the name of the currently selected file as
+       the tool as `GIT_GUITOOL`, the name of the currently selected file as
        'FILENAME', and the name of the current branch as 'CUR_BRANCH' (if
        the head is detached, 'CUR_BRANCH' is empty).
 
@@ -1608,7 +1617,7 @@ guitool.<name>.confirm::
 
 guitool.<name>.argPrompt::
        Request a string argument from the user, and pass it to the tool
-       through the 'ARGS' environment variable. Since requesting an
+       through the `ARGS` environment variable. Since requesting an
        argument implies confirmation, the 'confirm' option has no effect
        if this is enabled. If the option is set to 'true', 'yes', or '1',
        the dialog uses a built-in generic prompt; otherwise the exact
@@ -1616,7 +1625,7 @@ guitool.<name>.argPrompt::
 
 guitool.<name>.revPrompt::
        Request a single valid revision from the user, and set the
-       'REVISION' environment variable. In other aspects this option
+       `REVISION` environment variable. In other aspects this option
        is similar to 'argPrompt', and can be used together with it.
 
 guitool.<name>.revUnmerged::
@@ -1672,7 +1681,7 @@ http.proxyAuthMethod::
        only takes effect if the configured proxy string contains a user name part
        (i.e. is of the form 'user@host' or 'user@host:port'). This can be
        overridden on a per-remote basis; see `remote.<name>.proxyAuthMethod`.
-       Both can be overridden by the 'GIT_HTTP_PROXY_AUTHMETHOD' environment
+       Both can be overridden by the `GIT_HTTP_PROXY_AUTHMETHOD` environment
        variable.  Possible values are:
 +
 --
@@ -1731,9 +1740,9 @@ http.sslVersion::
        - tlsv1.2
 
 +
-Can be overridden by the 'GIT_SSL_VERSION' environment variable.
+Can be overridden by the `GIT_SSL_VERSION` environment variable.
 To force git to use libcurl's default ssl version and ignore any
-explicit http.sslversion option, set 'GIT_SSL_VERSION' to the
+explicit http.sslversion option, set `GIT_SSL_VERSION` to the
 empty string.
 
 http.sslCipherList::
@@ -1744,41 +1753,41 @@ http.sslCipherList::
   option; see the libcurl documentation for more details on the format
   of this list.
 +
-Can be overridden by the 'GIT_SSL_CIPHER_LIST' environment variable.
+Can be overridden by the `GIT_SSL_CIPHER_LIST` environment variable.
 To force git to use libcurl's default cipher list and ignore any
-explicit http.sslCipherList option, set 'GIT_SSL_CIPHER_LIST' to the
+explicit http.sslCipherList option, set `GIT_SSL_CIPHER_LIST` to the
 empty string.
 
 http.sslVerify::
        Whether to verify the SSL certificate when fetching or pushing
-       over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
+       over HTTPS. Can be overridden by the `GIT_SSL_NO_VERIFY` environment
        variable.
 
 http.sslCert::
        File containing the SSL certificate when fetching or pushing
-       over HTTPS. Can be overridden by the 'GIT_SSL_CERT' environment
+       over HTTPS. Can be overridden by the `GIT_SSL_CERT` environment
        variable.
 
 http.sslKey::
        File containing the SSL private key when fetching or pushing
-       over HTTPS. Can be overridden by the 'GIT_SSL_KEY' environment
+       over HTTPS. Can be overridden by the `GIT_SSL_KEY` environment
        variable.
 
 http.sslCertPasswordProtected::
        Enable Git's password prompt for the SSL certificate.  Otherwise
        OpenSSL will prompt the user, possibly many times, if the
        certificate or private key is encrypted.  Can be overridden by the
-       'GIT_SSL_CERT_PASSWORD_PROTECTED' environment variable.
+       `GIT_SSL_CERT_PASSWORD_PROTECTED` environment variable.
 
 http.sslCAInfo::
        File containing the certificates to verify the peer with when
        fetching or pushing over HTTPS. Can be overridden by the
-       'GIT_SSL_CAINFO' environment variable.
+       `GIT_SSL_CAINFO` environment variable.
 
 http.sslCAPath::
        Path containing files with the CA certificates to verify the peer
        with when fetching or pushing over HTTPS. Can be overridden
-       by the 'GIT_SSL_CAPATH' environment variable.
+       by the `GIT_SSL_CAPATH` environment variable.
 
 http.pinnedpubkey::
        Public key of the https service. It may either be the filename of
@@ -1798,7 +1807,7 @@ http.sslTry::
 
 http.maxRequests::
        How many HTTP requests to launch in parallel. Can be overridden
-       by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5.
+       by the `GIT_HTTP_MAX_REQUESTS` environment variable. Default is 5.
 
 http.minSessions::
        The number of curl sessions (counted across slots) to be kept across
@@ -1817,13 +1826,13 @@ http.postBuffer::
 http.lowSpeedLimit, http.lowSpeedTime::
        If the HTTP transfer speed is less than 'http.lowSpeedLimit'
        for longer than 'http.lowSpeedTime' seconds, the transfer is aborted.
-       Can be overridden by the 'GIT_HTTP_LOW_SPEED_LIMIT' and
-       'GIT_HTTP_LOW_SPEED_TIME' environment variables.
+       Can be overridden by the `GIT_HTTP_LOW_SPEED_LIMIT` and
+       `GIT_HTTP_LOW_SPEED_TIME` environment variables.
 
 http.noEPSV::
        A boolean which disables using of EPSV ftp command by curl.
        This can helpful with some "poor" ftp servers which don't
-       support EPSV mode. Can be overridden by the 'GIT_CURL_FTP_NO_EPSV'
+       support EPSV mode. Can be overridden by the `GIT_CURL_FTP_NO_EPSV`
        environment variable. Default is false (curl will use EPSV).
 
 http.userAgent::
@@ -1833,7 +1842,7 @@ http.userAgent::
        such as Mozilla/4.0.  This may be necessary, for instance, if
        connecting through a firewall that restricts HTTP connections to a set
        of common USER_AGENT strings (but not including those like git/1.7.1).
-       Can be overridden by the 'GIT_HTTP_USER_AGENT' environment variable.
+       Can be overridden by the `GIT_HTTP_USER_AGENT` environment variable.
 
 http.<url>.*::
        Any of the http.* options above can be applied selectively to some URLs.
@@ -1956,7 +1965,10 @@ log.decorate::
        command. If 'short' is specified, the ref name prefixes 'refs/heads/',
        'refs/tags/' and 'refs/remotes/' will not be printed. If 'full' is
        specified, the full ref name (including prefix) will be printed.
-       This is the same as the log commands '--decorate' option.
+       If 'auto' is specified, then if the output is going to a terminal,
+       the ref names are shown as if 'short' were given, otherwise no ref
+       names are shown. This is the same as the '--decorate' option
+       of the `git log`.
 
 log.follow::
        If `true`, `git log` will act as if the `--follow` option was used when
@@ -2627,7 +2639,7 @@ sendemail.identity::
        A configuration identity. When given, causes values in the
        'sendemail.<identity>' subsection to take precedence over
        values in the 'sendemail' section. The default identity is
-       the value of 'sendemail.identity'.
+       the value of `sendemail.identity`.
 
 sendemail.smtpEncryption::
        See linkgit:git-send-email[1] for description.  Note that this
@@ -2644,7 +2656,7 @@ sendemail.<identity>.*::
        Identity-specific versions of the 'sendemail.*' parameters
        found below, taking precedence over those when the this
        identity is selected, through command-line or
-       'sendemail.identity'.
+       `sendemail.identity`.
 
 sendemail.aliasesFile::
 sendemail.aliasFileType::
@@ -2674,7 +2686,7 @@ sendemail.xmailer::
        See linkgit:git-send-email[1] for description.
 
 sendemail.signedoffcc (deprecated)::
-       Deprecated alias for 'sendemail.signedoffbycc'.
+       Deprecated alias for `sendemail.signedoffbycc`.
 
 showbranch.default::
        The default set of branches for linkgit:git-show-branch[1].
@@ -2880,6 +2892,21 @@ uploadpack.keepAlive::
        `uploadpack.keepAlive` seconds. Setting this option to 0
        disables keepalive packets entirely. The default is 5 seconds.
 
+uploadpack.packObjectsHook::
+       If this option is set, when `upload-pack` would run
+       `git pack-objects` to create a packfile for a client, it will
+       run this shell command instead.  The `pack-objects` command and
+       arguments it _would_ have run (including the `git pack-objects`
+       at the beginning) are appended to the shell command. The stdin
+       and stdout of the hook are treated as if `pack-objects` itself
+       was run. I.e., `upload-pack` will feed input intended for
+       `pack-objects` to the hook, and expects a completed packfile on
+       stdout.
++
+Note that this configuration variable is ignored if it is seen in the
+repository-level config (this is a safety measure against fetching from
+untrusted repositories).
+
 url.<base>.insteadOf::
        Any URL that starts with this value will be rewritten to
        start, instead, with <base>. In cases where some site serves a
@@ -2906,17 +2933,17 @@ url.<base>.pushInsteadOf::
 
 user.email::
        Your email address to be recorded in any newly created commits.
-       Can be overridden by the 'GIT_AUTHOR_EMAIL', 'GIT_COMMITTER_EMAIL', and
-       'EMAIL' environment variables.  See linkgit:git-commit-tree[1].
+       Can be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and
+       `EMAIL` environment variables.  See linkgit:git-commit-tree[1].
 
 user.name::
        Your full name to be recorded in any newly created commits.
-       Can be overridden by the 'GIT_AUTHOR_NAME' and 'GIT_COMMITTER_NAME'
+       Can be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`
        environment variables.  See linkgit:git-commit-tree[1].
 
 user.useConfigOnly::
-       Instruct Git to avoid trying to guess defaults for 'user.email'
-       and 'user.name', and instead retrieve the values only from the
+       Instruct Git to avoid trying to guess defaults for `user.email`
+       and `user.name`, and instead retrieve the values only from the
        configuration. For example, if you have multiple email addresses
        and would like to use a different one for each repository, then
        with this configuration option set to `true` in the global config
index ccd1fc8..35e8da2 100644 (file)
@@ -1,7 +1,7 @@
 DATE FORMATS
 ------------
 
-The GIT_AUTHOR_DATE, GIT_COMMITTER_DATE environment variables
+The `GIT_AUTHOR_DATE`, `GIT_COMMITTER_DATE` environment variables
 ifdef::git-commit[]
 and the `--date` option
 endif::git-commit[]
index edba565..f1101c7 100644 (file)
@@ -75,7 +75,7 @@ diff.ignoreSubmodules::
        commands such as 'git diff-files'. 'git checkout' also honors
        this setting when reporting uncommitted changes. Setting it to
        'all' disables the submodule summary normally shown by 'git commit'
-       and 'git status' when 'status.submoduleSummary' is set unless it is
+       and 'git status' when `status.submoduleSummary` is set unless it is
        overridden by using the --ignore-submodules command-line option.
        The 'git submodule' commands are not affected by this setting.
 
@@ -170,6 +170,11 @@ diff.tool::
 
 include::mergetools-diff.txt[]
 
+diff.compactionHeuristic::
+       Set this option to `true` to enable an experimental heuristic that
+       shifts the hunk boundary in an attempt to make the resulting
+       patch easier to read.
+
 diff.algorithm::
        Choose a diff algorithm.  The variants are as follows:
 +
index bcf54da..c91afee 100644 (file)
@@ -6,7 +6,7 @@ with a '-p' option, "git diff" without the '--raw' option, or
 "git log" with the "-p" option, they
 do not produce the output described above; instead they produce a
 patch file.  You can customize the creation of such patches via the
-GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables.
+`GIT_EXTERNAL_DIFF` and the `GIT_DIFF_OPTS` environment variables.
 
 What the -p option produces is slightly different from the traditional
 diff format:
index 3cb3015..d9ae681 100644 (file)
@@ -63,6 +63,13 @@ ifndef::git-format-patch[]
        Synonym for `-p --raw`.
 endif::git-format-patch[]
 
+--compaction-heuristic::
+--no-compaction-heuristic::
+       These are to help debugging and tuning an experimental
+       heuristic (which is off by default) that shifts the hunk
+       boundary in an attempt to make the resulting patch easier
+       to read.
+
 --minimal::
        Spend extra time to make sure the smallest possible
        diff is produced.
index 036edfb..b05a834 100644 (file)
@@ -52,7 +52,7 @@ ifndef::git-pull[]
 
 -p::
 --prune::
-       After fetching, remove any remote-tracking references that no
+       Before fetching, remove any remote-tracking references that no
        longer exist on the remote.  Tags are not subject to pruning
        if they are fetched only because of the default tag
        auto-following or due to a --tags option.  However, if tags
index 13cdd7f..6348c29 100644 (file)
@@ -116,7 +116,8 @@ default.   You can use `--no-utf8` to override this.
        By default the command will try to detect the patch format
        automatically. This option allows the user to bypass the automatic
        detection and specify the patch format that the patch(es) should be
-       interpreted as. Valid formats are mbox, stgit, stgit-series and hg.
+       interpreted as. Valid formats are mbox, mboxrd,
+       stgit, stgit-series and hg.
 
 -i::
 --interactive::
index c06efbd..e015f5b 100644 (file)
@@ -366,7 +366,7 @@ skip" to do the same thing. (In fact the special exit code 125 makes
 
 Or if you want more control, you can inspect the current state using
 for example "git bisect visualize". It will launch gitk (or "git log"
-if the DISPLAY environment variable is not set) to help you find a
+if the `DISPLAY` environment variable is not set) to help you find a
 better bisection point.
 
 Either way, if you have a string of untestable commits, it might
index 7e79aae..d9f960b 100644 (file)
@@ -205,7 +205,7 @@ $ git bisect visualize
 
 `view` may also be used as a synonym for `visualize`.
 
-If the 'DISPLAY' environment variable is not set, 'git log' is used
+If the `DISPLAY` environment variable is not set, 'git log' is used
 instead.  You can also give command-line options such as `-p` and
 `--stat`.
 
index 6154e57..c104a59 100644 (file)
@@ -128,7 +128,7 @@ effect to your index in a row.
 
 --allow-empty-message::
        By default, cherry-picking a commit with an empty message will fail.
-       This option overrides that behaviour, allowing commits with empty
+       This option overrides that behavior, allowing commits with empty
        messages to be cherry picked.
 
 --keep-redundant-commits::
index 1b15cd7..ec41d3d 100644 (file)
@@ -191,9 +191,8 @@ objects from the source repository into a pack in the cloned repository.
        Create a 'shallow' clone with a history truncated to the
        specified number of commits. Implies `--single-branch` unless
        `--no-single-branch` is given to fetch the histories near the
-       tips of all branches. This implies `--shallow-submodules`. If
-       you want to have a shallow superproject clone, but full submodules,
-       also pass `--no-shallow-submodules`.
+       tips of all branches. If you want to clone submodules shallowly,
+       also pass `--shallow-submodules`.
 
 --[no-]single-branch::
        Clone only the history leading to the tip of a single branch,
index d474226..e704953 100644 (file)
@@ -201,7 +201,7 @@ default::
        Otherwise `whitespace`.
 --
 +
-The default can be changed by the 'commit.cleanup' configuration
+The default can be changed by the `commit.cleanup` configuration
 variable (see linkgit:git-config[1]).
 
 -e::
@@ -450,8 +450,8 @@ include::i18n.txt[]
 ENVIRONMENT AND CONFIGURATION VARIABLES
 ---------------------------------------
 The editor used to edit the commit log message will be chosen from the
-GIT_EDITOR environment variable, the core.editor configuration variable, the
-VISUAL environment variable, or the EDITOR environment variable (in that
+`GIT_EDITOR` environment variable, the core.editor configuration variable, the
+`VISUAL` environment variable, or the `EDITOR` environment variable (in that
 order).  See linkgit:git-var[1] for details.
 
 HOOKS
index 6843114..a89c304 100644 (file)
@@ -269,7 +269,7 @@ and '--unset'. *'git config' will only ever change one file at a time*.
 
 You can override these rules either by command-line options or by environment
 variables. The '--global' and the '--system' options will limit the file used
-to the global or system-wide file respectively. The GIT_CONFIG environment
+to the global or system-wide file respectively. The `GIT_CONFIG` environment
 variable has a similar effect, but you can specify any filename you want.
 
 
index a69b361..dc20275 100644 (file)
@@ -188,7 +188,7 @@ Git configuration files in that directory are readable by `<user>`.
        arguments. The external command can decide to decline the
        service by exiting with a non-zero status (or to allow it by
        exiting with a zero status).  It can also look at the $REMOTE_ADDR
-       and $REMOTE_PORT environment variables to learn about the
+       and `$REMOTE_PORT` environment variables to learn about the
        requestor when making this decision.
 +
 The external command can optionally write a single line to its
index 66910aa..644df99 100644 (file)
@@ -136,6 +136,8 @@ Performance and Compression Tuning
        Maximum size of each output packfile.
        The default is unlimited.
 
+fastimport.unpackLimit::
+       See linkgit:git-config[1]
 
 Performance
 -----------
index 003731f..bd560d3 100644 (file)
@@ -61,7 +61,7 @@ Filters
 The filters are applied in the order as listed below.  The <command>
 argument is always evaluated in the shell context using the 'eval' command
 (with the notable exception of the commit filter, for technical reasons).
-Prior to that, the $GIT_COMMIT environment variable will be set to contain
+Prior to that, the `$GIT_COMMIT` environment variable will be set to contain
 the id of the commit being rewritten.  Also, GIT_AUTHOR_NAME,
 GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL,
 and GIT_COMMITTER_DATE are taken from the current commit and exported to
index bdeecd5..9624c84 100644 (file)
@@ -58,7 +58,7 @@ output, unless the `--stdout` option is specified.
 
 If `-o` is specified, output files are created in <dir>.  Otherwise
 they are created in the current working directory. The default path
-can be set with the 'format.outputDirectory' configuration option.
+can be set with the `format.outputDirectory` configuration option.
 The `-o` option takes precedence over `format.outputDirectory`.
 To store patches in the current working directory even when
 `format.outputDirectory` points elsewhere, use `-o .`.
@@ -146,9 +146,9 @@ series, where the head is chosen from the cover letter, the
 `--in-reply-to`, and the first patch mail, in this order.  'deep'
 threading makes every mail a reply to the previous one.
 +
-The default is `--no-thread`, unless the 'format.thread' configuration
+The default is `--no-thread`, unless the `format.thread` configuration
 is set.  If `--thread` is specified without a style, it defaults to the
-style specified by 'format.thread' if any, or else `shallow`.
+style specified by `format.thread` if any, or else `shallow`.
 +
 Beware that the default for 'git send-email' is to thread emails
 itself.  If you want `git format-patch` to take care of threading, you
index fa15104..bed60f4 100644 (file)
@@ -82,13 +82,13 @@ automatic consolidation of packs.
 Configuration
 -------------
 
-The optional configuration variable 'gc.reflogExpire' can be
+The optional configuration variable `gc.reflogExpire` can be
 set to indicate how long historical entries within each branch's
 reflog should remain available in this repository.  The setting is
 expressed as a length of time, for example '90 days' or '3 months'.
 It defaults to '90 days'.
 
-The optional configuration variable 'gc.reflogExpireUnreachable'
+The optional configuration variable `gc.reflogExpireUnreachable`
 can be set to indicate how long historical reflog entries which
 are not part of the current branch should remain available in
 this repository.  These types of entries are generally created as
@@ -107,30 +107,30 @@ branches:
        reflogExpireUnreachable = 3 days
 ------------
 
-The optional configuration variable 'gc.rerereResolved' indicates
+The optional configuration variable `gc.rerereResolved` indicates
 how long records of conflicted merge you resolved earlier are
 kept.  This defaults to 60 days.
 
-The optional configuration variable 'gc.rerereUnresolved' indicates
+The optional configuration variable `gc.rerereUnresolved` indicates
 how long records of conflicted merge you have not resolved are
 kept.  This defaults to 15 days.
 
-The optional configuration variable 'gc.packRefs' determines if
+The optional configuration variable `gc.packRefs` determines if
 'git gc' runs 'git pack-refs'. This can be set to "notbare" to enable
 it within all non-bare repos or it can be set to a boolean value.
 This defaults to true.
 
-The optional configuration variable 'gc.aggressiveWindow' controls how
+The optional configuration variable `gc.aggressiveWindow` controls how
 much time is spent optimizing the delta compression of the objects in
 the repository when the --aggressive option is specified.  The larger
 the value, the more time is spent optimizing the delta compression.  See
 the documentation for the --window' option in linkgit:git-repack[1] for
 more details.  This defaults to 250.
 
-Similarly, the optional configuration variable 'gc.aggressiveDepth'
+Similarly, the optional configuration variable `gc.aggressiveDepth`
 controls --depth option in linkgit:git-repack[1]. This defaults to 250.
 
-The optional configuration variable 'gc.pruneExpire' controls how old
+The optional configuration variable `gc.pruneExpire` controls how old
 the unreferenced loose objects have to be before they are pruned.  The
 default is "2 weeks ago".
 
index cb0f6cf..40cfe37 100644 (file)
@@ -51,7 +51,7 @@ grep.patternType::
 
 grep.extendedRegexp::
        If set to true, enable '--extended-regexp' option by default. This
-       option is ignored when the 'grep.patternType' option is set to a value
+       option is ignored when the `grep.patternType` option is set to a value
        other than 'default'.
 
 grep.threads::
index 3956525..338b8d6 100644 (file)
@@ -57,10 +57,10 @@ OPTIONS
 --man::
        Display manual page for the command in the 'man' format. This
        option may be used to override a value set in the
-       'help.format' configuration variable.
+       `help.format` configuration variable.
 +
 By default the 'man' program will be used to display the manual page,
-but the 'man.viewer' configuration variable may be used to choose
+but the `man.viewer` configuration variable may be used to choose
 other display programs (see below).
 
 -w::
@@ -69,7 +69,7 @@ other display programs (see below).
        format. A web browser will be used for that purpose.
 +
 The web browser can be specified using the configuration variable
-'help.browser', or 'web.browser' if the former is not set. If none of
+`help.browser`, or `web.browser` if the former is not set. If none of
 these config variables is set, the 'git web{litdd}browse' helper script
 (called by 'git help') will pick a suitable default. See
 linkgit:git-web{litdd}browse[1] for more information about this.
@@ -80,7 +80,7 @@ CONFIGURATION VARIABLES
 help.format
 ~~~~~~~~~~~
 
-If no command-line option is passed, the 'help.format' configuration
+If no command-line option is passed, the `help.format` configuration
 variable will be checked. The following values are supported for this
 variable; they make 'git help' behave as their corresponding command-
 line option:
@@ -92,7 +92,7 @@ line option:
 help.browser, web.browser and browser.<tool>.path
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The 'help.browser', 'web.browser' and 'browser.<tool>.path' will also
+The `help.browser`, `web.browser` and `browser.<tool>.path` will also
 be checked if the 'web' format is chosen (either by command-line
 option or configuration variable). See '-w|--web' in the OPTIONS
 section above and linkgit:git-web{litdd}browse[1].
@@ -100,7 +100,7 @@ section above and linkgit:git-web{litdd}browse[1].
 man.viewer
 ~~~~~~~~~~
 
-The 'man.viewer' configuration variable will be checked if the 'man'
+The `man.viewer` configuration variable will be checked if the 'man'
 format is chosen. The following values are currently supported:
 
 * "man": use the 'man' program as usual,
@@ -110,9 +110,9 @@ format is chosen. The following values are currently supported:
 tab (see 'Note about konqueror' below).
 
 Values for other tools can be used if there is a corresponding
-'man.<tool>.cmd' configuration entry (see below).
+`man.<tool>.cmd` configuration entry (see below).
 
-Multiple values may be given to the 'man.viewer' configuration
+Multiple values may be given to the `man.viewer` configuration
 variable. Their corresponding programs will be tried in the order
 listed in the configuration file.
 
@@ -128,14 +128,14 @@ will try to use konqueror first. But this may fail (for example, if
 DISPLAY is not set) and in that case emacs' woman mode will be tried.
 
 If everything fails, or if no viewer is configured, the viewer specified
-in the GIT_MAN_VIEWER environment variable will be tried.  If that
+in the `GIT_MAN_VIEWER` environment variable will be tried.  If that
 fails too, the 'man' program will be tried anyway.
 
 man.<tool>.path
 ~~~~~~~~~~~~~~~
 
 You can explicitly provide a full path to your preferred man viewer by
-setting the configuration variable 'man.<tool>.path'. For example, you
+setting the configuration variable `man.<tool>.path`. For example, you
 can configure the absolute path to konqueror by setting
 'man.konqueror.path'. Otherwise, 'git help' assumes the tool is
 available in PATH.
@@ -143,9 +143,9 @@ available in PATH.
 man.<tool>.cmd
 ~~~~~~~~~~~~~~
 
-When the man viewer, specified by the 'man.viewer' configuration
+When the man viewer, specified by the `man.viewer` configuration
 variables, is not among the supported ones, then the corresponding
-'man.<tool>.cmd' configuration variable will be looked up. If this
+`man.<tool>.cmd` configuration variable will be looked up. If this
 variable exists then the specified tool will be treated as a custom
 command and a shell eval will be used to run the command with the man
 page passed as arguments.
@@ -153,7 +153,7 @@ page passed as arguments.
 Note about konqueror
 ~~~~~~~~~~~~~~~~~~~~
 
-When 'konqueror' is specified in the 'man.viewer' configuration
+When 'konqueror' is specified in the `man.viewer` configuration
 variable, we launch 'kfmclient' to try to open the man page on an
 already opened konqueror in a new tab if possible.
 
index 9268fb6..bb0db19 100644 (file)
@@ -21,7 +21,7 @@ pushing using the smart HTTP protocol.
 It verifies that the directory has the magic file
 "git-daemon-export-ok", and it will refuse to export any Git directory
 that hasn't explicitly been marked for export this way (unless the
-GIT_HTTP_EXPORT_ALL environmental variable is set).
+`GIT_HTTP_EXPORT_ALL` environmental variable is set).
 
 By default, only the `upload-pack` service is enabled, which serves
 'git fetch-pack' and 'git ls-remote' clients, which are invoked from
@@ -241,7 +241,7 @@ $HTTP["url"] =~ "^/git/private" {
 
 ENVIRONMENT
 -----------
-'git http-backend' relies upon the CGI environment variables set
+'git http-backend' relies upon the `CGI` environment variables set
 by the invoking web server, including:
 
 * PATH_INFO (if GIT_PROJECT_ROOT is set, otherwise PATH_TRANSLATED)
@@ -251,7 +251,7 @@ by the invoking web server, including:
 * QUERY_STRING
 * REQUEST_METHOD
 
-The GIT_HTTP_EXPORT_ALL environmental variable may be passed to
+The `GIT_HTTP_EXPORT_ALL` environmental variable may be passed to
 'git-http-backend' to bypass the check for the "git-daemon-export-ok"
 file in each repository before allowing export of that repository.
 
@@ -269,7 +269,7 @@ GIT_COMMITTER_EMAIL to '$\{REMOTE_USER}@http.$\{REMOTE_ADDR\}',
 ensuring that any reflogs created by 'git-receive-pack' contain some
 identifying information of the remote user who performed the push.
 
-All CGI environment variables are available to each of the hooks
+All `CGI` environment variables are available to each of the hooks
 invoked by the 'git-receive-pack'.
 
 GIT
index 6364e5d..9d27197 100644 (file)
@@ -47,7 +47,7 @@ Only print error and warning messages; all other output will be suppressed.
 
 --bare::
 
-Create a bare repository. If GIT_DIR environment is not set, it is set to the
+Create a bare repository. If `GIT_DIR` environment is not set, it is set to the
 current working directory.
 
 --template=<template_directory>::
index cc75b25..e8ecdbf 100644 (file)
@@ -80,8 +80,8 @@ You may specify configuration in your .git/config
 
 -----------------------------------------------------------------------
 
-If the configuration variable 'instaweb.browser' is not set,
-'web.browser' will be used instead if it is defined. See
+If the configuration variable `instaweb.browser` is not set,
+`web.browser` will be used instead if it is defined. See
 linkgit:git-web{litdd}browse[1] for more information about this.
 
 SEE ALSO
index 03f9580..4a6c47f 100644 (file)
@@ -29,12 +29,14 @@ OPTIONS
        (works only for a single file).
 
 --no-decorate::
---decorate[=short|full|no]::
+--decorate[=short|full|auto|no]::
        Print out the ref names of any commits that are shown. If 'short' is
        specified, the ref name prefixes 'refs/heads/', 'refs/tags/' and
        'refs/remotes/' will not be printed. If 'full' is specified, the
-       full ref name (including prefix) will be printed. The default option
-       is 'short'.
+       full ref name (including prefix) will be printed. If 'auto' is
+       specified, then if the output is going to a terminal, the ref names
+       are shown as if 'short' were given, otherwise no ref names are
+       shown. The default option is 'short'.
 
 --source::
        Print out the ref name given on the command line by which each
@@ -201,7 +203,7 @@ mailmap.*::
 
 notes.displayRef::
        Which refs, in addition to the default set by `core.notesRef`
-       or 'GIT_NOTES_REF', to read notes from when showing commit
+       or `GIT_NOTES_REF`, to read notes from when showing commit
        messages with the `log` family of commands.  See
        linkgit:git-notes[1].
 +
@@ -210,7 +212,7 @@ multiple times.  A warning will be issued for refs that do not exist,
 but a glob that does not match any refs is silently ignored.
 +
 This setting can be disabled by the `--no-notes` option,
-overridden by the 'GIT_NOTES_DISPLAY_REF' environment variable,
+overridden by the `GIT_NOTES_DISPLAY_REF` environment variable,
 and overridden by the `--notes=<ref>` option.
 
 GIT
index 4d1b871..e3b2a88 100644 (file)
@@ -8,7 +8,8 @@ git-mailsplit - Simple UNIX mbox splitter program
 SYNOPSIS
 --------
 [verse]
-'git mailsplit' [-b] [-f<nn>] [-d<prec>] [--keep-cr] -o<directory> [--] [(<mbox>|<Maildir>)...]
+'git mailsplit' [-b] [-f<nn>] [-d<prec>] [--keep-cr] [--mboxrd]
+               -o<directory> [--] [(<mbox>|<Maildir>)...]
 
 DESCRIPTION
 -----------
@@ -47,6 +48,10 @@ OPTIONS
 --keep-cr::
        Do not remove `\r` from lines ending with `\r\n`.
 
+--mboxrd::
+       Input is of the "mboxrd" format and "^>+From " line escaping is
+       reversed.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
index 9c4fd68..02a10bc 100644 (file)
@@ -161,7 +161,7 @@ OPTIONS
 
 --ref <ref>::
        Manipulate the notes tree in <ref>.  This overrides
-       'GIT_NOTES_REF' and the "core.notesRef" configuration.  The ref
+       `GIT_NOTES_REF` and the "core.notesRef" configuration.  The ref
        specifies the full refname when it begins with `refs/notes/`; when it
        begins with `notes/`, `refs/` and otherwise `refs/notes/` is prefixed
        to form a full name of the ref.
@@ -333,10 +333,10 @@ notes.<name>.mergeStrategy::
 notes.displayRef::
        Which ref (or refs, if a glob or specified more than once), in
        addition to the default set by `core.notesRef` or
-       'GIT_NOTES_REF', to read notes from when showing commit
+       `GIT_NOTES_REF`, to read notes from when showing commit
        messages with the 'git log' family of commands.
        This setting can be overridden on the command line or by the
-       'GIT_NOTES_DISPLAY_REF' environment variable.
+       `GIT_NOTES_DISPLAY_REF` environment variable.
        See linkgit:git-log[1].
 
 notes.rewrite.<command>::
@@ -345,7 +345,7 @@ notes.rewrite.<command>::
        notes from the original to the rewritten commit.  Defaults to
        `true`.  See also "`notes.rewriteRef`" below.
 +
-This setting can be overridden by the 'GIT_NOTES_REWRITE_REF'
+This setting can be overridden by the `GIT_NOTES_REWRITE_REF`
 environment variable.
 
 notes.rewriteMode::
@@ -366,33 +366,33 @@ notes.rewriteRef::
 Does not have a default value; you must configure this variable to
 enable note rewriting.
 +
-Can be overridden with the 'GIT_NOTES_REWRITE_REF' environment variable.
+Can be overridden with the `GIT_NOTES_REWRITE_REF` environment variable.
 
 
 ENVIRONMENT
 -----------
 
-'GIT_NOTES_REF'::
+`GIT_NOTES_REF`::
        Which ref to manipulate notes from, instead of `refs/notes/commits`.
        This overrides the `core.notesRef` setting.
 
-'GIT_NOTES_DISPLAY_REF'::
+`GIT_NOTES_DISPLAY_REF`::
        Colon-delimited list of refs or globs indicating which refs,
        in addition to the default from `core.notesRef` or
-       'GIT_NOTES_REF', to read notes from when showing commit
+       `GIT_NOTES_REF`, to read notes from when showing commit
        messages.
        This overrides the `notes.displayRef` setting.
 +
 A warning will be issued for refs that do not exist, but a glob that
 does not match any refs is silently ignored.
 
-'GIT_NOTES_REWRITE_MODE'::
+`GIT_NOTES_REWRITE_MODE`::
        When copying notes during a rewrite, what to do if the target
        commit already has a note.
        Must be one of `overwrite`, `concatenate`, `cat_sort_uniq`, or `ignore`.
        This overrides the `core.rewriteMode` setting.
 
-'GIT_NOTES_REWRITE_REF'::
+`GIT_NOTES_REWRITE_REF`::
        When rewriting commits, which notes to copy from the original
        to the rewritten commit.  Must be a colon-delimited list of
        refs or globs.
index 88ba42b..9d4f151 100644 (file)
@@ -134,7 +134,7 @@ Submit
 ~~~~~~
 Submitting changes from a Git repository back to the p4 repository
 requires a separate p4 client workspace.  This should be specified
-using the 'P4CLIENT' environment variable or the Git configuration
+using the `P4CLIENT` environment variable or the Git configuration
 variable 'git-p4.client'.  The p4 client must exist, but the client root
 will be created and populated if it does not already exist.
 
@@ -166,7 +166,7 @@ General options
 All commands except clone accept these options.
 
 --git-dir <dir>::
-       Set the 'GIT_DIR' environment variable.  See linkgit:git[1].
+       Set the `GIT_DIR` environment variable.  See linkgit:git[1].
 
 -v::
 --verbose::
index cf6ee4a..19f46b6 100644 (file)
@@ -137,8 +137,8 @@ already exists on the remote side.
        and also push annotated tags in `refs/tags` that are missing
        from the remote but are pointing at commit-ish that are
        reachable from the refs being pushed.  This can also be specified
-       with configuration variable 'push.followTags'.  For more
-       information, see 'push.followTags' in linkgit:git-config[1].
+       with configuration variable `push.followTags`.  For more
+       information, see `push.followTags` in linkgit:git-config[1].
 
 --[no-]signed::
 --sign=(true|false|if-asked)::
@@ -240,7 +240,7 @@ origin +master` to force a push to the `master` branch). See the
        For every branch that is up to date or successfully pushed, add
        upstream (tracking) reference, used by argument-less
        linkgit:git-pull[1] and other commands. For more information,
-       see 'branch.<name>.merge' in linkgit:git-config[1].
+       see `branch.<name>.merge` in linkgit:git-config[1].
 
 --[no-]thin::
        These options are passed to linkgit:git-send-pack[1]. A thin transfer
index ff633b0..8cf952b 100644 (file)
@@ -46,14 +46,14 @@ OPTIONS
        The directory to find the quilt patches.
 +
 The default for the patch directory is patches
-or the value of the $QUILT_PATCHES environment
+or the value of the `$QUILT_PATCHES` environment
 variable.
 
 --series <file>::
        The quilt series file.
 +
 The default for the series file is <patches>/series
-or the value of the $QUILT_SERIES environment
+or the value of the `$QUILT_SERIES` environment
 variable.
 
 GIT
index b9c02ce..b58b6b5 100644 (file)
@@ -128,6 +128,19 @@ other objects in that pack they already have locally.
        with `-b` or `repack.writeBitmaps`, as it ensures that the
        bitmapped packfile has the necessary objects.
 
+--unpack-unreachable=<when>::
+       When loosening unreachable objects, do not bother loosening any
+       objects older than `<when>`. This can be used to optimize out
+       the write of any objects that would be immediately pruned by
+       a follow-up `git prune`.
+
+-k::
+--keep-unreachable::
+       When used with `-ad`, any unreachable objects from existing
+       packs will be appended to the end of the packfile instead of
+       being removed. In addition, any unreachable loose objects will
+       be packed (and their loose counterparts removed).
+
 Configuration
 -------------
 
index 8fff598..e5c57ae 100644 (file)
@@ -51,7 +51,7 @@ $ git cat-file commit foo
 
 shows information about commit 'bar'.
 
-The 'GIT_NO_REPLACE_OBJECTS' environment variable can be set to
+The `GIT_NO_REPLACE_OBJECTS` environment variable can be set to
 achieve the same effect as the `--no-replace-objects` option.
 
 OPTIONS
index 771a7b5..d0b38b4 100644 (file)
@@ -47,18 +47,18 @@ Composing
 
 --annotate::
        Review and edit each patch you're about to send. Default is the value
-       of 'sendemail.annotate'. See the CONFIGURATION section for
-       'sendemail.multiEdit'.
+       of `sendemail.annotate`. See the CONFIGURATION section for
+       `sendemail.multiEdit`.
 
 --bcc=<address>,...::
        Specify a "Bcc:" value for each email. Default is the value of
-       'sendemail.bcc'.
+       `sendemail.bcc`.
 +
 This option may be specified multiple times.
 
 --cc=<address>,...::
        Specify a starting "Cc:" value for each email.
-       Default is the value of 'sendemail.cc'.
+       Default is the value of `sendemail.cc`.
 +
 This option may be specified multiple times.
 
@@ -74,12 +74,12 @@ and In-Reply-To headers will be used unless they are removed.
 +
 Missing From or In-Reply-To headers will be prompted for.
 +
-See the CONFIGURATION section for 'sendemail.multiEdit'.
+See the CONFIGURATION section for `sendemail.multiEdit`.
 
 --from=<address>::
        Specify the sender of the emails.  If not specified on the command line,
-       the value of the 'sendemail.from' configuration option is used.  If
-       neither the command-line option nor 'sendemail.from' are set, then the
+       the value of the `sendemail.from` configuration option is used.  If
+       neither the command-line option nor `sendemail.from` are set, then the
        user will be prompted for the value.  The default for the prompt will be
        the value of GIT_AUTHOR_IDENT, or GIT_COMMITTER_IDENT if that is not
        set, as returned by "git var -l".
@@ -114,7 +114,7 @@ is not set, this will be prompted for.
 --to=<address>,...::
        Specify the primary recipient of the emails generated. Generally, this
        will be the upstream maintainer of the project involved. Default is the
-       value of the 'sendemail.to' configuration value; if that is unspecified,
+       value of the `sendemail.to` configuration value; if that is unspecified,
        and --to-cmd is not specified, this will be prompted for.
 +
 This option may be specified multiple times.
@@ -138,7 +138,7 @@ Note that no attempts whatsoever are made to validate the encoding.
        can be useful when the repository contains files that contain carriage
        returns, but makes the raw patch email file (as saved from a MUA) much
        harder to inspect manually.  base64 is even more fool proof, but also
-       even more opaque.  Default is the value of the 'sendemail.transferEncoding'
+       even more opaque.  Default is the value of the `sendemail.transferEncoding`
        configuration value; if that is unspecified, git will use 8bit and not
        add a Content-Transfer-Encoding header.
 
@@ -157,20 +157,20 @@ Sending
        subscribed to a list. In order to use the 'From' address, set the
        value to "auto". If you use the sendmail binary, you must have
        suitable privileges for the -f parameter.  Default is the value of the
-       'sendemail.envelopeSender' configuration variable; if that is
+       `sendemail.envelopeSender` configuration variable; if that is
        unspecified, choosing the envelope sender is left to your MTA.
 
 --smtp-encryption=<encryption>::
        Specify the encryption to use, either 'ssl' or 'tls'.  Any other
        value reverts to plain SMTP.  Default is the value of
-       'sendemail.smtpEncryption'.
+       `sendemail.smtpEncryption`.
 
 --smtp-domain=<FQDN>::
        Specifies the Fully Qualified Domain Name (FQDN) used in the
        HELO/EHLO command to the SMTP server.  Some servers require the
        FQDN to match your IP address.  If not set, git send-email attempts
        to determine your FQDN automatically.  Default is the value of
-       'sendemail.smtpDomain'.
+       `sendemail.smtpDomain`.
 
 --smtp-auth=<mechanisms>::
        Whitespace-separated list of allowed SMTP-AUTH mechanisms. This setting
@@ -188,13 +188,13 @@ is specified, all mechanisms supported by the SASL library can be used.
 --smtp-pass[=<password>]::
        Password for SMTP-AUTH. The argument is optional: If no
        argument is specified, then the empty string is used as
-       the password. Default is the value of 'sendemail.smtpPass',
+       the password. Default is the value of `sendemail.smtpPass`,
        however '--smtp-pass' always overrides this value.
 +
 Furthermore, passwords need not be specified in configuration files
 or on the command line. If a username has been specified (with
-'--smtp-user' or a 'sendemail.smtpUser'), but no password has been
-specified (with '--smtp-pass' or 'sendemail.smtpPass'), then
+'--smtp-user' or a `sendemail.smtpUser`), but no password has been
+specified (with '--smtp-pass' or `sendemail.smtpPass`), then
 a password is obtained using 'git-credential'.
 
 --smtp-server=<host>::
@@ -202,7 +202,7 @@ a password is obtained using 'git-credential'.
        `smtp.example.com` or a raw IP address).  Alternatively it can
        specify a full pathname of a sendmail-like program instead;
        the program must support the `-i` option.  Default value can
-       be specified by the 'sendemail.smtpServer' configuration
+       be specified by the `sendemail.smtpServer` configuration
        option; the built-in default is `/usr/sbin/sendmail` or
        `/usr/lib/sendmail` if such program is available, or
        `localhost` otherwise.
@@ -213,11 +213,11 @@ a password is obtained using 'git-credential'.
        submission port 587, or the common SSL smtp port 465);
        symbolic port names (e.g. "submission" instead of 587)
        are also accepted. The port can also be set with the
-       'sendemail.smtpServerPort' configuration variable.
+       `sendemail.smtpServerPort` configuration variable.
 
 --smtp-server-option=<option>::
        If set, specifies the outgoing SMTP server option to use.
-       Default value can be specified by the 'sendemail.smtpServerOption'
+       Default value can be specified by the `sendemail.smtpServerOption`
        configuration option.
 +
 The --smtp-server-option option must be repeated for each option you want
@@ -234,13 +234,13 @@ must be used for each option.
        certificates concatenated together: see verify(1) -CAfile and
        -CApath for more information on these). Set it to an empty string
        to disable certificate verification. Defaults to the value of the
-       'sendemail.smtpsslcertpath' configuration variable, if set, or the
+       `sendemail.smtpsslcertpath` configuration variable, if set, or the
        backing SSL library's compiled-in default otherwise (which should
        be the best choice on most platforms).
 
 --smtp-user=<user>::
-       Username for SMTP-AUTH. Default is the value of 'sendemail.smtpUser';
-       if a username is not specified (with '--smtp-user' or 'sendemail.smtpUser'),
+       Username for SMTP-AUTH. Default is the value of `sendemail.smtpUser`;
+       if a username is not specified (with '--smtp-user' or `sendemail.smtpUser`),
        then authentication is not attempted.
 
 --smtp-debug=0|1::
@@ -261,25 +261,25 @@ Automating
        Specify a command to execute once per patch file which
        should generate patch file specific "Cc:" entries.
        Output of this command must be single email address per line.
-       Default is the value of 'sendemail.ccCmd' configuration value.
+       Default is the value of `sendemail.ccCmd` configuration value.
 
 --[no-]chain-reply-to::
        If this is set, each email will be sent as a reply to the previous
        email sent.  If disabled with "--no-chain-reply-to", all emails after
        the first will be sent as replies to the first email sent.  When using
        this, it is recommended that the first file given be an overview of the
-       entire patch series. Disabled by default, but the 'sendemail.chainReplyTo'
+       entire patch series. Disabled by default, but the `sendemail.chainReplyTo`
        configuration variable can be used to enable it.
 
 --identity=<identity>::
        A configuration identity. When given, causes values in the
        'sendemail.<identity>' subsection to take precedence over
        values in the 'sendemail' section. The default identity is
-       the value of 'sendemail.identity'.
+       the value of `sendemail.identity`.
 
 --[no-]signed-off-by-cc::
        If this is set, add emails found in Signed-off-by: or Cc: lines to the
-       cc list. Default is the value of 'sendemail.signedoffbycc' configuration
+       cc list. Default is the value of `sendemail.signedoffbycc` configuration
        value; if that is unspecified, default to --signed-off-by-cc.
 
 --[no-]cc-cover::
@@ -312,13 +312,13 @@ Automating
 - 'all' will suppress all auto cc values.
 --
 +
-Default is the value of 'sendemail.suppresscc' configuration value; if
+Default is the value of `sendemail.suppresscc` configuration value; if
 that is unspecified, default to 'self' if --suppress-from is
 specified, as well as 'body' if --no-signed-off-cc is specified.
 
 --[no-]suppress-from::
        If this is set, do not add the From: address to the cc: list.
-       Default is the value of 'sendemail.suppressFrom' configuration
+       Default is the value of `sendemail.suppressFrom` configuration
        value; if that is unspecified, default to --no-suppress-from.
 
 --[no-]thread::
@@ -330,7 +330,7 @@ specified, as well as 'body' if --no-signed-off-cc is specified.
 +
 If disabled with "--no-thread", those headers will not be added
 (unless specified with --in-reply-to).  Default is the value of the
-'sendemail.thread' configuration value; if that is unspecified,
+`sendemail.thread` configuration value; if that is unspecified,
 default to --thread.
 +
 It is up to the user to ensure that no In-Reply-To header already
@@ -355,7 +355,7 @@ Administering
 - 'auto' is equivalent to 'cc' + 'compose'
 --
 +
-Default is the value of 'sendemail.confirm' configuration value; if that
+Default is the value of `sendemail.confirm` configuration value; if that
 is unspecified, default to 'auto' unless any of the suppress options
 have been specified, in which case default to 'compose'.
 
@@ -381,7 +381,7 @@ have been specified, in which case default to 'compose'.
                        is due to SMTP limits as described by http://www.ietf.org/rfc/rfc2821.txt.
 --
 +
-Default is the value of 'sendemail.validate'; if this is not set,
+Default is the value of `sendemail.validate`; if this is not set,
 default to '--validate'.
 
 --force::
@@ -403,7 +403,7 @@ CONFIGURATION
 
 sendemail.aliasesFile::
        To avoid typing long email addresses, point this to one or more
-       email aliases files.  You must also supply 'sendemail.aliasFileType'.
+       email aliases files.  You must also supply `sendemail.aliasFileType`.
 
 sendemail.aliasFileType::
        Format of the file(s) specified in sendemail.aliasesFile. Must be
@@ -450,6 +450,19 @@ edit ~/.gitconfig to specify your account settings:
                smtpUser = yourname@gmail.com
                smtpServerPort = 587
 
+If you have multifactor authentication setup on your gmail account, you will
+need to generate an app-specific password for use with 'git send-email'. Visit
+https://security.google.com/settings/security/apppasswords to setup an
+app-specific password.  Once setup, you can store it with the credentials
+helper:
+
+       $ git credential fill
+       protocol=smtp
+       host=smtp.gmail.com
+       username=youname@gmail.com
+       password=app-password
+
+
 Once your commits are ready to be sent to the mailing list, run the
 following commands:
 
index 4f67c4c..8632612 100644 (file)
@@ -41,7 +41,7 @@ usage::
        die with the usage message.
 
 set_reflog_action::
-       Set GIT_REFLOG_ACTION environment to a given string (typically
+       Set `GIT_REFLOG_ACTION` environment to a given string (typically
        the name of the program) unless it is already set.  Whenever
        the script runs a `git` command that updates refs, a reflog
        entry is created using the value of this string to leave the
index fb23a98..698a668 100644 (file)
@@ -459,6 +459,20 @@ Any other arguments are passed directly to 'git log'
        Gets the Subversion property given as the first argument, for a
        file.  A specific revision can be specified with -r/--revision.
 
+'propset'::
+       Sets the Subversion property given as the first argument, to the
+       value given as the second argument for the file given as the
+       third argument.
++
+Example:
++
+------------------------------------------------------------------------
+git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile
+------------------------------------------------------------------------
++
+This will set the property 'svn:keywords' to 'FreeBSD=%H' for the file
+'devel/py-tipper/Makefile'.
+
 'show-externals'::
        Shows the Subversion externals.  Use -r/--revision to specify a
        specific revision.
@@ -748,7 +762,7 @@ svn-remote.<name>.rewriteUUID::
 
 svn-remote.<name>.pushurl::
 
-       Similar to Git's 'remote.<name>.pushurl', this key is designed
+       Similar to Git's `remote.<name>.pushurl`, this key is designed
        to be used in cases where 'url' points to an SVN repository
        via a read-only transport, to provide an alternate read/write
        transport. It is assumed that both keys point to the same
index abab481..6b89393 100644 (file)
@@ -78,7 +78,7 @@ OPTIONS
 
 -v::
 --verify::
-       Verify the gpg signature of the given tag names.
+       Verify the GPG signature of the given tag names.
 
 -n<num>::
        <num> specifies how many lines from the annotation, if any,
@@ -104,7 +104,7 @@ OPTIONS
        order can also be affected by the
        "versionsort.prereleaseSuffix" configuration variable.
        The keys supported are the same as those in `git for-each-ref`.
-       Sort order defaults to the value configured for the 'tag.sort'
+       Sort order defaults to the value configured for the `tag.sort`
        variable if it exists, or lexicographic order otherwise. See
        linkgit:git-config[1].
 
index 0abc806..822ad59 100644 (file)
@@ -9,8 +9,8 @@ git-upload-pack - Send objects packed back to git-fetch-pack
 SYNOPSIS
 --------
 [verse]
-'git-upload-pack' [--strict] [--timeout=<n>] <directory>
-
+'git-upload-pack' [--[no-]strict] [--timeout=<n>] [--stateless-rpc]
+                 [--advertise-refs] <directory>
 DESCRIPTION
 -----------
 Invoked by 'git fetch-pack', learns what
@@ -25,12 +25,22 @@ repository.  For push operations, see 'git send-pack'.
 OPTIONS
 -------
 
---strict::
+--[no-]strict::
        Do not try <directory>/.git/ if <directory> is no Git directory.
 
 --timeout=<n>::
        Interrupt transfer after <n> seconds of inactivity.
 
+--stateless-rpc::
+       Perform only a single read-write cycle with stdin and stdout.
+       This fits with the HTTP POST request processing model where
+       a program may read the request, write a response, and must exit.
+
+--advertise-refs::
+       Only the initial ref advertisement is output, and the program exits
+       immediately. This fits with the HTTP GET request model, where
+       no request content is received but a response must be produced.
+
 <directory>::
        The repository to sync from.
 
index ecf4da1..92097f6 100644 (file)
@@ -12,7 +12,7 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Validates the gpg signature created by 'git commit -S'.
+Validates the GPG signature created by 'git commit -S'.
 
 OPTIONS
 -------
index 16ede5b..7daa28f 100644 (file)
@@ -62,14 +62,14 @@ CONF.VAR (from -c option) and web.browser
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The web browser can be specified using a configuration variable passed
-with the -c (or --config) command-line option, or the 'web.browser'
+with the -c (or --config) command-line option, or the `web.browser`
 configuration variable if the former is not used.
 
 browser.<tool>.path
 ~~~~~~~~~~~~~~~~~~~
 
 You can explicitly provide a full path to your preferred browser by
-setting the configuration variable 'browser.<tool>.path'. For example,
+setting the configuration variable `browser.<tool>.path`. For example,
 you can configure the absolute path to firefox by setting
 'browser.firefox.path'. Otherwise, 'git web{litdd}browse' assumes the tool
 is available in PATH.
@@ -79,7 +79,7 @@ browser.<tool>.cmd
 
 When the browser, specified by options or configuration variables, is
 not among the supported ones, then the corresponding
-'browser.<tool>.cmd' configuration variable will be looked up. If this
+`browser.<tool>.cmd` configuration variable will be looked up. If this
 variable exists then 'git web{litdd}browse' will treat the specified tool
 as a custom command and will use a shell eval to run the command with
 the URLs passed as arguments.
index c622345..7c4cfb0 100644 (file)
@@ -10,8 +10,8 @@ SYNOPSIS
 --------
 [verse]
 'git worktree add' [-f] [--detach] [--checkout] [-b <new-branch>] <path> [<branch>]
-'git worktree prune' [-n] [-v] [--expire <expire>]
 'git worktree list' [--porcelain]
+'git worktree prune' [-n] [-v] [--expire <expire>]
 
 DESCRIPTION
 -----------
@@ -48,16 +48,13 @@ add <path> [<branch>]::
 
 Create `<path>` and checkout `<branch>` into it. The new working directory
 is linked to the current repository, sharing everything except working
-directory specific files such as HEAD, index, etc.
+directory specific files such as HEAD, index, etc. `-` may also be
+specified as `<branch>`; it is synonymous with `@{-1}`.
 +
 If `<branch>` is omitted and neither `-b` nor `-B` nor `--detached` used,
 then, as a convenience, a new branch based at HEAD is created automatically,
 as if `-b $(basename <path>)` was specified.
 
-prune::
-
-Prune working tree information in $GIT_DIR/worktrees.
-
 list::
 
 List details of each worktree.  The main worktree is listed first, followed by
@@ -65,6 +62,10 @@ each of the linked worktrees.  The output details include if the worktree is
 bare, the revision currently checked out, and the branch currently checked out
 (or 'detached HEAD' if none).
 
+prune::
+
+Prune working tree information in $GIT_DIR/worktrees.
+
 OPTIONS
 -------
 
index dd6dbf7..ca611c9 100644 (file)
@@ -43,9 +43,15 @@ unreleased) version of Git, that is available from the 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v2.8.3/git.html[documentation for release 2.8.3]
+* link:v2.9.0/git.html[documentation for release 2.9]
 
 * release notes for
+  link:RelNotes/2.9.0.txt[2.9].
+
+* link:v2.8.4/git.html[documentation for release 2.8.4]
+
+* release notes for
+  link:RelNotes/2.8.4.txt[2.8.4],
   link:RelNotes/2.8.3.txt[2.8.3],
   link:RelNotes/2.8.2.txt[2.8.2],
   link:RelNotes/2.8.1.txt[2.8.1],
@@ -571,7 +577,7 @@ foo.bar= ...`) sets `foo.bar` to the empty string.
 
 --git-dir=<path>::
        Set the path to the repository. This can also be controlled by
-       setting the GIT_DIR environment variable. It can be an absolute
+       setting the `GIT_DIR` environment variable. It can be an absolute
        path or relative path to current working directory.
 
 --work-tree=<path>::
@@ -821,46 +827,46 @@ These environment variables apply to 'all' core Git commands. Nb: it
 is worth noting that they may be used/overridden by SCMS sitting above
 Git so take care if using a foreign front-end.
 
-'GIT_INDEX_FILE'::
+`GIT_INDEX_FILE`::
        This environment allows the specification of an alternate
        index file. If not specified, the default of `$GIT_DIR/index`
        is used.
 
-'GIT_INDEX_VERSION'::
+`GIT_INDEX_VERSION`::
        This environment variable allows the specification of an index
        version for new repositories.  It won't affect existing index
        files.  By default index file version 2 or 3 is used. See
        linkgit:git-update-index[1] for more information.
 
-'GIT_OBJECT_DIRECTORY'::
+`GIT_OBJECT_DIRECTORY`::
        If the object storage directory is specified via this
        environment variable then the sha1 directories are created
        underneath - otherwise the default `$GIT_DIR/objects`
        directory is used.
 
-'GIT_ALTERNATE_OBJECT_DIRECTORIES'::
+`GIT_ALTERNATE_OBJECT_DIRECTORIES`::
        Due to the immutable nature of Git objects, old objects can be
        archived into shared, read-only directories. This variable
        specifies a ":" separated (on Windows ";" separated) list
        of Git object directories which can be used to search for Git
        objects. New objects will not be written to these directories.
 
-'GIT_DIR'::
-       If the 'GIT_DIR' environment variable is set then it
+`GIT_DIR`::
+       If the `GIT_DIR` environment variable is set then it
        specifies a path to use instead of the default `.git`
        for the base of the repository.
        The '--git-dir' command-line option also sets this value.
 
-'GIT_WORK_TREE'::
+`GIT_WORK_TREE`::
        Set the path to the root of the working tree.
        This can also be controlled by the '--work-tree' command-line
        option and the core.worktree configuration variable.
 
-'GIT_NAMESPACE'::
+`GIT_NAMESPACE`::
        Set the Git namespace; see linkgit:gitnamespaces[7] for details.
        The '--namespace' command-line option also sets this value.
 
-'GIT_CEILING_DIRECTORIES'::
+`GIT_CEILING_DIRECTORIES`::
        This should be a colon-separated list of absolute paths.  If
        set, it is a list of directories that Git should not chdir up
        into while looking for a repository directory (useful for
@@ -873,19 +879,19 @@ Git so take care if using a foreign front-end.
        can add an empty entry to the list to tell Git that the
        subsequent entries are not symlinks and needn't be resolved;
        e.g.,
-       'GIT_CEILING_DIRECTORIES=/maybe/symlink::/very/slow/non/symlink'.
+       `GIT_CEILING_DIRECTORIES=/maybe/symlink::/very/slow/non/symlink`.
 
-'GIT_DISCOVERY_ACROSS_FILESYSTEM'::
+`GIT_DISCOVERY_ACROSS_FILESYSTEM`::
        When run in a directory that does not have ".git" repository
        directory, Git tries to find such a directory in the parent
        directories to find the top of the working tree, but by default it
        does not cross filesystem boundaries.  This environment variable
        can be set to true to tell Git not to stop at filesystem
-       boundaries.  Like 'GIT_CEILING_DIRECTORIES', this will not affect
-       an explicit repository directory set via 'GIT_DIR' or on the
+       boundaries.  Like `GIT_CEILING_DIRECTORIES`, this will not affect
+       an explicit repository directory set via `GIT_DIR` or on the
        command line.
 
-'GIT_COMMON_DIR'::
+`GIT_COMMON_DIR`::
        If this variable is set to a path, non-worktree files that are
        normally in $GIT_DIR will be taken from this path
        instead. Worktree-specific files such as HEAD or index are
@@ -896,28 +902,28 @@ Git so take care if using a foreign front-end.
 
 Git Commits
 ~~~~~~~~~~~
-'GIT_AUTHOR_NAME'::
-'GIT_AUTHOR_EMAIL'::
-'GIT_AUTHOR_DATE'::
-'GIT_COMMITTER_NAME'::
-'GIT_COMMITTER_EMAIL'::
-'GIT_COMMITTER_DATE'::
+`GIT_AUTHOR_NAME`::
+`GIT_AUTHOR_EMAIL`::
+`GIT_AUTHOR_DATE`::
+`GIT_COMMITTER_NAME`::
+`GIT_COMMITTER_EMAIL`::
+`GIT_COMMITTER_DATE`::
 'EMAIL'::
        see linkgit:git-commit-tree[1]
 
 Git Diffs
 ~~~~~~~~~
-'GIT_DIFF_OPTS'::
+`GIT_DIFF_OPTS`::
        Only valid setting is "--unified=??" or "-u??" to set the
        number of context lines shown when a unified diff is created.
        This takes precedence over any "-U" or "--unified" option
        value passed on the Git diff command line.
 
-'GIT_EXTERNAL_DIFF'::
-       When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
+`GIT_EXTERNAL_DIFF`::
+       When the environment variable `GIT_EXTERNAL_DIFF` is set, the
        program named by it is called, instead of the diff invocation
        described above.  For a path that is added, removed, or modified,
-        'GIT_EXTERNAL_DIFF' is called with 7 parameters:
+       `GIT_EXTERNAL_DIFF` is called with 7 parameters:
 
        path old-file old-hex old-mode new-file new-hex new-mode
 +
@@ -931,42 +937,42 @@ where:
 The file parameters can point at the user's working file
 (e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file`
 when a new file is added), or a temporary file (e.g. `old-file` in the
-index).  'GIT_EXTERNAL_DIFF' should not worry about unlinking the
-temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits.
+index).  `GIT_EXTERNAL_DIFF` should not worry about unlinking the
+temporary file --- it is removed when `GIT_EXTERNAL_DIFF` exits.
 +
-For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
+For a path that is unmerged, `GIT_EXTERNAL_DIFF` is called with 1
 parameter, <path>.
 +
-For each path 'GIT_EXTERNAL_DIFF' is called, two environment variables,
-'GIT_DIFF_PATH_COUNTER' and 'GIT_DIFF_PATH_TOTAL' are set.
+For each path `GIT_EXTERNAL_DIFF` is called, two environment variables,
+`GIT_DIFF_PATH_COUNTER` and `GIT_DIFF_PATH_TOTAL` are set.
 
-'GIT_DIFF_PATH_COUNTER'::
+`GIT_DIFF_PATH_COUNTER`::
        A 1-based counter incremented by one for every path.
 
-'GIT_DIFF_PATH_TOTAL'::
+`GIT_DIFF_PATH_TOTAL`::
        The total number of paths.
 
 other
 ~~~~~
-'GIT_MERGE_VERBOSITY'::
+`GIT_MERGE_VERBOSITY`::
        A number controlling the amount of output shown by
        the recursive merge strategy.  Overrides merge.verbosity.
        See linkgit:git-merge[1]
 
-'GIT_PAGER'::
+`GIT_PAGER`::
        This environment variable overrides `$PAGER`. If it is set
        to an empty string or to the value "cat", Git will not launch
        a pager.  See also the `core.pager` option in
        linkgit:git-config[1].
 
-'GIT_EDITOR'::
+`GIT_EDITOR`::
        This environment variable overrides `$EDITOR` and `$VISUAL`.
        It is used by several Git commands when, on interactive mode,
        an editor is to be launched. See also linkgit:git-var[1]
        and the `core.editor` option in linkgit:git-config[1].
 
-'GIT_SSH'::
-'GIT_SSH_COMMAND'::
+`GIT_SSH`::
+`GIT_SSH_COMMAND`::
        If either of these environment variables is set then 'git fetch'
        and 'git push' will use the specified command instead of 'ssh'
        when they need to connect to a remote system.
@@ -986,18 +992,18 @@ Usually it is easier to configure any desired options through your
 personal `.ssh/config` file.  Please consult your ssh documentation
 for further details.
 
-'GIT_ASKPASS'::
+`GIT_ASKPASS`::
        If this environment variable is set, then Git commands which need to
        acquire passwords or passphrases (e.g. for HTTP or IMAP authentication)
        will call this program with a suitable prompt as command-line argument
-       and read the password from its STDOUT. See also the 'core.askPass'
+       and read the password from its STDOUT. See also the `core.askPass`
        option in linkgit:git-config[1].
 
-'GIT_TERMINAL_PROMPT'::
+`GIT_TERMINAL_PROMPT`::
        If this environment variable is set to `0`, git will not prompt
        on the terminal (e.g., when asking for HTTP authentication).
 
-'GIT_CONFIG_NOSYSTEM'::
+`GIT_CONFIG_NOSYSTEM`::
        Whether to skip reading settings from the system-wide
        `$(prefix)/etc/gitconfig` file.  This environment variable can
        be used along with `$HOME` and `$XDG_CONFIG_HOME` to create a
@@ -1005,7 +1011,7 @@ for further details.
        temporarily to avoid using a buggy `/etc/gitconfig` file while
        waiting for someone with sufficient permissions to fix it.
 
-'GIT_FLUSH'::
+`GIT_FLUSH`::
        If this environment variable is set to "1", then commands such
        as 'git blame' (in incremental mode), 'git rev-list', 'git log',
        'git check-attr' and 'git check-ignore' will
@@ -1016,7 +1022,7 @@ for further details.
        not set, Git will choose buffered or record-oriented flushing
        based on whether stdout appears to be redirected to a file or not.
 
-'GIT_TRACE'::
+`GIT_TRACE`::
        Enables general trace messages, e.g. alias expansion, built-in
        command execution and external command execution.
 +
@@ -1037,21 +1043,21 @@ into it.
 Unsetting the variable, or setting it to empty, "0" or
 "false" (case insensitive) disables trace messages.
 
-'GIT_TRACE_PACK_ACCESS'::
+`GIT_TRACE_PACK_ACCESS`::
        Enables trace messages for all accesses to any packs. For each
        access, the pack file name and an offset in the pack is
        recorded. This may be helpful for troubleshooting some
        pack-related performance problems.
-       See 'GIT_TRACE' for available trace output options.
+       See `GIT_TRACE` for available trace output options.
 
-'GIT_TRACE_PACKET'::
+`GIT_TRACE_PACKET`::
        Enables trace messages for all packets coming in or out of a
        given program. This can help with debugging object negotiation
        or other protocol issues. Tracing is turned off at a packet
-       starting with "PACK" (but see 'GIT_TRACE_PACKFILE' below).
-       See 'GIT_TRACE' for available trace output options.
+       starting with "PACK" (but see `GIT_TRACE_PACKFILE` below).
+       See `GIT_TRACE` for available trace output options.
 
-'GIT_TRACE_PACKFILE'::
+`GIT_TRACE_PACKFILE`::
        Enables tracing of packfiles sent or received by a
        given program. Unlike other trace output, this trace is
        verbatim: no headers, and no quoting of binary data. You almost
@@ -1062,22 +1068,30 @@ Unsetting the variable, or setting it to empty, "0" or
 Note that this is currently only implemented for the client side
 of clones and fetches.
 
-'GIT_TRACE_PERFORMANCE'::
+`GIT_TRACE_PERFORMANCE`::
        Enables performance related trace messages, e.g. total execution
        time of each Git command.
-       See 'GIT_TRACE' for available trace output options.
+       See `GIT_TRACE` for available trace output options.
 
-'GIT_TRACE_SETUP'::
+`GIT_TRACE_SETUP`::
        Enables trace messages printing the .git, working tree and current
        working directory after Git has completed its setup phase.
-       See 'GIT_TRACE' for available trace output options.
+       See `GIT_TRACE` for available trace output options.
 
-'GIT_TRACE_SHALLOW'::
+`GIT_TRACE_SHALLOW`::
        Enables trace messages that can help debugging fetching /
        cloning of shallow repositories.
-       See 'GIT_TRACE' for available trace output options.
+       See `GIT_TRACE` for available trace output options.
+
+`GIT_TRACE_CURL`::
+       Enables a curl full trace dump of all incoming and outgoing data,
+       including descriptive information, of the git transport protocol.
+       This is similar to doing curl `--trace-ascii` on the command line.
+       This option overrides setting the `GIT_CURL_VERBOSE` environment
+       variable.
+       See `GIT_TRACE` for available trace output options.
 
-'GIT_LITERAL_PATHSPECS'::
+`GIT_LITERAL_PATHSPECS`::
        Setting this variable to `1` will cause Git to treat all
        pathspecs literally, rather than as glob patterns. For example,
        running `GIT_LITERAL_PATHSPECS=1 git log -- '*.c'` will search
@@ -1086,19 +1100,19 @@ of clones and fetches.
        literal paths to Git (e.g., paths previously given to you by
        `git ls-tree`, `--raw` diff output, etc).
 
-'GIT_GLOB_PATHSPECS'::
+`GIT_GLOB_PATHSPECS`::
        Setting this variable to `1` will cause Git to treat all
        pathspecs as glob patterns (aka "glob" magic).
 
-'GIT_NOGLOB_PATHSPECS'::
+`GIT_NOGLOB_PATHSPECS`::
        Setting this variable to `1` will cause Git to treat all
        pathspecs as literal (aka "literal" magic).
 
-'GIT_ICASE_PATHSPECS'::
+`GIT_ICASE_PATHSPECS`::
        Setting this variable to `1` will cause Git to treat all
        pathspecs as case-insensitive.
 
-'GIT_REFLOG_ACTION'::
+`GIT_REFLOG_ACTION`::
        When a ref is updated, reflog entries are created to keep
        track of the reason why the ref was updated (which is
        typically the name of the high-level command that updated
@@ -1108,7 +1122,7 @@ of clones and fetches.
        variable when it is invoked as the top level command by the
        end user, to be recorded in the body of the reflog.
 
-'GIT_REF_PARANOIA'::
+`GIT_REF_PARANOIA`::
        If set to `1`, include broken or badly named refs when iterating
        over lists of refs. In a normal, non-corrupted repository, this
        does nothing. However, enabling it may help git to detect and
@@ -1119,7 +1133,7 @@ of clones and fetches.
        an operation has touched every ref (e.g., because you are
        cloning a repository to make a backup).
 
-'GIT_ALLOW_PROTOCOL'::
+`GIT_ALLOW_PROTOCOL`::
        If set, provide a colon-separated list of protocols which are
        allowed to be used with fetch/push/clone. This is useful to
        restrict recursive submodule initialization from an untrusted
index e3b1de8..8882a3e 100644 (file)
@@ -525,6 +525,8 @@ patterns are available:
 
 - `csharp` suitable for source code in the C# language.
 
+- `css` suitable for cascading style sheets.
+
 - `fortran` suitable for source code in the Fortran language.
 
 - `fountain` suitable for Fountain documents.
index 473623d..63260f0 100644 (file)
@@ -38,7 +38,7 @@ precedence, the last matching pattern decides the outcome):
  * Patterns read from `$GIT_DIR/info/exclude`.
 
  * Patterns read from the file specified by the configuration
-   variable 'core.excludesFile'.
+   variable `core.excludesFile`.
 
 Which file to place a pattern in depends on how the pattern is meant to
 be used.
index 78e0b27..1e86594 100644 (file)
@@ -43,7 +43,7 @@ arguments. The first argument specifies a remote repository as in Git;
 it is either the name of a configured remote or a URL. The second
 argument specifies a URL; it is usually of the form
 '<transport>://<address>', but any arbitrary string is possible.
-The 'GIT_DIR' environment variable is set up for the remote helper
+The `GIT_DIR` environment variable is set up for the remote helper
 and can be used to determine where to store additional data or from
 which directory to invoke auxiliary Git commands.
 
@@ -61,10 +61,10 @@ argument. If such a URL is encountered directly on the command line,
 the first argument is '<address>', and if it is encountered in a
 configured remote, the first argument is the name of that remote.
 
-Additionally, when a configured remote has 'remote.<name>.vcs' set to
+Additionally, when a configured remote has `remote.<name>.vcs` set to
 '<transport>', Git explicitly invokes 'git remote-<transport>' with
 '<name>' as the first argument. If set, the second argument is
-'remote.<name>.url'; otherwise, the second argument is omitted.
+`remote.<name>.url`; otherwise, the second argument is omitted.
 
 INPUT FORMAT
 ------------
index 8a42270..a79e350 100644 (file)
@@ -376,7 +376,7 @@ $site_name::
        Name of your site or organization, to appear in page titles.  Set it
        to something descriptive for clearer bookmarks etc.  If this variable
        is not set or is, then gitweb uses the value of the `SERVER_NAME`
-       CGI environment variable, setting site name to "$SERVER_NAME Git",
+       `CGI` environment variable, setting site name to "$SERVER_NAME Git",
        or "Untitled Git" if this variable is not set (e.g. if running gitweb
        as standalone script).
 +
index cd9c895..96156e5 100644 (file)
@@ -206,8 +206,8 @@ $export_auth_hook = sub {
 Per-repository gitweb configuration
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 You can configure individual repositories shown in gitweb by creating file
-in the 'GIT_DIR' of Git repository, or by setting some repo configuration
-variable (in 'GIT_DIR/config', see linkgit:git-config[1]).
+in the `GIT_DIR` of Git repository, or by setting some repo configuration
+variable (in `GIT_DIR/config`, see linkgit:git-config[1]).
 
 You can use the following files in repository:
 
index 002ca58..df3ea37 100644 (file)
@@ -61,7 +61,7 @@ merge.verbosity::
        message if conflicts were detected. Level 1 outputs only
        conflicts, 2 outputs conflicts and file changes.  Level 5 and
        above outputs debugging information.  The default is level 2.
-       Can be overridden by the 'GIT_MERGE_VERBOSITY' environment variable.
+       Can be overridden by the `GIT_MERGE_VERBOSITY` environment variable.
 
 merge.<driver>.name::
        Defines a human-readable name for a custom low-level
index 6c67182..e44fc8f 100644 (file)
@@ -26,7 +26,7 @@ people using 80-column terminals.
 --no-abbrev-commit::
        Show the full 40-byte hexadecimal commit object name. This negates
        `--abbrev-commit` and those options which imply it such as
-       "--oneline". It also overrides the 'log.abbrevCommit' variable.
+       "--oneline". It also overrides the `log.abbrevCommit` variable.
 
 --oneline::
        This is a shorthand for "--pretty=oneline --abbrev-commit"
@@ -65,7 +65,7 @@ ifndef::git-rev-list[]
        on the command line.
 +
 By default, the notes shown are from the notes refs listed in the
-'core.notesRef' and 'notes.displayRef' variables (or corresponding
+`core.notesRef` and `notes.displayRef` variables (or corresponding
 environment overrides). See linkgit:git-config[1] for more details.
 +
 With an optional '<treeish>' argument, use the treeish to find the notes
diff --git a/Documentation/technical/signature-format.txt b/Documentation/technical/signature-format.txt
new file mode 100644 (file)
index 0000000..2c9406a
--- /dev/null
@@ -0,0 +1,186 @@
+Git signature format
+====================
+
+== Overview
+
+Git uses cryptographic signatures in various places, currently objects (tags,
+commits, mergetags) and transactions (pushes). In every case, the command which
+is about to create an object or transaction determines a payload from that,
+calls gpg to obtain a detached signature for the payload (`gpg -bsa`) and
+embeds the signature into the object or transaction.
+
+Signatures always begin with `-----BEGIN PGP SIGNATURE-----`
+and end with `-----END PGP SIGNATURE-----`, unless gpg is told to
+produce RFC1991 signatures which use `MESSAGE` instead of `SIGNATURE`.
+
+The signed payload and the way the signature is embedded depends
+on the type of the object resp. transaction.
+
+== Tag signatures
+
+- created by: `git tag -s`
+- payload: annotated tag object
+- embedding: append the signature to the unsigned tag object
+- example: tag `signedtag` with subject `signed tag`
+
+----
+object 04b871796dc0420f8e7561a895b52484b701d51a
+type commit
+tag signedtag
+tagger C O Mitter <committer@example.com> 1465981006 +0000
+
+signed tag
+
+signed tag message body
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iQEcBAABAgAGBQJXYRhOAAoJEGEJLoW3InGJklkIAIcnhL7RwEb/+QeX9enkXhxn
+rxfdqrvWd1K80sl2TOt8Bg/NYwrUBw/RWJ+sg/hhHp4WtvE1HDGHlkEz3y11Lkuh
+8tSxS3qKTxXUGozyPGuE90sJfExhZlW4knIQ1wt/yWqM+33E9pN4hzPqLwyrdods
+q8FWEqPPUbSJXoMbRPw04S5jrLtZSsUWbRYjmJCHzlhSfFWW4eFd37uquIaLUBS0
+rkC3Jrx7420jkIpgFcTI2s60uhSQLzgcCwdA2ukSYIRnjg/zDkj8+3h/GaROJ72x
+lZyI6HWixKJkWw8lE9aAOD9TmTW9sFJwcVAzmAuFX2kUreDUKMZduGcoRYGpD7E=
+=jpXa
+-----END PGP SIGNATURE-----
+----
+
+- verify with: `git verify-tag [-v]` or `git tag -v`
+
+----
+gpg: Signature made Wed Jun 15 10:56:46 2016 CEST using RSA key ID B7227189
+gpg: Good signature from "Eris Discordia <discord@example.net>"
+gpg: WARNING: This key is not certified with a trusted signature!
+gpg:          There is no indication that the signature belongs to the owner.
+Primary key fingerprint: D4BE 2231 1AD3 131E 5EDA  29A4 6109 2E85 B722 7189
+object 04b871796dc0420f8e7561a895b52484b701d51a
+type commit
+tag signedtag
+tagger C O Mitter <committer@example.com> 1465981006 +0000
+
+signed tag
+
+signed tag message body
+----
+
+== Commit signatures
+
+- created by: `git commit -S`
+- payload: commit object
+- embedding: header entry `gpgsig`
+  (content is preceded by a space)
+- example: commit with subject `signed commit`
+
+----
+tree eebfed94e75e7760540d1485c740902590a00332
+parent 04b871796dc0420f8e7561a895b52484b701d51a
+author A U Thor <author@example.com> 1465981137 +0000
+committer C O Mitter <committer@example.com> 1465981137 +0000
+gpgsig -----BEGIN PGP SIGNATURE-----
+ Version: GnuPG v1
+
+ iQEcBAABAgAGBQJXYRjRAAoJEGEJLoW3InGJ3IwIAIY4SA6GxY3BjL60YyvsJPh/
+ HRCJwH+w7wt3Yc/9/bW2F+gF72kdHOOs2jfv+OZhq0q4OAN6fvVSczISY/82LpS7
+ DVdMQj2/YcHDT4xrDNBnXnviDO9G7am/9OE77kEbXrp7QPxvhjkicHNwy2rEflAA
+ zn075rtEERDHr8nRYiDh8eVrefSO7D+bdQ7gv+7GsYMsd2auJWi1dHOSfTr9HIF4
+ HJhWXT9d2f8W+diRYXGh4X0wYiGg6na/soXc+vdtDYBzIxanRqjg8jCAeo1eOTk1
+ EdTwhcTZlI0x5pvJ3H0+4hA2jtldVtmPM4OTB0cTrEWBad7XV6YgiyuII73Ve3I=
+ =jKHM
+ -----END PGP SIGNATURE-----
+
+signed commit
+
+signed commit message body
+----
+
+- verify with: `git verify-commit [-v]` (or `git show --show-signature`)
+
+----
+gpg: Signature made Wed Jun 15 10:58:57 2016 CEST using RSA key ID B7227189
+gpg: Good signature from "Eris Discordia <discord@example.net>"
+gpg: WARNING: This key is not certified with a trusted signature!
+gpg:          There is no indication that the signature belongs to the owner.
+Primary key fingerprint: D4BE 2231 1AD3 131E 5EDA  29A4 6109 2E85 B722 7189
+tree eebfed94e75e7760540d1485c740902590a00332
+parent 04b871796dc0420f8e7561a895b52484b701d51a
+author A U Thor <author@example.com> 1465981137 +0000
+committer C O Mitter <committer@example.com> 1465981137 +0000
+
+signed commit
+
+signed commit message body
+----
+
+== Mergetag signatures
+
+- created by: `git merge` on signed tag
+- payload/embedding: the whole signed tag object is embedded into
+  the (merge) commit object as header entry `mergetag`
+- example: merge of the signed tag `signedtag` as above
+
+----
+tree c7b1cff039a93f3600a1d18b82d26688668c7dea
+parent c33429be94b5f2d3ee9b0adad223f877f174b05d
+parent 04b871796dc0420f8e7561a895b52484b701d51a
+author A U Thor <author@example.com> 1465982009 +0000
+committer C O Mitter <committer@example.com> 1465982009 +0000
+mergetag object 04b871796dc0420f8e7561a895b52484b701d51a
+ type commit
+ tag signedtag
+ tagger C O Mitter <committer@example.com> 1465981006 +0000
+
+ signed tag
+
+ signed tag message body
+ -----BEGIN PGP SIGNATURE-----
+ Version: GnuPG v1
+
+ iQEcBAABAgAGBQJXYRhOAAoJEGEJLoW3InGJklkIAIcnhL7RwEb/+QeX9enkXhxn
+ rxfdqrvWd1K80sl2TOt8Bg/NYwrUBw/RWJ+sg/hhHp4WtvE1HDGHlkEz3y11Lkuh
+ 8tSxS3qKTxXUGozyPGuE90sJfExhZlW4knIQ1wt/yWqM+33E9pN4hzPqLwyrdods
+ q8FWEqPPUbSJXoMbRPw04S5jrLtZSsUWbRYjmJCHzlhSfFWW4eFd37uquIaLUBS0
+ rkC3Jrx7420jkIpgFcTI2s60uhSQLzgcCwdA2ukSYIRnjg/zDkj8+3h/GaROJ72x
+ lZyI6HWixKJkWw8lE9aAOD9TmTW9sFJwcVAzmAuFX2kUreDUKMZduGcoRYGpD7E=
+ =jpXa
+ -----END PGP SIGNATURE-----
+
+Merge tag 'signedtag' into downstream
+
+signed tag
+
+signed tag message body
+
+# gpg: Signature made Wed Jun 15 08:56:46 2016 UTC using RSA key ID B7227189
+# gpg: Good signature from "Eris Discordia <discord@example.net>"
+# gpg: WARNING: This key is not certified with a trusted signature!
+# gpg:          There is no indication that the signature belongs to the owner.
+# Primary key fingerprint: D4BE 2231 1AD3 131E 5EDA  29A4 6109 2E85 B722 7189
+----
+
+- verify with: verification is embedded in merge commit message by default,
+  alternatively with `git show --show-signature`:
+
+----
+commit 9863f0c76ff78712b6800e199a46aa56afbcbd49
+merged tag 'signedtag'
+gpg: Signature made Wed Jun 15 10:56:46 2016 CEST using RSA key ID B7227189
+gpg: Good signature from "Eris Discordia <discord@example.net>"
+gpg: WARNING: This key is not certified with a trusted signature!
+gpg:          There is no indication that the signature belongs to the owner.
+Primary key fingerprint: D4BE 2231 1AD3 131E 5EDA  29A4 6109 2E85 B722 7189
+Merge: c33429b 04b8717
+Author: A U Thor <author@example.com>
+Date:   Wed Jun 15 09:13:29 2016 +0000
+
+    Merge tag 'signedtag' into downstream
+
+    signed tag
+
+    signed tag message body
+
+    # gpg: Signature made Wed Jun 15 08:56:46 2016 UTC using RSA key ID B7227189
+    # gpg: Good signature from "Eris Discordia <discord@example.net>"
+    # gpg: WARNING: This key is not certified with a trusted signature!
+    # gpg:          There is no indication that the signature belongs to the owner.
+    # Primary key fingerprint: D4BE 2231 1AD3 131E 5EDA  29A4 6109 2E85 B722 7189
+----
index e3d0bed..0fe02a6 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.9.0-rc0
+DEF_VER=v2.9.0.GIT
 
 LF='
 '
index 0d59718..de5a030 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -375,13 +375,7 @@ GIT-VERSION-FILE: FORCE
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
 CFLAGS = -g -O2 -Wall
-LDFLAGS =
-ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
-ALL_LDFLAGS = $(LDFLAGS)
-STRIP ?= strip
-
-ifdef DEVELOPER
-CFLAGS += -Werror \
+DEVELOPER_CFLAGS = -Werror \
        -Wdeclaration-after-statement \
        -Wno-format-zero-length \
        -Wold-style-definition \
@@ -390,7 +384,10 @@ CFLAGS += -Werror \
        -Wstrict-prototypes \
        -Wunused \
        -Wvla
-endif
+LDFLAGS =
+ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
+ALL_LDFLAGS = $(LDFLAGS)
+STRIP ?= strip
 
 # Create as necessary, replace existing, make ranlib unneeded.
 ARFLAGS = rcs
@@ -951,6 +948,10 @@ include config.mak.uname
 -include config.mak.autogen
 -include config.mak
 
+ifdef DEVELOPER
+CFLAGS += $(DEVELOPER_CFLAGS)
+endif
+
 ifndef sysconfdir
 ifeq ($(prefix),/usr)
 sysconfdir = /etc
index 2087748..bd8a918 100644 (file)
--- a/README.md
+++ b/README.md
@@ -17,14 +17,14 @@ including full documentation and Git related tools.
 
 See [Documentation/gittutorial.txt][] to get started, then see
 [Documentation/giteveryday.txt][] for a useful minimum set of commands, and
-Documentation/git-*commandname*.txt for documentation of each command.
+Documentation/git-<commandname>.txt for documentation of each command.
 If git has been correctly installed, then the tutorial can also be
-read with "man gittutorial" or "git help tutorial", and the
-documentation of each command with "man git-*commandname*" or "git help
-*commandname*".
+read with `man gittutorial` or `git help tutorial`, and the
+documentation of each command with `man git-<commandname>` or `git help
+<commandname>`.
 
 CVS users may also want to read [Documentation/gitcvs-migration.txt][]
-("man gitcvs-migration" or "git help cvs-migration" if git is
+(`man gitcvs-migration` or `git help cvs-migration` if git is
 installed).
 
 The user discussion and development of Git take place on the Git
index 6660673..62615ff 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.9.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.10.0.txt
\ No newline at end of file
index 5d735ae..42df974 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -322,7 +322,7 @@ static int path_exists(struct tree *tree, const char *path)
        pathspec.recursive = 1;
        ret = read_tree_recursive(tree, "", 0, 0, &pathspec,
                                  reject_entry, &pathspec);
-       free_pathspec(&pathspec);
+       clear_pathspec(&pathspec);
        return ret != 0;
 }
 
index 6d93edb..dc13319 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -890,6 +890,7 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
        if (!opt.diffopt.output_format)
                opt.diffopt.output_format = DIFF_FORMAT_RAW;
 
+       setup_revisions(0, NULL, &opt, NULL);
        log_tree_commit(&opt, commit);
 }
 
index 145f06e..b1dddb4 100644 (file)
@@ -26,7 +26,7 @@ static int patch_interactive, add_interactive, edit_interactive;
 static int take_worktree_changes;
 
 struct update_callback_data {
-       int flags;
+       int flags, force_mode;
        int add_errors;
 };
 
@@ -65,7 +65,8 @@ static void update_callback(struct diff_queue_struct *q,
                        die(_("unexpected diff status %c"), p->status);
                case DIFF_STATUS_MODIFIED:
                case DIFF_STATUS_TYPE_CHANGED:
-                       if (add_file_to_index(&the_index, path, data->flags)) {
+                       if (add_file_to_index(&the_index, path,
+                                       data->flags, data->force_mode)) {
                                if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
                                        die(_("updating files failed"));
                                data->add_errors++;
@@ -83,14 +84,15 @@ static void update_callback(struct diff_queue_struct *q,
        }
 }
 
-int add_files_to_cache(const char *prefix,
-                      const struct pathspec *pathspec, int flags)
+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec,
+       int flags, int force_mode)
 {
        struct update_callback_data data;
        struct rev_info rev;
 
        memset(&data, 0, sizeof(data));
        data.flags = flags;
+       data.force_mode = force_mode;
 
        init_revisions(&rev, prefix);
        setup_revisions(0, NULL, &rev, NULL);
@@ -238,6 +240,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;
 static int addremove = ADDREMOVE_DEFAULT;
 static int addremove_explicit = -1; /* unspecified */
 
+static char *chmod_arg;
+
 static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
 {
        /* if we are told to ignore, we are not adding removals */
@@ -263,6 +267,7 @@ static struct option builtin_add_options[] = {
        OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
        OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
        OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
+       OPT_STRING( 0 , "chmod", &chmod_arg, N_("(+/-)x"), N_("override the executable bit of the listed files")),
        OPT_END(),
 };
 
@@ -276,7 +281,7 @@ static int add_config(const char *var, const char *value, void *cb)
        return git_default_config(var, value, cb);
 }
 
-static int add_files(struct dir_struct *dir, int flags)
+static int add_files(struct dir_struct *dir, int flags, int force_mode)
 {
        int i, exit_status = 0;
 
@@ -289,7 +294,8 @@ static int add_files(struct dir_struct *dir, int flags)
        }
 
        for (i = 0; i < dir->nr; i++)
-               if (add_file_to_cache(dir->entries[i]->name, flags)) {
+               if (add_file_to_index(&the_index, dir->entries[i]->name,
+                               flags, force_mode)) {
                        if (!ignore_add_errors)
                                die(_("adding files failed"));
                        exit_status = 1;
@@ -302,7 +308,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        int exit_status = 0;
        struct pathspec pathspec;
        struct dir_struct dir;
-       int flags;
+       int flags, force_mode;
        int add_new_files;
        int require_pathspec;
        char *seen = NULL;
@@ -336,6 +342,15 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        if (!show_only && ignore_missing)
                die(_("Option --ignore-missing can only be used together with --dry-run"));
 
+       if (!chmod_arg)
+               force_mode = 0;
+       else if (!strcmp(chmod_arg, "-x"))
+               force_mode = 0666;
+       else if (!strcmp(chmod_arg, "+x"))
+               force_mode = 0777;
+       else
+               die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
+
        add_new_files = !take_worktree_changes && !refresh_only;
        require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
 
@@ -426,10 +441,10 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
        plug_bulk_checkin();
 
-       exit_status |= add_files_to_cache(prefix, &pathspec, flags);
+       exit_status |= add_files_to_cache(prefix, &pathspec, flags, force_mode);
 
        if (add_new_files)
-               exit_status |= add_files(&dir, flags);
+               exit_status |= add_files(&dir, flags, force_mode);
 
        unplug_bulk_checkin();
 
index 3dfe70b..d5da5fe 100644 (file)
@@ -70,7 +70,8 @@ enum patch_format {
        PATCH_FORMAT_MBOX,
        PATCH_FORMAT_STGIT,
        PATCH_FORMAT_STGIT_SERIES,
-       PATCH_FORMAT_HG
+       PATCH_FORMAT_HG,
+       PATCH_FORMAT_MBOXRD
 };
 
 enum keep_type {
@@ -712,7 +713,8 @@ done:
  * Splits out individual email patches from `paths`, where each path is either
  * a mbox file or a Maildir. Returns 0 on success, -1 on failure.
  */
-static int split_mail_mbox(struct am_state *state, const char **paths, int keep_cr)
+static int split_mail_mbox(struct am_state *state, const char **paths,
+                               int keep_cr, int mboxrd)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
        struct strbuf last = STRBUF_INIT;
@@ -724,6 +726,8 @@ static int split_mail_mbox(struct am_state *state, const char **paths, int keep_
        argv_array_push(&cp.args, "-b");
        if (keep_cr)
                argv_array_push(&cp.args, "--keep-cr");
+       if (mboxrd)
+               argv_array_push(&cp.args, "--mboxrd");
        argv_array_push(&cp.args, "--");
        argv_array_pushv(&cp.args, paths);
 
@@ -965,13 +969,15 @@ static int split_mail(struct am_state *state, enum patch_format patch_format,
 
        switch (patch_format) {
        case PATCH_FORMAT_MBOX:
-               return split_mail_mbox(state, paths, keep_cr);
+               return split_mail_mbox(state, paths, keep_cr, 0);
        case PATCH_FORMAT_STGIT:
                return split_mail_conv(stgit_patch_to_mail, state, paths, keep_cr);
        case PATCH_FORMAT_STGIT_SERIES:
                return split_mail_stgit_series(state, paths, keep_cr);
        case PATCH_FORMAT_HG:
                return split_mail_conv(hg_patch_to_mail, state, paths, keep_cr);
+       case PATCH_FORMAT_MBOXRD:
+               return split_mail_mbox(state, paths, keep_cr, 1);
        default:
                die("BUG: invalid patch_format");
        }
@@ -2201,6 +2207,8 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
                *opt_value = PATCH_FORMAT_STGIT_SERIES;
        else if (!strcmp(arg, "hg"))
                *opt_value = PATCH_FORMAT_HG;
+       else if (!strcmp(arg, "mboxrd"))
+               *opt_value = PATCH_FORMAT_MBOXRD;
        else
                return error(_("Invalid value for --patch-format: %s"), arg);
        return 0;
index 8e4da2e..7fc5c3e 100644 (file)
 #include "ll-merge.h"
 #include "rerere.h"
 
-/*
- *  --check turns on checking that the working tree matches the
- *    files that are being modified, but doesn't apply the patch
- *  --stat does just a diffstat, and doesn't actually apply
- *  --numstat does numeric diffstat, and doesn't actually apply
- *  --index-info shows the old and new index info for paths if available.
- *  --index updates the cache as well.
- *  --cached updates only the cache without ever touching the working tree.
- */
-static const char *prefix;
-static int prefix_length = -1;
-static int newfd = -1;
-
-static int unidiff_zero;
-static int p_value = 1;
-static int p_value_known;
-static int check_index;
-static int update_index;
-static int cached;
-static int diffstat;
-static int numstat;
-static int summary;
-static int check;
-static int apply = 1;
-static int apply_in_reverse;
-static int apply_with_reject;
-static int apply_verbosely;
-static int allow_overlap;
-static int no_add;
-static int threeway;
-static int unsafe_paths;
-static const char *fake_ancestor;
-static int line_termination = '\n';
-static unsigned int p_context = UINT_MAX;
-static const char * const apply_usage[] = {
-       N_("git apply [<options>] [<patch>...]"),
-       NULL
-};
-
-static enum ws_error_action {
+enum ws_error_action {
        nowarn_ws_error,
        warn_on_ws_error,
        die_on_ws_error,
        correct_ws_error
-} ws_error_action = warn_on_ws_error;
-static int whitespace_error;
-static int squelch_whitespace_errors = 5;
-static int applied_after_fixing_ws;
+};
+
 
-static enum ws_ignore {
+enum ws_ignore {
        ignore_ws_none,
        ignore_ws_change
-} ws_ignore_action = ignore_ws_none;
+};
+
+/*
+ * We need to keep track of how symlinks in the preimage are
+ * manipulated by the patches.  A patch to add a/b/c where a/b
+ * is a symlink should not be allowed to affect the directory
+ * the symlink points at, but if the same patch removes a/b,
+ * it is perfectly fine, as the patch removes a/b to make room
+ * to create a directory a/b so that a/b/c can be created.
+ *
+ * See also "struct string_list symlink_changes" in "struct
+ * apply_state".
+ */
+#define SYMLINK_GOES_AWAY 01
+#define SYMLINK_IN_RESULT 02
 
+struct apply_state {
+       const char *prefix;
+       int prefix_length;
+
+       /* These are lock_file related */
+       struct lock_file *lock_file;
+       int newfd;
+
+       /* These control what gets looked at and modified */
+       int apply; /* this is not a dry-run */
+       int cached; /* apply to the index only */
+       int check; /* preimage must match working tree, don't actually apply */
+       int check_index; /* preimage must match the indexed version */
+       int update_index; /* check_index && apply */
+
+       /* These control cosmetic aspect of the output */
+       int diffstat; /* just show a diffstat, and don't actually apply */
+       int numstat; /* just show a numeric diffstat, and don't actually apply */
+       int summary; /* just report creation, deletion, etc, and don't actually apply */
+
+       /* These boolean parameters control how the apply is done */
+       int allow_overlap;
+       int apply_in_reverse;
+       int apply_with_reject;
+       int apply_verbosely;
+       int no_add;
+       int threeway;
+       int unidiff_zero;
+       int unsafe_paths;
+
+       /* Other non boolean parameters */
+       const char *fake_ancestor;
+       const char *patch_input_file;
+       int line_termination;
+       struct strbuf root;
+       int p_value;
+       int p_value_known;
+       unsigned int p_context;
+
+       /* Exclude and include path parameters */
+       struct string_list limit_by_name;
+       int has_include;
+
+       /* Various "current state" */
+       int linenr; /* current line number */
+       struct string_list symlink_changes; /* we have to track symlinks */
 
-static const char *patch_input_file;
-static struct strbuf root = STRBUF_INIT;
-static int read_stdin = 1;
-static int options;
+       /*
+        * For "diff-stat" like behaviour, we keep track of the biggest change
+        * we've seen, and the longest filename. That allows us to do simple
+        * scaling.
+        */
+       int max_change;
+       int max_len;
 
-static void parse_whitespace_option(const char *option)
+       /*
+        * Records filenames that have been touched, in order to handle
+        * the case where more than one patches touch the same file.
+        */
+       struct string_list fn_table;
+
+       /* These control whitespace errors */
+       enum ws_error_action ws_error_action;
+       enum ws_ignore ws_ignore_action;
+       const char *whitespace_option;
+       int whitespace_error;
+       int squelch_whitespace_errors;
+       int applied_after_fixing_ws;
+};
+
+static const char * const apply_usage[] = {
+       N_("git apply [<options>] [<patch>...]"),
+       NULL
+};
+
+static void parse_whitespace_option(struct apply_state *state, const char *option)
 {
        if (!option) {
-               ws_error_action = warn_on_ws_error;
+               state->ws_error_action = warn_on_ws_error;
                return;
        }
        if (!strcmp(option, "warn")) {
-               ws_error_action = warn_on_ws_error;
+               state->ws_error_action = warn_on_ws_error;
                return;
        }
        if (!strcmp(option, "nowarn")) {
-               ws_error_action = nowarn_ws_error;
+               state->ws_error_action = nowarn_ws_error;
                return;
        }
        if (!strcmp(option, "error")) {
-               ws_error_action = die_on_ws_error;
+               state->ws_error_action = die_on_ws_error;
                return;
        }
        if (!strcmp(option, "error-all")) {
-               ws_error_action = die_on_ws_error;
-               squelch_whitespace_errors = 0;
+               state->ws_error_action = die_on_ws_error;
+               state->squelch_whitespace_errors = 0;
                return;
        }
        if (!strcmp(option, "strip") || !strcmp(option, "fix")) {
-               ws_error_action = correct_ws_error;
+               state->ws_error_action = correct_ws_error;
                return;
        }
        die(_("unrecognized whitespace option '%s'"), option);
 }
 
-static void parse_ignorewhitespace_option(const char *option)
+static void parse_ignorewhitespace_option(struct apply_state *state,
+                                         const char *option)
 {
        if (!option || !strcmp(option, "no") ||
            !strcmp(option, "false") || !strcmp(option, "never") ||
            !strcmp(option, "none")) {
-               ws_ignore_action = ignore_ws_none;
+               state->ws_ignore_action = ignore_ws_none;
                return;
        }
        if (!strcmp(option, "change")) {
-               ws_ignore_action = ignore_ws_change;
+               state->ws_ignore_action = ignore_ws_change;
                return;
        }
        die(_("unrecognized whitespace ignore option '%s'"), option);
 }
 
-static void set_default_whitespace_mode(const char *whitespace_option)
+static void set_default_whitespace_mode(struct apply_state *state)
 {
-       if (!whitespace_option && !apply_default_whitespace)
-               ws_error_action = (apply ? warn_on_ws_error : nowarn_ws_error);
+       if (!state->whitespace_option && !apply_default_whitespace)
+               state->ws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);
 }
 
-/*
- * For "diff-stat" like behaviour, we keep track of the biggest change
- * we've seen, and the longest filename. That allows us to do simple
- * scaling.
- */
-static int max_change, max_len;
-
-/*
- * Various "current state", notably line numbers and what
- * file (and how) we're patching right now.. The "is_xxxx"
- * things are flags, where -1 means "don't know yet".
- */
-static int linenr = 1;
-
 /*
  * This represents one "hunk" from a patch, starting with
  * "@@ -oldpos,oldlines +newpos,newlines @@" marker.  The
@@ -265,13 +294,6 @@ struct image {
        struct line *line;
 };
 
-/*
- * Records filenames that have been touched, in order to handle
- * the case where more than one patches touch the same file.
- */
-
-static struct string_list fn_table;
-
 static uint32_t hash_line(const char *cp, size_t len)
 {
        size_t i;
@@ -442,7 +464,7 @@ static int is_dev_null(const char *str)
 #define TERM_SPACE     1
 #define TERM_TAB       2
 
-static int name_terminate(const char *name, int namelen, int c, int terminate)
+static int name_terminate(int c, int terminate)
 {
        if (c == ' ' && !(terminate & TERM_SPACE))
                return 0;
@@ -469,7 +491,10 @@ static char *squash_slash(char *name)
        return name;
 }
 
-static char *find_name_gnu(const char *line, const char *def, int p_value)
+static char *find_name_gnu(struct apply_state *state,
+                          const char *line,
+                          const char *def,
+                          int p_value)
 {
        struct strbuf name = STRBUF_INIT;
        char *cp;
@@ -493,8 +518,8 @@ static char *find_name_gnu(const char *line, const char *def, int p_value)
        }
 
        strbuf_remove(&name, 0, cp - name.buf);
-       if (root.len)
-               strbuf_insert(&name, 0, root.buf, root.len);
+       if (state->root.len)
+               strbuf_insert(&name, 0, state->root.buf, state->root.len);
        return squash_slash(strbuf_detach(&name, NULL));
 }
 
@@ -657,8 +682,12 @@ static size_t diff_timestamp_len(const char *line, size_t len)
        return line + len - end;
 }
 
-static char *find_name_common(const char *line, const char *def,
-                             int p_value, const char *end, int terminate)
+static char *find_name_common(struct apply_state *state,
+                             const char *line,
+                             const char *def,
+                             int p_value,
+                             const char *end,
+                             int terminate)
 {
        int len;
        const char *start = NULL;
@@ -671,7 +700,7 @@ static char *find_name_common(const char *line, const char *def,
                if (!end && isspace(c)) {
                        if (c == '\n')
                                break;
-                       if (name_terminate(start, line-start, c, terminate))
+                       if (name_terminate(c, terminate))
                                break;
                }
                line++;
@@ -696,32 +725,39 @@ static char *find_name_common(const char *line, const char *def,
                        return squash_slash(xstrdup(def));
        }
 
-       if (root.len) {
-               char *ret = xstrfmt("%s%.*s", root.buf, len, start);
+       if (state->root.len) {
+               char *ret = xstrfmt("%s%.*s", state->root.buf, len, start);
                return squash_slash(ret);
        }
 
        return squash_slash(xmemdupz(start, len));
 }
 
-static char *find_name(const char *line, char *def, int p_value, int terminate)
+static char *find_name(struct apply_state *state,
+                      const char *line,
+                      char *def,
+                      int p_value,
+                      int terminate)
 {
        if (*line == '"') {
-               char *name = find_name_gnu(line, def, p_value);
+               char *name = find_name_gnu(state, line, def, p_value);
                if (name)
                        return name;
        }
 
-       return find_name_common(line, def, p_value, NULL, terminate);
+       return find_name_common(state, line, def, p_value, NULL, terminate);
 }
 
-static char *find_name_traditional(const char *line, char *def, int p_value)
+static char *find_name_traditional(struct apply_state *state,
+                                  const char *line,
+                                  char *def,
+                                  int p_value)
 {
        size_t len;
        size_t date_len;
 
        if (*line == '"') {
-               char *name = find_name_gnu(line, def, p_value);
+               char *name = find_name_gnu(state, line, def, p_value);
                if (name)
                        return name;
        }
@@ -729,10 +765,10 @@ static char *find_name_traditional(const char *line, char *def, int p_value)
        len = strchrnul(line, '\n') - line;
        date_len = diff_timestamp_len(line, len);
        if (!date_len)
-               return find_name_common(line, def, p_value, NULL, TERM_TAB);
+               return find_name_common(state, line, def, p_value, NULL, TERM_TAB);
        len -= date_len;
 
-       return find_name_common(line, def, p_value, line + len, 0);
+       return find_name_common(state, line, def, p_value, line + len, 0);
 }
 
 static int count_slashes(const char *cp)
@@ -750,30 +786,30 @@ static int count_slashes(const char *cp)
  * Given the string after "--- " or "+++ ", guess the appropriate
  * p_value for the given patch.
  */
-static int guess_p_value(const char *nameline)
+static int guess_p_value(struct apply_state *state, const char *nameline)
 {
        char *name, *cp;
        int val = -1;
 
        if (is_dev_null(nameline))
                return -1;
-       name = find_name_traditional(nameline, NULL, 0);
+       name = find_name_traditional(state, nameline, NULL, 0);
        if (!name)
                return -1;
        cp = strchr(name, '/');
        if (!cp)
                val = 0;
-       else if (prefix) {
+       else if (state->prefix) {
                /*
                 * Does it begin with "a/$our-prefix" and such?  Then this is
                 * very likely to apply to our directory.
                 */
-               if (!strncmp(name, prefix, prefix_length))
-                       val = count_slashes(prefix);
+               if (!strncmp(name, state->prefix, state->prefix_length))
+                       val = count_slashes(state->prefix);
                else {
                        cp++;
-                       if (!strncmp(cp, prefix, prefix_length))
-                               val = count_slashes(prefix) + 1;
+                       if (!strncmp(cp, state->prefix, state->prefix_length))
+                               val = count_slashes(state->prefix) + 1;
                }
        }
        free(name);
@@ -860,36 +896,39 @@ static int has_epoch_timestamp(const char *nameline)
  * files, we can happily check the index for a match, but for creating a
  * new file we should try to match whatever "patch" does. I have no idea.
  */
-static void parse_traditional_patch(const char *first, const char *second, struct patch *patch)
+static void parse_traditional_patch(struct apply_state *state,
+                                   const char *first,
+                                   const char *second,
+                                   struct patch *patch)
 {
        char *name;
 
        first += 4;     /* skip "--- " */
        second += 4;    /* skip "+++ " */
-       if (!p_value_known) {
+       if (!state->p_value_known) {
                int p, q;
-               p = guess_p_value(first);
-               q = guess_p_value(second);
+               p = guess_p_value(state, first);
+               q = guess_p_value(state, second);
                if (p < 0) p = q;
                if (0 <= p && p == q) {
-                       p_value = p;
-                       p_value_known = 1;
+                       state->p_value = p;
+                       state->p_value_known = 1;
                }
        }
        if (is_dev_null(first)) {
                patch->is_new = 1;
                patch->is_delete = 0;
-               name = find_name_traditional(second, NULL, p_value);
+               name = find_name_traditional(state, second, NULL, state->p_value);
                patch->new_name = name;
        } else if (is_dev_null(second)) {
                patch->is_new = 0;
                patch->is_delete = 1;
-               name = find_name_traditional(first, NULL, p_value);
+               name = find_name_traditional(state, first, NULL, state->p_value);
                patch->old_name = name;
        } else {
                char *first_name;
-               first_name = find_name_traditional(first, NULL, p_value);
-               name = find_name_traditional(second, first_name, p_value);
+               first_name = find_name_traditional(state, first, NULL, state->p_value);
+               name = find_name_traditional(state, second, first_name, state->p_value);
                free(first_name);
                if (has_epoch_timestamp(first)) {
                        patch->is_new = 1;
@@ -905,10 +944,12 @@ static void parse_traditional_patch(const char *first, const char *second, struc
                }
        }
        if (!name)
-               die(_("unable to find filename in patch at line %d"), linenr);
+               die(_("unable to find filename in patch at line %d"), state->linenr);
 }
 
-static int gitdiff_hdrend(const char *line, struct patch *patch)
+static int gitdiff_hdrend(struct apply_state *state,
+                         const char *line,
+                         struct patch *patch)
 {
        return -1;
 }
@@ -925,107 +966,135 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
 #define DIFF_OLD_NAME 0
 #define DIFF_NEW_NAME 1
 
-static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, int side)
+static void gitdiff_verify_name(struct apply_state *state,
+                               const char *line,
+                               int isnull,
+                               char **name,
+                               int side)
 {
-       if (!orig_name && !isnull)
-               return find_name(line, NULL, p_value, TERM_TAB);
+       if (!*name && !isnull) {
+               *name = find_name(state, line, NULL, state->p_value, TERM_TAB);
+               return;
+       }
 
-       if (orig_name) {
-               int len = strlen(orig_name);
+       if (*name) {
+               int len = strlen(*name);
                char *another;
                if (isnull)
                        die(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
-                           orig_name, linenr);
-               another = find_name(line, NULL, p_value, TERM_TAB);
-               if (!another || memcmp(another, orig_name, len + 1))
+                           *name, state->linenr);
+               another = find_name(state, line, NULL, state->p_value, TERM_TAB);
+               if (!another || memcmp(another, *name, len + 1))
                        die((side == DIFF_NEW_NAME) ?
                            _("git apply: bad git-diff - inconsistent new filename on line %d") :
-                           _("git apply: bad git-diff - inconsistent old filename on line %d"), linenr);
+                           _("git apply: bad git-diff - inconsistent old filename on line %d"), state->linenr);
                free(another);
-               return orig_name;
        } else {
                /* expect "/dev/null" */
                if (memcmp("/dev/null", line, 9) || line[9] != '\n')
-                       die(_("git apply: bad git-diff - expected /dev/null on line %d"), linenr);
-               return NULL;
+                       die(_("git apply: bad git-diff - expected /dev/null on line %d"), state->linenr);
        }
 }
 
-static int gitdiff_oldname(const char *line, struct patch *patch)
+static int gitdiff_oldname(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
-       patch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name,
-                                             DIFF_OLD_NAME);
+       gitdiff_verify_name(state, line,
+                           patch->is_new, &patch->old_name,
+                           DIFF_OLD_NAME);
        return 0;
 }
 
-static int gitdiff_newname(const char *line, struct patch *patch)
+static int gitdiff_newname(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
-       patch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name,
-                                             DIFF_NEW_NAME);
+       gitdiff_verify_name(state, line,
+                           patch->is_delete, &patch->new_name,
+                           DIFF_NEW_NAME);
        return 0;
 }
 
-static int gitdiff_oldmode(const char *line, struct patch *patch)
+static int gitdiff_oldmode(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
        patch->old_mode = strtoul(line, NULL, 8);
        return 0;
 }
 
-static int gitdiff_newmode(const char *line, struct patch *patch)
+static int gitdiff_newmode(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
        patch->new_mode = strtoul(line, NULL, 8);
        return 0;
 }
 
-static int gitdiff_delete(const char *line, struct patch *patch)
+static int gitdiff_delete(struct apply_state *state,
+                         const char *line,
+                         struct patch *patch)
 {
        patch->is_delete = 1;
        free(patch->old_name);
        patch->old_name = xstrdup_or_null(patch->def_name);
-       return gitdiff_oldmode(line, patch);
+       return gitdiff_oldmode(state, line, patch);
 }
 
-static int gitdiff_newfile(const char *line, struct patch *patch)
+static int gitdiff_newfile(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
        patch->is_new = 1;
        free(patch->new_name);
        patch->new_name = xstrdup_or_null(patch->def_name);
-       return gitdiff_newmode(line, patch);
+       return gitdiff_newmode(state, line, patch);
 }
 
-static int gitdiff_copysrc(const char *line, struct patch *patch)
+static int gitdiff_copysrc(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
        patch->is_copy = 1;
        free(patch->old_name);
-       patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
+       patch->old_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
        return 0;
 }
 
-static int gitdiff_copydst(const char *line, struct patch *patch)
+static int gitdiff_copydst(struct apply_state *state,
+                          const char *line,
+                          struct patch *patch)
 {
        patch->is_copy = 1;
        free(patch->new_name);
-       patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
+       patch->new_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
        return 0;
 }
 
-static int gitdiff_renamesrc(const char *line, struct patch *patch)
+static int gitdiff_renamesrc(struct apply_state *state,
+                            const char *line,
+                            struct patch *patch)
 {
        patch->is_rename = 1;
        free(patch->old_name);
-       patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
+       patch->old_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
        return 0;
 }
 
-static int gitdiff_renamedst(const char *line, struct patch *patch)
+static int gitdiff_renamedst(struct apply_state *state,
+                            const char *line,
+                            struct patch *patch)
 {
        patch->is_rename = 1;
        free(patch->new_name);
-       patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
+       patch->new_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
        return 0;
 }
 
-static int gitdiff_similarity(const char *line, struct patch *patch)
+static int gitdiff_similarity(struct apply_state *state,
+                             const char *line,
+                             struct patch *patch)
 {
        unsigned long val = strtoul(line, NULL, 10);
        if (val <= 100)
@@ -1033,7 +1102,9 @@ static int gitdiff_similarity(const char *line, struct patch *patch)
        return 0;
 }
 
-static int gitdiff_dissimilarity(const char *line, struct patch *patch)
+static int gitdiff_dissimilarity(struct apply_state *state,
+                                const char *line,
+                                struct patch *patch)
 {
        unsigned long val = strtoul(line, NULL, 10);
        if (val <= 100)
@@ -1041,7 +1112,9 @@ static int gitdiff_dissimilarity(const char *line, struct patch *patch)
        return 0;
 }
 
-static int gitdiff_index(const char *line, struct patch *patch)
+static int gitdiff_index(struct apply_state *state,
+                        const char *line,
+                        struct patch *patch)
 {
        /*
         * index line is N hexadecimal, "..", N hexadecimal,
@@ -1078,7 +1151,9 @@ static int gitdiff_index(const char *line, struct patch *patch)
  * This is normal for a diff that doesn't change anything: we'll fall through
  * into the next diff. Tell the parser to break out.
  */
-static int gitdiff_unrecognized(const char *line, struct patch *patch)
+static int gitdiff_unrecognized(struct apply_state *state,
+                               const char *line,
+                               struct patch *patch)
 {
        return -1;
 }
@@ -1087,15 +1162,17 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch)
  * Skip p_value leading components from "line"; as we do not accept
  * absolute paths, return NULL in that case.
  */
-static const char *skip_tree_prefix(const char *line, int llen)
+static const char *skip_tree_prefix(struct apply_state *state,
+                                   const char *line,
+                                   int llen)
 {
        int nslash;
        int i;
 
-       if (!p_value)
+       if (!state->p_value)
                return (llen && line[0] == '/') ? NULL : line;
 
-       nslash = p_value;
+       nslash = state->p_value;
        for (i = 0; i < llen; i++) {
                int ch = line[i];
                if (ch == '/' && --nslash <= 0)
@@ -1112,7 +1189,9 @@ static const char *skip_tree_prefix(const char *line, int llen)
  * creation or deletion of an empty file.  In any of these cases,
  * both sides are the same name under a/ and b/ respectively.
  */
-static char *git_header_name(const char *line, int llen)
+static char *git_header_name(struct apply_state *state,
+                            const char *line,
+                            int llen)
 {
        const char *name;
        const char *second = NULL;
@@ -1130,7 +1209,7 @@ static char *git_header_name(const char *line, int llen)
                        goto free_and_fail1;
 
                /* strip the a/b prefix including trailing slash */
-               cp = skip_tree_prefix(first.buf, first.len);
+               cp = skip_tree_prefix(state, first.buf, first.len);
                if (!cp)
                        goto free_and_fail1;
                strbuf_remove(&first, 0, cp - first.buf);
@@ -1147,7 +1226,7 @@ static char *git_header_name(const char *line, int llen)
                if (*second == '"') {
                        if (unquote_c_style(&sp, second, NULL))
                                goto free_and_fail1;
-                       cp = skip_tree_prefix(sp.buf, sp.len);
+                       cp = skip_tree_prefix(state, sp.buf, sp.len);
                        if (!cp)
                                goto free_and_fail1;
                        /* They must match, otherwise ignore */
@@ -1158,7 +1237,7 @@ static char *git_header_name(const char *line, int llen)
                }
 
                /* unquoted second */
-               cp = skip_tree_prefix(second, line + llen - second);
+               cp = skip_tree_prefix(state, second, line + llen - second);
                if (!cp)
                        goto free_and_fail1;
                if (line + llen - cp != first.len ||
@@ -1173,7 +1252,7 @@ static char *git_header_name(const char *line, int llen)
        }
 
        /* unquoted first name */
-       name = skip_tree_prefix(line, llen);
+       name = skip_tree_prefix(state, line, llen);
        if (!name)
                return NULL;
 
@@ -1189,7 +1268,7 @@ static char *git_header_name(const char *line, int llen)
                        if (unquote_c_style(&sp, second, NULL))
                                goto free_and_fail2;
 
-                       np = skip_tree_prefix(sp.buf, sp.len);
+                       np = skip_tree_prefix(state, sp.buf, sp.len);
                        if (!np)
                                goto free_and_fail2;
 
@@ -1233,7 +1312,7 @@ static char *git_header_name(const char *line, int llen)
                         */
                        if (!name[len + 1])
                                return NULL; /* no postimage name */
-                       second = skip_tree_prefix(name + len + 1,
+                       second = skip_tree_prefix(state, name + len + 1,
                                                  line_len - (len + 1));
                        if (!second)
                                return NULL;
@@ -1249,7 +1328,11 @@ static char *git_header_name(const char *line, int llen)
 }
 
 /* Verify that we recognize the lines following a git header */
-static int parse_git_header(const char *line, int len, unsigned int size, struct patch *patch)
+static int parse_git_header(struct apply_state *state,
+                           const char *line,
+                           int len,
+                           unsigned int size,
+                           struct patch *patch)
 {
        unsigned long offset;
 
@@ -1263,20 +1346,20 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
         * or removing or adding empty files), so we get
         * the default name from the header.
         */
-       patch->def_name = git_header_name(line, len);
-       if (patch->def_name && root.len) {
-               char *s = xstrfmt("%s%s", root.buf, patch->def_name);
+       patch->def_name = git_header_name(state, line, len);
+       if (patch->def_name && state->root.len) {
+               char *s = xstrfmt("%s%s", state->root.buf, patch->def_name);
                free(patch->def_name);
                patch->def_name = s;
        }
 
        line += len;
        size -= len;
-       linenr++;
-       for (offset = len ; size > 0 ; offset += len, size -= len, line += len, linenr++) {
+       state->linenr++;
+       for (offset = len ; size > 0 ; offset += len, size -= len, line += len, state->linenr++) {
                static const struct opentry {
                        const char *str;
-                       int (*fn)(const char *, struct patch *);
+                       int (*fn)(struct apply_state *, const char *, struct patch *);
                } optable[] = {
                        { "@@ -", gitdiff_hdrend },
                        { "--- ", gitdiff_oldname },
@@ -1306,7 +1389,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
                        int oplen = strlen(p->str);
                        if (len < oplen || memcmp(p->str, line, oplen))
                                continue;
-                       if (p->fn(line + oplen, patch) < 0)
+                       if (p->fn(state, line + oplen, patch) < 0)
                                return offset;
                        break;
                }
@@ -1431,7 +1514,11 @@ static int parse_fragment_header(const char *line, int len, struct fragment *fra
        return offset;
 }
 
-static int find_header(const char *line, unsigned long size, int *hdrsize, struct patch *patch)
+static int find_header(struct apply_state *state,
+                      const char *line,
+                      unsigned long size,
+                      int *hdrsize,
+                      struct patch *patch)
 {
        unsigned long offset, len;
 
@@ -1440,7 +1527,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc
        patch->is_new = patch->is_delete = -1;
        patch->old_mode = patch->new_mode = 0;
        patch->old_name = patch->new_name = NULL;
-       for (offset = 0; size > 0; offset += len, size -= len, line += len, linenr++) {
+       for (offset = 0; size > 0; offset += len, size -= len, line += len, state->linenr++) {
                unsigned long nextlen;
 
                len = linelen(line, size);
@@ -1461,7 +1548,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc
                        if (parse_fragment_header(line, len, &dummy) < 0)
                                continue;
                        die(_("patch fragment without header at line %d: %.*s"),
-                           linenr, (int)len-1, line);
+                           state->linenr, (int)len-1, line);
                }
 
                if (size < len + 6)
@@ -1472,7 +1559,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc
                 * or mode change, so we handle that specially
                 */
                if (!memcmp("diff --git ", line, 11)) {
-                       int git_hdr_len = parse_git_header(line, len, size, patch);
+                       int git_hdr_len = parse_git_header(state, line, len, size, patch);
                        if (git_hdr_len <= len)
                                continue;
                        if (!patch->old_name && !patch->new_name) {
@@ -1481,14 +1568,14 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc
                                               "%d leading pathname component (line %d)",
                                               "git diff header lacks filename information when removing "
                                               "%d leading pathname components (line %d)",
-                                              p_value),
-                                           p_value, linenr);
+                                              state->p_value),
+                                           state->p_value, state->linenr);
                                patch->old_name = xstrdup(patch->def_name);
                                patch->new_name = xstrdup(patch->def_name);
                        }
                        if (!patch->is_delete && !patch->new_name)
                                die("git diff header lacks filename information "
-                                   "(line %d)", linenr);
+                                   "(line %d)", state->linenr);
                        patch->is_toplevel_relative = 1;
                        *hdrsize = git_hdr_len;
                        return offset;
@@ -1508,37 +1595,44 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc
                        continue;
 
                /* Ok, we'll consider it a patch */
-               parse_traditional_patch(line, line+len, patch);
+               parse_traditional_patch(state, line, line+len, patch);
                *hdrsize = len + nextlen;
-               linenr += 2;
+               state->linenr += 2;
                return offset;
        }
        return -1;
 }
 
-static void record_ws_error(unsigned result, const char *line, int len, int linenr)
+static void record_ws_error(struct apply_state *state,
+                           unsigned result,
+                           const char *line,
+                           int len,
+                           int linenr)
 {
        char *err;
 
        if (!result)
                return;
 
-       whitespace_error++;
-       if (squelch_whitespace_errors &&
-           squelch_whitespace_errors < whitespace_error)
+       state->whitespace_error++;
+       if (state->squelch_whitespace_errors &&
+           state->squelch_whitespace_errors < state->whitespace_error)
                return;
 
        err = whitespace_error_string(result);
        fprintf(stderr, "%s:%d: %s.\n%.*s\n",
-               patch_input_file, linenr, err, len, line);
+               state->patch_input_file, linenr, err, len, line);
        free(err);
 }
 
-static void check_whitespace(const char *line, int len, unsigned ws_rule)
+static void check_whitespace(struct apply_state *state,
+                            const char *line,
+                            int len,
+                            unsigned ws_rule)
 {
        unsigned result = ws_check(line + 1, len - 1, ws_rule);
 
-       record_ws_error(result, line + 1, len - 2, linenr);
+       record_ws_error(state, result, line + 1, len - 2, state->linenr);
 }
 
 /*
@@ -1547,8 +1641,11 @@ static void check_whitespace(const char *line, int len, unsigned ws_rule)
  * between a "---" that is part of a patch, and a "---" that starts
  * the next patch is to look at the line counts..
  */
-static int parse_fragment(const char *line, unsigned long size,
-                         struct patch *patch, struct fragment *fragment)
+static int parse_fragment(struct apply_state *state,
+                         const char *line,
+                         unsigned long size,
+                         struct patch *patch,
+                         struct fragment *fragment)
 {
        int added, deleted;
        int len = linelen(line, size), offset;
@@ -1568,11 +1665,11 @@ static int parse_fragment(const char *line, unsigned long size,
        /* Parse the thing.. */
        line += len;
        size -= len;
-       linenr++;
+       state->linenr++;
        added = deleted = 0;
        for (offset = len;
             0 < size;
-            offset += len, size -= len, line += len, linenr++) {
+            offset += len, size -= len, line += len, state->linenr++) {
                if (!oldlines && !newlines)
                        break;
                len = linelen(line, size);
@@ -1588,22 +1685,22 @@ static int parse_fragment(const char *line, unsigned long size,
                        if (!deleted && !added)
                                leading++;
                        trailing++;
-                       if (!apply_in_reverse &&
-                           ws_error_action == correct_ws_error)
-                               check_whitespace(line, len, patch->ws_rule);
+                       if (!state->apply_in_reverse &&
+                           state->ws_error_action == correct_ws_error)
+                               check_whitespace(state, line, len, patch->ws_rule);
                        break;
                case '-':
-                       if (apply_in_reverse &&
-                           ws_error_action != nowarn_ws_error)
-                               check_whitespace(line, len, patch->ws_rule);
+                       if (state->apply_in_reverse &&
+                           state->ws_error_action != nowarn_ws_error)
+                               check_whitespace(state, line, len, patch->ws_rule);
                        deleted++;
                        oldlines--;
                        trailing = 0;
                        break;
                case '+':
-                       if (!apply_in_reverse &&
-                           ws_error_action != nowarn_ws_error)
-                               check_whitespace(line, len, patch->ws_rule);
+                       if (!state->apply_in_reverse &&
+                           state->ws_error_action != nowarn_ws_error)
+                               check_whitespace(state, line, len, patch->ws_rule);
                        added++;
                        newlines--;
                        trailing = 0;
@@ -1657,7 +1754,10 @@ static int parse_fragment(const char *line, unsigned long size,
  * The (fragment->patch, fragment->size) pair points into the memory given
  * by the caller, not a copy, when we return.
  */
-static int parse_single_patch(const char *line, unsigned long size, struct patch *patch)
+static int parse_single_patch(struct apply_state *state,
+                             const char *line,
+                             unsigned long size,
+                             struct patch *patch)
 {
        unsigned long offset = 0;
        unsigned long oldlines = 0, newlines = 0, context = 0;
@@ -1668,10 +1768,10 @@ static int parse_single_patch(const char *line, unsigned long size, struct patch
                int len;
 
                fragment = xcalloc(1, sizeof(*fragment));
-               fragment->linenr = linenr;
-               len = parse_fragment(line, size, patch, fragment);
+               fragment->linenr = state->linenr;
+               len = parse_fragment(state, line, size, patch, fragment);
                if (len <= 0)
-                       die(_("corrupt patch at line %d"), linenr);
+                       die(_("corrupt patch at line %d"), state->linenr);
                fragment->patch = line;
                fragment->size = len;
                oldlines += fragment->oldlines;
@@ -1757,7 +1857,8 @@ static char *inflate_it(const void *data, unsigned long size,
  * points at an allocated memory that the caller must free, so
  * it is marked as "->free_patch = 1".
  */
-static struct fragment *parse_binary_hunk(char **buf_p,
+static struct fragment *parse_binary_hunk(struct apply_state *state,
+                                         char **buf_p,
                                          unsigned long *sz_p,
                                          int *status_p,
                                          int *used_p)
@@ -1799,13 +1900,13 @@ static struct fragment *parse_binary_hunk(char **buf_p,
        else
                return NULL;
 
-       linenr++;
+       state->linenr++;
        buffer += llen;
        while (1) {
                int byte_length, max_byte_length, newsize;
                llen = linelen(buffer, size);
                used += llen;
-               linenr++;
+               state->linenr++;
                if (llen == 1) {
                        /* consume the blank line */
                        buffer++;
@@ -1859,7 +1960,7 @@ static struct fragment *parse_binary_hunk(char **buf_p,
        free(data);
        *status_p = -1;
        error(_("corrupt binary patch at line %d: %.*s"),
-             linenr-1, llen-1, buffer);
+             state->linenr-1, llen-1, buffer);
        return NULL;
 }
 
@@ -1868,7 +1969,10 @@ static struct fragment *parse_binary_hunk(char **buf_p,
  *   -1 in case of error,
  *   the length of the parsed binary patch otherwise
  */
-static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
+static int parse_binary(struct apply_state *state,
+                       char *buffer,
+                       unsigned long size,
+                       struct patch *patch)
 {
        /*
         * We have read "GIT binary patch\n"; what follows is a line
@@ -1889,15 +1993,15 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
        int status;
        int used, used_1;
 
-       forward = parse_binary_hunk(&buffer, &size, &status, &used);
+       forward = parse_binary_hunk(state, &buffer, &size, &status, &used);
        if (!forward && !status)
                /* there has to be one hunk (forward hunk) */
-               return error(_("unrecognized binary patch at line %d"), linenr-1);
+               return error(_("unrecognized binary patch at line %d"), state->linenr-1);
        if (status)
                /* otherwise we already gave an error message */
                return status;
 
-       reverse = parse_binary_hunk(&buffer, &size, &status, &used_1);
+       reverse = parse_binary_hunk(state, &buffer, &size, &status, &used_1);
        if (reverse)
                used += used_1;
        else if (status) {
@@ -1915,53 +2019,53 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
        return used;
 }
 
-static void prefix_one(char **name)
+static void prefix_one(struct apply_state *state, char **name)
 {
        char *old_name = *name;
        if (!old_name)
                return;
-       *name = xstrdup(prefix_filename(prefix, prefix_length, *name));
+       *name = xstrdup(prefix_filename(state->prefix, state->prefix_length, *name));
        free(old_name);
 }
 
-static void prefix_patch(struct patch *p)
+static void prefix_patch(struct apply_state *state, struct patch *p)
 {
-       if (!prefix || p->is_toplevel_relative)
+       if (!state->prefix || p->is_toplevel_relative)
                return;
-       prefix_one(&p->new_name);
-       prefix_one(&p->old_name);
+       prefix_one(state, &p->new_name);
+       prefix_one(state, &p->old_name);
 }
 
 /*
  * include/exclude
  */
 
-static struct string_list limit_by_name;
-static int has_include;
-static void add_name_limit(const char *name, int exclude)
+static void add_name_limit(struct apply_state *state,
+                          const char *name,
+                          int exclude)
 {
        struct string_list_item *it;
 
-       it = string_list_append(&limit_by_name, name);
+       it = string_list_append(&state->limit_by_name, name);
        it->util = exclude ? NULL : (void *) 1;
 }
 
-static int use_patch(struct patch *p)
+static int use_patch(struct apply_state *state, struct patch *p)
 {
        const char *pathname = p->new_name ? p->new_name : p->old_name;
        int i;
 
        /* Paths outside are not touched regardless of "--include" */
-       if (0 < prefix_length) {
+       if (0 < state->prefix_length) {
                int pathlen = strlen(pathname);
-               if (pathlen <= prefix_length ||
-                   memcmp(prefix, pathname, prefix_length))
+               if (pathlen <= state->prefix_length ||
+                   memcmp(state->prefix, pathname, state->prefix_length))
                        return 0;
        }
 
        /* See if it matches any of exclude/include rule */
-       for (i = 0; i < limit_by_name.nr; i++) {
-               struct string_list_item *it = &limit_by_name.items[i];
+       for (i = 0; i < state->limit_by_name.nr; i++) {
+               struct string_list_item *it = &state->limit_by_name.items[i];
                if (!wildmatch(it->string, pathname, 0, NULL))
                        return (it->util != NULL);
        }
@@ -1971,7 +2075,7 @@ static int use_patch(struct patch *p)
         * not used.  Otherwise, we saw bunch of exclude rules (or none)
         * and such a path is used.
         */
-       return !has_include;
+       return !state->has_include;
 }
 
 
@@ -1982,25 +2086,27 @@ static int use_patch(struct patch *p)
  * Return the number of bytes consumed, so that the caller can call us
  * again for the next patch.
  */
-static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
+static int parse_chunk(struct apply_state *state, char *buffer, unsigned long size, struct patch *patch)
 {
        int hdrsize, patchsize;
-       int offset = find_header(buffer, size, &hdrsize, patch);
+       int offset = find_header(state, buffer, size, &hdrsize, patch);
 
        if (offset < 0)
                return offset;
 
-       prefix_patch(patch);
+       prefix_patch(state, patch);
 
-       if (!use_patch(patch))
+       if (!use_patch(state, patch))
                patch->ws_rule = 0;
        else
                patch->ws_rule = whitespace_rule(patch->new_name
                                                 ? patch->new_name
                                                 : patch->old_name);
 
-       patchsize = parse_single_patch(buffer + offset + hdrsize,
-                                      size - offset - hdrsize, patch);
+       patchsize = parse_single_patch(state,
+                                      buffer + offset + hdrsize,
+                                      size - offset - hdrsize,
+                                      patch);
 
        if (!patchsize) {
                static const char git_binary[] = "GIT binary patch\n";
@@ -2010,8 +2116,8 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
                if (llen == sizeof(git_binary) - 1 &&
                    !memcmp(git_binary, buffer + hd, llen)) {
                        int used;
-                       linenr++;
-                       used = parse_binary(buffer + hd + llen,
+                       state->linenr++;
+                       used = parse_binary(state, buffer + hd + llen,
                                            size - hd - llen, patch);
                        if (used < 0)
                                return -1;
@@ -2031,7 +2137,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
                                int len = strlen(binhdr[i]);
                                if (len < size - hd &&
                                    !memcmp(binhdr[i], buffer + hd, len)) {
-                                       linenr++;
+                                       state->linenr++;
                                        patch->is_binary = 1;
                                        patchsize = llen;
                                        break;
@@ -2043,9 +2149,9 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
                 * without metadata change.  A binary patch appears
                 * empty to us here.
                 */
-               if ((apply || check) &&
+               if ((state->apply || state->check) &&
                    (!patch->is_binary && !metadata_changes(patch)))
-                       die(_("patch with only garbage at line %d"), linenr);
+                       die(_("patch with only garbage at line %d"), state->linenr);
        }
 
        return offset + hdrsize + patchsize;
@@ -2083,7 +2189,7 @@ static const char pluses[] =
 static const char minuses[]=
 "----------------------------------------------------------------------";
 
-static void show_stats(struct patch *patch)
+static void show_stats(struct apply_state *state, struct patch *patch)
 {
        struct strbuf qname = STRBUF_INIT;
        char *cp = patch->new_name ? patch->new_name : patch->old_name;
@@ -2094,7 +2200,7 @@ static void show_stats(struct patch *patch)
        /*
         * "scale" the filename
         */
-       max = max_len;
+       max = state->max_len;
        if (max > 50)
                max = 50;
 
@@ -2117,13 +2223,13 @@ static void show_stats(struct patch *patch)
        /*
         * scale the add/delete
         */
-       max = max + max_change > 70 ? 70 - max : max_change;
+       max = max + state->max_change > 70 ? 70 - max : state->max_change;
        add = patch->lines_added;
        del = patch->lines_deleted;
 
-       if (max_change > 0) {
-               int total = ((add + del) * max + max_change / 2) / max_change;
-               add = (add * max + max_change / 2) / max_change;
+       if (state->max_change > 0) {
+               int total = ((add + del) * max + state->max_change / 2) / state->max_change;
+               add = (add * max + state->max_change / 2) / state->max_change;
                del = total - add;
        }
        printf("%5d %.*s%.*s\n", patch->lines_added + patch->lines_deleted,
@@ -2194,17 +2300,17 @@ static void update_pre_post_images(struct image *preimage,
        fixed = preimage->buf;
 
        for (i = reduced = ctx = 0; i < postimage->nr; i++) {
-               size_t len = postimage->line[i].len;
+               size_t l_len = postimage->line[i].len;
                if (!(postimage->line[i].flag & LINE_COMMON)) {
                        /* an added line -- no counterparts in preimage */
-                       memmove(new, old, len);
-                       old += len;
-                       new += len;
+                       memmove(new, old, l_len);
+                       old += l_len;
+                       new += l_len;
                        continue;
                }
 
                /* a common context -- skip it in the original postimage */
-               old += len;
+               old += l_len;
 
                /* and find the corresponding one in the fixed preimage */
                while (ctx < preimage->nr &&
@@ -2223,11 +2329,11 @@ static void update_pre_post_images(struct image *preimage,
                }
 
                /* and copy it in, while fixing the line length */
-               len = preimage->line[ctx].len;
-               memcpy(new, fixed, len);
-               new += len;
-               fixed += len;
-               postimage->line[i].len = len;
+               l_len = preimage->line[ctx].len;
+               memcpy(new, fixed, l_len);
+               new += l_len;
+               fixed += l_len;
+               postimage->line[i].len = l_len;
                ctx++;
        }
 
@@ -2242,7 +2348,76 @@ static void update_pre_post_images(struct image *preimage,
        postimage->nr -= reduced;
 }
 
-static int match_fragment(struct image *img,
+static int line_by_line_fuzzy_match(struct image *img,
+                                   struct image *preimage,
+                                   struct image *postimage,
+                                   unsigned long try,
+                                   int try_lno,
+                                   int preimage_limit)
+{
+       int i;
+       size_t imgoff = 0;
+       size_t preoff = 0;
+       size_t postlen = postimage->len;
+       size_t extra_chars;
+       char *buf;
+       char *preimage_eof;
+       char *preimage_end;
+       struct strbuf fixed;
+       char *fixed_buf;
+       size_t fixed_len;
+
+       for (i = 0; i < preimage_limit; i++) {
+               size_t prelen = preimage->line[i].len;
+               size_t imglen = img->line[try_lno+i].len;
+
+               if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
+                                     preimage->buf + preoff, prelen))
+                       return 0;
+               if (preimage->line[i].flag & LINE_COMMON)
+                       postlen += imglen - prelen;
+               imgoff += imglen;
+               preoff += prelen;
+       }
+
+       /*
+        * Ok, the preimage matches with whitespace fuzz.
+        *
+        * imgoff now holds the true length of the target that
+        * matches the preimage before the end of the file.
+        *
+        * Count the number of characters in the preimage that fall
+        * beyond the end of the file and make sure that all of them
+        * are whitespace characters. (This can only happen if
+        * we are removing blank lines at the end of the file.)
+        */
+       buf = preimage_eof = preimage->buf + preoff;
+       for ( ; i < preimage->nr; i++)
+               preoff += preimage->line[i].len;
+       preimage_end = preimage->buf + preoff;
+       for ( ; buf < preimage_end; buf++)
+               if (!isspace(*buf))
+                       return 0;
+
+       /*
+        * Update the preimage and the common postimage context
+        * lines to use the same whitespace as the target.
+        * If whitespace is missing in the target (i.e.
+        * if the preimage extends beyond the end of the file),
+        * use the whitespace from the preimage.
+        */
+       extra_chars = preimage_end - preimage_eof;
+       strbuf_init(&fixed, imgoff + extra_chars);
+       strbuf_add(&fixed, img->buf + try, imgoff);
+       strbuf_add(&fixed, preimage_eof, extra_chars);
+       fixed_buf = strbuf_detach(&fixed, &fixed_len);
+       update_pre_post_images(preimage, postimage,
+                              fixed_buf, fixed_len, postlen);
+       return 1;
+}
+
+static int match_fragment(struct apply_state *state,
+                         struct image *img,
                          struct image *preimage,
                          struct image *postimage,
                          unsigned long try,
@@ -2263,7 +2438,7 @@ static int match_fragment(struct image *img,
                preimage_limit = preimage->nr;
                if (match_end && (preimage->nr + try_lno != img->nr))
                        return 0;
-       } else if (ws_error_action == correct_ws_error &&
+       } else if (state->ws_error_action == correct_ws_error &&
                   (ws_rule & WS_BLANK_AT_EOF)) {
                /*
                 * This hunk extends beyond the end of img, and we are
@@ -2331,63 +2506,11 @@ static int match_fragment(struct image *img,
         * fuzzy matching. We collect all the line length information because
         * we need it to adjust whitespace if we match.
         */
-       if (ws_ignore_action == ignore_ws_change) {
-               size_t imgoff = 0;
-               size_t preoff = 0;
-               size_t postlen = postimage->len;
-               size_t extra_chars;
-               char *preimage_eof;
-               char *preimage_end;
-               for (i = 0; i < preimage_limit; i++) {
-                       size_t prelen = preimage->line[i].len;
-                       size_t imglen = img->line[try_lno+i].len;
-
-                       if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
-                                             preimage->buf + preoff, prelen))
-                               return 0;
-                       if (preimage->line[i].flag & LINE_COMMON)
-                               postlen += imglen - prelen;
-                       imgoff += imglen;
-                       preoff += prelen;
-               }
+       if (state->ws_ignore_action == ignore_ws_change)
+               return line_by_line_fuzzy_match(img, preimage, postimage,
+                                               try, try_lno, preimage_limit);
 
-               /*
-                * Ok, the preimage matches with whitespace fuzz.
-                *
-                * imgoff now holds the true length of the target that
-                * matches the preimage before the end of the file.
-                *
-                * Count the number of characters in the preimage that fall
-                * beyond the end of the file and make sure that all of them
-                * are whitespace characters. (This can only happen if
-                * we are removing blank lines at the end of the file.)
-                */
-               buf = preimage_eof = preimage->buf + preoff;
-               for ( ; i < preimage->nr; i++)
-                       preoff += preimage->line[i].len;
-               preimage_end = preimage->buf + preoff;
-               for ( ; buf < preimage_end; buf++)
-                       if (!isspace(*buf))
-                               return 0;
-
-               /*
-                * Update the preimage and the common postimage context
-                * lines to use the same whitespace as the target.
-                * If whitespace is missing in the target (i.e.
-                * if the preimage extends beyond the end of the file),
-                * use the whitespace from the preimage.
-                */
-               extra_chars = preimage_end - preimage_eof;
-               strbuf_init(&fixed, imgoff + extra_chars);
-               strbuf_add(&fixed, img->buf + try, imgoff);
-               strbuf_add(&fixed, preimage_eof, extra_chars);
-               fixed_buf = strbuf_detach(&fixed, &fixed_len);
-               update_pre_post_images(preimage, postimage,
-                               fixed_buf, fixed_len, postlen);
-               return 1;
-       }
-
-       if (ws_error_action != correct_ws_error)
+       if (state->ws_error_action != correct_ws_error)
                return 0;
 
        /*
@@ -2499,7 +2622,8 @@ static int match_fragment(struct image *img,
        return 0;
 }
 
-static int find_pos(struct image *img,
+static int find_pos(struct apply_state *state,
+                   struct image *img,
                    struct image *preimage,
                    struct image *postimage,
                    int line,
@@ -2543,7 +2667,7 @@ static int find_pos(struct image *img,
        try_lno = line;
 
        for (i = 0; ; i++) {
-               if (match_fragment(img, preimage, postimage,
+               if (match_fragment(state, img, preimage, postimage,
                                   try, try_lno, ws_rule,
                                   match_beginning, match_end))
                        return try_lno;
@@ -2594,7 +2718,8 @@ static void remove_last_line(struct image *img)
  * apply at applied_pos (counts in line numbers) in "img".
  * Update "img" to remove "preimage" and replace it with "postimage".
  */
-static void update_image(struct image *img,
+static void update_image(struct apply_state *state,
+                        struct image *img,
                         int applied_pos,
                         struct image *preimage,
                         struct image *postimage)
@@ -2659,7 +2784,7 @@ static void update_image(struct image *img,
        memcpy(img->line + applied_pos,
               postimage->line,
               postimage->nr * sizeof(*img->line));
-       if (!allow_overlap)
+       if (!state->allow_overlap)
                for (i = 0; i < postimage->nr; i++)
                        img->line[applied_pos + i].flag |= LINE_PATCHED;
        img->nr = nr;
@@ -2670,7 +2795,8 @@ static void update_image(struct image *img,
  * postimage) for the hunk.  Find lines that match "preimage" in "img" and
  * replace the part of "img" with "postimage" text.
  */
-static int apply_one_fragment(struct image *img, struct fragment *frag,
+static int apply_one_fragment(struct apply_state *state,
+                             struct image *img, struct fragment *frag,
                              int inaccurate_eof, unsigned ws_rule,
                              int nth_fragment)
 {
@@ -2715,7 +2841,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
                if (len < size && patch[len] == '\\')
                        plen--;
                first = *patch;
-               if (apply_in_reverse) {
+               if (state->apply_in_reverse) {
                        if (first == '-')
                                first = '+';
                        else if (first == '+')
@@ -2748,17 +2874,17 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
                /* Fall-through for ' ' */
                case '+':
                        /* --no-add does not add new lines */
-                       if (first == '+' && no_add)
+                       if (first == '+' && state->no_add)
                                break;
 
                        start = newlines.len;
                        if (first != '+' ||
-                           !whitespace_error ||
-                           ws_error_action != correct_ws_error) {
+                           !state->whitespace_error ||
+                           state->ws_error_action != correct_ws_error) {
                                strbuf_add(&newlines, patch + 1, plen);
                        }
                        else {
-                               ws_fix_copy(&newlines, patch + 1, plen, ws_rule, &applied_after_fixing_ws);
+                               ws_fix_copy(&newlines, patch + 1, plen, ws_rule, &state->applied_after_fixing_ws);
                        }
                        add_line_info(&postimage, newlines.buf + start, newlines.len - start,
                                      (first == '+' ? 0 : LINE_COMMON));
@@ -2771,7 +2897,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
                        /* Ignore it, we already handled it */
                        break;
                default:
-                       if (apply_verbosely)
+                       if (state->apply_verbosely)
                                error(_("invalid start of line: '%c'"), first);
                        applied_pos = -1;
                        goto out;
@@ -2812,7 +2938,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
         * without leading context must match at the beginning.
         */
        match_beginning = (!frag->oldpos ||
-                          (frag->oldpos == 1 && !unidiff_zero));
+                          (frag->oldpos == 1 && !state->unidiff_zero));
 
        /*
         * A hunk without trailing lines must match at the end.
@@ -2820,7 +2946,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
         * from the lack of trailing lines if the patch was generated
         * with unidiff without any context.
         */
-       match_end = !unidiff_zero && !trailing;
+       match_end = !state->unidiff_zero && !trailing;
 
        pos = frag->newpos ? (frag->newpos - 1) : 0;
        preimage.buf = oldlines;
@@ -2832,14 +2958,14 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
 
        for (;;) {
 
-               applied_pos = find_pos(img, &preimage, &postimage, pos,
+               applied_pos = find_pos(state, img, &preimage, &postimage, pos,
                                       ws_rule, match_beginning, match_end);
 
                if (applied_pos >= 0)
                        break;
 
                /* Am I at my context limits? */
-               if ((leading <= p_context) && (trailing <= p_context))
+               if ((leading <= state->p_context) && (trailing <= state->p_context))
                        break;
                if (match_beginning || match_end) {
                        match_beginning = match_end = 0;
@@ -2868,10 +2994,10 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
                if (new_blank_lines_at_end &&
                    preimage.nr + applied_pos >= img->nr &&
                    (ws_rule & WS_BLANK_AT_EOF) &&
-                   ws_error_action != nowarn_ws_error) {
-                       record_ws_error(WS_BLANK_AT_EOF, "+", 1,
+                   state->ws_error_action != nowarn_ws_error) {
+                       record_ws_error(state, WS_BLANK_AT_EOF, "+", 1,
                                        found_new_blank_lines_at_end);
-                       if (ws_error_action == correct_ws_error) {
+                       if (state->ws_error_action == correct_ws_error) {
                                while (new_blank_lines_at_end--)
                                        remove_last_line(&postimage);
                        }
@@ -2882,13 +3008,13 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
                         * apply_patch->check_patch_list->check_patch->
                         * apply_data->apply_fragments->apply_one_fragment
                         */
-                       if (ws_error_action == die_on_ws_error)
-                               apply = 0;
+                       if (state->ws_error_action == die_on_ws_error)
+                               state->apply = 0;
                }
 
-               if (apply_verbosely && applied_pos != pos) {
+               if (state->apply_verbosely && applied_pos != pos) {
                        int offset = applied_pos - pos;
-                       if (apply_in_reverse)
+                       if (state->apply_in_reverse)
                                offset = 0 - offset;
                        fprintf_ln(stderr,
                                   Q_("Hunk #%d succeeded at %d (offset %d line).",
@@ -2906,9 +3032,9 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
                        fprintf_ln(stderr, _("Context reduced to (%ld/%ld)"
                                             " to apply fragment at %d"),
                                   leading, trailing, applied_pos+1);
-               update_image(img, applied_pos, &preimage, &postimage);
+               update_image(state, img, applied_pos, &preimage, &postimage);
        } else {
-               if (apply_verbosely)
+               if (state->apply_verbosely)
                        error(_("while searching for:\n%.*s"),
                              (int)(old - oldlines), oldlines);
        }
@@ -2922,7 +3048,9 @@ out:
        return (applied_pos < 0);
 }
 
-static int apply_binary_fragment(struct image *img, struct patch *patch)
+static int apply_binary_fragment(struct apply_state *state,
+                                struct image *img,
+                                struct patch *patch)
 {
        struct fragment *fragment = patch->fragments;
        unsigned long len;
@@ -2935,7 +3063,7 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)
                             patch->old_name);
 
        /* Binary patch is irreversible without the optional second hunk */
-       if (apply_in_reverse) {
+       if (state->apply_in_reverse) {
                if (!fragment->next)
                        return error("cannot reverse-apply a binary patch "
                                     "without the reverse hunk to '%s'",
@@ -2968,7 +3096,9 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)
  * but the preimage prepared by the caller in "img" is freed here
  * or in the helper function apply_binary_fragment() this calls.
  */
-static int apply_binary(struct image *img, struct patch *patch)
+static int apply_binary(struct apply_state *state,
+                       struct image *img,
+                       struct patch *patch)
 {
        const char *name = patch->old_name ? patch->old_name : patch->new_name;
        unsigned char sha1[20];
@@ -3029,7 +3159,7 @@ static int apply_binary(struct image *img, struct patch *patch)
                 * apply the patch data to it, which is stored
                 * in the patch->fragments->{patch,size}.
                 */
-               if (apply_binary_fragment(img, patch))
+               if (apply_binary_fragment(state, img, patch))
                        return error(_("binary patch does not apply to '%s'"),
                                     name);
 
@@ -3043,7 +3173,7 @@ static int apply_binary(struct image *img, struct patch *patch)
        return 0;
 }
 
-static int apply_fragments(struct image *img, struct patch *patch)
+static int apply_fragments(struct apply_state *state, struct image *img, struct patch *patch)
 {
        struct fragment *frag = patch->fragments;
        const char *name = patch->old_name ? patch->old_name : patch->new_name;
@@ -3052,13 +3182,13 @@ static int apply_fragments(struct image *img, struct patch *patch)
        int nth = 0;
 
        if (patch->is_binary)
-               return apply_binary(img, patch);
+               return apply_binary(state, img, patch);
 
        while (frag) {
                nth++;
-               if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) {
+               if (apply_one_fragment(state, img, frag, inaccurate_eof, ws_rule, nth)) {
                        error(_("patch failed: %s:%ld"), name, frag->oldpos);
-                       if (!apply_with_reject)
+                       if (!state->apply_with_reject)
                                return -1;
                        frag->rejected = 1;
                }
@@ -3093,14 +3223,14 @@ static int read_file_or_gitlink(const struct cache_entry *ce, struct strbuf *buf
        return read_blob_object(buf, ce->sha1, ce->ce_mode);
 }
 
-static struct patch *in_fn_table(const char *name)
+static struct patch *in_fn_table(struct apply_state *state, const char *name)
 {
        struct string_list_item *item;
 
        if (name == NULL)
                return NULL;
 
-       item = string_list_lookup(&fn_table, name);
+       item = string_list_lookup(&state->fn_table, name);
        if (item != NULL)
                return (struct patch *)item->util;
 
@@ -3132,7 +3262,7 @@ static int was_deleted(struct patch *patch)
        return patch == PATH_WAS_DELETED;
 }
 
-static void add_to_fn_table(struct patch *patch)
+static void add_to_fn_table(struct apply_state *state, struct patch *patch)
 {
        struct string_list_item *item;
 
@@ -3142,7 +3272,7 @@ static void add_to_fn_table(struct patch *patch)
         * file creations and copies
         */
        if (patch->new_name != NULL) {
-               item = string_list_insert(&fn_table, patch->new_name);
+               item = string_list_insert(&state->fn_table, patch->new_name);
                item->util = patch;
        }
 
@@ -3151,12 +3281,12 @@ static void add_to_fn_table(struct patch *patch)
         * later chunks shouldn't patch old names
         */
        if ((patch->new_name == NULL) || (patch->is_rename)) {
-               item = string_list_insert(&fn_table, patch->old_name);
+               item = string_list_insert(&state->fn_table, patch->old_name);
                item->util = PATH_WAS_DELETED;
        }
 }
 
-static void prepare_fn_table(struct patch *patch)
+static void prepare_fn_table(struct apply_state *state, struct patch *patch)
 {
        /*
         * store information about incoming file deletion
@@ -3164,7 +3294,7 @@ static void prepare_fn_table(struct patch *patch)
        while (patch) {
                if ((patch->new_name == NULL) || (patch->is_rename)) {
                        struct string_list_item *item;
-                       item = string_list_insert(&fn_table, patch->old_name);
+                       item = string_list_insert(&state->fn_table, patch->old_name);
                        item->util = PATH_TO_BE_DELETED;
                }
                patch = patch->next;
@@ -3185,7 +3315,9 @@ static int checkout_target(struct index_state *istate,
        return 0;
 }
 
-static struct patch *previous_patch(struct patch *patch, int *gone)
+static struct patch *previous_patch(struct apply_state *state,
+                                   struct patch *patch,
+                                   int *gone)
 {
        struct patch *previous;
 
@@ -3193,7 +3325,7 @@ static struct patch *previous_patch(struct patch *patch, int *gone)
        if (patch->is_copy || patch->is_rename)
                return NULL; /* "git" patches do not depend on the order */
 
-       previous = in_fn_table(patch->old_name);
+       previous = in_fn_table(state, patch->old_name);
        if (!previous)
                return NULL;
 
@@ -3218,13 +3350,14 @@ static int verify_index_match(const struct cache_entry *ce, struct stat *st)
 
 #define SUBMODULE_PATCH_WITHOUT_INDEX 1
 
-static int load_patch_target(struct strbuf *buf,
+static int load_patch_target(struct apply_state *state,
+                            struct strbuf *buf,
                             const struct cache_entry *ce,
                             struct stat *st,
                             const char *name,
                             unsigned expected_mode)
 {
-       if (cached || check_index) {
+       if (state->cached || state->check_index) {
                if (read_file_or_gitlink(ce, buf))
                        return error(_("read of %s failed"), name);
        } else if (name) {
@@ -3250,7 +3383,8 @@ static int load_patch_target(struct strbuf *buf,
  * applying a non-git patch that incrementally updates the tree,
  * we read from the result of a previous diff.
  */
-static int load_preimage(struct image *image,
+static int load_preimage(struct apply_state *state,
+                        struct image *image,
                         struct patch *patch, struct stat *st,
                         const struct cache_entry *ce)
 {
@@ -3260,7 +3394,7 @@ static int load_preimage(struct image *image,
        struct patch *previous;
        int status;
 
-       previous = previous_patch(patch, &status);
+       previous = previous_patch(state, patch, &status);
        if (status)
                return error(_("path %s has been renamed/deleted"),
                             patch->old_name);
@@ -3268,7 +3402,7 @@ static int load_preimage(struct image *image,
                /* We have a patched copy in memory; use that. */
                strbuf_add(&buf, previous->result, previous->resultsize);
        } else {
-               status = load_patch_target(&buf, ce, st,
+               status = load_patch_target(state, &buf, ce, st,
                                           patch->old_name, patch->old_mode);
                if (status < 0)
                        return status;
@@ -3327,7 +3461,9 @@ static int three_way_merge(struct image *image,
  * the current contents of the new_name.  In no cases other than that
  * this function will be called.
  */
-static int load_current(struct image *image, struct patch *patch)
+static int load_current(struct apply_state *state,
+                       struct image *image,
+                       struct patch *patch)
 {
        struct strbuf buf = STRBUF_INIT;
        int status, pos;
@@ -3354,7 +3490,7 @@ static int load_current(struct image *image, struct patch *patch)
        if (verify_index_match(ce, &st))
                return error(_("%s: does not match index"), name);
 
-       status = load_patch_target(&buf, ce, &st, name, mode);
+       status = load_patch_target(state, &buf, ce, &st, name, mode);
        if (status < 0)
                return status;
        else if (status)
@@ -3364,8 +3500,11 @@ static int load_current(struct image *image, struct patch *patch)
        return 0;
 }
 
-static int try_threeway(struct image *image, struct patch *patch,
-                       struct stat *st, const struct cache_entry *ce)
+static int try_threeway(struct apply_state *state,
+                       struct image *image,
+                       struct patch *patch,
+                       struct stat *st,
+                       const struct cache_entry *ce)
 {
        unsigned char pre_sha1[20], post_sha1[20], our_sha1[20];
        struct strbuf buf = STRBUF_INIT;
@@ -3391,7 +3530,7 @@ static int try_threeway(struct image *image, struct patch *patch,
        img = strbuf_detach(&buf, &len);
        prepare_image(&tmp_image, img, len, 1);
        /* Apply the patch to get the post image */
-       if (apply_fragments(&tmp_image, patch) < 0) {
+       if (apply_fragments(state, &tmp_image, patch) < 0) {
                clear_image(&tmp_image);
                return -1;
        }
@@ -3401,11 +3540,11 @@ static int try_threeway(struct image *image, struct patch *patch,
 
        /* our_sha1[] is ours */
        if (patch->is_new) {
-               if (load_current(&tmp_image, patch))
+               if (load_current(state, &tmp_image, patch))
                        return error("cannot read the current contents of '%s'",
                                     patch->new_name);
        } else {
-               if (load_preimage(&tmp_image, patch, st, ce))
+               if (load_preimage(state, &tmp_image, patch, st, ce))
                        return error("cannot read the current contents of '%s'",
                                     patch->old_name);
        }
@@ -3435,22 +3574,23 @@ static int try_threeway(struct image *image, struct patch *patch,
        return 0;
 }
 
-static int apply_data(struct patch *patch, struct stat *st, const struct cache_entry *ce)
+static int apply_data(struct apply_state *state, struct patch *patch,
+                     struct stat *st, const struct cache_entry *ce)
 {
        struct image image;
 
-       if (load_preimage(&image, patch, st, ce) < 0)
+       if (load_preimage(state, &image, patch, st, ce) < 0)
                return -1;
 
        if (patch->direct_to_threeway ||
-           apply_fragments(&image, patch) < 0) {
+           apply_fragments(state, &image, patch) < 0) {
                /* Note: with --reject, apply_fragments() returns 0 */
-               if (!threeway || try_threeway(&image, patch, st, ce) < 0)
+               if (!state->threeway || try_threeway(state, &image, patch, st, ce) < 0)
                        return -1;
        }
        patch->result = image.buf;
        patch->resultsize = image.len;
-       add_to_fn_table(patch);
+       add_to_fn_table(state, patch);
        free(image.line_allocated);
 
        if (0 < patch->is_delete && patch->resultsize)
@@ -3470,7 +3610,10 @@ static int apply_data(struct patch *patch, struct stat *st, const struct cache_e
  * check_patch() separately makes sure (and errors out otherwise) that
  * the path the patch creates does not exist in the current tree.
  */
-static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)
+static int check_preimage(struct apply_state *state,
+                         struct patch *patch,
+                         struct cache_entry **ce,
+                         struct stat *st)
 {
        const char *old_name = patch->old_name;
        struct patch *previous = NULL;
@@ -3481,19 +3624,19 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
                return 0;
 
        assert(patch->is_new <= 0);
-       previous = previous_patch(patch, &status);
+       previous = previous_patch(state, patch, &status);
 
        if (status)
                return error(_("path %s has been renamed/deleted"), old_name);
        if (previous) {
                st_mode = previous->new_mode;
-       } else if (!cached) {
+       } else if (!state->cached) {
                stat_ret = lstat(old_name, st);
                if (stat_ret && errno != ENOENT)
                        return error(_("%s: %s"), old_name, strerror(errno));
        }
 
-       if (check_index && !previous) {
+       if (state->check_index && !previous) {
                int pos = cache_name_pos(old_name, strlen(old_name));
                if (pos < 0) {
                        if (patch->is_new < 0)
@@ -3505,9 +3648,9 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
                        if (checkout_target(&the_index, *ce, st))
                                return -1;
                }
-               if (!cached && verify_index_match(*ce, st))
+               if (!state->cached && verify_index_match(*ce, st))
                        return error(_("%s: does not match index"), old_name);
-               if (cached)
+               if (state->cached)
                        st_mode = (*ce)->ce_mode;
        } else if (stat_ret < 0) {
                if (patch->is_new < 0)
@@ -3515,7 +3658,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
                return error(_("%s: %s"), old_name, strerror(errno));
        }
 
-       if (!cached && !previous)
+       if (!state->cached && !previous)
                st_mode = ce_mode_from_stat(*ce, st->st_mode);
 
        if (patch->is_new < 0)
@@ -3543,15 +3686,17 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
 #define EXISTS_IN_INDEX 1
 #define EXISTS_IN_WORKTREE 2
 
-static int check_to_create(const char *new_name, int ok_if_exists)
+static int check_to_create(struct apply_state *state,
+                          const char *new_name,
+                          int ok_if_exists)
 {
        struct stat nst;
 
-       if (check_index &&
+       if (state->check_index &&
            cache_name_pos(new_name, strlen(new_name)) >= 0 &&
            !ok_if_exists)
                return EXISTS_IN_INDEX;
-       if (cached)
+       if (state->cached)
                return 0;
 
        if (!lstat(new_name, &nst)) {
@@ -3574,56 +3719,46 @@ static int check_to_create(const char *new_name, int ok_if_exists)
        return 0;
 }
 
-/*
- * We need to keep track of how symlinks in the preimage are
- * manipulated by the patches.  A patch to add a/b/c where a/b
- * is a symlink should not be allowed to affect the directory
- * the symlink points at, but if the same patch removes a/b,
- * it is perfectly fine, as the patch removes a/b to make room
- * to create a directory a/b so that a/b/c can be created.
- */
-static struct string_list symlink_changes;
-#define SYMLINK_GOES_AWAY 01
-#define SYMLINK_IN_RESULT 02
-
-static uintptr_t register_symlink_changes(const char *path, uintptr_t what)
+static uintptr_t register_symlink_changes(struct apply_state *state,
+                                         const char *path,
+                                         uintptr_t what)
 {
        struct string_list_item *ent;
 
-       ent = string_list_lookup(&symlink_changes, path);
+       ent = string_list_lookup(&state->symlink_changes, path);
        if (!ent) {
-               ent = string_list_insert(&symlink_changes, path);
+               ent = string_list_insert(&state->symlink_changes, path);
                ent->util = (void *)0;
        }
        ent->util = (void *)(what | ((uintptr_t)ent->util));
        return (uintptr_t)ent->util;
 }
 
-static uintptr_t check_symlink_changes(const char *path)
+static uintptr_t check_symlink_changes(struct apply_state *state, const char *path)
 {
        struct string_list_item *ent;
 
-       ent = string_list_lookup(&symlink_changes, path);
+       ent = string_list_lookup(&state->symlink_changes, path);
        if (!ent)
                return 0;
        return (uintptr_t)ent->util;
 }
 
-static void prepare_symlink_changes(struct patch *patch)
+static void prepare_symlink_changes(struct apply_state *state, struct patch *patch)
 {
        for ( ; patch; patch = patch->next) {
                if ((patch->old_name && S_ISLNK(patch->old_mode)) &&
                    (patch->is_rename || patch->is_delete))
                        /* the symlink at patch->old_name is removed */
-                       register_symlink_changes(patch->old_name, SYMLINK_GOES_AWAY);
+                       register_symlink_changes(state, patch->old_name, SYMLINK_GOES_AWAY);
 
                if (patch->new_name && S_ISLNK(patch->new_mode))
                        /* the symlink at patch->new_name is created or remains */
-                       register_symlink_changes(patch->new_name, SYMLINK_IN_RESULT);
+                       register_symlink_changes(state, patch->new_name, SYMLINK_IN_RESULT);
        }
 }
 
-static int path_is_beyond_symlink_1(struct strbuf *name)
+static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *name)
 {
        do {
                unsigned int change;
@@ -3633,7 +3768,7 @@ static int path_is_beyond_symlink_1(struct strbuf *name)
                if (!name->len)
                        break;
                name->buf[name->len] = '\0';
-               change = check_symlink_changes(name->buf);
+               change = check_symlink_changes(state, name->buf);
                if (change & SYMLINK_IN_RESULT)
                        return 1;
                if (change & SYMLINK_GOES_AWAY)
@@ -3644,7 +3779,7 @@ static int path_is_beyond_symlink_1(struct strbuf *name)
                        continue;
 
                /* otherwise, check the preimage */
-               if (check_index) {
+               if (state->check_index) {
                        struct cache_entry *ce;
 
                        ce = cache_file_exists(name->buf, name->len, ignore_case);
@@ -3659,14 +3794,14 @@ static int path_is_beyond_symlink_1(struct strbuf *name)
        return 0;
 }
 
-static int path_is_beyond_symlink(const char *name_)
+static int path_is_beyond_symlink(struct apply_state *state, const char *name_)
 {
        int ret;
        struct strbuf name = STRBUF_INIT;
 
        assert(*name_ != '\0');
        strbuf_addstr(&name, name_);
-       ret = path_is_beyond_symlink_1(&name);
+       ret = path_is_beyond_symlink_1(state, &name);
        strbuf_release(&name);
 
        return ret;
@@ -3693,7 +3828,7 @@ static void die_on_unsafe_path(struct patch *patch)
  * Check and apply the patch in-core; leave the result in patch->result
  * for the caller to write it out to the final destination.
  */
-static int check_patch(struct patch *patch)
+static int check_patch(struct apply_state *state, struct patch *patch)
 {
        struct stat st;
        const char *old_name = patch->old_name;
@@ -3706,7 +3841,7 @@ static int check_patch(struct patch *patch)
 
        patch->rejected = 1; /* we will drop this after we succeed */
 
-       status = check_preimage(patch, &ce, &st);
+       status = check_preimage(state, patch, &ce, &st);
        if (status)
                return status;
        old_name = patch->old_name;
@@ -3725,7 +3860,7 @@ static int check_patch(struct patch *patch)
         * B and rename from A to B is handled the same way by asking
         * was_deleted().
         */
-       if ((tpatch = in_fn_table(new_name)) &&
+       if ((tpatch = in_fn_table(state, new_name)) &&
            (was_deleted(tpatch) || to_be_deleted(tpatch)))
                ok_if_exists = 1;
        else
@@ -3733,9 +3868,9 @@ static int check_patch(struct patch *patch)
 
        if (new_name &&
            ((0 < patch->is_new) || patch->is_rename || patch->is_copy)) {
-               int err = check_to_create(new_name, ok_if_exists);
+               int err = check_to_create(state, new_name, ok_if_exists);
 
-               if (err && threeway) {
+               if (err && state->threeway) {
                        patch->direct_to_threeway = 1;
                } else switch (err) {
                case 0:
@@ -3776,7 +3911,7 @@ static int check_patch(struct patch *patch)
                }
        }
 
-       if (!unsafe_paths)
+       if (!state->unsafe_paths)
                die_on_unsafe_path(patch);
 
        /*
@@ -3788,27 +3923,27 @@ static int check_patch(struct patch *patch)
         * is not deposited to a path that is beyond a symbolic link
         * here.
         */
-       if (!patch->is_delete && path_is_beyond_symlink(patch->new_name))
+       if (!patch->is_delete && path_is_beyond_symlink(state, patch->new_name))
                return error(_("affected file '%s' is beyond a symbolic link"),
                             patch->new_name);
 
-       if (apply_data(patch, &st, ce) < 0)
+       if (apply_data(state, patch, &st, ce) < 0)
                return error(_("%s: patch does not apply"), name);
        patch->rejected = 0;
        return 0;
 }
 
-static int check_patch_list(struct patch *patch)
+static int check_patch_list(struct apply_state *state, struct patch *patch)
 {
        int err = 0;
 
-       prepare_symlink_changes(patch);
-       prepare_fn_table(patch);
+       prepare_symlink_changes(state, patch);
+       prepare_fn_table(state, patch);
        while (patch) {
-               if (apply_verbosely)
+               if (state->apply_verbosely)
                        say_patch_name(stderr,
                                       _("Checking patch %s..."), patch);
-               err |= check_patch(patch);
+               err |= check_patch(state, patch);
                patch = patch->next;
        }
        return err;
@@ -3912,7 +4047,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)
        discard_index(&result);
 }
 
-static void stat_patch_list(struct patch *patch)
+static void stat_patch_list(struct apply_state *state, struct patch *patch)
 {
        int files, adds, dels;
 
@@ -3920,13 +4055,14 @@ static void stat_patch_list(struct patch *patch)
                files++;
                adds += patch->lines_added;
                dels += patch->lines_deleted;
-               show_stats(patch);
+               show_stats(state, patch);
        }
 
        print_stat_summary(stdout, files, adds, dels);
 }
 
-static void numstat_patch_list(struct patch *patch)
+static void numstat_patch_list(struct apply_state *state,
+                              struct patch *patch)
 {
        for ( ; patch; patch = patch->next) {
                const char *name;
@@ -3935,7 +4071,7 @@ static void numstat_patch_list(struct patch *patch)
                        printf("-\t-\t");
                else
                        printf("%d\t%d\t", patch->lines_added, patch->lines_deleted);
-               write_name_quoted(name, stdout, line_termination);
+               write_name_quoted(name, stdout, state->line_termination);
        }
 }
 
@@ -4017,49 +4153,53 @@ static void summary_patch_list(struct patch *patch)
        }
 }
 
-static void patch_stats(struct patch *patch)
+static void patch_stats(struct apply_state *state, struct patch *patch)
 {
        int lines = patch->lines_added + patch->lines_deleted;
 
-       if (lines > max_change)
-               max_change = lines;
+       if (lines > state->max_change)
+               state->max_change = lines;
        if (patch->old_name) {
                int len = quote_c_style(patch->old_name, NULL, NULL, 0);
                if (!len)
                        len = strlen(patch->old_name);
-               if (len > max_len)
-                       max_len = len;
+               if (len > state->max_len)
+                       state->max_len = len;
        }
        if (patch->new_name) {
                int len = quote_c_style(patch->new_name, NULL, NULL, 0);
                if (!len)
                        len = strlen(patch->new_name);
-               if (len > max_len)
-                       max_len = len;
+               if (len > state->max_len)
+                       state->max_len = len;
        }
 }
 
-static void remove_file(struct patch *patch, int rmdir_empty)
+static void remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)
 {
-       if (update_index) {
+       if (state->update_index) {
                if (remove_file_from_cache(patch->old_name) < 0)
                        die(_("unable to remove %s from index"), patch->old_name);
        }
-       if (!cached) {
+       if (!state->cached) {
                if (!remove_or_warn(patch->old_mode, patch->old_name) && rmdir_empty) {
                        remove_path(patch->old_name);
                }
        }
 }
 
-static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)
+static void add_index_file(struct apply_state *state,
+                          const char *path,
+                          unsigned mode,
+                          void *buf,
+                          unsigned long size)
 {
        struct stat st;
        struct cache_entry *ce;
        int namelen = strlen(path);
        unsigned ce_size = cache_entry_size(namelen);
 
-       if (!update_index)
+       if (!state->update_index)
                return;
 
        ce = xcalloc(1, ce_size);
@@ -4074,7 +4214,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
                    get_sha1_hex(s, ce->sha1))
                        die(_("corrupt patch for submodule %s"), path);
        } else {
-               if (!cached) {
+               if (!state->cached) {
                        if (lstat(path, &st) < 0)
                                die_errno(_("unable to stat newly created file '%s'"),
                                          path);
@@ -4126,9 +4266,13 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
  * which is true 99% of the time anyway. If they don't,
  * we create them and try again.
  */
-static void create_one_file(char *path, unsigned mode, const char *buf, unsigned long size)
+static void create_one_file(struct apply_state *state,
+                           char *path,
+                           unsigned mode,
+                           const char *buf,
+                           unsigned long size)
 {
-       if (cached)
+       if (state->cached)
                return;
        if (!try_create_file(path, mode, buf, size))
                return;
@@ -4169,13 +4313,14 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
        die_errno(_("unable to write file '%s' mode %o"), path, mode);
 }
 
-static void add_conflicted_stages_file(struct patch *patch)
+static void add_conflicted_stages_file(struct apply_state *state,
+                                      struct patch *patch)
 {
        int stage, namelen;
        unsigned ce_size, mode;
        struct cache_entry *ce;
 
-       if (!update_index)
+       if (!state->update_index)
                return;
        namelen = strlen(patch->new_name);
        ce_size = cache_entry_size(namelen);
@@ -4196,7 +4341,7 @@ static void add_conflicted_stages_file(struct patch *patch)
        }
 }
 
-static void create_file(struct patch *patch)
+static void create_file(struct apply_state *state, struct patch *patch)
 {
        char *path = patch->new_name;
        unsigned mode = patch->new_mode;
@@ -4205,25 +4350,27 @@ static void create_file(struct patch *patch)
 
        if (!mode)
                mode = S_IFREG | 0644;
-       create_one_file(path, mode, buf, size);
+       create_one_file(state, path, mode, buf, size);
 
        if (patch->conflicted_threeway)
-               add_conflicted_stages_file(patch);
+               add_conflicted_stages_file(state, patch);
        else
-               add_index_file(path, mode, buf, size);
+               add_index_file(state, path, mode, buf, size);
 }
 
 /* phase zero is to remove, phase one is to create */
-static void write_out_one_result(struct patch *patch, int phase)
+static void write_out_one_result(struct apply_state *state,
+                                struct patch *patch,
+                                int phase)
 {
        if (patch->is_delete > 0) {
                if (phase == 0)
-                       remove_file(patch, 1);
+                       remove_file(state, patch, 1);
                return;
        }
        if (patch->is_new > 0 || patch->is_copy) {
                if (phase == 1)
-                       create_file(patch);
+                       create_file(state, patch);
                return;
        }
        /*
@@ -4231,12 +4378,12 @@ static void write_out_one_result(struct patch *patch, int phase)
         * thing: remove the old, write the new
         */
        if (phase == 0)
-               remove_file(patch, patch->is_rename);
+               remove_file(state, patch, patch->is_rename);
        if (phase == 1)
-               create_file(patch);
+               create_file(state, patch);
 }
 
-static int write_out_one_reject(struct patch *patch)
+static int write_out_one_reject(struct apply_state *state, struct patch *patch)
 {
        FILE *rej;
        char namebuf[PATH_MAX];
@@ -4251,7 +4398,7 @@ static int write_out_one_reject(struct patch *patch)
        }
 
        if (!cnt) {
-               if (apply_verbosely)
+               if (state->apply_verbosely)
                        say_patch_name(stderr,
                                       _("Applied patch %s cleanly."), patch);
                return 0;
@@ -4307,7 +4454,7 @@ static int write_out_one_reject(struct patch *patch)
        return -1;
 }
 
-static int write_out_results(struct patch *list)
+static int write_out_results(struct apply_state *state, struct patch *list)
 {
        int phase;
        int errs = 0;
@@ -4320,9 +4467,9 @@ static int write_out_results(struct patch *list)
                        if (l->rejected)
                                errs = 1;
                        else {
-                               write_out_one_result(l, phase);
+                               write_out_one_result(state, l, phase);
                                if (phase == 1) {
-                                       if (write_out_one_reject(l))
+                                       if (write_out_one_reject(state, l))
                                                errs = 1;
                                        if (l->conflicted_threeway) {
                                                string_list_append(&cpath, l->new_name);
@@ -4353,14 +4500,17 @@ static struct lock_file lock_file;
 #define INACCURATE_EOF (1<<0)
 #define RECOUNT                (1<<1)
 
-static int apply_patch(int fd, const char *filename, int options)
+static int apply_patch(struct apply_state *state,
+                      int fd,
+                      const char *filename,
+                      int options)
 {
        size_t offset;
        struct strbuf buf = STRBUF_INIT; /* owns the patch text */
        struct patch *list = NULL, **listp = &list;
        int skipped_patch = 0;
 
-       patch_input_file = filename;
+       state->patch_input_file = filename;
        read_patch_file(&buf, fd);
        offset = 0;
        while (offset < buf.len) {
@@ -4370,20 +4520,20 @@ static int apply_patch(int fd, const char *filename, int options)
                patch = xcalloc(1, sizeof(*patch));
                patch->inaccurate_eof = !!(options & INACCURATE_EOF);
                patch->recount =  !!(options & RECOUNT);
-               nr = parse_chunk(buf.buf + offset, buf.len - offset, patch);
+               nr = parse_chunk(state, buf.buf + offset, buf.len - offset, patch);
                if (nr < 0) {
                        free_patch(patch);
                        break;
                }
-               if (apply_in_reverse)
+               if (state->apply_in_reverse)
                        reverse_patches(patch);
-               if (use_patch(patch)) {
-                       patch_stats(patch);
+               if (use_patch(state, patch)) {
+                       patch_stats(state, patch);
                        *listp = patch;
                        listp = &patch->next;
                }
                else {
-                       if (apply_verbosely)
+                       if (state->apply_verbosely)
                                say_patch_name(stderr, _("Skipped patch '%s'."), patch);
                        free_patch(patch);
                        skipped_patch++;
@@ -4394,45 +4544,45 @@ static int apply_patch(int fd, const char *filename, int options)
        if (!list && !skipped_patch)
                die(_("unrecognized input"));
 
-       if (whitespace_error && (ws_error_action == die_on_ws_error))
-               apply = 0;
+       if (state->whitespace_error && (state->ws_error_action == die_on_ws_error))
+               state->apply = 0;
 
-       update_index = check_index && apply;
-       if (update_index && newfd < 0)
-               newfd = hold_locked_index(&lock_file, 1);
+       state->update_index = state->check_index && state->apply;
+       if (state->update_index && state->newfd < 0)
+               state->newfd = hold_locked_index(state->lock_file, 1);
 
-       if (check_index) {
+       if (state->check_index) {
                if (read_cache() < 0)
                        die(_("unable to read index file"));
        }
 
-       if ((check || apply) &&
-           check_patch_list(list) < 0 &&
-           !apply_with_reject)
+       if ((state->check || state->apply) &&
+           check_patch_list(state, list) < 0 &&
+           !state->apply_with_reject)
                exit(1);
 
-       if (apply && write_out_results(list)) {
-               if (apply_with_reject)
+       if (state->apply && write_out_results(state, list)) {
+               if (state->apply_with_reject)
                        exit(1);
                /* with --3way, we still need to write the index out */
                return 1;
        }
 
-       if (fake_ancestor)
-               build_fake_ancestor(list, fake_ancestor);
+       if (state->fake_ancestor)
+               build_fake_ancestor(list, state->fake_ancestor);
 
-       if (diffstat)
-               stat_patch_list(list);
+       if (state->diffstat)
+               stat_patch_list(state, list);
 
-       if (numstat)
-               numstat_patch_list(list);
+       if (state->numstat)
+               numstat_patch_list(state, list);
 
-       if (summary)
+       if (state->summary)
                summary_patch_list(list);
 
        free_patch_list(list);
        strbuf_release(&buf);
-       string_list_clear(&fn_table, 0);
+       string_list_clear(&state->fn_table, 0);
        return 0;
 }
 
@@ -4446,220 +4596,284 @@ static void git_apply_config(void)
 static int option_parse_exclude(const struct option *opt,
                                const char *arg, int unset)
 {
-       add_name_limit(arg, 1);
+       struct apply_state *state = opt->value;
+       add_name_limit(state, arg, 1);
        return 0;
 }
 
 static int option_parse_include(const struct option *opt,
                                const char *arg, int unset)
 {
-       add_name_limit(arg, 0);
-       has_include = 1;
+       struct apply_state *state = opt->value;
+       add_name_limit(state, arg, 0);
+       state->has_include = 1;
        return 0;
 }
 
 static int option_parse_p(const struct option *opt,
-                         const char *arg, int unset)
+                         const char *arg,
+                         int unset)
 {
-       p_value = atoi(arg);
-       p_value_known = 1;
+       struct apply_state *state = opt->value;
+       state->p_value = atoi(arg);
+       state->p_value_known = 1;
        return 0;
 }
 
 static int option_parse_space_change(const struct option *opt,
-                         const char *arg, int unset)
+                                    const char *arg, int unset)
 {
+       struct apply_state *state = opt->value;
        if (unset)
-               ws_ignore_action = ignore_ws_none;
+               state->ws_ignore_action = ignore_ws_none;
        else
-               ws_ignore_action = ignore_ws_change;
+               state->ws_ignore_action = ignore_ws_change;
        return 0;
 }
 
 static int option_parse_whitespace(const struct option *opt,
                                   const char *arg, int unset)
 {
-       const char **whitespace_option = opt->value;
-
-       *whitespace_option = arg;
-       parse_whitespace_option(arg);
+       struct apply_state *state = opt->value;
+       state->whitespace_option = arg;
+       parse_whitespace_option(state, arg);
        return 0;
 }
 
 static int option_parse_directory(const struct option *opt,
                                  const char *arg, int unset)
 {
-       strbuf_reset(&root);
-       strbuf_addstr(&root, arg);
-       strbuf_complete(&root, '/');
+       struct apply_state *state = opt->value;
+       strbuf_reset(&state->root);
+       strbuf_addstr(&state->root, arg);
+       strbuf_complete(&state->root, '/');
        return 0;
 }
 
-int cmd_apply(int argc, const char **argv, const char *prefix_)
+static void init_apply_state(struct apply_state *state,
+                            const char *prefix,
+                            struct lock_file *lock_file)
+{
+       memset(state, 0, sizeof(*state));
+       state->prefix = prefix;
+       state->prefix_length = state->prefix ? strlen(state->prefix) : 0;
+       state->lock_file = lock_file;
+       state->newfd = -1;
+       state->apply = 1;
+       state->line_termination = '\n';
+       state->p_value = 1;
+       state->p_context = UINT_MAX;
+       state->squelch_whitespace_errors = 5;
+       state->ws_error_action = warn_on_ws_error;
+       state->ws_ignore_action = ignore_ws_none;
+       state->linenr = 1;
+       string_list_init(&state->fn_table, 0);
+       string_list_init(&state->limit_by_name, 0);
+       string_list_init(&state->symlink_changes, 0);
+       strbuf_init(&state->root, 0);
+
+       git_apply_config();
+       if (apply_default_whitespace)
+               parse_whitespace_option(state, apply_default_whitespace);
+       if (apply_default_ignorewhitespace)
+               parse_ignorewhitespace_option(state, apply_default_ignorewhitespace);
+}
+
+static void clear_apply_state(struct apply_state *state)
+{
+       string_list_clear(&state->limit_by_name, 0);
+       string_list_clear(&state->symlink_changes, 0);
+       strbuf_release(&state->root);
+
+       /* &state->fn_table is cleared at the end of apply_patch() */
+}
+
+static void check_apply_state(struct apply_state *state, int force_apply)
+{
+       int is_not_gitdir = !startup_info->have_repository;
+
+       if (state->apply_with_reject && state->threeway)
+               die("--reject and --3way cannot be used together.");
+       if (state->cached && state->threeway)
+               die("--cached and --3way cannot be used together.");
+       if (state->threeway) {
+               if (is_not_gitdir)
+                       die(_("--3way outside a repository"));
+               state->check_index = 1;
+       }
+       if (state->apply_with_reject)
+               state->apply = state->apply_verbosely = 1;
+       if (!force_apply && (state->diffstat || state->numstat || state->summary || state->check || state->fake_ancestor))
+               state->apply = 0;
+       if (state->check_index && is_not_gitdir)
+               die(_("--index outside a repository"));
+       if (state->cached) {
+               if (is_not_gitdir)
+                       die(_("--cached outside a repository"));
+               state->check_index = 1;
+       }
+       if (state->check_index)
+               state->unsafe_paths = 0;
+       if (!state->lock_file)
+               die("BUG: state->lock_file should not be NULL");
+}
+
+static int apply_all_patches(struct apply_state *state,
+                            int argc,
+                            const char **argv,
+                            int options)
 {
        int i;
        int errs = 0;
-       int is_not_gitdir = !startup_info->have_repository;
-       int force_apply = 0;
+       int read_stdin = 1;
+
+       for (i = 0; i < argc; i++) {
+               const char *arg = argv[i];
+               int fd;
+
+               if (!strcmp(arg, "-")) {
+                       errs |= apply_patch(state, 0, "<stdin>", options);
+                       read_stdin = 0;
+                       continue;
+               } else if (0 < state->prefix_length)
+                       arg = prefix_filename(state->prefix,
+                                             state->prefix_length,
+                                             arg);
+
+               fd = open(arg, O_RDONLY);
+               if (fd < 0)
+                       die_errno(_("can't open patch '%s'"), arg);
+               read_stdin = 0;
+               set_default_whitespace_mode(state);
+               errs |= apply_patch(state, fd, arg, options);
+               close(fd);
+       }
+       set_default_whitespace_mode(state);
+       if (read_stdin)
+               errs |= apply_patch(state, 0, "<stdin>", options);
+
+       if (state->whitespace_error) {
+               if (state->squelch_whitespace_errors &&
+                   state->squelch_whitespace_errors < state->whitespace_error) {
+                       int squelched =
+                               state->whitespace_error - state->squelch_whitespace_errors;
+                       warning(Q_("squelched %d whitespace error",
+                                  "squelched %d whitespace errors",
+                                  squelched),
+                               squelched);
+               }
+               if (state->ws_error_action == die_on_ws_error)
+                       die(Q_("%d line adds whitespace errors.",
+                              "%d lines add whitespace errors.",
+                              state->whitespace_error),
+                           state->whitespace_error);
+               if (state->applied_after_fixing_ws && state->apply)
+                       warning("%d line%s applied after"
+                               " fixing whitespace errors.",
+                               state->applied_after_fixing_ws,
+                               state->applied_after_fixing_ws == 1 ? "" : "s");
+               else if (state->whitespace_error)
+                       warning(Q_("%d line adds whitespace errors.",
+                                  "%d lines add whitespace errors.",
+                                  state->whitespace_error),
+                               state->whitespace_error);
+       }
+
+       if (state->update_index) {
+               if (write_locked_index(&the_index, state->lock_file, COMMIT_LOCK))
+                       die(_("Unable to write new index file"));
+               state->newfd = -1;
+       }
+
+       return !!errs;
+}
 
-       const char *whitespace_option = NULL;