Merge branch 'da/difftool' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 6 Jun 2016 21:27:37 +0000 (14:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 6 Jun 2016 21:27:37 +0000 (14:27 -0700)
"git difftool" learned to handle unmerged paths correctly in
dir-diff mode.

* da/difftool:
difftool: handle unmerged files in dir-diff mode
difftool: initialize variables for readability

109 files changed:
.mailmap
.travis.yml
Documentation/RelNotes/2.8.3.txt
Documentation/RelNotes/2.8.4.txt [new file with mode: 0644]
Documentation/SubmittingPatches
Documentation/config.txt
Documentation/diff-options.txt
Documentation/everyday.txto
Documentation/git-check-ignore.txt
Documentation/git-config.txt
Documentation/git-filter-branch.txt
Documentation/git-for-each-ref.txt
Documentation/git-mailinfo.txt
Documentation/git-notes.txt
Documentation/git-pack-objects.txt
Documentation/git-repack.txt
Documentation/git-submodule.txt
Documentation/git.txt
Documentation/glossary-content.txt
Documentation/merge-options.txt
Documentation/pretty-formats.txt
Documentation/technical/api-credentials.txt
Documentation/technical/pack-protocol.txt
GIT-VERSION-GEN
Makefile
RelNotes
archive-tar.c
builtin/branch.c
builtin/diff-files.c
builtin/diff-index.c
builtin/diff-tree.c
builtin/diff.c
builtin/index-pack.c
builtin/mv.c
builtin/name-rev.c
builtin/notes.c
builtin/pack-objects.c
builtin/pull.c
builtin/remote-ext.c
builtin/remote.c
builtin/rm.c
bundle.c
cache.h
ci/test-documentation.sh [new file with mode: 0755]
compat/mingw.c
compat/mingw.h
compat/precompose_utf8.c
compat/win32/pthread.h
compat/win32mmap.c
config.c
convert.c
credential-cache.c
dir.c
dir.h
environment.c
fetch-pack.c
fsck.c
git-cvsserver.perl
git-difftool--helper.sh
git-mergetool--lib.sh
git-mergetool.sh
git-p4.py
git-parse-remote.sh
git-rebase--interactive.sh
git-send-email.perl
git-submodule.sh
gitweb/gitweb.perl
http.c
ident.c
path.c
perl/Git.pm
remote.c
run-command.c
run-command.h
send-pack.c
split-index.c
string-list.c
submodule-config.c
t/README
t/lib-git-p4.sh
t/t0000-basic.sh
t/t0001-init.sh
t/t0027-auto-crlf.sh
t/t1450-fsck.sh
t/t3513-revert-submodule.sh
t/t3910-mac-os-precompose.sh
t/t4151-am-abort.sh
t/t5504-fetch-receive-strict.sh
t/t5510-fetch.sh
t/t5601-clone.sh
t/t5611-clone-config.sh
t/t6041-bisect-submodule.sh
t/t7001-mv.sh
t/t7300-clean.sh
t/t7400-submodule-basic.sh
t/t7609-merge-co-error-msgs.sh
t/t7800-difftool.sh
t/t9802-git-p4-filetype.sh
t/t9824-git-p4-git-lfs.sh
t/t9903-bash-prompt.sh
t/test-lib-functions.sh
t/test-lib.sh
transport-helper.c
unpack-trees.c
utf8.h
wildmatch.c
worktree.c
wrapper.c
wt-status.c
index e5b4126bec557db55924b7b60ed70349626ea2c4..a9162c0095a2d8a4787f86c4121e399aaaddf2cb 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -51,6 +51,7 @@ Dirk Süsserott <newsletter@dirk.my1.cc>
 Eric Blake <eblake@redhat.com> <ebb9@byu.net>
 Eric Hanchrow <eric.hanchrow@gmail.com> <offby1@blarg.net>
 Eric S. Raymond <esr@thyrsus.com>
+Eric Wong <e@80x24.org> <normalperson@yhbt.net>
 Erik Faye-Lund <kusmabite@gmail.com> <kusmabite@googlemail.com>
 Eyvind Bernhardsen <eyvind.bernhardsen@gmail.com> <eyvind-git@orakel.ntnu.no>
 Florian Achleitner <florian.achleitner.2.6.31@gmail.com> <florian.achleitner2.6.31@gmail.com>
index 78e433ba718df00d112a5f57d523afb8db189c79..adab5b89bba7b41a07a2a000dddbd4496ba7c7d3 100644 (file)
@@ -22,8 +22,11 @@ addons:
 env:
   global:
     - DEVELOPER=1
-    - P4_VERSION="15.2"
-    - GIT_LFS_VERSION="1.1.0"
+    # The Linux build installs the defined dependency versions below.
+    # The OS X build installs the latest available versions. Keep that
+    # in mind when you encounter a broken OS X build!
+    - LINUX_P4_VERSION="16.1"
+    - LINUX_GIT_LFS_VERSION="1.2.0"
     - DEFAULT_TEST_TARGET=prove
     - GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save"
     - GIT_TEST_OPTS="--verbose --tee"
@@ -32,23 +35,38 @@ env:
     # t9816 occasionally fails with "TAP out of sequence errors" on Travis CI OS X
     - GIT_SKIP_TESTS="t9810 t9816"
 
+matrix:
+  include:
+    - env: Documentation
+      os: linux
+      compiler: clang
+      addons:
+        apt:
+          packages:
+          - asciidoc
+          - xmlto
+      before_install:
+      before_script:
+      script: ci/test-documentation.sh
+      after_failure:
+
 before_install:
   - >
     case "${TRAVIS_OS_NAME:-linux}" in
     linux)
       mkdir --parents custom/p4
       pushd custom/p4
-        wget --quiet http://filehost.perforce.com/perforce/r$P4_VERSION/bin.linux26x86_64/p4d
-        wget --quiet http://filehost.perforce.com/perforce/r$P4_VERSION/bin.linux26x86_64/p4
+        wget --quiet http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION/bin.linux26x86_64/p4d
+        wget --quiet http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION/bin.linux26x86_64/p4
         chmod u+x p4d
         chmod u+x p4
         export PATH="$(pwd):$PATH"
       popd
       mkdir --parents custom/git-lfs
       pushd custom/git-lfs
-        wget --quiet https://github.com/github/git-lfs/releases/download/v$GIT_LFS_VERSION/git-lfs-linux-amd64-$GIT_LFS_VERSION.tar.gz
-        tar --extract --gunzip --file "git-lfs-linux-amd64-$GIT_LFS_VERSION.tar.gz"
-        cp git-lfs-$GIT_LFS_VERSION/git-lfs .
+        wget --quiet https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz
+        tar --extract --gunzip --file "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz"
+        cp git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs .
         export PATH="$(pwd):$PATH"
       popd
       ;;
index af184783bc07534b1519b0b5081d2350d029029b..fedd9968e5e3f20984cfedb54ec6ebcb0c4514e5 100644 (file)
@@ -67,4 +67,35 @@ Fixes since v2.8.2
    recurses into, but this was incorrect when the command was not run
    from the root level of the superproject.
 
+ * The test scripts for "git p4" (but not "git p4" implementation
+   itself) has been updated so that they would work even on a system
+   where the installed version of Python is python 3.
+
+ * The "user.useConfigOnly" configuration variable makes it an error
+   if users do not explicitly set user.name and user.email.  However,
+   its check was not done early enough and allowed another error to
+   trigger, reporting that the default value we guessed from the
+   system setting was unusable.  This was a suboptimal end-user
+   experience as we want the users to set user.name/user.email without
+   relying on the auto-detection at all.
+
+ * "git mv old new" did not adjust the path for a submodule that lives
+   as a subdirectory inside old/ directory correctly.
+
+ * "git push" from a corrupt repository that attempts to push a large
+   number of refs deadlocked; the thread to relay rejection notices
+   for these ref updates blocked on writing them to the main thread,
+   after the main thread at the receiving end notices that the push
+   failed and decides not to read these notices and return a failure.
+
+ * A question by "git send-email" to ask the identity of the sender
+   has been updated.
+
+ * Recent update to Git LFS broke "git p4" by changing the output from
+   its "lfs pointer" subcommand.
+
+ * Some multi-byte encoding can have a backslash byte as a later part
+   of one letter, which would confuse "highlight" filter used in
+   gitweb.
+
 Also contains minor documentation updates and code clean-ups.
diff --git a/Documentation/RelNotes/2.8.4.txt b/Documentation/RelNotes/2.8.4.txt
new file mode 100644 (file)
index 0000000..8d484b1
--- /dev/null
@@ -0,0 +1,55 @@
+Git v2.8.4 Release Notes
+========================
+
+Fixes since v2.8.3
+------------------
+
+ * 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.
+
+ * 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.
+
+ * Portability enhancement for "rebase -i" to help platforms whose
+   shell does not like "for i in <empty>" (which is not POSIX-kosher).
+
+ * "git fsck" learned to catch NUL byte in a commit object as
+   potential error and warn.
+
+ * CI test was taught to build documentation pages.
+
+ * 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.
+
+Also contains other minor documentation updates and code clean-ups.
index 98fc4cc1d002f3db2fc064bbc87d567503dc2624..e8ad978824ce88aa8c7b1b0f7cde64c1977b8682 100644 (file)
@@ -61,23 +61,28 @@ Make sure that you have tests for the bug you are fixing.  See
 t/README for guidance.
 
 When adding a new feature, make sure that you have new tests to show
-the feature triggers the new behaviour when it should, and to show the
-feature does not trigger when it shouldn't.  Also make sure that the
-test suite passes after your commit.  Do not forget to update the
-documentation to describe the updated behaviour.
-
-Speaking of the documentation, it is currently a liberal mixture of US
-and UK English norms for spelling and grammar, which is somewhat
-unfortunate.  A huge patch that touches the files all over the place
-only to correct the inconsistency is not welcome, though.  Potential
-clashes with other changes that can result from such a patch are not
-worth it.  We prefer to gradually reconcile the inconsistencies in
-favor of US English, with small and easily digestible patches, as a
-side effect of doing some other real work in the vicinity (e.g.
-rewriting a paragraph for clarity, while turning en_UK spelling to
-en_US).  Obvious typographical fixes are much more welcomed ("teh ->
-"the"), preferably submitted as independent patches separate from
-other documentation changes.
+the feature triggers the new behavior when it should, and to show the
+feature does not trigger when it shouldn't.  After any code change, make
+sure that the entire test suite passes.
+
+If you have an account at GitHub (and you can get one for free to work
+on open source projects), you can use their Travis CI integration to
+test your changes on Linux, Mac (and hopefully soon Windows).  See
+GitHub-Travis CI hints section for details.
+
+Do not forget to update the documentation to describe the updated
+behavior and make sure that the resulting documentation set formats
+well. It is currently a liberal mixture of US and UK English norms for
+spelling and grammar, which is somewhat unfortunate.  A huge patch that
+touches the files all over the place only to correct the inconsistency
+is not welcome, though.  Potential clashes with other changes that can
+result from such a patch are not worth it.  We prefer to gradually
+reconcile the inconsistencies in favor of US English, with small and
+easily digestible patches, as a side effect of doing some other real
+work in the vicinity (e.g. rewriting a paragraph for clarity, while
+turning en_UK spelling to en_US).  Obvious typographical fixes are much
+more welcomed ("teh -> "the"), preferably submitted as independent
+patches separate from other documentation changes.
 
 Oh, another thing.  We are picky about whitespaces.  Make sure your
 changes do not trigger errors with the sample pre-commit hook shipped
@@ -370,6 +375,47 @@ Know the status of your patch after submission
   entitled "What's cooking in git.git" and "What's in git.git" giving
   the status of various proposed changes.
 
+--------------------------------------------------
+GitHub-Travis CI hints
+
+With an account at GitHub (you can get one for free to work on open
+source projects), you can use Travis CI to test your changes on Linux,
+Mac (and hopefully soon Windows).  You can find a successful example
+test build here: https://travis-ci.org/git/git/builds/120473209
+
+Follow these steps for the initial setup:
+
+ (1) Fork https://github.com/git/git to your GitHub account.
+     You can find detailed instructions how to fork here:
+     https://help.github.com/articles/fork-a-repo/
+
+ (2) Open the Travis CI website: https://travis-ci.org
+
+ (3) Press the "Sign in with GitHub" button.
+
+ (4) Grant Travis CI permissions to access your GitHub account.
+     You can find more information about the required permissions here:
+     https://docs.travis-ci.com/user/github-oauth-scopes
+
+ (5) Open your Travis CI profile page: https://travis-ci.org/profile
+
+ (6) Enable Travis CI builds for your Git fork.
+
+After the initial setup, Travis CI will run whenever you push new changes
+to your fork of Git on GitHub.  You can monitor the test state of all your
+branches here: https://travis-ci.org/<Your GitHub handle>/git/branches
+
+If a branch did not pass all test cases then it is marked with a red
+cross.  In that case you can click on the failing Travis CI job and
+scroll all the way down in the log.  Find the line "<-- Click here to see
+detailed test output!" and click on the triangle next to the log line
+number to expand the detailed test output.  Here is such a failing
+example: https://travis-ci.org/git/git/jobs/122676187
+
+Fix the problem and push your fix to your Git fork.  This will trigger
+a new Travis CI build to ensure all tests pass.
+
+
 ------------------------------------------------
 MUA specific hints
 
index 2cd6bdd7d2bc2816c1a9aed1c6a26bbd3285777c..02696208c9d8f014ad148eca4874b06f9db2fcfb 100644 (file)
@@ -81,13 +81,16 @@ Includes
 
 You can include one config file from another by setting the special
 `include.path` variable to the name of the file to be included. The
+variable takes a pathname as its value, and is subject to tilde
+expansion.
+
+The
 included file is expanded immediately, as if its contents had been
 found at the location of the include directive. If the value of the
 `include.path` variable is a relative path, the path is considered to be
 relative to the configuration file in which the include directive was
-found. The value of `include.path` is subject to tilde expansion: `~/`
-is expanded to the value of `$HOME`, and `~user/` to the specified
-user's home directory. See below for examples.
+found.  See below for examples.
+
 
 Example
 ~~~~~~~
@@ -114,7 +117,7 @@ Example
        [include]
                path = /path/to/foo.inc ; include by absolute path
                path = foo ; expand "foo" relative to the current file
-               path = ~/foo ; expand "foo" in your $HOME directory
+               path = ~/foo ; expand "foo" in your `$HOME` directory
 
 
 Values
@@ -169,6 +172,13 @@ thing on the same output line (e.g. opening parenthesis before the
 list of branch names in `log --decorate` output) is set to be
 painted with `bold` or some other attribute.
 
+pathname::
+       A variable that takes a pathname value can be given a
+       string that begins with "`~/`" or "`~user/`", and the usual
+       tilde expansion happens to such a string: `~/`
+       is expanded to the value of `$HOME`, and `~user/` to the
+       specified user's home directory.
+
 
 Variables
 ~~~~~~~~~
@@ -269,6 +279,12 @@ See linkgit:git-update-index[1].
 +
 The default is true (when core.filemode is not specified in the config file).
 
+core.hideDotFiles::
+       (Windows-only) If true, mark newly-created directories and files whose
+       name starts with a dot as hidden.  If 'dotGitOnly', only the `.git/`
+       directory is hidden, but no other files starting with a dot.  The
+       default mode is 'dotGitOnly'.
+
 core.ignoreCase::
        If true, this option enables various workarounds to enable
        Git to work better on filesystems that are not case sensitive,
@@ -337,9 +353,9 @@ core.quotePath::
 
 core.eol::
        Sets the line ending type to use in the working directory for
-       files that have the `text` property set.  Alternatives are
-       'lf', 'crlf' and 'native', which uses the platform's native
-       line ending.  The default value is `native`.  See
+       files that have the `text` property set when core.autocrlf is false.
+       Alternatives are 'lf', 'crlf' and 'native', which uses the platform's
+       native line ending.  The default value is `native`.  See
        linkgit:gitattributes[5] for more information on end-of-line
        conversion.
 
@@ -486,10 +502,10 @@ repository's usual working tree).
 
 core.logAllRefUpdates::
        Enable the reflog. Updates to a ref <ref> is logged to the file
-       "$GIT_DIR/logs/<ref>", by appending the new and old
+       "`$GIT_DIR/logs/<ref>`", by appending the new and old
        SHA-1, the date/time and the reason of the update, but
        only when the file exists.  If this configuration
-       variable is set to true, missing "$GIT_DIR/logs/<ref>"
+       variable is set to true, missing "`$GIT_DIR/logs/<ref>`"
        file is automatically created for branch heads (i.e. under
        refs/heads/), remote refs (i.e. under refs/remotes/),
        note refs (i.e. under refs/notes/), and the symbolic ref HEAD.
@@ -593,12 +609,11 @@ be delta compressed, but larger binary media files won't be.
 Common unit suffixes of 'k', 'm', or 'g' are supported.
 
 core.excludesFile::
-       In addition to '.gitignore' (per-directory) and
-       '.git/info/exclude', Git looks into this file for patterns
-       of files which are not meant to be tracked.  "`~/`" is expanded
-       to the value of `$HOME` and "`~user/`" to the specified user's
-       home directory. Its default value is $XDG_CONFIG_HOME/git/ignore.
-       If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore
+       Specifies the pathname to the file that contains patterns to
+       describe paths that are not meant to be tracked, in addition
+       to '.gitignore' (per-directory) and '.git/info/exclude'.
+       Defaults to `$XDG_CONFIG_HOME/git/ignore`.
+       If `$XDG_CONFIG_HOME` is either not set or empty, `$HOME/.config/git/ignore`
        is used instead. See linkgit:gitignore[5].
 
 core.askPass::
@@ -615,8 +630,8 @@ core.attributesFile::
        '.git/info/attributes', Git looks into this file for attributes
        (see linkgit:gitattributes[5]). Path expansions are made the same
        way as for `core.excludesFile`. Its default value is
-       $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not
-       set or empty, $HOME/.config/git/attributes is used instead.
+       `$XDG_CONFIG_HOME/git/attributes`. If `$XDG_CONFIG_HOME` is either not
+       set or empty, `$HOME/.config/git/attributes` is used instead.
 
 core.editor::
        Commands such as `commit` and `tag` that lets you edit
@@ -1106,9 +1121,8 @@ commit.status::
        message.  Defaults to true.
 
 commit.template::
-       Specify a file to use as the template for new commit messages.
-       "`~/`" is expanded to the value of `$HOME` and "`~user/`" to the
-       specified user's home directory.
+       Specify the pathname of a file to use as the template for
+       new commit messages.
 
 credential.helper::
        Specify an external helper to be called when a username or
@@ -1334,7 +1348,7 @@ gc.worktreePruneExpire::
        'git worktree prune --expire 3.months.ago'.
        This config variable can be used to set a different grace
        period. The value "now" may be used to disable the grace
-       period and prune $GIT_DIR/worktrees immediately, or "never"
+       period and prune `$GIT_DIR/worktrees` immediately, or "never"
        may be used to suppress pruning.
 
 gc.reflogExpire::
@@ -1474,13 +1488,13 @@ grep.fallbackToNoIndex::
        is executed outside of a git repository.  Defaults to false.
 
 gpg.program::
-       Use this custom program instead of "gpg" found on $PATH when
+       Use this custom program instead of "`gpg`" found on `$PATH` when
        making or verifying a PGP signature. The program must support the
        same command-line interface as GPG, namely, to verify a detached
-       signature, "gpg --verify $file - <$signature" is run, and the
+       signature, "`gpg --verify $file - <$signature`" is run, and the
        program is expected to signal a good signature by exiting with
        code 0, and to generate an ASCII-armored detached signature, the
-       standard input of "gpg -bsau $key" is fed with the contents to be
+       standard input of "`gpg -bsau $key`" is fed with the contents to be
        signed, and the program is expected to send the result to its
        standard output.
 
@@ -1493,7 +1507,7 @@ gui.diffContext::
        made by the linkgit:git-gui[1]. The default is "5".
 
 gui.displayUntracked::
-       Determines if linkgit::git-gui[1] shows untracked files
+       Determines if linkgit:git-gui[1] shows untracked files
        in the file list. The default is "true".
 
 gui.encoding::
@@ -1655,11 +1669,12 @@ http.emptyAuth::
        authentication.
 
 http.cookieFile::
-       File containing previously stored cookie lines which should be used
+       The pathname of a file containing previously stored cookie lines,
+       which should be used
        in the Git http session, if they match the server. The file format
        of the file to read cookies from should be plain HTTP headers or
-       the Netscape/Mozilla cookie file format (see linkgit:curl[1]).
-       NOTE that the file specified with http.cookieFile is only used as
+       the Netscape/Mozilla cookie file format (see `curl(1)`).
+       NOTE that the file specified with http.cookieFile is used only as
        input unless http.saveCookies is set.
 
 http.saveCookies::
@@ -2147,8 +2162,11 @@ pack.packSizeLimit::
        The maximum size of a pack.  This setting only affects
        packing to a file when repacking, i.e. the git:// protocol
        is unaffected.  It can be overridden by the `--max-pack-size`
-       option of linkgit:git-repack[1]. The minimum size allowed is
-       limited to 1 MiB. The default is unlimited.
+       option of linkgit:git-repack[1].  Reaching this limit results
+       in the creation of multiple packfiles; which in turn prevents
+       bitmaps from being created.
+       The minimum size allowed is limited to 1 MiB.
+       The default is unlimited.
        Common unit suffixes of 'k', 'm', or 'g' are
        supported.
 
@@ -2548,8 +2566,9 @@ repack.writeBitmaps::
        objects to disk (e.g., when `git repack -a` is run).  This
        index can speed up the "counting objects" phase of subsequent
        packs created for clones and fetches, at the cost of some disk
-       space and extra time spent on the initial repack.  Defaults to
-       false.
+       space and extra time spent on the initial repack.  This has
+       no effect if multiple packfiles are created.
+       Defaults to false.
 
 rerere.autoUpdate::
        When set to true, `git-rerere` updates the index with the
index 4b0318e2ac159eb56ff4fbafe2f3c2ebfa374392..3cb301556eb2c6571298020cdea0374eb771638f 100644 (file)
@@ -271,7 +271,7 @@ For example, `--word-diff-regex=.` will treat each character as a word
 and, correspondingly, show differences character by character.
 +
 The regex can also be set via a diff driver or configuration option, see
-linkgit:gitattributes[1] or linkgit:git-config[1].  Giving it explicitly
+linkgit:gitattributes[5] or linkgit:git-config[1].  Giving it explicitly
 overrides any diff driver or configuration setting.  Diff drivers
 override configuration settings.
 
index c5047d8f9be9db6c776cca34361732e6c286d2fc..ae555bd47e123544c03a7480ed8000a73610029f 100644 (file)
@@ -1,7 +1,7 @@
 Everyday Git With 20 Commands Or So
 ===================================
 
-This document has been moved to linkgit:giteveryday[1].
+This document has been moved to linkgit:giteveryday[7].
 
 Please let the owners of the referring site know so that they can update the
 link you clicked to get here.
index e94367a5ed8e8b94bca7036ff7616bc3cfa9ca97..611754f10bb86d62edcb3265cc29ccdc97c259ae 100644 (file)
@@ -112,7 +112,7 @@ EXIT STATUS
 SEE ALSO
 --------
 linkgit:gitignore[5]
-linkgit:gitconfig[5]
+linkgit:git-config[1]
 linkgit:git-ls-files[1]
 
 GIT
index 6fc08e3d890007238528e60f843b6e01cda4f1fa..6843114fc034098e23707947f146ce36c518ed1f 100644 (file)
@@ -58,10 +58,10 @@ that location (you can say '--local' but that is the default).
 This command will fail with non-zero status upon error.  Some exit
 codes are:
 
-- The config file is invalid (ret=3),
-- can not write to the config file (ret=4),
+- The section or key is invalid (ret=1),
 - no section or name was provided (ret=2),
-- the section or key is invalid (ret=1),
+- the config file is invalid (ret=3),
+- the config file cannot be written (ret=4),
 - you try to unset an option which does not exist (ret=5),
 - you try to unset/set an option for which multiple lines match (ret=5), or
 - you try to use an invalid regexp (ret=6).
index 73fd9e8230a89a988bdf16497eb3686ab18dfb91..003731f6a990559fc4f0c785687a639bae218468 100644 (file)
@@ -205,7 +205,7 @@ to other tags will be rewritten to point to the underlying commit.
 Remap to ancestor
 ~~~~~~~~~~~~~~~~~
 
-By using linkgit:rev-list[1] arguments, e.g., path limiters, you can limit the
+By using linkgit:git-rev-list[1] arguments, e.g., path limiters, you can limit the
 set of revisions which get rewritten. However, positive refs on the command
 line are distinguished: we don't let them be excluded by such limiters. For
 this purpose, they are instead rewritten to point at the nearest ancestor that
index c52578bb87ccfec1cf37defd4c3be4afbb16259b..d9d406dcfb7d6bc9f26799635b7333bae7f7fd43 100644 (file)
@@ -179,7 +179,7 @@ returns an empty string instead.
 
 As a special case for the date-type fields, you may specify a format for
 the date by adding `:` followed by date format name (see the
-values the `--date` option to linkgit::git-rev-list[1] takes).
+values the `--date` option to linkgit:git-rev-list[1] takes).
 
 
 EXAMPLES
index 0947084140f217a4e7fe1d6fa203e4d7e9a36ffe..3bbc731f67e50bdd65dd361cd9ca249ff706728f 100644 (file)
@@ -85,7 +85,7 @@ with comments and suggestions on the message you are responding to, and to
 conclude it with a patch submission, separating the discussion and the
 beginning of the proposed commit log message with a scissors line.
 +
-This can enabled by default with the configuration option mailinfo.scissors.
+This can be enabled by default with the configuration option mailinfo.scissors.
 
 --no-scissors::
        Ignore scissors lines. Useful for overriding mailinfo.scissors settings.
index 8de349968a3be4ea7e65a4a254041b0f0fb63347..9c4fd6812cc07b8537fb28a12f4119354a2dc5c8 100644 (file)
@@ -402,4 +402,4 @@ on the `notes.rewrite.<command>` and `notes.rewriteRef` settings.
 
 GIT
 ---
-Part of the linkgit:git[7] suite
+Part of the linkgit:git[1] suite
index bbea5294ca9680dd7efee9caeea861711dafc3a5..19cdcd03417dfa7ff7c744686466af733c367945 100644 (file)
@@ -110,7 +110,8 @@ base-name::
 --max-pack-size=<n>::
        Maximum size of each output pack file. The size can be suffixed with
        "k", "m", or "g". The minimum size allowed is limited to 1 MiB.
-       If specified,  multiple packfiles may be created.
+       If specified, multiple packfiles may be created, which also
+       prevents the creation of a bitmap index.
        The default is unlimited, unless the config variable
        `pack.packSizeLimit` is set.
 
index af230d06475eedf99ee4a27eab5f1cc204f71aa1..b9c02ce48134dd44b05053275ec4b219f3999091 100644 (file)
@@ -106,7 +106,8 @@ other objects in that pack they already have locally.
 --max-pack-size=<n>::
        Maximum size of each output pack file. The size can be suffixed with
        "k", "m", or "g". The minimum size allowed is limited to 1 MiB.
-       If specified,  multiple packfiles may be created.
+       If specified, multiple packfiles may be created, which also
+       prevents the creation of a bitmap index.
        The default is unlimited, unless the config variable
        `pack.packSizeLimit` is set.
 
@@ -115,7 +116,8 @@ other objects in that pack they already have locally.
        Write a reachability bitmap index as part of the repack. This
        only makes sense when used with `-a` or `-A`, as the bitmaps
        must be able to refer to all reachable objects. This option
-       overrides the setting of `pack.writeBitmaps`.
+       overrides the setting of `repack.writeBitmaps`.  This option
+       has no effect if multiple packfiles are created.
 
 --pack-kept-objects::
        Include objects in `.keep` files when repacking.  Note that we
@@ -123,7 +125,7 @@ other objects in that pack they already have locally.
        This means that we may duplicate objects, but this makes the
        option safe to use when there are concurrent pushes or fetches.
        This option is generally only useful if you are writing bitmaps
-       with `-b` or `pack.writeBitmaps`, as it ensures that the
+       with `-b` or `repack.writeBitmaps`, as it ensures that the
        bitmapped packfile has the necessary objects.
 
 Configuration
index 1572f058f59ad1f75c4b5ed6e34fae9110414bad..ad851838cc96df3e6b920c83f62a02061b8cae80 100644 (file)
@@ -13,7 +13,7 @@ SYNOPSIS
              [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]
 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
 'git submodule' [--quiet] init [--] [<path>...]
-'git submodule' [--quiet] deinit [-f|--force] [--] <path>...
+'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]
              [-f|--force] [--rebase|--merge] [--reference <repository>]
              [--depth <depth>] [--recursive] [--] [<path>...]
@@ -140,12 +140,15 @@ deinit::
        tree. Further calls to `git submodule update`, `git submodule foreach`
        and `git submodule sync` will skip any unregistered submodules until
        they are initialized again, so use this command if you don't want to
-       have a local checkout of the submodule in your work tree anymore. If
+       have a local checkout of the submodule in your working tree anymore. If
        you really want to remove a submodule from the repository and commit
        that use linkgit:git-rm[1] instead.
 +
-If `--force` is specified, the submodule's work tree will be removed even if
-it contains local modifications.
+When the command is run without pathspec, it errors out,
+instead of deinit-ing everything, to prevent mistakes.
++
+If `--force` is specified, the submodule's working tree will
+be removed even if it contains local modifications.
 
 update::
 +
@@ -247,6 +250,10 @@ OPTIONS
 --quiet::
        Only print error messages.
 
+--all::
+       This option is only valid for the deinit command. Unregister all
+       submodules in the working tree.
+
 -b::
 --branch::
        Branch of repository to add as submodule.
@@ -257,8 +264,8 @@ OPTIONS
 --force::
        This option is only valid for add, deinit and update commands.
        When running add, allow adding an otherwise ignored submodule path.
-       When running deinit the submodule work trees will be removed even if
-       they contain local changes.
+       When running deinit the submodule working trees will be removed even
+       if they contain local changes.
        When running update (only effective with the checkout procedure),
        throw away local changes in submodules when switching to a
        different commit; and always run a checkout operation in the
index 34ff007a98156162431d5dd03abaaffe5d0c29a0..dd6dbf7dd909bb14300706bfdc7ea83a164998d2 100644 (file)
@@ -43,11 +43,12 @@ 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.2/git.html[documentation for release 2.8.2]
+* link:v2.8.3/git.html[documentation for release 2.8.3]
 
 * release notes for
-  link:RelNotes/2.8.2.txt[2.8.2].
-  link:RelNotes/2.8.1.txt[2.8.1].
+  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],
   link:RelNotes/2.8.0.txt[2.8].
 
 * link:v2.7.3/git.html[documentation for release 2.7.3]
index cafc2843599102fae1dc070c484bc6987b84b367..8ad29e61a950c2cb1f33779977a33c63ae0df33b 100644 (file)
@@ -145,7 +145,7 @@ current branch integrates with) obviously do not work, as there is no
        A fast-forward is a special type of <<def_merge,merge>> where you have a
        <<def_revision,revision>> and you are "merging" another
        <<def_branch,branch>>'s changes that happen to be a descendant of what
-       you have. In such these cases, you do not make a new <<def_merge,merge>>
+       you have. In such a case, you do not make a new <<def_merge,merge>>
        <<def_commit,commit>> but instead just update to his
        revision. This will happen frequently on a
        <<def_remote_tracking_branch,remote-tracking branch>> of a remote
index f08e9b80c562faa1de2408cd4cfdb7253d3be1f2..30808a01e7657164618c18182704768e2df0d37e 100644 (file)
@@ -89,8 +89,11 @@ option can be used to override --squash.
 
 --verify-signatures::
 --no-verify-signatures::
-       Verify that the commits being merged have good and trusted GPG signatures
-       and abort the merge in case they do not.
+       Verify that the tip commit of the side branch being merged is
+       signed with a valid key, i.e. a key that has a valid uid: in the
+       default trust model, this means the signing key has been signed by
+       a trusted key.  If the tip commit of the side branch is not signed
+       with a valid key, the merge is aborted.
 
 --summary::
 --no-summary::
index 671cebd95c36f2dc6e17fb599219e305a567bc55..29b19b992f2e652d6fc9258cbd64cad51f86c2ef 100644 (file)
@@ -143,8 +143,8 @@ ifndef::git-rev-list[]
 - '%N': commit notes
 endif::git-rev-list[]
 - '%GG': raw verification message from GPG for a signed commit
-- '%G?': show "G" for a Good signature, "B" for a Bad signature, "U" for a good,
-  untrusted signature and "N" for no signature
+- '%G?': show "G" for a good (valid) signature, "B" for a bad signature,
+  "U" for a good signature with unknown validity and "N" for no signature
 - '%GS': show the name of the signer for a signed commit
 - '%GK': show the key used to sign a signed commit
 - '%gD': reflog selector, e.g., `refs/stash@{1}`
index e44426dd041516b8d9220ce9f1b2413be0319703..75368f26ca28a4afd381c5ab180a5b90a8368c84 100644 (file)
@@ -243,7 +243,7 @@ appended to its command line, which is one of:
 The details of the credential will be provided on the helper's stdin
 stream. The exact format is the same as the input/output format of the
 `git credential` plumbing command (see the section `INPUT/OUTPUT
-FORMAT` in linkgit:git-credential[7] for a detailed specification).
+FORMAT` in linkgit:git-credential[1] for a detailed specification).
 
 For a `get` operation, the helper should produce a list of attributes
 on stdout in the same format. A helper is free to produce a subset, or
@@ -268,4 +268,4 @@ See also
 
 linkgit:gitcredentials[7]
 
-linkgit:git-config[5] (See configuration variables `credential.*`)
+linkgit:git-config[1] (See configuration variables `credential.*`)
index c6977bbc5af9c9bcdd21dc26ddb93588686a38d8..8b363438021bf1ac635042b002976ad75816caed 100644 (file)
@@ -526,7 +526,7 @@ Push Certificate
 
 A push certificate begins with a set of header lines.  After the
 header and an empty line, the protocol commands follow, one per
-line. Note that the the trailing LF in push-cert PKT-LINEs is _not_
+line. Note that the trailing LF in push-cert PKT-LINEs is _not_
 optional; it must be present.
 
 Currently, the following header fields are defined:
index 5f99f23cadea4d17d88331871fa428a0c50c9811..596965a4de6c3d965a6967a2ed94eb79eb762b5f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.8.2
+DEF_VER=v2.8.3
 
 LF='
 '
index a83e322f468a2bd3cad4058a7dffffbda822033f..e11e626d05213f4734815f03f8077ffae6793a51 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2063,7 +2063,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
        --keyword=gettextln --keyword=eval_gettextln
 XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
 LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
-LOCALIZED_SH = $(SCRIPT_SH)
+LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh
 LOCALIZED_PERL = $(SCRIPT_PERL)
 
 ifdef XGETTEXT_INCLUDE_TESTS
index 04710daa9567fb905c8213deb8634558d9d0a7aa..eb82eea64fef8ce0d4bcd18e4daab09aa53e026a 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.8.2.txt
\ No newline at end of file
+Documentation/RelNotes/2.8.3.txt
\ No newline at end of file
index 501ca97760b1f62ada876d372bd1abbbc41c6cd0..cb99df28142f164da62f5a728eb9019e57804157 100644 (file)
@@ -181,7 +181,7 @@ static void prepare_header(struct archiver_args *args,
        memcpy(header->magic, "ustar", 6);
        memcpy(header->version, "00", 2);
 
-       snprintf(header->chksum, sizeof(header->chksum), "%07o", ustar_header_chksum(header));
+       xsnprintf(header->chksum, sizeof(header->chksum), "%07o", ustar_header_chksum(header));
 }
 
 static int write_extended_header(struct archiver_args *args,
index 0adba629d2ae35a4db74fb9d1450b54bb11e51e3..37af77161e4f899f9897db0838f0b736b8450bec 100644 (file)
@@ -375,12 +375,14 @@ static char *get_head_description(void)
                strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
                            state.branch);
        else if (state.detached_from) {
-               /* TRANSLATORS: make sure these match _("HEAD detached at ")
-                  and _("HEAD detached from ") in wt-status.c */
                if (state.detached_at)
+                       /* TRANSLATORS: make sure this matches
+                          "HEAD detached at " in wt-status.c */
                        strbuf_addf(&desc, _("(HEAD detached at %s)"),
                                state.detached_from);
                else
+                       /* TRANSLATORS: make sure this matches
+                          "HEAD detached from " in wt-status.c */
                        strbuf_addf(&desc, _("(HEAD detached from %s)"),
                                state.detached_from);
        }
@@ -630,7 +632,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                        BRANCH_TRACK_EXPLICIT),
                OPT_SET_INT( 0, "set-upstream",  &track, N_("change upstream info"),
                        BRANCH_TRACK_OVERRIDE),
-               OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"),
+               OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")),
                OPT_BOOL(0, "unset-upstream", &unset_upstream, "Unset the upstream info"),
                OPT__COLOR(&branch_use_color, N_("use colored output")),
                OPT_SET_INT('r', "remotes",     &filter.kind, N_("act on remote-tracking branches"),
@@ -838,8 +840,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                if (argc == 1 && track == BRANCH_TRACK_OVERRIDE &&
                    !branch_existed && remote_tracking) {
                        fprintf(stderr, _("\nIf you wanted to make '%s' track '%s', do this:\n\n"), head, branch->name);
-                       fprintf(stderr, _("    git branch -d %s\n"), branch->name);
-                       fprintf(stderr, _("    git branch --set-upstream-to %s\n"), branch->name);
+                       fprintf(stderr, "    git branch -d %s\n", branch->name);
+                       fprintf(stderr, "    git branch --set-upstream-to %s\n", branch->name);
                }
 
        } else
index 8ed2eb8813a442b64c8f43ed23acbdbd1c0dd452..15c61fd8d1ef891b013404ea5e7cbe42befac7bd 100644 (file)
@@ -24,6 +24,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
        gitmodules_config();
        git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
        rev.abbrev = 0;
+       precompose_argv(argc, argv);
 
        argc = setup_revisions(argc, argv, &rev, NULL);
        while (1 < argc && argv[1][0] == '-') {
index d979824f9395a0cbc8ffffa9cede524589710d43..1af373d0021f56f539a1d261e908a60d92ff5b4f 100644 (file)
@@ -21,6 +21,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
        gitmodules_config();
        git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
        rev.abbrev = 0;
+       precompose_argv(argc, argv);
 
        argc = setup_revisions(argc, argv, &rev, NULL);
        for (i = 1; i < argc; i++) {
index 2a12b81e065bfb75f05baf6694e1a9d53129bc40..806dd7a885e9e7b87e19ca8acd2b6d0383b41d85 100644 (file)
@@ -114,6 +114,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
        opt->disable_stdin = 1;
        memset(&s_r_opt, 0, sizeof(s_r_opt));
        s_r_opt.tweak = diff_tree_tweak_rev;
+
+       precompose_argv(argc, argv);
        argc = setup_revisions(argc, argv, opt, &s_r_opt);
 
        while (--argc > 0) {
index 52c98a9217c60a60f0012dbdafbb193e78ec8a33..d6b8f9834d8f1ef26da5994a24db73c1b0b83221 100644 (file)
@@ -319,6 +319,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        if (!no_index)
                gitmodules_config();
        git_config(git_diff_ui_config, NULL);
+       precompose_argv(argc, argv);
 
        init_revisions(&rev, prefix);
 
index 2d1eb8bb8a433e6bda50e93e3001ae6d43db093f..e8c71fc1d2e44ef9bd93c37ff714eeefc53664cf 100644 (file)
@@ -1250,7 +1250,9 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
                       nr_unresolved * sizeof(*objects));
                f = sha1fd(output_fd, curr_pack);
                fix_unresolved_deltas(f);
-               strbuf_addf(&msg, _("completed with %d local objects"),
+               strbuf_addf(&msg, Q_("completed with %d local object",
+                                    "completed with %d local objects",
+                                    nr_objects - nr_objects_initial),
                            nr_objects - nr_objects_initial);
                stop_progress_msg(&progress, msg.buf);
                strbuf_release(&msg);
index aeae855e2b95399db4ae6032d118848449488267..a2014266b6b33d7940627777af9ae860c7850c2d 100644 (file)
@@ -252,15 +252,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                int pos;
                if (show_only || verbose)
                        printf(_("Renaming %s to %s\n"), src, dst);
-               if (!show_only && mode != INDEX) {
-                       if (rename(src, dst) < 0 && !ignore_errors)
-                               die_errno(_("renaming '%s' failed"), src);
-                       if (submodule_gitfile[i]) {
-                               if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
-                                       connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
-                               if (!update_path_in_gitmodules(src, dst))
-                                       gitmodules_modified = 1;
-                       }
+               if (show_only)
+                       continue;
+               if (mode != INDEX && rename(src, dst) < 0) {
+                       if (ignore_errors)
+                               continue;
+                       die_errno(_("renaming '%s' failed"), src);
+               }
+               if (submodule_gitfile[i]) {
+                       if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
+                               connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
+                       if (!update_path_in_gitmodules(src, dst))
+                               gitmodules_modified = 1;
                }
 
                if (mode == WORKING_DIRECTORY)
index 092e03c3cc9b24445ee5ed92cee5b202e04c9ec7..57be35faf583d5bcb112c9f487b67ae4df8bf368 100644 (file)
@@ -10,6 +10,7 @@
 
 typedef struct rev_name {
        const char *tip_name;
+       unsigned long taggerdate;
        int generation;
        int distance;
 } rev_name;
@@ -20,7 +21,8 @@ static long cutoff = LONG_MAX;
 #define MERGE_TRAVERSAL_WEIGHT 65535
 
 static void name_rev(struct commit *commit,
-               const char *tip_name, int generation, int distance,
+               const char *tip_name, unsigned long taggerdate,
+               int generation, int distance,
                int deref)
 {
        struct rev_name *name = (struct rev_name *)commit->util;
@@ -43,9 +45,12 @@ static void name_rev(struct commit *commit,
                name = xmalloc(sizeof(rev_name));
                commit->util = name;
                goto copy_data;
-       } else if (name->distance > distance) {
+       } else if (name->taggerdate > taggerdate ||
+                       (name->taggerdate == taggerdate &&
+                        name->distance > distance)) {
 copy_data:
                name->tip_name = tip_name;
+               name->taggerdate = taggerdate;
                name->generation = generation;
                name->distance = distance;
        } else
@@ -66,11 +71,11 @@ static void name_rev(struct commit *commit,
                                new_name = xstrfmt("%.*s^%d", (int)len, tip_name,
                                                   parent_number);
 
-                       name_rev(parents->item, new_name, 0,
+                       name_rev(parents->item, new_name, taggerdate, 0,
                                distance + MERGE_TRAVERSAL_WEIGHT, 0);
                } else {
-                       name_rev(parents->item, tip_name, generation + 1,
-                               distance + 1, 0);
+                       name_rev(parents->item, tip_name, taggerdate,
+                               generation + 1, distance + 1, 0);
                }
        }
 }
@@ -140,6 +145,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
        struct name_ref_data *data = cb_data;
        int can_abbreviate_output = data->tags_only && data->name_only;
        int deref = 0;
+       unsigned long taggerdate = ULONG_MAX;
 
        if (data->tags_only && !starts_with(path, "refs/tags/"))
                return 0;
@@ -164,12 +170,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
                        break; /* broken repository */
                o = parse_object(t->tagged->oid.hash);
                deref = 1;
+               taggerdate = t->date;
        }
        if (o && o->type == OBJ_COMMIT) {
                struct commit *commit = (struct commit *)o;
 
                path = name_ref_abbrev(path, can_abbreviate_output);
-               name_rev(commit, xstrdup(path), 0, 0, deref);
+               name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref);
        }
        return 0;
 }
index ed6f2222f4bf9c54535a7a23971c7749ca8d05d5..6fd058de9272631a3d5135ccbbd79bf1b4ff135c 100644 (file)
@@ -744,13 +744,14 @@ static int merge_commit(struct notes_merge_options *o)
 static int git_config_get_notes_strategy(const char *key,
                                         enum notes_merge_strategy *strategy)
 {
-       const char *value;
+       char *value;
 
-       if (git_config_get_string_const(key, &value))
+       if (git_config_get_string(key, &value))
                return 1;
        if (parse_notes_merge_strategy(value, strategy))
                git_die_config(key, "unknown notes merge strategy %s", value);
 
+       free(value);
        return 0;
 }
 
index a27de5b323f3fc7852a48fdc6de99414e8005c10..b6664ce4d8d72cde05e1f1be5edcd967f003f0ef 100644 (file)
@@ -759,6 +759,10 @@ static off_t write_reused_pack(struct sha1file *f)
        return reuse_packfile_offset - sizeof(struct pack_header);
 }
 
+static const char no_split_warning[] = N_(
+"disabling bitmap writing, packs are split due to pack.packSizeLimit"
+);
+
 static void write_pack_file(void)
 {
        uint32_t i = 0, j;
@@ -813,7 +817,10 @@ static void write_pack_file(void)
                        fixup_pack_header_footer(fd, sha1, pack_tmp_name,
                                                 nr_written, sha1, offset);
                        close(fd);
-                       write_bitmap_index = 0;
+                       if (write_bitmap_index) {
+                               warning(_(no_split_warning));
+                               write_bitmap_index = 0;
+                       }
                }
 
                if (!pack_to_stdout) {
index 10eff03967e0b9cb473d262b443949c55681fd1b..6214af9b10c213046e13b81fb30cea64abc0e619 100644 (file)
@@ -458,13 +458,13 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs
                        fprintf_ln(stderr, _("Please specify which branch you want to merge with."));
                fprintf_ln(stderr, _("See git-pull(1) for details."));
                fprintf(stderr, "\n");
-               fprintf_ln(stderr, "    git pull <remote> <branch>");
+               fprintf_ln(stderr, "    git pull %s %s", _("<remote>"), _("<branch>"));
                fprintf(stderr, "\n");
        } else if (!curr_branch->merge_nr) {
                const char *remote_name = NULL;
 
                if (for_each_remote(get_only_remote, &remote_name) || !remote_name)
-                       remote_name = "<remote>";
+                       remote_name = _("<remote>");
 
                fprintf_ln(stderr, _("There is no tracking information for the current branch."));
                if (opt_rebase)
@@ -473,12 +473,12 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs
                        fprintf_ln(stderr, _("Please specify which branch you want to merge with."));
                fprintf_ln(stderr, _("See git-pull(1) for details."));
                fprintf(stderr, "\n");
-               fprintf_ln(stderr, "    git pull <remote> <branch>");
+               fprintf_ln(stderr, "    git pull %s %s", _("<remote>"), _("<branch>"));
                fprintf(stderr, "\n");
-               fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:\n"
-                               "\n"
-                               "    git branch --set-upstream-to=%s/<branch> %s\n"),
-                               remote_name, curr_branch->name);
+               fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:"));
+               fprintf(stderr, "\n");
+               fprintf_ln(stderr, "    git branch --set-upstream-to=%s/%s %s\n",
+                               remote_name, _("<branch>"), curr_branch->name);
        } else
                fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n"
                        "from the remote, but no such ref was fetched."),
index 7457c743e8d8539c4f08df81f86c8b27c0bce392..88eb8f901367aceffa008cf33b35ca8bee848626 100644 (file)
@@ -168,7 +168,7 @@ static int command_loop(const char *child)
                size_t i;
                if (!fgets(buffer, MAXCOMMAND - 1, stdin)) {
                        if (ferror(stdin))
-                               die("Comammand input error");
+                               die("Command input error");
                        exit(0);
                }
                /* Strip end of line characters. */
index fda5c2e53d28ae84f4876ca77ac9fefebee9ada2..d33766be395ad637c4505f5ca9024a9b8331d99d 100644 (file)
@@ -1154,6 +1154,8 @@ static int show(int argc, const char **argv)
                        url_nr = states.remote->url_nr;
                }
                for (i = 0; i < url_nr; i++)
+                       /* TRANSLATORS: the colon ':' should align with
+                          the one in "  Fetch URL: %s" translation */
                        printf_ln(_("  Push  URL: %s"), url[i]);
                if (!i)
                        printf_ln(_("  Push  URL: %s"), "(no URL)");
index 8829b09d0ba5d49edbad5f37f8246123dad3fd5f..be83c4347a9cd6fdd6a76a9575f8e39a5b2bd6c2 100644 (file)
@@ -314,7 +314,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
                list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
                if (list.entry[list.nr++].is_submodule &&
                    !is_staging_gitmodules_ok())
-                       die (_("Please, stage your changes to .gitmodules or stash them to proceed"));
+                       die (_("Please stage your changes to .gitmodules or stash them to proceed"));
        }
 
        if (pathspec.nr) {
index 506ac49691bb7d53b07baf2a1d2581bf6f7ca82a..bbf4efa0a0a38ac8f13ee1c2178eff1d2127c802 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -435,12 +435,14 @@ int create_bundle(struct bundle_header *header, const char *path,
 
        /* write prerequisites */
        if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
-               return -1;
+               goto err;
 
        argc = setup_revisions(argc, argv, &revs, NULL);
 
-       if (argc > 1)
-               return error(_("unrecognized argument: %s"), argv[1]);
+       if (argc > 1) {
+               error(_("unrecognized argument: %s"), argv[1]);
+               goto err;
+       }
 
        object_array_remove_duplicates(&revs.pending);
 
@@ -448,17 +450,26 @@ int create_bundle(struct bundle_header *header, const char *path,
        if (!ref_count)
                die(_("Refusing to create empty bundle."));
        else if (ref_count < 0)
-               return -1;
+               goto err;
 
        /* write pack */
-       if (write_pack_data(bundle_fd, &revs))
-               return -1;
+       if (write_pack_data(bundle_fd, &revs)) {
+               bundle_fd = -1; /* already closed by the above call */
+               goto err;
+       }
 
        if (!bundle_to_stdout) {
                if (commit_lock_file(&lock))
                        die_errno(_("cannot create '%s'"), path);
        }
        return 0;
+err:
+       if (!bundle_to_stdout) {
+               if (0 <= bundle_fd)
+                       close(bundle_fd);
+               rollback_lock_file(&lock);
+       }
+       return -1;
 }
 
 int unbundle(struct bundle_header *header, int bundle_fd, int flags)
diff --git a/cache.h b/cache.h
index 2711048cad7d5c7bba04c5737aa6142caf49d023..4ff196c25926cb1a6662f7582969ed665bae5ee3 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -700,6 +700,14 @@ extern int ref_paranoia;
 extern char comment_line_char;
 extern int auto_comment_line_char;
 
+/* Windows only */
+enum hide_dotfiles_type {
+       HIDE_DOTFILES_FALSE = 0,
+       HIDE_DOTFILES_TRUE,
+       HIDE_DOTFILES_DOTGITONLY
+};
+extern enum hide_dotfiles_type hide_dotfiles;
+
 enum branch_track {
        BRANCH_TRACK_UNSPECIFIED = -1,
        BRANCH_TRACK_NEVER = 0,
@@ -958,8 +966,6 @@ static inline int is_empty_blob_sha1(const unsigned char *sha1)
 
 int git_mkstemp(char *path, size_t n, const char *template);
 
-int git_mkstemps(char *path, size_t n, const char *template, int suffix_len);
-
 /* set default permissions by passing mode arguments to open(2) */
 int git_mkstemps_mode(char *pattern, int suffix_len, int mode);
 int git_mkstemp_mode(char *pattern, int mode);
diff --git a/ci/test-documentation.sh b/ci/test-documentation.sh
new file mode 100755 (executable)
index 0000000..579d540
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Perform sanity checks on documentation and build it.
+#
+
+set -e
+
+make check-builtins
+make check-docs
+make doc
+
+test -s Documentation/git.html
+test -s Documentation/git.xml
+test -s Documentation/git.1
index 0413d5c3cdd128ca721c75b588dc557bdbb1f949..a8218e6f0f2177e769cf3841b1c7d7d9b9ed270d 100644 (file)
@@ -286,6 +286,49 @@ int mingw_rmdir(const char *pathname)
        return ret;
 }
 
+static inline int needs_hiding(const char *path)
+{
+       const char *basename;
+
+       if (hide_dotfiles == HIDE_DOTFILES_FALSE)
+               return 0;
+
+       /* We cannot use basename(), as it would remove trailing slashes */
+       mingw_skip_dos_drive_prefix((char **)&path);
+       if (!*path)
+               return 0;
+
+       for (basename = path; *path; path++)
+               if (is_dir_sep(*path)) {
+                       do {
+                               path++;
+                       } while (is_dir_sep(*path));
+                       /* ignore trailing slashes */
+                       if (*path)
+                               basename = path;
+               }
+
+       if (hide_dotfiles == HIDE_DOTFILES_TRUE)
+               return *basename == '.';
+
+       assert(hide_dotfiles == HIDE_DOTFILES_DOTGITONLY);
+       return !strncasecmp(".git", basename, 4) &&
+               (!basename[4] || is_dir_sep(basename[4]));
+}
+
+static int set_hidden_flag(const wchar_t *path, int set)
+{
+       DWORD original = GetFileAttributesW(path), modified;
+       if (set)
+               modified = original | FILE_ATTRIBUTE_HIDDEN;
+       else
+               modified = original & ~FILE_ATTRIBUTE_HIDDEN;
+       if (original == modified || SetFileAttributesW(path, modified))
+               return 0;
+       errno = err_win_to_posix(GetLastError());
+       return -1;
+}
+
 int mingw_mkdir(const char *path, int mode)
 {
        int ret;
@@ -293,6 +336,8 @@ int mingw_mkdir(const char *path, int mode)
        if (xutftowcs_path(wpath, path) < 0)
                return -1;
        ret = _wmkdir(wpath);
+       if (!ret && needs_hiding(path))
+               return set_hidden_flag(wpath, 1);
        return ret;
 }
 
@@ -319,6 +364,21 @@ int mingw_open (const char *filename, int oflags, ...)
                if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
                        errno = EISDIR;
        }
+       if ((oflags & O_CREAT) && needs_hiding(filename)) {
+               /*
+                * Internally, _wopen() uses the CreateFile() API which errors
+                * out with an ERROR_ACCESS_DENIED if CREATE_ALWAYS was
+                * specified and an already existing file's attributes do not
+                * match *exactly*. As there is no mode or flag we can set that
+                * would correspond to FILE_ATTRIBUTE_HIDDEN, let's just try
+                * again *without* the O_CREAT flag (that corresponds to the
+                * CREATE_ALWAYS flag of CreateFile()).
+                */
+               if (fd < 0 && errno == EACCES)
+                       fd = _wopen(wfilename, oflags & ~O_CREAT, mode);
+               if (fd >= 0 && set_hidden_flag(wfilename, 1))
+                       warning("could not mark '%s' as hidden.", filename);
+       }
        return fd;
 }
 
@@ -350,6 +410,7 @@ int mingw_fgetc(FILE *stream)
 #undef fopen
 FILE *mingw_fopen (const char *filename, const char *otype)
 {
+       int hide = needs_hiding(filename);
        FILE *file;
        wchar_t wfilename[MAX_PATH], wotype[4];
        if (filename && !strcmp(filename, "/dev/null"))
@@ -357,12 +418,19 @@ FILE *mingw_fopen (const char *filename, const char *otype)
        if (xutftowcs_path(wfilename, filename) < 0 ||
                xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
                return NULL;
+       if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
+               error("could not unhide %s", filename);
+               return NULL;
+       }
        file = _wfopen(wfilename, wotype);
+       if (file && hide && set_hidden_flag(wfilename, 1))
+               warning("could not mark '%s' as hidden.", filename);
        return file;
 }
 
 FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
 {
+       int hide = needs_hiding(filename);
        FILE *file;
        wchar_t wfilename[MAX_PATH], wotype[4];
        if (filename && !strcmp(filename, "/dev/null"))
@@ -370,7 +438,13 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
        if (xutftowcs_path(wfilename, filename) < 0 ||
                xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
                return NULL;
+       if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
+               error("could not unhide %s", filename);
+               return NULL;
+       }
        file = _wfreopen(wfilename, wotype, stream);
+       if (file && hide && set_hidden_flag(wfilename, 1))
+               warning("could not mark '%s' as hidden.", filename);
        return file;
 }
 
index 1de70ffd62a63070ca79d27ad0b323dfbcacb5aa..69bb43dc35d4c28724f007d9684715ec40421542 100644 (file)
@@ -142,6 +142,7 @@ static inline int fcntl(int fd, int cmd, ...)
 #define sigemptyset(x) (void)0
 static inline int sigaddset(sigset_t *set, int signum)
 { return 0; }
+#define SIG_BLOCK 0
 #define SIG_UNBLOCK 0
 static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 { return 0; }
@@ -416,9 +417,6 @@ int mingw_offset_1st_component(const char *path);
 void mingw_open_html(const char *path);
 #define open_html mingw_open_html
 
-void mingw_mark_as_git_dir(const char *dir);
-#define mark_as_git_dir mingw_mark_as_git_dir
-
 /**
  * Converts UTF-8 encoded string to UTF-16LE.
  *
index dfbe6d84081c8b8eea50450a4c23c9a80b3b57a7..4293b53b171f5002127d7a354309d343706c0272 100644 (file)
@@ -147,7 +147,7 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir)
                                if (errno || inleft) {
                                        /*
                                         * iconv() failed and errno could be E2BIG, EILSEQ, EINVAL, EBADF
-                                        * MacOS X avoids illegal byte sequemces.
+                                        * MacOS X avoids illegal byte sequences.
                                         * If they occur on a mounted drive (e.g. NFS) it is not worth to
                                         * die() for that, but rather let the user see the original name
                                        */
index b6ed9e74621fe0bc506beb893e477bff26e88756..1c164088fbb64d2f0143f536f3186f481d876d28 100644 (file)
@@ -104,4 +104,11 @@ static inline void *pthread_getspecific(pthread_key_t key)
        return TlsGetValue(key);
 }
 
+#ifndef __MINGW64_VERSION_MAJOR
+static inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
+{
+       return 0;
+}
+#endif
+
 #endif /* PTHREAD_H */
index 80a8c9af4f0ddcc883370fe05781337cef0d5ef0..519d51f2b60a2dd0d477863f237e87b1beae1627 100644 (file)
@@ -2,37 +2,42 @@
 
 void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
 {
-       HANDLE hmap;
+       HANDLE osfhandle, hmap;
        void *temp;
-       off_t len;
-       struct stat st;
+       LARGE_INTEGER len;
        uint64_t o = offset;
        uint32_t l = o & 0xFFFFFFFF;
        uint32_t h = (o >> 32) & 0xFFFFFFFF;
 
-       if (!fstat(fd, &st))
-               len = st.st_size;
-       else
+       osfhandle = (HANDLE)_get_osfhandle(fd);
+       if (!GetFileSizeEx(osfhandle, &len))
                die("mmap: could not determine filesize");
 
-       if ((length + offset) > len)
-               length = xsize_t(len - offset);
+       if ((length + offset) > len.QuadPart)
+               length = xsize_t(len.QuadPart - offset);
 
        if (!(flags & MAP_PRIVATE))
                die("Invalid usage of mmap when built with USE_WIN32_MMAP");
 
-       hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL,
-               PAGE_WRITECOPY, 0, 0, NULL);
+       hmap = CreateFileMapping(osfhandle, NULL,
+               prot == PROT_READ ? PAGE_READONLY : PAGE_WRITECOPY, 0, 0, NULL);
 
-       if (!hmap)
+       if (!hmap) {
+               errno = EINVAL;
                return MAP_FAILED;
+       }
 
-       temp = MapViewOfFileEx(hmap, FILE_MAP_COPY, h, l, length, start);
+       temp = MapViewOfFileEx(hmap, prot == PROT_READ ?
+                       FILE_MAP_READ : FILE_MAP_COPY, h, l, length, start);
 
        if (!CloseHandle(hmap))
                warning("unable to close file mapping handle");
 
-       return temp ? temp : MAP_FAILED;
+       if (temp)
+               return temp;
+
+       errno = GetLastError() == ERROR_COMMITMENT_LIMIT ? EFBIG : EINVAL;
+       return MAP_FAILED;
 }
 
 int git_munmap(void *start, size_t length)
index 47b2ce1d5a753f11bb1876e709e6a7324aa47e54..6dbc8a409e7e6e674e399e1d9b8ef8ef3c9290b7 100644 (file)
--- a/config.c
+++ b/config.c
@@ -803,8 +803,6 @@ static int git_default_core_config(const char *var, const char *value)
 
        if (!strcmp(var, "core.autocrlf")) {
                if (value && !strcasecmp(value, "input")) {
-                       if (core_eol == EOL_CRLF)
-                               return error("core.autocrlf=input conflicts with core.eol=crlf");
                        auto_crlf = AUTO_CRLF_INPUT;
                        return 0;
                }
@@ -830,8 +828,6 @@ static int git_default_core_config(const char *var, const char *value)
                        core_eol = EOL_NATIVE;
                else
                        core_eol = EOL_UNSET;
-               if (core_eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
-                       return error("core.autocrlf=input conflicts with core.eol=crlf");
                return 0;
        }
 
@@ -912,6 +908,14 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.hidedotfiles")) {
+               if (value && !strcasecmp(value, "dotgitonly"))
+                       hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
+               else
+                       hide_dotfiles = git_config_bool(var, value);
+               return 0;
+       }
+
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
 }
@@ -1309,14 +1313,11 @@ static struct config_set_element *configset_find_element(struct config_set *cs,
        struct config_set_element k;
        struct config_set_element *found_entry;
        char *normalized_key;
-       int ret;
        /*
         * `key` may come from the user, so normalize it before using it
         * for querying entries from the hashmap.
         */
-       ret = git_config_parse_key(key, &normalized_key, NULL);
-
-       if (ret)
+       if (git_config_parse_key(key, &normalized_key, NULL))
                return NULL;
 
        hashmap_entry_init(&k, strhash(normalized_key));
index f524b8d7f4daf70a610a1e00af2ae6f1c23f8f62..b1614bf7ff0d38325baa427da09859fb4e36e1c9 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -1380,27 +1380,22 @@ static struct stream_filter *ident_filter(const unsigned char *sha1)
 struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1)
 {
        struct conv_attrs ca;
-       enum crlf_action crlf_action;
        struct stream_filter *filter = NULL;
 
        convert_attrs(&ca, path);
-
        if (ca.drv && (ca.drv->smudge || ca.drv->clean))
-               return filter;
+               return NULL;
+
+       if (ca.crlf_action == CRLF_AUTO || ca.crlf_action == CRLF_AUTO_CRLF)
+               return NULL;
 
        if (ca.ident)
                filter = ident_filter(sha1);
 
-       crlf_action = ca.crlf_action;
-
-       if ((crlf_action == CRLF_BINARY) ||
-                       crlf_action == CRLF_AUTO_INPUT ||
-                       (crlf_action == CRLF_TEXT_INPUT))
-               filter = cascade_filter(filter, &null_filter_singleton);
-
-       else if (output_eol(crlf_action) == EOL_CRLF &&
-                !(crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_CRLF))
+       if (output_eol(ca.crlf_action) == EOL_CRLF)
                filter = cascade_filter(filter, lf_to_crlf_filter());
+       else
+               filter = cascade_filter(filter, &null_filter_singleton);
 
        return filter;
 }
index f4afdc6988c32cd95769dee488f8495b8a6ce5b6..86e21de49be4d48defd3e9da5cde170291bca600 100644 (file)
@@ -32,6 +32,7 @@ static int send_request(const char *socket, const struct strbuf *out)
                write_or_die(1, in, r);
                got_data = 1;
        }
+       close(fd);
        return got_data;
 }
 
diff --git a/dir.c b/dir.c
index 996653b0d3b6d81b15a3185d8d63314de647c53d..656f272adc69b633ddd06277bf9cc77205a7e8ee 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -64,13 +64,6 @@ int strncmp_icase(const char *a, const char *b, size_t count)
        return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
 }
 
-int fnmatch_icase(const char *pattern, const char *string, int flags)
-{
-       return wildmatch(pattern, string,
-                        flags | (ignore_case ? WM_CASEFOLD : 0),
-                        NULL);
-}
-
 int git_fnmatch(const struct pathspec_item *item,
                const char *pattern, const char *string,
                int prefix)
diff --git a/dir.h b/dir.h
index 301b737a37236c1d61d109b29fa556143c28df46..d56d2fb48f68191d54fdfb8c5c104cb87cba1c41 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -272,7 +272,6 @@ extern int remove_path(const char *path);
 
 extern int strcmp_icase(const char *a, const char *b);
 extern int strncmp_icase(const char *a, const char *b, size_t count);
-extern int fnmatch_icase(const char *pattern, const char *string, int flags);
 
 /*
  * The prefix part of pattern must not contains wildcards.
index 57acb2fe2aee79a30c4c956dcececd6a7122aeb6..96160a75a53340fcc9b2e1a81d2198d073bd4562 100644 (file)
@@ -63,6 +63,7 @@ int core_apply_sparse_checkout;
 int merge_log_config = -1;
 int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
 unsigned long pack_size_limit_cfg;
+enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
 
 #ifndef PROTECT_HFS_DEFAULT
 #define PROTECT_HFS_DEFAULT 0
index f96f6dfb35afb419ac38fcec9b4013fbf0e6d36d..b501d5c320a5117020a934a50fce2a356b0c2f0e 100644 (file)
@@ -15,7 +15,6 @@
 #include "version.h"
 #include "prio-queue.h"
 #include "sha1-array.h"
-#include "sigchain.h"
 
 static int transfer_unpack_limit = -1;
 static int fetch_unpack_limit = -1;
@@ -674,10 +673,8 @@ static int sideband_demux(int in, int out, void *data)
        int *xd = data;
        int ret;
 
-       sigchain_push(SIGPIPE, SIG_IGN);
        ret = recv_sideband("fetch-pack", xd[0], out);
        close(out);
-       sigchain_pop(SIGPIPE);
        return ret;
 }
 
@@ -701,6 +698,7 @@ static int get_pack(struct fetch_pack_args *args,
                demux.proc = sideband_demux;
                demux.data = xd;
                demux.out = -1;
+               demux.isolate_sigpipe = 1;
                if (start_async(&demux))
                        die("fetch-pack: unable to fork off sideband"
                            " demultiplexer");
diff --git a/fsck.c b/fsck.c
index ca4c68537788496dea803b559e2ffd4cf1dbeea7..3366b3fb620fddaf542d7c23e1f6c1c564f8fbe8 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -59,6 +59,7 @@
        FUNC(HAS_DOTGIT, WARN) \
        FUNC(NULL_SHA1, WARN) \
        FUNC(ZERO_PADDED_FILEMODE, WARN) \
+       FUNC(NUL_IN_COMMIT, WARN) \
        /* infos (reported as warnings, but ignored by default) */ \
        FUNC(BAD_TAG_NAME, INFO) \
        FUNC(MISSING_TAGGER_ENTRY, INFO)
@@ -610,6 +611,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
        struct commit_graft *graft;
        unsigned parent_count, parent_line_count = 0, author_count;
        int err;
+       const char *buffer_begin = buffer;
 
        if (verify_headers(buffer, size, &commit->object, options))
                return -1;
@@ -666,9 +668,17 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
        err = fsck_ident(&buffer, &commit->object, options);
        if (err)
                return err;
-       if (!commit->tree)
-               return report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
-
+       if (!commit->tree) {
+               err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
+               if (err)
+                       return err;
+       }
+       if (memchr(buffer_begin, '\0', size)) {
+               err = report(options, &commit->object, FSCK_MSG_NUL_IN_COMMIT,
+                            "NUL byte in the commit object body");
+               if (err)
+                       return err;
+       }
        return 0;
 }
 
index 02c0445be1057619e01e56bd6792f78fc011dc42..d50c85ed7ba719a0dc04f7ca96cf05216104599d 100755 (executable)
@@ -1156,7 +1156,7 @@ sub prepDirForOutput
     # FUTURE: This would more accurately emulate CVS by sending
     #   another copy of sticky after processing the files in that
     #   directory.  Or intermediate: perhaps send all sticky's for
-    #   $seendirs after after processing all files.
+    #   $seendirs after processing all files.
 }
 
 # update \n
@@ -2824,7 +2824,7 @@ sub statecleanup
 }
 
 # Return working directory CVS revision "1.X" out
-# of the the working directory "entries" state, for the given filename.
+# of the working directory "entries" state, for the given filename.
 # This is prefixed with a dash if the file is scheduled for removal
 # when it is committed.
 sub revparse
@@ -2935,7 +2935,7 @@ sub filecleanup
     return $filename;
 }
 
-# Remove prependdir from the path, so that is is relative to the directory
+# Remove prependdir from the path, so that it is relative to the directory
 # the CVS client was started from, rather than the top of the project.
 # Essentially the inverse of filecleanup().
 sub remove_prependdir
index 2b11b1d6fe33cf3f61dd35b8f48d6953f7a25bff..84d6cc021c51ac53b68a8b9fdbdd3ed0f8d9d30a 100755 (executable)
@@ -44,10 +44,10 @@ launch_merge_tool () {
                        "$GIT_DIFF_PATH_TOTAL" "$MERGED"
                if use_ext_cmd
                then
-                       printf "Launch '%s' [Y/n]: " \
+                       printf "Launch '%s' [Y/n]? " \
                                "$GIT_DIFFTOOL_EXTCMD"
                else
-                       printf "Launch '%s' [Y/n]: " "$merge_tool"
+                       printf "Launch '%s' [Y/n]? " "$merge_tool"
                fi
                read ans || return
                if test "$ans" = n
index 54ac8e484674710ca21ea0038d07dcbefbe2fb1e..92adcc0d0785f8b78fce2c49bbcc40e49020ee24 100644 (file)
@@ -100,7 +100,7 @@ check_unchanged () {
                while true
                do
                        echo "$MERGED seems unchanged."
-                       printf "Was the merge successful? [y/n] "
+                       printf "Was the merge successful [y/n]? "
                        read answer || return 1
                        case "$answer" in
                        y*|Y*) return 0 ;;
index f67bab55e85d00b06601fa488ba01975eb865359..bf862705d8c654a5dd58ec70d6781583b7dbefc3 100755 (executable)
@@ -413,7 +413,7 @@ done
 prompt_after_failed_merge () {
        while true
        do
-               printf "Continue merging other unresolved paths (y/n) ? "
+               printf "Continue merging other unresolved paths [y/n]? "
                read ans || return 1
                case "$ans" in
                [yY]*)
index 825b9f32d5540ab1f8d373fff2d3bf79caabee00..e752153f6f16247c23ff390e20ae18cf51158a30 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -1064,8 +1064,15 @@ def generatePointer(self, contentFile):
         if pointerProcess.wait():
             os.remove(contentFile)
             die('git-lfs pointer command failed. Did you install the extension?')
-        pointerContents = [i+'\n' for i in pointerFile.split('\n')[2:][:-1]]
-        oid = pointerContents[1].split(' ')[1].split(':')[1][:-1]
+
+        # Git LFS removed the preamble in the output of the 'pointer' command
+        # starting from version 1.2.0. Check for the preamble here to support
+        # earlier versions.
+        # c.f. https://github.com/github/git-lfs/commit/da2935d9a739592bc775c98d8ef4df9c72ea3b43
+        if pointerFile.startswith('Git LFS pointer for'):
+            pointerFile = re.sub(r'Git LFS pointer for.*\n\n', '', pointerFile)
+
+        oid = re.search(r'^oid \w+:(\w+)', pointerFile, re.MULTILINE).group(1)
         localLargeFile = os.path.join(
             os.getcwd(),
             '.git', 'lfs', 'objects', oid[:2], oid[2:4],
@@ -1073,7 +1080,7 @@ def generatePointer(self, contentFile):
         )
         # LFS Spec states that pointer files should not have the executable bit set.
         gitMode = '100644'
-        return (gitMode, pointerContents, localLargeFile)
+        return (gitMode, pointerFile, localLargeFile)
 
     def pushFile(self, localLargeFile):
         uploadProcess = subprocess.Popen(
index 55fe8d56c9d5107df0843378ef137d64a48b2980..d3c39980f3fe2c346e4264d4b99a49acf7140301 100644 (file)
@@ -56,11 +56,13 @@ get_remote_merge_branch () {
 error_on_missing_default_upstream () {
        cmd="$1"
        op_type="$2"
-       op_prep="$3"
+       op_prep="$3" # FIXME: op_prep is no longer used
        example="$4"
        branch_name=$(git symbolic-ref -q HEAD)
+       display_branch_name="${branch_name#refs/heads/}"
        # If there's only one remote, use that in the suggestion
-       remote="<remote>"
+       remote="$(gettext "<remote>")"
+       branch="$(gettext "<branch>")"
        if test $(git remote | wc -l) = 1
        then
                remote=$(git remote)
@@ -68,22 +70,32 @@ error_on_missing_default_upstream () {
 
        if test -z "$branch_name"
        then
-               echo "You are not currently on a branch. Please specify which
-branch you want to $op_type $op_prep. See git-${cmd}(1) for details.
-
-    $example
-"
+               gettextln "You are not currently on a branch."
        else
-               echo "There is no tracking information for the current branch.
-Please specify which branch you want to $op_type $op_prep.
-See git-${cmd}(1) for details
-
-    $example
-
-If you wish to set tracking information for this branch you can do so with:
-
-    git branch --set-upstream-to=$remote/<branch> ${branch_name#refs/heads/}
-"
+               gettextln "There is no tracking information for the current branch."
+       fi
+       case "$op_type" in
+       rebase)
+               gettextln "Please specify which branch you want to rebase against."
+               ;;
+       merge)
+               gettextln "Please specify which branch you want to merge with."
+               ;;
+       *)
+               echo >&2 "BUG: unknown operation type: $op_type"
+               exit 1
+               ;;
+       esac
+       eval_gettextln "See git-\${cmd}(1) for details."
+       echo
+       echo "    $example"
+       echo
+       if test -n "$branch_name"
+       then
+               gettextln "If you wish to set tracking information for this branch you can do so with:"
+               echo
+               echo "    git branch --set-upstream-to=$remote/$branch $display_branch_name"
+               echo
        fi
        exit 1
 }
index 4cde685b43a4463bac5f96bcb4f8ed8b3e9347be..655ebaa4717fe6e43b4b16a69e5eb282140edd6d 100644 (file)
@@ -82,6 +82,7 @@ rewritten_pending="$state_dir"/rewritten-pending
 cr=$(printf "\015")
 
 strategy_args=${strategy:+--strategy=$strategy}
+test -n "$strategy_opts" &&
 eval '
        for strategy_opt in '"$strategy_opts"'
        do
index 1406f64d780a481cfc8be0e09a66f0c76887badd..69587856df1706a2da42d6ce2a87c25a054e9eb6 100755 (executable)
@@ -827,9 +827,10 @@ sub file_declares_8bit_cte {
 # But it's a no-op to run sanitize_address on an already sanitized address.
 $sender = sanitize_address($sender);
 
+my $to_whom = "To whom should the emails be sent (if anyone)?";
 my $prompting = 0;
 if (!@initial_to && !defined $to_cmd) {
-       my $to = ask("Who should the emails be sent to (if any)? ",
+       my $to = ask("$to_whom ",
                     default => "",
                     valid_re => qr/\@.*\./, confirm_only => 1);
        push @initial_to, parse_address_line($to) if defined $to; # sanitized/validated later
@@ -924,7 +925,7 @@ sub validate_address {
                        cleanup_compose_files();
                        exit(0);
                }
-               $address = ask("Who should the email be sent to (if any)? ",
+               $address = ask("$to_whom ",
                        default => "",
                        valid_re => qr/\@.*\./, confirm_only => 1);
        }
index 753a90d3071d1917495ca725fe15a944f84b6f60..d56207ea05db971f8ebdf566848b31df86b81c64 100755 (executable)
@@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
 USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
-   or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
+   or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
@@ -521,6 +521,7 @@ cmd_init()
 cmd_deinit()
 {
        # parse $args after "submodule ... deinit".
+       deinit_all=
        while test $# -ne 0
        do
                case "$1" in
@@ -530,6 +531,9 @@ cmd_deinit()
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
+               --all)
+                       deinit_all=t
+                       ;;
                --)
                        shift
                        break
@@ -544,9 +548,14 @@ cmd_deinit()
                shift
        done
 
-       if test $# = 0
+       if test -n "$deinit_all" && test "$#" -ne 0
+       then
+               echo >&2 "$(eval_gettext "pathspec and --all are incompatible")"
+               usage
+       fi
+       if test $# = 0 && test -z "$deinit_all"
        then
-               die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")"
+               die "$(eval_gettext "Use '--all' if you really want to deinitialize all submodules")"
        fi
 
        git submodule--helper list --prefix "$wt_prefix" "$@" |
index 05d7910b7cdbd6fea7c835491caa774a46e4b7f8..2fddf750fabf9ac2d079777ad7bd7953c2477f9c 100755 (executable)
@@ -3935,6 +3935,9 @@ sub run_highlighter {
 
        close $fd;
        open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
+                 quote_command($^X, '-CO', '-MEncode=decode,FB_DEFAULT', '-pse',
+                   '$_ = decode($fe, $_, FB_DEFAULT) if !utf8::decode($_);',
+                   '--', "-fe=$fallback_encoding")." | ".
                  quote_command($highlight_bin).
                  " --replace-tabs=8 --fragment --syntax $syntax |"
                or die_error(500, "Couldn't open file or run syntax highlighter");
diff --git a/http.c b/http.c
index 4304b80ad3ac9d8ae249bc0bc007074bc5aa6181..1044f9ba0e28ff825fa58c56d535861cd9f56a59 100644 (file)
--- a/http.c
+++ b/http.c
@@ -293,7 +293,7 @@ static int http_options(const char *var, const char *value, void *cb)
                return git_config_string(&http_proxy_authmethod, var, value);
 
        if (!strcmp("http.cookiefile", var))
-               return git_config_string(&curl_cookie_file, var, value);
+               return git_config_pathname(&curl_cookie_file, var, value);
        if (!strcmp("http.savecookies", var)) {
                curl_save_cookies = git_config_bool(var, value);
                return 0;
diff --git a/ident.c b/ident.c
index 6e125821f0563c46eaf8253f31e19d9d97a94e7e..4fd82d104365c2e2c1ab7e1597e7e246c8eded24 100644 (file)
--- a/ident.c
+++ b/ident.c
@@ -351,15 +351,17 @@ const char *fmt_ident(const char *name, const char *email,
        if (want_name) {
                int using_default = 0;
                if (!name) {
+                       if (strict && ident_use_config_only
+                           && !(ident_config_given & IDENT_NAME_GIVEN)) {
+                               fputs(env_hint, stderr);
+                               die("no name was given and auto-detection is disabled");
+                       }
                        name = ident_default_name();
                        using_default = 1;
                        if (strict && default_name_is_bogus) {
                                fputs(env_hint, stderr);
                                die("unable to auto-detect name (got '%s')", name);
                        }
-                       if (strict && ident_use_config_only
-                           && !(ident_config_given & IDENT_NAME_GIVEN))
-                               die("user.useConfigOnly set but no name given");
                }
                if (!*name) {
                        struct passwd *pw;
@@ -374,14 +376,16 @@ const char *fmt_ident(const char *name, const char *email,
        }
 
        if (!email) {
+               if (strict && ident_use_config_only
+                   && !(ident_config_given & IDENT_MAIL_GIVEN)) {
+                       fputs(env_hint, stderr);
+                       die("no email was given and auto-detection is disabled");
+               }
                email = ident_default_email();
                if (strict && default_email_is_bogus) {
                        fputs(env_hint, stderr);
                        die("unable to auto-detect email address (got '%s')", email);
                }
-               if (strict && ident_use_config_only
-                   && !(ident_config_given & IDENT_MAIL_GIVEN))
-                       die("user.useConfigOnly set but no mail given");
        }
 
        strbuf_reset(&ident);
diff --git a/path.c b/path.c
index bbaea5ab0bf73056dfa74063474f62685fda1d5e..503766784c4c0c1be71edacbaae6ec4bd698ee8d 100644 (file)
--- a/path.c
+++ b/path.c
@@ -134,7 +134,7 @@ static struct common_dir common_list[] = {
  * definite
  * definition
  *
- * The trie would look look like:
+ * The trie would look like:
  * root: len = 0, children a and d non-NULL, value = NULL.
  *    a: len = 2, contents = bc, value = (data for "abc")
  *    d: len = 2, contents = ef, children i non-NULL, value = (data for "def")
index 49eb88af8d052e2bd71b83576034f8d338290013..ce7e4e8da3947bb2c527c49d6d09e1e49b0392c3 100644 (file)
@@ -393,7 +393,7 @@ sub command_close_pipe {
 Execute the given C<COMMAND> in the same way as command_output_pipe()
 does but return both an input pipe filehandle and an output pipe filehandle.
 
-The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>.
+The function will return C<($pid, $pipe_in, $pipe_out, $ctx)>.
 See C<command_close_bidi_pipe()> for details.
 
 =cut
index 28fd676acbbf4985422d74c9f1987dd0a5765039..a326e4e2516e2129e7a08bfc149786402ec160fb 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1660,7 +1660,7 @@ int branch_merge_matches(struct branch *branch,
        return refname_match(branch->merge[i]->src, refname);
 }
 
-__attribute((format (printf,2,3)))
+__attribute__((format (printf,2,3)))
 static const char *error_buf(struct strbuf *err, const char *fmt, ...)
 {
        if (err) {
@@ -2108,7 +2108,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)
                           "Your branch and '%s' have diverged,\n"
                               "and have %d and %d different commits each, "
                               "respectively.\n",
-                          theirs),
+                          ours + theirs),
                        base, ours, theirs);
                if (advice_status_hints)
                        strbuf_addf(sb,
index c72601056cf5ae7be2593ae89af4effc26a1b043..2d6628012d7f3dc555d9bf385e990ac2c4ec6885 100644 (file)
@@ -590,6 +590,16 @@ static void *run_thread(void *data)
        struct async *async = data;
        intptr_t ret;
 
+       if (async->isolate_sigpipe) {
+               sigset_t mask;
+               sigemptyset(&mask);
+               sigaddset(&mask, SIGPIPE);
+               if (pthread_sigmask(SIG_BLOCK, &mask, NULL) < 0) {
+                       ret = error("unable to block SIGPIPE in async thread");
+                       return (void *)ret;
+               }
+       }
+
        pthread_setspecific(async_key, async);
        ret = async->proc(async->proc_in, async->proc_out, async->data);
        return (void *)ret;
index 3d1e59e26e33d062a10698fc139f7fc0f4ae14ec..49ba764c6c1d6b6d14e2e1cd56f3a5b6e8a37c12 100644 (file)
@@ -116,6 +116,7 @@ struct async {
        int proc_in;
        int proc_out;
 #endif
+       int isolate_sigpipe;
 };
 
 int start_async(struct async *async);
index 047bd18fde3d09921902ebb656ab78bfbcf940a8..37ee04ea3bf41b3bc4b0b920d52449c2f6d681d7 100644 (file)
@@ -518,6 +518,7 @@ int send_pack(struct send_pack_args *args,
                demux.proc = sideband_demux;
                demux.data = fd;
                demux.out = -1;
+               demux.isolate_sigpipe = 1;
                if (start_async(&demux))
                        die("send-pack: unable to fork off sideband demultiplexer");
                in = demux.out;
@@ -531,8 +532,10 @@ int send_pack(struct send_pack_args *args,
                                close(out);
                        if (git_connection_is_socket(conn))
                                shutdown(fd[0], SHUT_WR);
-                       if (use_sideband)
+                       if (use_sideband) {
+                               close(demux.out);
                                finish_async(&demux);
+                       }
                        fd[1] = -1;
                        return -1;
                }
@@ -551,11 +554,11 @@ int send_pack(struct send_pack_args *args,
                packet_flush(out);
 
        if (use_sideband && cmds_sent) {
+               close(demux.out);
                if (finish_async(&demux)) {
                        error("error in sideband demultiplexer");
                        ret = -1;
                }
-               close(demux.out);
        }
 
        if (ret < 0)
index 968b780a06d1f17b190395f06f78fc3124fcf445..3c75d4b9ce717fa92520881ef754485d068a3a60 100644 (file)
@@ -60,7 +60,7 @@ static void mark_base_index_entries(struct index_state *base)
         * To keep track of the shared entries between
         * istate->base->cache[] and istate->cache[], base entry
         * position is stored in each base entry. All positions start
-        * from 1 instead of 0, which is resrved to say "this is a new
+        * from 1 instead of 0, which is reserved to say "this is a new
         * entry".
         */
        for (i = 0; i < base->cache_nr; i++)
index 2a32a3f1f5d250d7ea2a1b4a65998eeddb44962e..62d20846cbead5aba6a4b3859475b454ad606205 100644 (file)
@@ -231,12 +231,12 @@ void string_list_sort(struct string_list *list)
 struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
                                                     const char *string)
 {
-       int i;
+       struct string_list_item *item;
        compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
 
-       for (i = 0; i < list->nr; i++)
-               if (!cmp(string, list->items[i].string))
-                       return list->items + i;
+       for_each_string_list_item(item, list)
+               if (!cmp(string, item->string))
+                       return item;
        return NULL;
 }
 
index 8476e0fa0f89c968e95182fd44211c0018a4b1f8..7f67ec0c6a826cca0ba80ce5990d5f0f3a0dcaa6 100644 (file)
@@ -30,7 +30,7 @@ enum lookup_type {
        lookup_path
 };
 
-static struct submodule_cache cache;
+static struct submodule_cache the_submodule_cache;
 static int is_cache_init;
 
 static int config_path_cmp(const struct submodule_entry *a,
@@ -457,14 +457,14 @@ static void ensure_cache_init(void)
        if (is_cache_init)
                return;
 
-       cache_init(&cache);
+       cache_init(&the_submodule_cache);
        is_cache_init = 1;
 }
 
 int parse_submodule_config_option(const char *var, const char *value)
 {
        struct parse_config_parameter parameter;
-       parameter.cache = &cache;
+       parameter.cache = &the_submodule_cache;
        parameter.commit_sha1 = NULL;
        parameter.gitmodules_sha1 = null_sha1;
        parameter.overwrite = 1;
@@ -477,18 +477,18 @@ const struct submodule *submodule_from_name(const unsigned char *commit_sha1,
                const char *name)
 {
        ensure_cache_init();
-       return config_from_name(&cache, commit_sha1, name);
+       return config_from_name(&the_submodule_cache, commit_sha1, name);
 }
 
 const struct submodule *submodule_from_path(const unsigned char *commit_sha1,
                const char *path)
 {
        ensure_cache_init();
-       return config_from_path(&cache, commit_sha1, path);
+       return config_from_path(&the_submodule_cache, commit_sha1, path);
 }
 
 void submodule_free(void)
 {
-       cache_free(&cache);
+       cache_free(&the_submodule_cache);
        is_cache_init = 0;
 }
index 1dc908e43a993502bed611023448aa76fc9da6ad..76a0daa3ac00d298bc515c655f4548403095f5f3 100644 (file)
--- a/t/README
+++ b/t/README
@@ -84,9 +84,9 @@ appropriately before running "make".
 
 -x::
        Turn on shell tracing (i.e., `set -x`) during the tests
-       themselves. Implies `--verbose`. Note that this can cause
-       failures in some tests which redirect and test the
-       output of shell functions. Use with caution.
+       themselves. Implies `--verbose`. Note that in non-bash shells,
+       this can cause failures in some tests which redirect and test
+       the output of shell functions. Use with caution.
 
 -d::
 --debug::
index f9ae1d780dceb526fcfbce2684e3e7dc9b06f5eb..012d40e74695f8c195236a22802fd3ca6d60a8d8 100644 (file)
@@ -50,7 +50,7 @@ native_path() {
 # at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
 # function could fix that but it is not in Python until 3.3.
 time_in_seconds() {
-       python -c 'import time; print int(time.time())'
+       (cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
 }
 
 # Try to pick a unique port: guess a large number, then hope
@@ -198,9 +198,10 @@ marshal_dump() {
        cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
        import marshal
        import sys
+       instream = getattr(sys.stdin, 'buffer', sys.stdin)
        for i in range($line):
-           d = marshal.load(sys.stdin)
-       print d['$what']
+           d = marshal.load(instream)
+       print(d[b'$what'].decode('utf-8'))
        EOF
        "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
 }
index 79b9074172ce00771c92a8f3cda35ebf4ac24d89..60811a3a7ca56f995ecda5944121127e2a330bc0 100755 (executable)
@@ -98,7 +98,7 @@ check_sub_test_lib_test () {
 }
 
 check_sub_test_lib_test_err () {
-       name="$1" # stdin is the expected output output from the test
+       name="$1" # stdin is the expected output from the test
        # expected error output is in descriptior 3
        (
                cd "$name" &&
index a5b9e7a4c7e85a2f09718ee7618ae6fb48c600fe..a6fdd5ef3a66f06f5b4a787ca8ad8db2ab4da96f 100755 (executable)
@@ -354,4 +354,34 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' '
        test_path_is_dir realgitdir/refs
 '
 
+# Tests for the hidden file attribute on windows
+is_hidden () {
+       # Use the output of `attrib`, ignore the absolute path
+       case "$(attrib "$1")" in *H*?:*) return 0;; esac
+       return 1
+}
+
+test_expect_success MINGW '.git hidden' '
+       rm -rf newdir &&
+       (
+               unset GIT_DIR GIT_WORK_TREE
+               mkdir newdir &&
+               cd newdir &&
+               git init &&
+               is_hidden .git
+       ) &&
+       check_config newdir/.git false unset
+'
+
+test_expect_success MINGW 'bare git dir not hidden' '
+       rm -rf newdir &&
+       (
+               unset GIT_DIR GIT_WORK_TREE GIT_CONFIG
+               mkdir newdir &&
+               cd newdir &&
+               git --bare init
+       ) &&
+       ! is_hidden newdir
+'
+
 test_done
index f33962b178238126d4cbe88cfbda7dd7bb747490..93725895a4050dca835fd61ef5eee75aa1174ed5 100755 (executable)
@@ -12,7 +12,7 @@ fi
 
 compare_files () {
        tr '\015\000' QN <"$1" >"$1".expect &&
-       tr '\015\000' QN <"$2" >"$2".actual &&
+       tr '\015\000' QN <"$2" | tr -d 'Z' >"$2".actual &&
        test_cmp "$1".expect "$2".actual &&
        rm "$1".expect "$2".actual
 }
@@ -52,14 +52,17 @@ create_gitattributes () {
 create_NNO_files () {
        for crlf in false true input
        do
-               for attr in "" auto text -text lf crlf
+               for attr in "" auto text -text
                do
-                       pfx=NNO_${crlf}_attr_${attr} &&
-                       cp CRLF_mix_LF ${pfx}_LF.txt &&
-                       cp CRLF_mix_LF ${pfx}_CRLF.txt &&
-                       cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
-                       cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt &&
-                       cp CRLF_mix_LF ${pfx}_CRLF_nul.txt
+                       for aeol in "" lf crlf
+                       do
+                               pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
+                               cp CRLF_mix_LF ${pfx}_LF.txt &&
+                               cp CRLF_mix_LF ${pfx}_CRLF.txt &&
+                               cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
+                               cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt &&
+                               cp CRLF_mix_LF ${pfx}_CRLF_nul.txt
+                       done
                done
        done
 }
@@ -100,20 +103,22 @@ commit_check_warn () {
 }
 
 commit_chk_wrnNNO () {
-       crlf=$1
-       attr=$2
-       lfwarn=$3
-       crlfwarn=$4
-       lfmixcrlf=$5
-       lfmixcr=$6
-       crlfnul=$7
-       pfx=NNO_${crlf}_attr_${attr}
+       attr=$1 ; shift
+       aeol=$1 ; shift
+       crlf=$1 ; shift
+       lfwarn=$1 ; shift
+       crlfwarn=$1 ; shift
+       lfmixcrlf=$1 ; shift
+       lfmixcr=$1 ; shift
+       crlfnul=$1 ; shift
+       pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
        #Commit files on top of existing file
-       create_gitattributes "$attr" &&
+       create_gitattributes "$attr" $aeol &&
        for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
        do
                fname=${pfx}_$f.txt &&
                cp $f $fname &&
+               printf Z >>"$fname" &&
                git -c core.autocrlf=$crlf add $fname 2>/dev/null &&
                git -c core.autocrlf=$crlf commit -m "commit_$fname" $fname >"${pfx}_$f.err" 2>&1
        done
@@ -121,19 +126,19 @@ commit_chk_wrnNNO () {
        test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
                check_warning "$lfwarn" ${pfx}_LF.err
        '
-       test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF" '
+       test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF" '
                check_warning "$crlfwarn" ${pfx}_CRLF.err
        '
 
-       test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_mix_LF" '
+       test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_mix_LF" '
                check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err
        '
 
-       test_expect_success "commit NNO files crlf=$crlf attr=$attr LF_mix_cr" '
+       test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf LF_mix_cr" '
                check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err
        '
 
-       test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_nul" '
+       test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_nul" '
                check_warning "$crlfnul" ${pfx}_CRLF_nul.err
        '
 }
@@ -162,6 +167,7 @@ stats_ascii () {
 
 # contruct the attr/ returned by git ls-files --eol
 # Take none (=empty), one or two args
+# convert.c: eol=XX overrides text=auto
 attr_ascii () {
        case $1,$2 in
        -text,*)   echo "-text" ;;
@@ -169,8 +175,8 @@ attr_ascii () {
        text,lf)   echo "text eol=lf" ;;
        text,crlf) echo "text eol=crlf" ;;
        auto,)     echo "text=auto" ;;
-       auto,lf)   echo "text=auto eol=lf" ;;
-       auto,crlf) echo "text=auto eol=crlf" ;;
+       auto,lf)   echo "text eol=lf" ;;
+       auto,crlf) echo "text eol=crlf" ;;
        lf,)       echo "text eol=lf" ;;
        crlf,)     echo "text eol=crlf" ;;
        ,) echo "" ;;
@@ -195,28 +201,29 @@ check_files_in_repo () {
 }
 
 check_in_repo_NNO () {
-       crlf=$1
-       attr=$2
-       lfname=$3
-       crlfname=$4
-       lfmixcrlf=$5
-       lfmixcr=$6
-       crlfnul=$7
-       pfx=NNO_${crlf}_attr_${attr}_
-       test_expect_success "compare_files $lfname ${pfx}LF.txt" '
-               compare_files $lfname ${pfx}LF.txt
+       attr=$1 ; shift
+       aeol=$1 ; shift
+       crlf=$1 ; shift
+       lfname=$1 ; shift
+       crlfname=$1 ; shift
+       lfmixcrlf=$1 ; shift
+       lfmixcr=$1 ; shift
+       crlfnul=$1 ; shift
+       pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
+       test_expect_success "compare_files $lfname ${pfx}_LF.txt" '
+               compare_files $lfname ${pfx}_LF.txt
        '
-       test_expect_success "compare_files $crlfname ${pfx}CRLF.txt" '
-               compare_files $crlfname ${pfx}CRLF.txt
+       test_expect_success "compare_files $crlfname ${pfx}_CRLF.txt" '
+               compare_files $crlfname ${pfx}_CRLF.txt
        '
-       test_expect_success "compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt" '
-               compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt
+       test_expect_success "compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt" '
+               compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt
        '
-       test_expect_success "compare_files $lfmixcr ${pfx}LF_mix_CR.txt" '
-               compare_files $lfmixcr ${pfx}LF_mix_CR.txt
+       test_expect_success "compare_files $lfmixcr ${pfx}_LF_mix_CR.txt" '
+               compare_files $lfmixcr ${pfx}_LF_mix_CR.txt
        '
-       test_expect_success "compare_files $crlfnul ${pfx}CRLF_nul.txt" '
-               compare_files $crlfnul ${pfx}CRLF_nul.txt
+       test_expect_success "compare_files $crlfnul ${pfx}_CRLF_nul.txt" '
+               compare_files $crlfnul ${pfx}_CRLF_nul.txt
        '
 }
 
@@ -231,7 +238,7 @@ checkout_files () {
        lfmixcrlf=$1 ; shift
        lfmixcr=$1 ; shift
        crlfnul=$1 ; shift
-       create_gitattributes "$attr" "$ident" &&
+       create_gitattributes "$attr" $ident $aeol &&
        git config core.autocrlf $crlf &&
        pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
        for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
@@ -244,7 +251,7 @@ checkout_files () {
                fi
        done
 
-       test_expect_success "ls-files --eol attr=$attr $ident $aeol core.autocrlf=$crlf core.eol=$ceol" '
+       test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
                test_when_finished "rm expect actual" &&
                sort <<-EOF >expect &&
                i/crlf w/$(stats_ascii $crlfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF.txt
@@ -259,19 +266,19 @@ checkout_files () {
                sort >actual &&
                test_cmp expect actual
        '
-       test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF" "
+       test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF" "
                compare_ws_file $pfx $lfname    crlf_false_attr__LF.txt
        "
-       test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" "
+       test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" "
                compare_ws_file $pfx $crlfname  crlf_false_attr__CRLF.txt
        "
-       test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" "
+       test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" "
                compare_ws_file $pfx $lfmixcrlf crlf_false_attr__CRLF_mix_LF.txt
        "
-       test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" "
+       test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" "
                compare_ws_file $pfx $lfmixcr   crlf_false_attr__LF_mix_CR.txt
        "
-       test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" "
+       test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" "
                compare_ws_file $pfx $crlfnul   crlf_false_attr__LF_nul.txt
        "
 }
@@ -385,31 +392,31 @@ test_expect_success 'commit files attr=crlf' '
        commit_check_warn input "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""
 '
 
-#                       attr   LF        CRLF      CRLFmixLF    LF_mix_CR   CRLFNUL
-commit_chk_wrnNNO false ""     ""        ""        ""           ""              ""
-commit_chk_wrnNNO true  ""     "LF_CRLF" ""        ""           ""              ""
-commit_chk_wrnNNO input ""     ""        ""        ""           ""              ""
-
+#                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
+commit_chk_wrnNNO ""      ""      false   ""        ""        ""          ""          ""
+commit_chk_wrnNNO ""      ""      true    LF_CRLF   ""        ""          ""          ""
+commit_chk_wrnNNO ""      ""      input   ""        ""        ""          ""          ""
 
-commit_chk_wrnNNO false "auto" "$WILC"   "$WICL"   "$WAMIX"     ""              ""
-commit_chk_wrnNNO true  "auto" "LF_CRLF" ""        "LF_CRLF"    ""              ""
-commit_chk_wrnNNO input "auto" ""        "CRLF_LF" "CRLF_LF"    ""              ""
+commit_chk_wrnNNO "auto"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    ""          ""
+commit_chk_wrnNNO "auto"  ""      true    LF_CRLF   ""        LF_CRLF     ""          ""
+commit_chk_wrnNNO "auto"  ""      input   ""        CRLF_LF   CRLF_LF     ""          ""
 
-commit_chk_wrnNNO false "text" "$WILC"   "$WICL"   "$WAMIX"     "$WILC"         "$WICL"
-commit_chk_wrnNNO true  "text" "LF_CRLF" ""        "LF_CRLF"    "LF_CRLF"       ""
-commit_chk_wrnNNO input "text" ""        "CRLF_LF" "CRLF_LF"    ""              "CRLF_LF"
-
-commit_chk_wrnNNO false "-text" ""       ""        ""           ""              ""
-commit_chk_wrnNNO true  "-text" ""       ""        ""           ""              ""
-commit_chk_wrnNNO input "-text" ""       ""        ""           ""              ""
-
-commit_chk_wrnNNO false "lf"    ""       "CRLF_LF" "CRLF_LF"     ""             "CRLF_LF"
-commit_chk_wrnNNO true  "lf"    ""       "CRLF_LF" "CRLF_LF"     ""             "CRLF_LF"
-commit_chk_wrnNNO input "lf"    ""       "CRLF_LF" "CRLF_LF"     ""             "CRLF_LF"
+for crlf in true false input
+do
+       commit_chk_wrnNNO -text ""      $crlf   ""        ""        ""          ""          ""
+       commit_chk_wrnNNO -text lf      $crlf   ""        ""        ""          ""          ""
+       commit_chk_wrnNNO -text crlf    $crlf   ""        ""        ""          ""          ""
+       commit_chk_wrnNNO ""    lf      $crlf   ""       CRLF_LF    CRLF_LF      ""         CRLF_LF
+       commit_chk_wrnNNO ""    crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
+       commit_chk_wrnNNO auto  lf      $crlf   ""       CRLF_LF    CRLF_LF     ""          CRLF_LF
+       commit_chk_wrnNNO auto  crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
+       commit_chk_wrnNNO text  lf      $crlf   ""       CRLF_LF    CRLF_LF     ""          CRLF_LF
+       commit_chk_wrnNNO text  crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
+done
 
-commit_chk_wrnNNO false "crlf" "LF_CRLF" ""        "LF_CRLF"    "LF_CRLF"       ""
-commit_chk_wrnNNO true  "crlf" "LF_CRLF" ""        "LF_CRLF"    "LF_CRLF"       ""
-commit_chk_wrnNNO input "crlf" "LF_CRLF" ""        "LF_CRLF"    "LF_CRLF"       ""
+commit_chk_wrnNNO "text"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    "$WILC"     "$WICL"
+commit_chk_wrnNNO "text"  ""      true    LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
+commit_chk_wrnNNO "text"  ""      input   ""        CRLF_LF   CRLF_LF     ""          CRLF_LF
 
 test_expect_success 'create files cleanup' '
        rm -f *.txt &&
@@ -440,24 +447,20 @@ test_expect_success 'commit -text' '
        check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
 '
 
-#                       attr    LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLFNUL
-check_in_repo_NNO false ""      LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLF_nul
-check_in_repo_NNO true  ""      LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLF_nul
-check_in_repo_NNO input ""      LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLF_nul
-
-check_in_repo_NNO false "auto"  LF        LF        LF           LF_mix_CR     CRLF_nul
-check_in_repo_NNO true  "auto"  LF        LF        LF           LF_mix_CR     CRLF_nul
-check_in_repo_NNO input "auto"  LF        LF        LF           LF_mix_CR     CRLF_nul
-
-check_in_repo_NNO false "text"  LF        LF        LF           LF_mix_CR     LF_nul
-check_in_repo_NNO true  "text"  LF        LF        LF           LF_mix_CR     LF_nul
-check_in_repo_NNO input "text"  LF        LF        LF           LF_mix_CR     LF_nul
-
-check_in_repo_NNO false "-text" LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLF_nul
-check_in_repo_NNO true  "-text" LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLF_nul
-check_in_repo_NNO input "-text" LF        CRLF      CRLF_mix_LF  LF_mix_CR     CRLF_nul
-
-
+for crlf in true false input
+do
+       #                 attr  aeol           LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLFNUL
+       check_in_repo_NNO ""    ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
+       check_in_repo_NNO -text ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
+       check_in_repo_NNO -text lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
+       check_in_repo_NNO -text crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
+       check_in_repo_NNO auto  ""     $crlf   LF  LF    LF           LF_mix_CR  CRLF_nul
+       check_in_repo_NNO auto  lf     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
+       check_in_repo_NNO auto  crlf   $crlf   LF  LF    LF           LF_mix_CR  LF_nul
+       check_in_repo_NNO text  ""     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
+       check_in_repo_NNO text  lf     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
+       check_in_repo_NNO text  crlf   $crlf   LF  LF    LF           LF_mix_CR  LF_nul
+done
 ################################################################################
 # Check how files in the repo are changed when they are checked out
 # How to read the table below:
@@ -489,89 +492,47 @@ LFNUL=LF_nul
 fi
 export CRLF_MIX_LF_CR MIX NL
 
-checkout_files ""      ""       ""    false  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    false  crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    false  native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    true   ""       CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    true   crlf     CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    true   lf       CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ""       ""    true   native   CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    false  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    false  crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    false  native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    true   ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    true   crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    true   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files ""      ident ""    true   native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    false  ""       $NL   CRLF  $MIX_CRLF_LF LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    false  crlf     CRLF  CRLF  CRLF         LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    false  native   $NL   CRLF  $MIX_CRLF_LF LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    true   ""       CRLF  CRLF  CRLF         LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    true   crlf     CRLF  CRLF  CRLF         LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    true   lf       CRLF  CRLF  CRLF         LF_mix_CR    LF_nul
-checkout_files "auto"  ""       ""    true   native   CRLF  CRLF  CRLF         LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    false  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    false  crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    false  native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    true   ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    true   crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    true   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-checkout_files "auto"  ident ""    true   native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-
-for id in "" ident;
+# Same handling with and without ident
+for id in "" ident
 do
-       checkout_files "crlf"  "$id" ""    false  ""       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    false  crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    false  lf       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    false  native   CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    input  ""       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    input  lf       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    true   ""       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    true   crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    true   lf       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "crlf"  "$id" ""    true   native   CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "lf"    "$id" ""    false  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    false  crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    false  native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    true   ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    true   crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    true   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "lf"    "$id" ""    true   native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "text"  "$id" ""    false  ""       $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
-       checkout_files "text"  "$id" ""    false  crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "text"  "$id" ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "text"  "$id" ""    false  native   $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
-       checkout_files "text"  "$id" ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "text"  "$id" ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "text"  "$id" ""    true   ""       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "text"  "$id" ""    true   crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "text"  "$id" ""    true   lf       CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "text"  "$id" ""    true   native   CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
-       checkout_files "-text" "$id" ""    false  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    false  crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    false  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    false  native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    input  ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    input  lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    true   ""       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    true   crlf     LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    true   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
-       checkout_files "-text" "$id" ""    true   native   LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+       for ceol in lf crlf native
+       do
+               for crlf in true false input
+               do
+                       # -text overrides core.autocrlf and core.eol
+                       # text and eol=crlf or eol=lf override core.autocrlf and core.eol
+                       checkout_files -text "$id" ""     "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+                       checkout_files -text "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+                       checkout_files -text "$id" "crlf" "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+                       # text
+                       checkout_files text  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+                       checkout_files text  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
+                       # currently the same as text, eol=XXX
+                       checkout_files auto  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+                       checkout_files auto  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
+               done
+
+               # core.autocrlf false, different core.eol
+               checkout_files   ""    "$id" ""     false   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+               # core.autocrlf true
+               checkout_files   ""    "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+               # text: core.autocrlf = true overrides core.eol
+               checkout_files   auto  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF         LF_mix_CR    LF_nul
+               checkout_files   text  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
+               # text: core.autocrlf = input overrides core.eol
+               checkout_files   text  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+               checkout_files   auto  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+               # text=auto + eol=XXX
+       done
+       # text: core.autocrlf=false uses core.eol
+       checkout_files     text  "$id" ""     false   crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
+       checkout_files     text  "$id" ""     false   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
+       # text: core.autocrlf=false and core.eol unset(or native) uses native eol
+       checkout_files     text  "$id" ""     false   ""       $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
+       checkout_files     text  "$id" ""     false   native   $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
+       # auto: core.autocrlf=false and core.eol unset(or native) uses native eol
+       checkout_files     auto  "$id" ""     false   ""       $NL   CRLF  $MIX_CRLF_LF LF_mix_CR    LF_nul
+       checkout_files     auto  "$id" ""     false   native   $NL   CRLF  $MIX_CRLF_LF LF_mix_CR    LF_nul
 done
 
 # Should be the last test case: remove some files from the worktree
index e66b7cb697bc8a4ef7268e5d8d29f0b69a8ac213..7ee8ea004f1731b1efbaedf0a8022cdb4946c7cf 100755 (executable)
@@ -427,6 +427,24 @@ test_expect_success 'fsck allows .Ňit' '
        )
 '
 
+test_expect_success 'NUL in commit' '
+       rm -fr nul-in-commit &&
+       git init nul-in-commit &&
+       (
+               cd nul-in-commit &&
+               git commit --allow-empty -m "initial commitQNUL after message" &&
+               git cat-file commit HEAD >original &&
+               q_to_nul <original >munged &&
+               git hash-object -w -t commit --stdin <munged >name &&
+               git branch bad $(cat name) &&
+
+               test_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 &&
+               grep nulInCommit warn.1 &&
+               git fsck 2>warn.2 &&
+               grep nulInCommit warn.2
+       )
+'
+
 # create a static test repo which is broken by omitting
 # one particular object ($1, which is looked up via rev-parse
 # in the new repository).
index a1c4e0216ff7421082a957e5b7789f3cc9a13181..db9378142a93338d2988f40e2748bc476490bcd5 100755 (executable)
@@ -14,11 +14,11 @@ test_description='revert can handle submodules'
 git_revert () {
        git status -su >expect &&
        ls -1pR * >>expect &&
-       tar czf "$TRASH_DIRECTORY/tmp.tgz" * &&
+       tar cf "$TRASH_DIRECTORY/tmp.tar" * &&
        git checkout "$1" &&
        git revert HEAD &&
        rm -rf * &&
-       tar xzf "$TRASH_DIRECTORY/tmp.tgz" &&
+       tar xf "$TRASH_DIRECTORY/tmp.tar" &&
        git status -su >actual &&
        ls -1pR * >>actual &&
        test_cmp expect actual &&
index 831935665e012c04bbe4c57feee92c0310df5c04..26dd5b7f78a7f7e65ddda24c4686d2ae26fc30de 100755 (executable)
@@ -49,12 +49,54 @@ test_expect_success "setup" '
 test_expect_success "setup case mac" '
        git checkout -b mac_os
 '
+# This will test nfd2nfc in git diff
+test_expect_success "git diff f.Adiar" '
+       touch f.$Adiarnfc &&
+       git add f.$Adiarnfc &&
+       echo f.Adiarnfc >f.$Adiarnfc &&
+       git diff f.$Adiarnfd >expect &&
+       git diff f.$Adiarnfc >actual &&
+       test_cmp expect actual &&
+       git reset HEAD f.Adiarnfc &&
+       rm f.$Adiarnfc expect actual
+'
+# This will test nfd2nfc in git diff-files
+test_expect_success "git diff-files f.Adiar" '
+       touch f.$Adiarnfc &&
+       git add f.$Adiarnfc &&
+       echo f.Adiarnfc >f.$Adiarnfc &&
+       git diff-files f.$Adiarnfd >expect &&
+       git diff-files f.$Adiarnfc >actual &&
+       test_cmp expect actual &&
+       git reset HEAD f.Adiarnfc &&
+       rm f.$Adiarnfc expect actual
+'
+# This will test nfd2nfc in git diff-index
+test_expect_success "git diff-index f.Adiar" '
+       touch f.$Adiarnfc &&
+       git add f.$Adiarnfc &&
+       echo f.Adiarnfc >f.$Adiarnfc &&
+       git diff-index HEAD f.$Adiarnfd >expect &&
+       git diff-index HEAD f.$Adiarnfc >actual &&
+       test_cmp expect actual &&
+       git reset HEAD f.Adiarnfc &&
+       rm f.$Adiarnfc expect actual
+'
 # This will test nfd2nfc in readdir()
 test_expect_success "add file Adiarnfc" '
        echo f.Adiarnfc >f.$Adiarnfc &&
        git add f.$Adiarnfc &&
        git commit -m "add f.$Adiarnfc"
 '
+# This will test nfd2nfc in git diff-tree
+test_expect_success "git diff-tree f.Adiar" '
+       echo f.Adiarnfc >>f.$Adiarnfc &&
+       git diff-tree HEAD f.$Adiarnfd >expect &&
+       git diff-tree HEAD f.$Adiarnfc >actual &&
+       test_cmp expect actual &&
+       git checkout f.$Adiarnfc &&
+       rm expect actual
+'
 # This will test nfd2nfc in git stage()
 test_expect_success "stage file d.Adiarnfd/f.Adiarnfd" '
        mkdir d.$Adiarnfd &&
index ea5ace99a14f7f31b63dfd9cf25123725a525519..9473c2779ef0df109f6943a949583676ea5ceabf 100755 (executable)
@@ -82,7 +82,7 @@ test_expect_success 'am -3 --abort removes otherfile-4' '
        test 4 = "$(cat otherfile-4)" &&
        git am --abort &&
        test_cmp_rev initial HEAD &&
-       test -z $(git ls-files -u) &&
+       test -z "$(git ls-files -u)" &&
        test_path_is_missing otherfile-4
 '
 
index a3e12d295afedb170b3a917ce9d23122c1a0bc1d..44f3d5fb284e9848180df9ed9cfbc44a91762277 100755 (executable)
@@ -100,11 +100,8 @@ test_expect_success 'push with receive.fsckobjects' '
                git config receive.fsckobjects true &&
                git config transfer.fsckobjects false
        ) &&
-       test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act &&
-       {
-               test_cmp exp act ||
-               ! test -s act
-       }
+       test_must_fail git push --porcelain dst master:refs/heads/test >act &&
+       test_cmp exp act
 '
 
 test_expect_success 'push with transfer.fsckobjects' '
@@ -114,7 +111,8 @@ test_expect_success 'push with transfer.fsckobjects' '
                cd dst &&
                git config transfer.fsckobjects true
        ) &&
-       test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act
+       test_must_fail git push --porcelain dst master:refs/heads/test >act &&
+       test_cmp exp act
 '
 
 cat >bogus-commit <<\EOF
index 38321d19efbee0da62a9327f5849521093fbe077..454d896390c03667442ce12925066b14593b3cd1 100755 (executable)
@@ -682,6 +682,7 @@ test_expect_success 'fetching with auto-gc does not lock up' '
        (
                cd auto-gc &&
                git config gc.autoPackLimit 1 &&
+               git config gc.autoDetach false &&
                GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 &&
                ! grep "Should I try again" fetch.out
        )
index c1efb8e445402cccdddda987e1eafad4d4bb75f9..1789d0be3d2c7b1841d5203f7bc11e05651ad886 100755 (executable)
@@ -466,7 +466,7 @@ test_expect_success 'clone ssh://host.xz:22/~repo' '
 #IPv6
 for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]:
 do
-       ehost=$(echo $tuah | sed -e "s/1]:/1]/ "| tr -d "[]")
+       ehost=$(echo $tuah | sed -e "s/1]:/1]/| tr -d "[]")
        test_expect_success "clone ssh://$tuah/home/user/repo" "
          test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo
        "
index 27d730c0a7209480c5349e4ace65f92c9e75c699..e4850b778c2f20df02ce187cc8cd057df2759d7d 100755 (executable)
@@ -37,4 +37,24 @@ test_expect_success 'clone -c config is available during clone' '
        test_cmp expect child/file
 '
 
+# Tests for the hidden file attribute on windows
+is_hidden () {
+       # Use the output of `attrib`, ignore the absolute path
+       case "$(attrib "$1")" in *H*?:*) return 0;; esac
+       return 1
+}
+
+test_expect_success MINGW 'clone -c core.hideDotFiles' '
+       test_commit attributes .gitattributes "" &&
+       rm -rf child &&
+       git clone -c core.hideDotFiles=false . child &&
+       ! is_hidden child/.gitattributes &&
+       rm -rf child &&
+       git clone -c core.hideDotFiles=dotGitOnly . child &&
+       ! is_hidden child/.gitattributes &&
+       rm -rf child &&
+       git clone -c core.hideDotFiles=true . child &&
+       is_hidden child/.gitattributes
+'
+
 test_done
index c6b7aa6977e0a5a1017c759d93f8883cad3713b0..62b8a2e7bbd1cf26710be0a0eb90041d5e3f7d2c 100755 (executable)
@@ -8,7 +8,7 @@ test_description='bisect can handle submodules'
 git_bisect () {
        git status -su >expect &&
        ls -1pR * >>expect &&
-       tar czf "$TRASH_DIRECTORY/tmp.tgz" * &&
+       tar cf "$TRASH_DIRECTORY/tmp.tar" * &&
        GOOD=$(git rev-parse --verify HEAD) &&
        git checkout "$1" &&
        echo "foo" >bar &&
@@ -20,7 +20,7 @@ git_bisect () {
        git bisect start &&
        git bisect good $GOOD &&
        rm -rf * &&
-       tar xzf "$TRASH_DIRECTORY/tmp.tgz" &&
+       tar xf "$TRASH_DIRECTORY/tmp.tar" &&
        git status -su >actual &&
        ls -1pR * >>actual &&
        test_cmp expect actual &&
index 4008faead8ec4ea0d08e82d2916dbc3e17327c8a..4a2570ed959410ca34503c6260141f10debd752b 100755 (executable)
@@ -292,6 +292,9 @@ test_expect_success 'setup submodule' '
        echo content >file &&
        git add file &&
        git commit -m "added sub and file" &&
+       mkdir -p deep/directory/hierachy &&
+       git submodule add ./. deep/directory/hierachy/sub &&
+       git commit -m "added another submodule" &&
        git branch submodule
 '
 
@@ -475,4 +478,17 @@ test_expect_success 'mv -k does not accidentally destroy submodules' '
        git checkout .
 '
 
+test_expect_success 'moving a submodule in nested directories' '
+       (
+               cd deep &&
+               git mv directory ../ &&
+               # git status would fail if the update of linking git dir to
+               # work dir of the submodule failed.
+               git status &&
+               git config -f ../.gitmodules submodule.deep/directory/hierachy/sub.path >../actual &&
+               echo "directory/hierachy/sub" >../expect
+       ) &&
+       test_cmp actual expect
+'
+
 test_done
index 86ceb38b015807ada68357fa80ffa45f4f85f287..b89fd2a6ada025fc0e68b1a1c3d7e739aacec688 100755 (executable)
@@ -495,7 +495,7 @@ test_expect_success 'should not clean submodules' '
        test_path_is_missing to_clean
 '
 
-test_expect_success POSIXPERM 'should avoid cleaning possible submodules' '
+test_expect_success POSIXPERM,SANITY 'should avoid cleaning possible submodules' '
        rm -fr to_clean possible_sub1 &&
        mkdir to_clean possible_sub1 &&
        test_when_finished "rm -rf possible_sub*" &&
index a41be3142e85112af7de1c2e865b7b2e261e7ebd..75db02389885d74942e0b20da55796130c0d2c62 100755 (executable)
@@ -11,6 +11,10 @@ subcommands of git submodule.
 
 . ./test-lib.sh
 
+test_expect_success 'submodule deinit works on empty repository' '
+       git submodule deinit --all
+'
+
 test_expect_success 'setup - initial commit' '
        >t &&
        git add t &&
@@ -899,7 +903,8 @@ test_expect_success 'submodule deinit works on repository without submodules' '
                >file &&
                git add file &&
                git commit -m "repo should not be empty"
-               git submodule deinit .
+               git submodule deinit . &&
+               git submodule deinit --all
        )
 '
 
@@ -941,6 +946,19 @@ test_expect_success 'submodule deinit . deinits all initialized submodules' '
        rmdir init example2
 '
 
+test_expect_success 'submodule deinit --all deinits all initialized submodules' '
+       git submodule update --init &&
+       git config submodule.example.foo bar &&
+       git config submodule.example2.frotz nitfol &&
+       test_must_fail git submodule deinit &&
+       git submodule deinit --all >actual &&
+       test -z "$(git config --get-regexp "submodule\.example\.")" &&
+       test -z "$(git config --get-regexp "submodule\.example2\.")" &&
+       test_i18ngrep "Cleared directory .init" actual &&
+       test_i18ngrep "Cleared directory .example2" actual &&
+       rmdir init example2
+'
+
 test_expect_success 'submodule deinit deinits a submodule when its work tree is missing or empty' '
        git submodule update --init &&
        rm -rf init example2/* example2/.git &&
@@ -1007,6 +1025,10 @@ test_expect_success 'submodule deinit is silent when used on an uninitialized su
        test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
        test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
        test_i18ngrep "Cleared directory .init" actual &&
+       git submodule deinit --all >actual &&
+       test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
+       test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
+       test_i18ngrep "Cleared directory .init" actual &&
        rmdir init example2
 '
 
index 0e4a682c6428a96af4d98bb7e24b0de7f4be865c..6729cb379fdb16160c79393b96a2f5b3025540f4 100755 (executable)
@@ -37,14 +37,14 @@ EOF
 
 test_expect_success 'untracked files overwritten by merge (fast and non-fast forward)' '
        test_must_fail git merge branch 2>out &&
-       test_cmp out expect &&
+       test_i18ncmp out expect &&
        git commit --allow-empty -m empty &&
        (
                GIT_MERGE_VERBOSITY=0 &&
                export GIT_MERGE_VERBOSITY &&
                test_must_fail git merge branch 2>out2
        ) &&
-       test_cmp out2 expect &&
+       test_i18ncmp out2 expect &&
        git reset --hard HEAD^
 '
 
@@ -53,7 +53,7 @@ error: Your local changes to the following files would be overwritten by merge:
        four
        three
        two
-Please, commit your changes or stash them before you can merge.
+Please commit your changes or stash them before you can merge.
 error: The following untracked working tree files would be overwritten by merge:
        five
 Please move or remove them before you can merge.
@@ -65,14 +65,14 @@ test_expect_success 'untracked files or local changes ovewritten by merge' '
        git add three &&
        git add four &&
        test_must_fail git merge branch 2>out &&
-       test_cmp out expect
+       test_i18ncmp out expect
 '
 
 cat >expect <<\EOF
 error: Your local changes to the following files would be overwritten by checkout:
        rep/one
        rep/two
-Please, commit your changes or stash them before you can switch branches.
+Please commit your changes or stash them before you can switch branches.
 Aborting
 EOF
 
@@ -87,21 +87,21 @@ test_expect_success 'cannot switch branches because of local changes' '
        echo uno >rep/one &&
        echo dos >rep/two &&
        test_must_fail git checkout branch 2>out &&
-       test_cmp out expect
+       test_i18ncmp out expect
 '
 
 cat >expect <<\EOF
 error: Your local changes to the following files would be overwritten by checkout:
        rep/one
        rep/two
-Please, commit your changes or stash them before you can switch branches.
+Please commit your changes or stash them before you can switch branches.
 Aborting
 EOF
 
 test_expect_success 'not uptodate file porcelain checkout error' '
        git add rep/one rep/two &&
        test_must_fail git checkout branch 2>out &&
-       test_cmp out expect
+       test_i18ncmp out expect
 '
 
 cat >expect <<\EOF
@@ -132,7 +132,7 @@ test_expect_success 'not_uptodate_dir porcelain checkout error' '
        >rep/untracked-file &&
        >rep2/untracked-file &&
        test_must_fail git checkout branch 2>out &&
-       test_cmp out ../expect
+       test_i18ncmp out ../expect
 '
 
 test_done
index 6a7207b9506d76beed912698be63afffcd503991..7ce4cd753eb0c50f42b68653da79f90b19edd764 100755 (executable)
@@ -20,7 +20,7 @@ difftool_test_setup ()
 prompt_given ()
 {
        prompt="$1"
-       test "$prompt" = "Launch 'test-tool' [Y/n]: branch"
+       test "$prompt" = "Launch 'test-tool' [Y/n]? branch"
 }
 
 # Create a file on master and change it on branch
index 66d3fc91a739a7f04bb73694a2f5d75034045d10..eb9a8ed197b4c6383a4c688f5e5c3a3fcb102b12 100755 (executable)
@@ -223,12 +223,12 @@ build_gendouble() {
        import sys
        import struct
 
-       s = struct.pack(">LL18s",
+       s = struct.pack(b">LL18s",
                        0x00051607,  # AppleDouble
                        0x00020000,  # version 2
-                       ""           # pad to 26 bytes
+                       b""          # pad to 26 bytes
        )
-       sys.stdout.write(s)
+       getattr(sys.stdout, 'buffer', sys.stdout).write(s)
        EOF
 }
 
index 0b664a377c453d56ada45153b587a1422c837ecc..110a7e792475fcf19ef782fae1d265ae81653853 100755 (executable)
@@ -13,6 +13,10 @@ test_file_in_lfs () {
        FILE="$1" &&
        SIZE="$2" &&
        EXPECTED_CONTENT="$3" &&
+       sed -n '1,1 p' "$FILE" | grep "^version " &&
+       sed -n '2,2 p' "$FILE" | grep "^oid " &&
+       sed -n '3,3 p' "$FILE" | grep "^size " &&
+       test_line_count = 3 "$FILE" &&
        cat "$FILE" | grep "size $SIZE" &&
        HASH=$(cat "$FILE" | grep "oid sha256:" | sed -e "s/oid sha256://g") &&
        LFS_FILE=".git/lfs/objects/$(echo "$HASH" | cut -c1-2)/$(echo "$HASH" | cut -c3-4)/$HASH" &&
@@ -265,7 +269,7 @@ test_expect_success 'Add big files to repo and store files in LFS based on compr
                # We only import HEAD here ("@all" is missing!)
                git p4 clone --destination="$git" //depot &&
 
-               test_file_in_lfs file6.bin 13 "content 6 bin 39 bytes XXXXXYYYYYZZZZZ"
+               test_file_in_lfs file6.bin 39 "content 6 bin 39 bytes XXXXXYYYYYZZZZZ" &&
                test_file_count_in_dir ".git/lfs/objects" 1 &&
 
                cat >expect <<-\EOF &&
index ffbfa0efb8712f06cb14adc986ae29c4d1c23bf1..0db4469c89492ae625307629cb7132178c3b9671 100755 (executable)
@@ -107,7 +107,7 @@ test_expect_success 'prompt - describe detached head - contains' '
 '
 
 test_expect_success 'prompt - describe detached head - branch' '
-       printf " ((b1~1))" >expected &&
+       printf " ((tags/t2~1))" >expected &&
        git checkout b1^ &&
        test_when_finished "git checkout master" &&
        (
index 8d99eb303fd62a1c179ab31f471a3376898586b0..3978fc0b45de2645560207cc6e884a505506215d 100644 (file)
@@ -718,20 +718,13 @@ test_cmp_rev () {
        test_cmp expect.rev actual.rev
 }
 
-# Print a sequence of numbers or letters in increasing order.  This is
-# similar to GNU seq(1), but the latter might not be available
-# everywhere (and does not do letters).  It may be used like:
-#
-#      for i in $(test_seq 100)
-#      do
-#              for j in $(test_seq 10 20)
-#              do
-#                      for k in $(test_seq a z)
-#                      do
-#                              echo $i-$j-$k
-#                      done
-#              done
-#      done
+# Print a sequence of integers in increasing order, either with
+# two arguments (start and end):
+#
+#     test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time
+#
+# or with one argument (end), in which case it starts counting
+# from 1.
 
 test_seq () {
        case $# in
@@ -739,7 +732,12 @@ test_seq () {
        2)      ;;
        *)      error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
        esac
-       perl -le 'print for $ARGV[0]..$ARGV[1]' -- "$@"
+       test_seq_counter__=$1
+       while test "$test_seq_counter__" -le "$2"
+       do
+               echo "$test_seq_counter__"
+               test_seq_counter__=$(( $test_seq_counter__ + 1 ))
+       done
 }
 
 # This function can be used to schedule some commands to be run
index 0b47eb6bb299492d31111c94557c216bb3f32c7f..39c70f03269c263fb4872efed88a4142aec25be1 100644 (file)
@@ -202,13 +202,13 @@ do
                }
                run_list=$1; shift ;;
        --run=*)
-               run_list=$(expr "z$1" : 'z[^=]*=\(.*\)'); shift ;;
+               run_list=${1#--*=}; shift ;;
        -h|--h|--he|--hel|--help)
                help=t; shift ;;
        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
                verbose=t; shift ;;
        --verbose-only=*)
-               verbose_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               verbose_only=${1#--*=}
                shift ;;
        -q|--q|--qu|--qui|--quie|--quiet)
                # Ignore --quiet under a TAP::Harness. Saying how many tests
@@ -222,15 +222,15 @@ do
                valgrind=memcheck
                shift ;;
        --valgrind=*)
-               valgrind=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               valgrind=${1#--*=}
                shift ;;
        --valgrind-only=*)
-               valgrind_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               valgrind_only=${1#--*=}
                shift ;;
        --tee)
                shift ;; # was handled already
        --root=*)
-               root=$(expr "z$1" : 'z[^=]*=\(.*\)')
+               root=${1#--*=}
                shift ;;
        --chain-lint)
                GIT_TEST_CHAIN_LINT=1
@@ -322,6 +322,19 @@ else
        exec 4>/dev/null 3>/dev/null
 fi
 
+# Send any "-x" output directly to stderr to avoid polluting tests
+# which capture stderr. We can do this unconditionally since it
+# has no effect if tracing isn't turned on.
+#
+# Note that this sets up the trace fd as soon as we assign the variable, so it
+# must come after the creation of descriptor 4 above. Likewise, we must never
+# unset this, as it has the side effect of closing descriptor 4, which we
+# use to show verbose tests to the user.
+#
+# Note also that we don't need or want to export it. The tracing is local to
+# this shell, and we would not want to influence any shells we exec.
+BASH_XTRACEFD=4
+
 test_failure=0
 test_count=0
 test_fixed=0
index b934183236ca571093f55818f5018c278150e274..13b7a57a759c8f15d92cd3f61e22cdd0010db570 100644 (file)
@@ -1152,7 +1152,7 @@ static void udt_close_if_finished(struct unidirectional_transfer *t)
 }
 
 /*
- * Tries to read read data from source into buffer. If buffer is full,
+ * Tries to read data from source into buffer. If buffer is full,
  * no data is read. Returns 0 on success, -1 on error.
  */
 static int udt_do_read(struct unidirectional_transfer *t)
index 9f55cc28b9dd41231644053b49875671f5a505fa..aea9aa749f2904739b72fef285f148b8b2aa83a8 100644 (file)
@@ -58,40 +58,74 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
        int i;
        const char **msgs = opts->msgs;
        const char *msg;
-       const char *cmd2 = strcmp(cmd, "checkout") ? cmd : "switch branches";
 
-       if (advice_commit_before_merge)
-               msg = "Your local changes to the following files would be overwritten by %s:\n%%s"
-                       "Please, commit your changes or stash them before you can %s.";
+       if (!strcmp(cmd, "checkout"))
+               msg = advice_commit_before_merge
+                     ? _("Your local changes to the following files would be overwritten by checkout:\n%%s"
+                         "Please commit your changes or stash them before you can switch branches.")
+                     : _("Your local changes to the following files would be overwritten by checkout:\n%%s");
+       else if (!strcmp(cmd, "merge"))
+               msg = advice_commit_before_merge
+                     ? _("Your local changes to the following files would be overwritten by merge:\n%%s"
+                         "Please commit your changes or stash them before you can merge.")
+                     : _("Your local changes to the following files would be overwritten by merge:\n%%s");
        else
-               msg = "Your local changes to the following files would be overwritten by %s:\n%%s";
+               msg = advice_commit_before_merge
+                     ? _("Your local changes to the following files would be overwritten by %s:\n%%s"
+                         "Please commit your changes or stash them before you can %s.")
+                     : _("Your local changes to the following files would be overwritten by %s:\n%%s");
        msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] =
-               xstrfmt(msg, cmd, cmd2);
+               xstrfmt(msg, cmd, cmd);
 
        msgs[ERROR_NOT_UPTODATE_DIR] =
-               "Updating the following directories would lose untracked files in it:\n%s";
-
-       if (advice_commit_before_merge)
-               msg = "The following untracked working tree files would be %s by %s:\n%%s"
-                       "Please move or remove them before you can %s.";
+               _("Updating the following directories would lose untracked files in it:\n%s");
+
+       if (!strcmp(cmd, "checkout"))
+               msg = advice_commit_before_merge
+                     ? _("The following untracked working tree files would be removed by checkout:\n%%s"
+                         "Please move or remove them before you can switch branches.")
+                     : _("The following untracked working tree files would be removed by checkout:\n%%s");
+       else if (!strcmp(cmd, "merge"))
+               msg = advice_commit_before_merge
+                     ? _("The following untracked working tree files would be removed by merge:\n%%s"
+                         "Please move or remove them before you can merge.")
+                     : _("The following untracked working tree files would be removed by merge:\n%%s");
        else
-               msg = "The following untracked working tree files would be %s by %s:\n%%s";
-
-       msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, "removed", cmd, cmd2);
-       msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, "overwritten", cmd, cmd2);
+               msg = advice_commit_before_merge
+                     ? _("The following untracked working tree files would be removed by %s:\n%%s"
+                         "Please move or remove them before you can %s.")
+                     : _("The following untracked working tree files would be removed by %s:\n%%s");
+       msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, cmd, cmd);
+
+       if (!strcmp(cmd, "checkout"))
+               msg = advice_commit_before_merge
+                     ? _("The following untracked working tree files would be overwritten by checkout:\n%%s"
+                         "Please move or remove them before you can switch branches.")
+                     : _("The following untracked working tree files would be overwritten by checkout:\n%%s");
+       else if (!strcmp(cmd, "merge"))
+               msg = advice_commit_before_merge
+                     ? _("The following untracked working tree files would be overwritten by merge:\n%%s"
+                         "Please move or remove them before you can merge.")
+                     : _("The following untracked working tree files would be overwritten by merge:\n%%s");
+       else
+               msg = advice_commit_before_merge
+                     ? _("The following untracked working tree files would be overwritten by %s:\n%%s"
+                         "Please move or remove them before you can %s.")
+                     : _("The following untracked working tree files would be overwritten by %s:\n%%s");
+       msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, cmd, cmd);
 
        /*
         * Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we
         * cannot easily display it as a list.
         */
-       msgs[ERROR_BIND_OVERLAP] = "Entry '%s' overlaps with '%s'.  Cannot bind.";
+       msgs[ERROR_BIND_OVERLAP] = _("Entry '%s' overlaps with '%s'.  Cannot bind.");
 
        msgs[ERROR_SPARSE_NOT_UPTODATE_FILE] =
-               "Cannot update sparse checkout: the following entries are not up-to-date:\n%s";
+               _("Cannot update sparse checkout: the following entries are not up-to-date:\n%s");
        msgs[ERROR_WOULD_LOSE_ORPHANED_OVERWRITTEN] =
-               "The following Working tree files would be overwritten by sparse checkout update:\n%s";
+               _("The following Working tree files would be overwritten by sparse checkout update:\n%s");
        msgs[ERROR_WOULD_LOSE_ORPHANED_REMOVED] =
-               "The following Working tree files would be removed by sparse checkout update:\n%s";
+               _("The following Working tree files would be removed by sparse checkout update:\n%s");
 
        opts->show_all_errors = 1;
        /* rejected paths may not have a static buffer */
@@ -168,7 +202,7 @@ static void display_error_msgs(struct unpack_trees_options *o)
                string_list_clear(rejects, 0);
        }
        if (something_displayed)
-               fprintf(stderr, "Aborting\n");
+               fprintf(stderr, _("Aborting\n"));
 }
 
 /*
diff --git a/utf8.h b/utf8.h
index 7930b44f19c701cc671d9639289782abb1812034..6bbcf31a831d60faf119fdc3f82f1eb10233e255 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -48,7 +48,7 @@ static inline char *reencode_string(const char *in,
 int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding);
 
 /*
- * Returns true if the the path would match ".git" after HFS case-folding.
+ * Returns true if the path would match ".git" after HFS case-folding.
  * The path should be NUL-terminated, but we will match variants of both ".git\0"
  * and ".git/..." (but _not_ ".../.git"). This makes it suitable for both fsck
  * and verify_path().
index f91ba99f32c047e5f3238668ae83de647ab92df2..57c876580592ab246d0c5c20cf20079d2097243c 100644 (file)
@@ -136,7 +136,7 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
                                /*
                                 * Try to advance faster when an asterisk is
                                 * followed by a literal. We know in this case
-                                * that the the string before the literal
+                                * that the string before the literal
                                 * must belong to "*".
                                 * If match_slash is false, do not look past
                                 * the first slash as it cannot belong to '*'.
index 6181a66f1ee2e1e45d7d8b2c88d312746473661f..89ebe67a505f6e7772f74bd92363230955dc2b74 100644 (file)
@@ -18,7 +18,7 @@ void free_worktrees(struct worktree **worktrees)
 
 /*
  * read 'path_to_ref' into 'ref'.  Also if is_detached is not NULL,
- * set is_detached to 1 (0) if the ref is detatched (is not detached).
+ * set is_detached to 1 (0) if the ref is detached (is not detached).
  *
  * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside $GIT_DIR so
  * for linked worktrees, `resolve_ref_unsafe()` won't work (it uses
index 9afc1a021c224d4ff2230fffeb0e4f0882d4a99e..9009f8bd3d32a768454ad5fbe6cb8f7b88781a24 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -446,23 +446,6 @@ int git_mkstemp(char *path, size_t len, const char *template)
        return mkstemp(path);
 }
 
-/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */
-int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)
-{
-       const char *tmp;
-       size_t n;
-
-       tmp = getenv("TMPDIR");
-       if (!tmp)
-               tmp = "/tmp";
-       n = snprintf(path, len, "%s/%s", tmp, template);
-       if (len <= n) {
-               errno = ENAMETOOLONG;
-               return -1;
-       }
-       return mkstemps(path, suffix_len);
-}
-
 /* Adapted from libiberty's mkstemp.c. */
 
 #undef TMP_MAX
index ef7486474a1eafb7d5d1344323cd6abf012c31db..1ea2ebe4c00d23885515ac48f43844fdb03f70b9 100644 (file)
@@ -1063,9 +1063,7 @@ static void abbrev_sha1_in_line(struct strbuf *line)
                                strbuf_addf(line, "%s", split[i]->buf);
                }
        }
-       for (i = 0; split[i]; i++)
-               strbuf_release(split[i]);
-
+       strbuf_list_free(split);
 }
 
 static void read_rebase_todolist(const char *fname, struct string_list *lines)