1
0
mirror of https://github.com/git/git synced 2024-07-05 00:58:49 +00:00
Commit Graph

215 Commits

Author SHA1 Message Date
Johannes Schindelin
288a74bcd2 is_ntfs_dotgit(): only verify the leading segment
The config setting `core.protectNTFS` is specifically designed to work
not only on Windows, but anywhere, to allow for repositories hosted on,
say, Linux servers to be protected against NTFS-specific attack vectors.

As a consequence, `is_ntfs_dotgit()` manually splits backslash-separated
paths (but does not do the same for paths separated by forward slashes),
under the assumption that the backslash might not be a valid directory
separator on the _current_ Operating System.

However, the two callers, `verify_path()` and `fsck_tree()`, are
supposed to feed only individual path segments to the `is_ntfs_dotgit()`
function.

This causes a lot of duplicate scanning (and very inefficient scanning,
too, as the inner loop of `is_ntfs_dotgit()` was optimized for
readability rather than for speed.

Let's simplify the design of `is_ntfs_dotgit()` by putting the burden of
splitting the paths by backslashes as directory separators on the
callers of said function.

Consequently, the `verify_path()` function, which already splits the
path by directory separators, now treats backslashes as directory
separators _explicitly_ when `core.protectNTFS` is turned on, even on
platforms where the backslash is _not_ a directory separator.

Note that we have to repeat some code in `verify_path()`: if the
backslash is not a directory separator on the current Operating System,
we want to allow file names like `\`, but we _do_ want to disallow paths
that are clearly intended to cause harm when the repository is cloned on
Windows.

The `fsck_tree()` function (the other caller of `is_ntfs_dotgit()`) now
needs to look for backslashes in tree entries' names specifically when
`core.protectNTFS` is turned on. While it would be tempting to
completely disallow backslashes in that case (much like `fsck` reports
names containing forward slashes as "full paths"), this would be
overzealous: when `core.protectNTFS` is turned on in a non-Windows
setup, backslashes are perfectly valid characters in file names while we
_still_ want to disallow tree entries that are clearly designed to
exploit NTFS-specific behavior.

This simplification will make subsequent changes easier to implement,
such as turning `core.protectNTFS` on by default (not only on Windows)
or protecting against attack vectors involving NTFS Alternate Data
Streams.

Incidentally, this change allows for catching malicious repositories
that contain tree entries of the form `dir\.gitmodules` already on the
server side rather than only on the client side (and previously only on
Windows): in contrast to `is_ntfs_dotgit()`, the
`is_ntfs_dotgitmodules()` function already expects the caller to split
the paths by directory separators.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-12-05 15:36:50 +01:00
Johannes Schindelin
525e7fba78 path.c: document the purpose of is_ntfs_dotgit()
Previously, this function was completely undocumented. It is worth,
though, to explain what is going on, as it is not really obvious at all.

Suggested-by: Garima Singh <garima.singh@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-12-04 13:20:05 +01:00
Junio C Hamano
7b01c71b64 Sync with Git 2.13.7
* maint-2.13:
  Git 2.13.7
  verify_path: disallow symlinks in .gitmodules
  update-index: stat updated files earlier
  verify_dotfile: mention case-insensitivity in comment
  verify_path: drop clever fallthrough
  skip_prefix: add case-insensitive variant
  is_{hfs,ntfs}_dotgitmodules: add tests
  is_ntfs_dotgit: match other .git files
  is_hfs_dotgit: match other .git files
  is_ntfs_dotgit: use a size_t for traversing string
  submodule-config: verify submodule names as paths
2018-05-22 14:10:49 +09:00
Johannes Schindelin
e7cb0b4455 is_ntfs_dotgit: match other .git files
When we started to catch NTFS short names that clash with .git, we only
looked for GIT~1. This is sufficient because we only ever clone into an
empty directory, so .git is guaranteed to be the first subdirectory or
file in that directory.

However, even with a fresh clone, .gitmodules is *not* necessarily the
first file to be written that would want the NTFS short name GITMOD~1: a
malicious repository can add .gitmodul0000 and friends, which sorts
before `.gitmodules` and is therefore checked out *first*. For that
reason, we have to test not only for ~1 short names, but for others,
too.

It's hard to just adapt the existing checks in is_ntfs_dotgit(): since
Windows 2000 (i.e., in all Windows versions still supported by Git),
NTFS short names are only generated in the <prefix>~<number> form up to
number 4. After that, a *different* prefix is used, calculated from the
long file name using an undocumented, but stable algorithm.

For example, the short name of .gitmodules would be GITMOD~1, but if it
is taken, and all of ~2, ~3 and ~4 are taken, too, the short name
GI7EBA~1 will be used. From there, collisions are handled by
incrementing the number, shortening the prefix as needed (until ~9999999
is reached, in which case NTFS will not allow the file to be created).

We'd also want to handle .gitignore and .gitattributes, which suffer
from a similar problem, using the fall-back short names GI250A~1 and
GI7D29~1, respectively.

To accommodate for that, we could reimplement the hashing algorithm, but
it is just safer and simpler to provide the known prefixes. This
algorithm has been reverse-engineered and described at
https://usn.pw/blog/gen/2015/06/09/filenames/, which is defunct but
still available via https://web.archive.org/.

These can be recomputed by running the following Perl script:

-- snip --
use warnings;
use strict;

sub compute_short_name_hash ($) {
        my $checksum = 0;
        foreach (split('', $_[0])) {
                $checksum = ($checksum * 0x25 + ord($_)) & 0xffff;
        }

        $checksum = ($checksum * 314159269) & 0xffffffff;
        $checksum = 1 + (~$checksum & 0x7fffffff) if ($checksum & 0x80000000);
        $checksum -= (($checksum * 1152921497) >> 60) * 1000000007;

        return scalar reverse sprintf("%x", $checksum & 0xffff);
}

print compute_short_name_hash($ARGV[0]);
-- snap --

E.g., running that with the argument ".gitignore" will
result in "250a" (which then becomes "gi250a" in the code).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Jeff King <peff@peff.net>
2018-05-21 23:50:11 -04:00
Jeff King
11a9f4d807 is_ntfs_dotgit: use a size_t for traversing string
We walk through the "name" string using an int, which can
wrap to a negative value and cause us to read random memory
before our array (e.g., by creating a tree with a name >2GB,
since "int" is still 32 bits even on most 64-bit platforms).
Worse, this is easy to trigger during the fsck_tree() check,
which is supposed to be protecting us from malicious
garbage.

Note one bit of trickiness in the existing code: we
sometimes assign -1 to "len" at the end of the loop, and
then rely on the "len++" in the for-loop's increment to take
it back to 0. This is still legal with a size_t, since
assigning -1 will turn into SIZE_MAX, which then wraps
around to 0 on increment.

Signed-off-by: Jeff King <peff@peff.net>
2018-05-21 23:50:11 -04:00
Junio C Hamano
41052b11bc Merge branch 'jk/validate-headref-fix' into maint
Code clean-up.

* jk/validate-headref-fix:
  validate_headref: use get_oid_hex for detached HEADs
  validate_headref: use skip_prefix for symref parsing
  validate_headref: NUL-terminate HEAD buffer
2017-10-18 14:19:12 +09:00
Jeff King
8262715b8e path.c: fix uninitialized memory access
In cleanup_path we're passing in a char array, run a memcmp on it, and
run through it without ever checking if something is in the array in the
first place.  This can lead us to access uninitialized memory, for
example in t5541-http-push-smart.sh test 7, when run under valgrind:

==4423== Conditional jump or move depends on uninitialised value(s)
==4423==    at 0x242FA9: cleanup_path (path.c:35)
==4423==    by 0x242FA9: mkpath (path.c:456)
==4423==    by 0x256CC7: refname_match (refs.c:364)
==4423==    by 0x26C181: count_refspec_match (remote.c:1015)
==4423==    by 0x26C181: match_explicit_lhs (remote.c:1126)
==4423==    by 0x26C181: check_push_refs (remote.c:1409)
==4423==    by 0x2ABB4D: transport_push (transport.c:870)
==4423==    by 0x186703: push_with_options (push.c:332)
==4423==    by 0x18746D: do_push (push.c:409)
==4423==    by 0x18746D: cmd_push (push.c:566)
==4423==    by 0x1183E0: run_builtin (git.c:352)
==4423==    by 0x11973E: handle_builtin (git.c:539)
==4423==    by 0x11973E: run_argv (git.c:593)
==4423==    by 0x11973E: main (git.c:698)
==4423==  Uninitialised value was created by a heap allocation
==4423==    at 0x4C2CD8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4423==    by 0x4C2F195: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4423==    by 0x2C196B: xrealloc (wrapper.c:137)
==4423==    by 0x29A30B: strbuf_grow (strbuf.c:66)
==4423==    by 0x29A30B: strbuf_vaddf (strbuf.c:277)
==4423==    by 0x242F9F: mkpath (path.c:454)
==4423==    by 0x256CC7: refname_match (refs.c:364)
==4423==    by 0x26C181: count_refspec_match (remote.c:1015)
==4423==    by 0x26C181: match_explicit_lhs (remote.c:1126)
==4423==    by 0x26C181: check_push_refs (remote.c:1409)
==4423==    by 0x2ABB4D: transport_push (transport.c:870)
==4423==    by 0x186703: push_with_options (push.c:332)
==4423==    by 0x18746D: do_push (push.c:409)
==4423==    by 0x18746D: cmd_push (push.c:566)
==4423==    by 0x1183E0: run_builtin (git.c:352)
==4423==    by 0x11973E: handle_builtin (git.c:539)
==4423==    by 0x11973E: run_argv (git.c:593)
==4423==    by 0x11973E: main (git.c:698)
==4423==

Avoid this by using skip_prefix(), which knows not to go beyond the
end of the string.

Reported-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-10-04 13:47:16 +09:00
Jeff King
0bca165fdb validate_headref: use get_oid_hex for detached HEADs
If a candidate HEAD isn't a symref, we check that it
contains a viable sha1. But in a post-sha1 world, we should
be checking whether it has any plausible object-id.

We can do that by switching to get_oid_hex().

Note that both before and after this patch, we only check
for a plausible object id at the start of the file, and then
call that good enough.  We ignore any content _after_ the
hex, so a string like:

  0123456789012345678901234567890123456789 foo

is accepted. Though we do put extra bytes like this into
some pseudorefs (e.g., FETCH_HEAD), we don't typically do so
with HEAD. We could tighten this up by using parse_oid_hex(),
like:

  if (!parse_oid_hex(buffer, &oid, &end) &&
      *end++ == '\n' && *end == '\0')
          return 0;

But we're probably better to remain on the loose side. We're
just checking here for a plausible-looking repository
directory, so heuristics are acceptable (if we really want
to be meticulous, we should use the actual ref code to parse
HEAD).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-27 16:07:22 +09:00
Jeff King
7eb4b9d025 validate_headref: use skip_prefix for symref parsing
Since the previous commit guarantees that our symref buffer
is NUL-terminated, we can just use skip_prefix() and friends
to parse it. This is shorter and saves us having to deal
with magic numbers and keeping the "len" counter up to date.

While we're at it, let's name the rather obscure "buf" to
"refname", since that is the thing we are parsing with it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-27 16:06:31 +09:00
Jeff King
6e68c91410 validate_headref: NUL-terminate HEAD buffer
When we are checking to see if we have a git repo, we peek
into the HEAD file and see if it's a plausible symlink,
symref, or detached HEAD.

For the latter two, we read the contents with read_in_full(),
which means they aren't NUL-terminated. The symref check is
careful to respect the length we got, but the sha1 check
will happily parse up to 40 bytes, even if we read fewer.

E.g.,:

  echo 1234 >.git/HEAD
  git rev-parse

will parse 36 uninitialized bytes from our stack buffer.

This isn't a big deal in practice. Our buffer is 256 bytes,
so we know we'll never read outside of it. The worst case is
that the uninitialized bytes look like valid hex, and we
claim a bogus HEAD file is valid. The chances of this
happening randomly are quite slim, but let's be careful.

One option would be to check that "len == 41" before feeding
the buffer to get_sha1_hex(). But we'd like to eventually
prepare for a world with variable-length hashes. Let's
NUL-terminate as soon as we've read the buffer (we already
even leave a spare byte to do so!). That fixes this problem
without depending on the size of an object id.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-27 16:01:24 +09:00
Junio C Hamano
230ce07d13 Git 2.13.5
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJZgNa+AAoJELC16IaWr+bLaMIP/1tHYbkQ/iMvYE8RpV5SXZOC
 nKm8IHP4Hu+05gmp874Gw3XtF+FELC53Q2nMc3L4mJ/ZSjuJOuein9aVisapBluw
 IZ8UaxmgN1NUA8gDVkXULNMJGDaOQw+VckMrEAI3A0uYXGY2eAiHR3Q+p0txhHb9
 jfhSsnl7Rv3q6LeDOPMKpwPVT0+uxBklrli7YcIn9IssbQhAvDUpbZ0Ab/fEOH6j
 NDIsZZ8opEESsUE5WBCOVXKUYjZOpLLpU4dQXa+JBj019LRmUYxLgjGVt2BSuUh/
 K8xe6/3P1FOQF1tMY4Bjb2iIUnc0wzIQYULn9dqJthV0Ybz0qwT5bTt4IYYKs86I
 /XjJPI9cAQHNirafyUyTrWy95HGnvYSyvmNC4a2ElvD24i/GKCuRQY7O5MCT3fjB
 5jUH2VxxA5E1TvkeG4VHl0d8WZib+/4CWd0OwSXk9LJJC/C/OTUlBa2dakOpwtgS
 RNGM+8+gzzd5rv1/UL+vAiqtCYjDfU+uqsjP5fRnMyTZiCmbhRcdW9b1TRc4OMoe
 wpbSbz0L18IAsyqZ+KLhyZOCr5mxjrVCxV++efI+NhsRecmO5nbPNtRGKf7/AtAQ
 +e5hROZRSFwf8/bXoobcOvhpuvW36+0mVXxIOGIoYtXB6AdtvGFXi9TnC/rTLBZG
 zuj/z2fmgo3F0G2tnNxk
 =t0hU
 -----END PGP SIGNATURE-----

Merge tag 'v2.13.5' into maint
2017-08-04 12:40:37 -07:00
Junio C Hamano
e312af164c Git 2.12.4
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJZflhUAAoJELC16IaWr+bLDyAP/jWDc9ic8S1ZH8W4ijAB24vP
 YRyQ1gbnRLhpEpbHYCUp7Uw9mrJBfdwYFlqxGJPH4JZL9qYLJUe5DJMWi5uAEptg
 tYPpPMLV5hgvGICwJbOaS5NlNf2NzLjRvzziOpUnE5CcR5Bw7doCPk4Uw6AVvAvK
 0x/6KDNLdKCBl3ZIoLdp9eW2PrTfYx6AK+Wf9oEgdMSB9+23acL7R/QEmH7oh9gl
 BS0riRQVHnku5akybMnRjeba7SvdhJlIV8rPc4WpuMRz0g2lPzOKQ+okeRtdQrfi
 REdEZ920EJR65KtxUgxYLrpPpmdRBxNI0jXC3Sm2Kac85MLvjFqhaosBWhTQuoOf
 tra68Gb9WSVkKLwRhRBYOG+dx00m1UETs7cYm6pw37RiMss1pcZWNdzjNNouVEEp
 3LBXcPJSpCbEjI+U/H2CqLqCk9gMfKLJXB9hK4b9jBcB9yrON2d75tPMhOcNx+Ej
 x6vZ4Zql6r1Bhe8y7T6KMnLe6vdli8Vrd7Tj5btogcEUmVfRQVHZzV94utevv9A5
 UEXLeCjJSjcY7rYtTdSLXgESioHW8WNfG+TPiyxjujSybtxGKmkcrSGCrugT26K8
 UT5VH2mYJOuHRtWnjWEEEhjayaXLv0mHNQ5XVfNDNPEFqRBQmIhLhcIf/aOF6r+F
 4Q6qN9QceJUEiaFnHsyO
 =ZBXN
 -----END PGP SIGNATURE-----

Merge tag 'v2.12.4' into maint
2017-08-01 12:27:31 -07:00
Junio C Hamano
05bb78abc1 Git 2.10.4
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJZflbsAAoJELC16IaWr+bLUUAQAONDi4Ty/I9K79Nwv9/15HcV
 4oMfCC56Y8nLUs83GsS0aZadX15iABsOACtZUA0kPQB8PV2XYcUnM6rPFtpeovRI
 sfs0XqfK5l+cVDoMMb2sGAfQYEBIXRy8sUb1EXIuJ4MzHxfRbmm1sKd7ko3lg6hN
 JHhGsNpzIVRspuUZh+yXp0Qa8CKKnekhwEntVd5b71eahG3lJNBO7UXvDAkDyl33
 amoc5eqKdoGvjs3yYBvOV0qX8ePV53wieKwL5uBG6LdjMrjtWpLJOuMk6IYR18Sm
 ++A+WiCb14lQ/6Wfu+r7WhjaWIXHHMPV/5YMhm1OzrWKiw+DuucLVaorl3cSPA2G
 zNPoHGUGxfnKz0NLiMkpbjUfB0gYqqLKts5pcnKeTconUcLZlpYKEYNpypfgbJyr
 XvIgkjAt3KwRa8mrGvCURkelmYKzFzd+hZdxvXiJ/flk4CcssgMgYorWCMwwy86a
 uErlgWDcGh9wtV9Pwy8M7EwXcRDggBND5jqH2dpFUaQ+8Kzm11lX5BRseZIOASzL
 ++MuZGEQiETz2HkWb+DWMIDAJMej2N2DF1eq7DnsmEUZgOarf2ZP3Lsd84W43WLI
 PdLhA1zpL2YVz9EEeFT/hLSX3fC16+lkeVQhtV5pJlIiLumHOdWYBElsnX694Nv3
 JTE4X1l38kCBQ4on8eEo
 =R9MM
 -----END PGP SIGNATURE-----

Merge tag 'v2.10.4' into maint-2.11

Git 2.10.4
2017-07-30 15:01:31 -07:00
Junio C Hamano
d78f06a1b7 Git 2.9.5
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJZflVaAAoJELC16IaWr+bL/5QP/1NoUGqrwB+zwJ8+oDqd+Djl
 PX8qyafoMXJr/w/fACk8r/tCSGKgK8Gx9FqZ9GIBCAZVNXkQnheRElOjiuRg4rbl
 +USiN2XM4ue/X7GqEBc7YVAmd+ifFFQ+ckm1g72A53B4Qh4/Ca4MnPYLOi7eKfC1
 85f+/zMj/5pYsmboFZzFiUPq+Khyb2e85Mm9ok+l/8zAXt4ER5cf4mhY3KSEtnfA
 6qGVUJ3fS9FzE4ud+/cx2qidsTrzZI/Hpv+3TVVXzSv5j32D3srnumLs+XnVIarV
 nJFoVUZV/XSC80YUkwbcdY6Rs2gVfhHJK6zVcs8MfHC28o+ZJDM+ceGVnUKcdpDW
 Gejsc7l0Blt0IodLoHAemBOsF3eeQBh5M5vodHdEFTiCdGRcCX3lvPxikCILW1Fv
 4FPmrjfOlWEz0ktV4eKacX+DVAa2p9P09v0B6pKFt/l5MiHKla8qdYXLjEnEHHaN
 ywIJPK0Lbgr+rjf3XcEQ96sjP+2XOcmtwTxychEcQ7Z2IwqyJA/GtdyCh1/jinap
 0M9odRHtYHRk1qUcZBLosM3C3Y0rgc2k1RZJRgdAY1kiBezctoU6FkH5Pb7LFRtH
 hr3/llk9X1ivh6fruLZ6Lu2EZ/vJVOwtUNLFqPO8fLP4cABkhDdxX13o5PS+qYMJ
 THXReDUV4vgtmzKrgJ+7
 =w1+M
 -----END PGP SIGNATURE-----

Merge tag 'v2.9.5' into maint-2.10

Git 2.9.5
2017-07-30 14:57:33 -07:00
Junio C Hamano
af0178aec7 Git 2.8.6
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJZflRcAAoJELC16IaWr+bLOnAQAIEtjMActDfpYb+tXftBIzzm
 Od/tBG3WZMRPyq/fWExV9nPO5xYOf6O9PlU6H7rNMDh+2n5/ypxqEXDvjzNHRMyh
 TIk1oAjG0zDiSe/fHO4v3fcCeIne0C0ZDwzYjS9+mSnybmPRLMQ1j8ykV7oBIUlB
 A081Tcb86bxG9kdxO4Sih+0zIglZ1lNA9fH7PqY5v/DqBY9TkaZIuoEjCIo7wUYu
 k+kSrNjXWz8HdYovpO/snhgtU7TFS7OtWmYEvXBg4+p6R1nGCuSWejHeWrbqx3fI
 QPXdLXIua/NqZKdd6ad4K+K91XW1OaqnK49IY58sSzHXYiDRnfnmBDzduyuagEE1
 C3BQhALMvkGZBmkNI1unZBqxsz4E7hviyxeOt1W3Z/I8mt6IGGnLWg+oVEy4b3yj
 TAx4rQJs1xmGU5maR25yBnQI/ElZWHNg+vrtGhdt5XvklASwn8egukjAjUWJodie
 hs/BiMKf+Rk7dVPY6RnK94pHWtNpkTlD9VCaLXhmFN863Zc3DwYBcbUF2D78d5G8
 zLG1pQRtWizAjF9XJ/q01JAutHUyyoYGWwa8lKJvplxQaXwe0bntzPILZN81G1Cy
 mC955bsbyIGv+88elRAeYpu7SxQJ1uGmpMYcamdLr7irDF2bUZp7n55Ogia4IKvK
 LgvwELkejo1WgDBYvqET
 =iOsd
 -----END PGP SIGNATURE-----

Merge tag 'v2.8.6' into maint-2.9

Git 2.8.6
2017-07-30 14:52:14 -07:00
Junio C Hamano
7720c33f63 Git 2.7.6
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJZflNxAAoJELC16IaWr+bLpSsQAIT1s4c/uKAXJBw8CegM4SP1
 SeB5NMnjz7VVtBsdXKPy6fVXBHCjffON/MvNXcXwGqzx3lh6SiMAVNjYknBkQcKN
 b639dD9HEEBRFf62a+QAyRYbFeg0NONVydB25s7RfR57HUNxFibaJDT5SoymO0/5
 YCdmMENuvijvCYcwyb3MSjAKCkwDDErPzyI4NZ2YZpC7IG46Uoxq8BCdHpKhXa5I
 3TNEDruBAd/UJCIQiMW1HP3OMQXzXmCTL5i4QSr/uloO1kNzkWgCZDkkFrSGFPdx
 UeTRXOM0r5QdFXZC36zZNoL5ELflgzrYFSerj6VkCAbiG4FAWL+43CCxuUcq5OkZ
 JsTYObieBMFiaowTn9hKo3ix1xDSjR2+p0bfZbOPy5jMB85oegnjV3Rp/eBoXsDm
 h4qo+5kv0h8H2wKdxcBfVg6LkpBZGsvEOveAtWZIcFIVIOyULj9UAsnTwOotwQiL
 NHO4J2fJhcvSYUj6oGB3SpabKZfcbVXRE2fzZq+3+Mt4DdzSdSmx5CEJfUmxN7sQ
 YLb8UKSr2vv03YfKRghCGxqjOcmQL5vY79O8+QSN3cCDFFAwxzNYaGeHJ+/chvh2
 NySOkUf/uA7H1xQiZmJI1mfwQvi527MEzblCPDButm6n8ty6QyWOQ+kQYzcW5jjI
 kPWdqc5pCZQ+Q+q6lQc0
 =rNay
 -----END PGP SIGNATURE-----

Merge tag 'v2.7.6' into maint-2.8

Git 2.7.6
2017-07-30 14:46:43 -07:00
Jeff King
2491f77b90 connect: factor out "looks like command line option" check
We reject hostnames that start with a dash because they may
be confused for command-line options. Let's factor out that
notion into a helper function, as we'll use it in more
places. And while it's simple now, it's not clear if some
systems might need more complex logic to handle all cases.

Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-28 15:51:56 -07:00
Brandon Williams
b42b0c0919 path: add repo_worktree_path and strbuf_repo_worktree_path
Introduce 'repo_worktree_path' and 'strbuf_repo_worktree_path' which
take a repository struct and constructs a path relative to the
repository's worktree.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
3181d86320 path: add repo_git_path and strbuf_repo_git_path
Introduce 'repo_git_path' and 'strbuf_repo_git_path' which take a
repository struct and constructs a path into the repository's git
directory.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
543107333b path: worktree_git_path() should not use file relocation
git_path is a convenience function that usually produces a string
$GIT_DIR/<path>.  Since v2.5.0-rc0~143^2~35 (git_path(): be aware of
file relocation in $GIT_DIR, 2014-11-30), as a side benefit callers
get support for path relocation variables like $GIT_OBJECT_DIRECTORY:

- git_path("index") is $GIT_INDEX_FILE when set
- git_path("info/grafts") is $GIT_GRAFTS_FILE when set
- git_path("objects/<foo>") is $GIT_OBJECT_DIRECTORY/<foo> when set
- git_path("hooks/<foo>") is <foo> under core.hookspath when set
- git_path("refs/<foo>") etc (see path.c::common_list) is relative
  to $GIT_COMMON_DIR instead of $GIT_DIR

worktree_git_path, by comparison, is designed to resolve files in a
specific worktree's git dir.  Unfortunately, it shares code with
git_path and performs the same relocation.  The result is that paths
that are meant to be relative to the specified worktree's git dir end
up replaced by paths from environment variables within the current git
dir.

Luckily, no current callers pass such arguments.  The relocation was
noticed when testing the result of merging two patches under review,
one of which introduces a caller:

* The first patch made git prune check the index file in each
  worktree's git dir (using worktree_git_path(wt, "index")) for
  objects not to prune.  This would trigger the unwanted relocation
  when GIT_INDEX_FILE is set, causing objects reachable from the
  index to be pruned.

* The second patch simplified the relocation logic for index,
  info/grafts, objects, and hooks to happen unconditionally instead of
  based on whether environment or configuration variables are set.
  This caused the relocation to trigger even when GIT_INDEX_FILE is
  not set.

[jn: rewrote commit message; skipping all relocation instead of just
 GIT_INDEX_FILE]

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
f9a8a47e39 path: convert do_git_path to take a 'struct repository'
In preparation to adding 'git_path' like functions which operate on a
'struct repository' convert 'do_git_path' to take a 'struct repository'.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
b337172c83 path: convert strbuf_git_common_path to take a 'struct repository'
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
7aee36013a path: always pass in commondir to update_common_dir
Instead of passing in 'NULL' and having 'update_common_dir()' query for
the commondir, have the callers of 'update_common_dir()' be responsible
for providing the commondir.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
e7d72d0753 path: create path.h
Move all path related declarations from cache.h to a new path.h header
file.  This makes cache.h smaller and makes it easier to add new path
related functions.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Brandon Williams
c14c234f22 environment: place key repository state in the_repository
Migrate 'git_dir', 'git_common_dir', 'git_object_dir', 'git_index_file',
'git_graft_file', and 'namespace' to be stored in 'the_repository'.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 18:24:34 -07:00
Junio C Hamano
a2e2c04683 Merge branch 'nd/conditional-config-include'
$GIT_DIR may in some cases be normalized with all symlinks resolved
while "gitdir" path expansion in the pattern does not receive the
same treatment, leading to incorrect mismatch.  This has been fixed.

* nd/conditional-config-include:
  config: resolve symlinks in conditional include's patterns
  path.c: and an option to call real_path() in expand_user_path()
2017-04-23 22:07:46 -07:00
Junio C Hamano
5ab8f2261f Merge branch 'nd/files-backend-git-dir'
The "submodule" specific field in the ref_store structure is
replaced with a more generic "gitdir" that can later be used also
when dealing with ref_store that represents the set of refs visible
from the other worktrees.

* nd/files-backend-git-dir: (28 commits)
  refs.h: add a note about sorting order of for_each_ref_*
  t1406: new tests for submodule ref store
  t1405: some basic tests on main ref store
  t/helper: add test-ref-store to test ref-store functions
  refs: delete pack_refs() in favor of refs_pack_refs()
  files-backend: avoid ref api targeting main ref store
  refs: new transaction related ref-store api
  refs: add new ref-store api
  refs: rename get_ref_store() to get_submodule_ref_store() and make it public
  files-backend: replace submodule_allowed check in files_downcast()
  refs: move submodule code out of files-backend.c
  path.c: move some code out of strbuf_git_path_submodule()
  refs.c: make get_main_ref_store() public and use it
  refs.c: kill register_ref_store(), add register_submodule_ref_store()
  refs.c: flatten get_ref_store() a bit
  refs: rename lookup_ref_store() to lookup_submodule_ref_store()
  refs.c: introduce get_main_ref_store()
  files-backend: remove the use of git_path()
  files-backend: add and use files_ref_path()
  files-backend: add and use files_reflog_path()
  ...
2017-04-19 21:37:19 -07:00
Nguyễn Thái Ngọc Duy
4aad2f1627 path.c: and an option to call real_path() in expand_user_path()
In the next patch we need the ability to expand '~' to
real_path($HOME). But we can't do that from outside because '~' is part
of a pattern, not a true path. Add an option to expand_user_path() to do
so.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-14 23:51:38 -07:00
Nguyễn Thái Ngọc Duy
bbbb7de7ac path.c: move some code out of strbuf_git_path_submodule()
refs is learning to avoid path rewriting that is done by
strbuf_git_path_submodule(). Factor out this code so it could be reused
by refs_* functions.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-27 10:23:40 -07:00
Devin Lehmacher
e7f136bf93 path.c: add xdg_cache_home
We already have xdg_config_home to format paths relative to
XDG_CONFIG_HOME. Let's provide a similar function xdg_cache_home to do
the same for paths relative to XDG_CACHE_HOME.

Signed-off-by: Devin Lehmacher <lehmacdj@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-13 14:39:36 -07:00
Junio C Hamano
07ec05d9e6 Merge branch 'js/normalize-path-copy-ceil' into maint
A pathname that begins with "//" or "\\" on Windows is special but
path normalization logic was unaware of it.

* js/normalize-path-copy-ceil:
  normalize_path_copy(): fix pushing to //server/share/dir on Windows
2017-01-17 15:11:03 -08:00
Junio C Hamano
4833b7ec25 Merge branch 'js/normalize-path-copy-ceil'
A pathname that begins with "//" or "\\" on Windows is special but
path normalization logic was unaware of it.

* js/normalize-path-copy-ceil:
  normalize_path_copy(): fix pushing to //server/share/dir on Windows
2016-12-19 14:45:37 -08:00
Johannes Sixt
7814fbe3f1 normalize_path_copy(): fix pushing to //server/share/dir on Windows
normalize_path_copy() is not prepared to keep the double-slash of a
//server/share/dir kind of path, but treats it like a regular POSIX
style path and transforms it to /server/share/dir.

The bug manifests when 'git push //server/share/dir master' is run,
because tmp_objdir_add_as_alternate() uses the path in normalized
form when it registers the quarantine object database via
link_alt_odb_entries(). Needless to say that the directory cannot be
accessed using the wrongly normalized path.

Fix it by skipping all of the root part, not just a potential drive
prefix. offset_1st_component takes care of this, see the
implementation in compat/mingw.c::mingw_offset_1st_component().

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-12-16 13:10:43 -08:00
Junio C Hamano
00d7cc0c0b Merge branch 'rs/ring-buffer-wraparound'
The code that we have used for the past 10+ years to cycle
4-element ring buffers turns out to be not quite portable in
theoretical world.

* rs/ring-buffer-wraparound:
  hex: make wraparound of the index into ring-buffer explicit
2016-10-27 14:58:49 -07:00
René Scharfe
bb84735c80 hex: make wraparound of the index into ring-buffer explicit
Overflow is defined for unsigned integers, but not for signed ones.

We could make the ring-buffer index in sha1_to_hex() and
get_pathname() unsigned to be on the safe side to resolve this, but
let's make it explicit that we are wrapping around at whatever the
number of elements the ring-buffer has.  The compiler is smart enough
to turn modulus into bitmask for these codepaths that use
ring-buffers of a size that is a power of 2.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-26 10:54:11 -07:00
Junio C Hamano
305d7f1339 Merge branch 'jk/diff-submodule-diff-inline'
The "git diff --submodule={short,log}" mechanism has been enhanced
to allow "--submodule=diff" to show the patch between the submodule
commits bound to the superproject.

* jk/diff-submodule-diff-inline:
  diff: teach diff to display submodule difference with an inline diff
  submodule: refactor show_submodule_summary with helper function
  submodule: convert show_submodule_summary to use struct object_id *
  allow do_submodule_path to work even if submodule isn't checked out
  diff: prepare for additional submodule formats
  graph: add support for --line-prefix on all graph-aware output
  diff.c: remove output_prefix_length field
  cache: add empty_tree_oid object and helper function
2016-09-12 15:34:31 -07:00
Jacob Keller
99b43a61f2 allow do_submodule_path to work even if submodule isn't checked out
Currently, do_submodule_path will attempt locating the .git directory by
using read_gitfile on <path>/.git. If this fails it just assumes the
<path>/.git is actually a git directory.

This is good because it allows for handling submodules which were cloned
in a regular manner first before being added to the superproject.

Unfortunately this fails if the <path> is not actually checked out any
longer, such as by removing the directory.

Fix this by checking if the directory we found is actually a gitdir. In
the case it is not, attempt to lookup the submodule configuration and
find the name of where it is stored in the .git/modules/ directory of
the superproject.

If we can't locate the submodule configuration, this might occur because
for example a submodule gitlink was added but the corresponding
.gitmodules file was not properly updated.  A die() here would not be
pleasant to the users of submodule diff formats, so instead, modify
do_submodule_path() to return an error code:

 - git_pathdup_submodule() returns NULL when we fail to find a path.
 - strbuf_git_path_submodule() propagates the error code to the caller.

Modify the callers of these functions to check the error code and fail
properly. This ensures we don't attempt to use a bad path that doesn't
match the corresponding submodule.

Because this change fixes add_submodule_odb() to work even if the
submodule is not checked out, update the wording of the submodule log
diff format to correctly display that the submodule is "not initialized"
instead of "not checked out"

Add tests to ensure this change works as expected.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-08-31 18:07:10 -07:00
Junio C Hamano
d05d0e9966 Merge branch 'ab/hooks'
"git rev-parse --git-path hooks/<hook>" learned to take
core.hooksPath configuration variable (introduced during 2.9 cycle)
into account.

* ab/hooks:
  rev-parse: respect core.hooksPath in --git-path
2016-08-19 15:34:16 -07:00
Johannes Schindelin
9445b4921e rev-parse: respect core.hooksPath in --git-path
The idea of the --git-path option is not only to avoid having to
prefix paths with the output of --git-dir all the time, but also to
respect overrides for specific common paths inside the .git directory
(e.g. `git rev-parse --git-path objects` will report the value of the
environment variable GIT_OBJECT_DIRECTORY, if set).

When introducing the core.hooksPath setting, we forgot to adjust
git_path() accordingly. This patch fixes that.

While at it, revert the special-casing of core.hooksPath in
run-command.c, as it is now no longer needed.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-08-16 12:03:26 -07:00
Junio C Hamano
48aa37ed42 Merge branch 'rs/use-strbuf-addbuf' into maint
Code cleanup.

* rs/use-strbuf-addbuf:
  strbuf: avoid calling strbuf_grow() twice in strbuf_addbuf()
  use strbuf_addbuf() for appending a strbuf to another
2016-08-08 14:21:42 -07:00
Junio C Hamano
b4e8a847ba Merge branch 'rs/use-strbuf-addbuf'
Code cleanup.

* rs/use-strbuf-addbuf:
  strbuf: avoid calling strbuf_grow() twice in strbuf_addbuf()
  use strbuf_addbuf() for appending a strbuf to another
2016-07-25 14:13:47 -07:00
René Scharfe
8109984d61 use strbuf_addbuf() for appending a strbuf to another
Use strbuf_addbuf() where possible; it's shorter and more efficient.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-19 11:48:35 -07:00
Junio C Hamano
d07211b5fa Merge branch 'lp/typofixes' into maint
Typofixes.

* lp/typofixes:
  typofix: assorted typofixes in comments, documentation and messages
2016-05-26 13:17:21 -07:00
Junio C Hamano
352d72a30e Merge branch 'nd/worktree-various-heads'
The experimental "multiple worktree" feature gains more safety to
forbid operations on a branch that is checked out or being actively
worked on elsewhere, by noticing that e.g. it is being rebased.

* nd/worktree-various-heads:
  branch: do not rename a branch under bisect or rebase
  worktree.c: check whether branch is bisected in another worktree
  wt-status.c: split bisect detection out of wt_status_get_state()
  worktree.c: check whether branch is rebased in another worktree
  worktree.c: avoid referencing to worktrees[i] multiple times
  wt-status.c: make wt_status_check_rebase() work on any worktree
  wt-status.c: split rebase detection out of wt_status_get_state()
  path.c: refactor and add worktree_git_path()
  worktree.c: mark current worktree
  worktree.c: make find_shared_symref() return struct worktree *
  worktree.c: store "id" instead of "git_dir"
  path.c: add git_common_path() and strbuf_git_common_path()
  dir.c: rename str(n)cmp_icase to fspath(n)cmp
2016-05-23 14:54:29 -07:00
Junio C Hamano
3241d4f6fb Merge branch 'lp/typofixes'
* lp/typofixes:
  typofix: assorted typofixes in comments, documentation and messages
2016-05-17 14:38:20 -07:00
Li Peng
832c0e5e63 typofix: assorted typofixes in comments, documentation and messages
Many instances of duplicate words (e.g. "the the path") and
a few typoes are fixed, originally in multiple patches.

    wildmatch: fix duplicate words of "the"
    t: fix duplicate words of "output"
    transport-helper: fix duplicate words of "read"
    Git.pm: fix duplicate words of "return"
    path: fix duplicate words of "look"
    pack-protocol.txt: fix duplicate words of "the"
    precompose-utf8: fix typo of "sequences"
    split-index: fix typo
    worktree.c: fix typo
    remote-ext: fix typo
    utf8: fix duplicate words of "the"
    git-cvsserver: fix duplicate words

Signed-off-by: Li Peng <lip@dtdream.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-06 13:16:37 -07:00
Junio C Hamano
8591654998 Merge branch 'jk/check-repository-format' into maint
The repository set-up sequence has been streamlined (the biggest
change is that there is no longer git_config_early()), so that we
do not attempt to look into refs/* when we know we do not have a
Git repository.

* jk/check-repository-format:
  verify_repository_format: mark messages for translation
  setup: drop repository_format_version global
  setup: unify repository version callbacks
  init: use setup.c's repo version verification
  setup: refactor repo format reading and verification
  config: drop git_config_early
  check_repository_format_gently: stop using git_config_early
  lazily load core.sharedrepository
  wrap shared_repository global in get/set accessors
  setup: document check_repository_format()
2016-05-02 14:24:04 -07:00
Nguyễn Thái Ngọc Duy
2e641d5825 path.c: refactor and add worktree_git_path()
do_git_path(), which is the common code for all git_path* functions, is
modified to take a worktree struct and can produce paths for any
worktree.

worktree_git_path() is the first function that makes use of this. It can
be used to write code that can examine any worktree. For example,
wt_status_get_state() will be converted using this to take
am/rebase/... state of any worktree.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-22 14:09:38 -07:00
Nguyễn Thái Ngọc Duy
15cdfea734 path.c: add git_common_path() and strbuf_git_common_path()
These are mostly convenient functions to reduce code duplication. Most
of the time, we should be able to get by with git_path() which handles
$GIT_COMMON_DIR internally. However there are a few cases where we need
to construct paths manually, for example some paths from a specific
worktree. These functions will enable that.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-22 14:09:37 -07:00
Junio C Hamano
907c416534 Merge branch 'jk/check-repository-format'
The repository set-up sequence has been streamlined (the biggest
change is that there is no longer git_config_early()), so that we
do not attempt to look into refs/* when we know we do not have a
Git repository.

* jk/check-repository-format:
  verify_repository_format: mark messages for translation
  setup: drop repository_format_version global
  setup: unify repository version callbacks
  init: use setup.c's repo version verification
  setup: refactor repo format reading and verification
  config: drop git_config_early
  check_repository_format_gently: stop using git_config_early
  lazily load core.sharedrepository
  wrap shared_repository global in get/set accessors
  setup: document check_repository_format()
2016-04-13 14:12:28 -07:00