Commit Graph

60552 Commits

Author SHA1 Message Date
Karsten Blees
170c248112 Win32: support long paths
Windows paths are typically limited to MAX_PATH = 260 characters, even
though the underlying NTFS file system supports paths up to 32,767 chars.
This limitation is also evident in Windows Explorer, cmd.exe and many
other applications (including IDEs).

Particularly annoying is that most Windows APIs return bogus error codes
if a relative path only barely exceeds MAX_PATH in conjunction with the
current directory, e.g. ERROR_PATH_NOT_FOUND / ENOENT instead of the
infinitely more helpful ERROR_FILENAME_EXCED_RANGE / ENAMETOOLONG.

Many Windows wide char APIs support longer than MAX_PATH paths through the
file namespace prefix ('\\?\' or '\\?\UNC\') followed by an absolute path.
Notable exceptions include functions dealing with executables and the
current directory (CreateProcess, LoadLibrary, Get/SetCurrentDirectory) as
well as the entire shell API (ShellExecute, SHGetSpecialFolderPath...).

Introduce a handle_long_path function to check the length of a specified
path properly (and fail with ENAMETOOLONG), and to optionally expand long
paths using the '\\?\' file namespace prefix. Short paths will not be
modified, so we don't need to worry about device names (NUL, CON, AUX).

Contrary to MSDN docs, the GetFullPathNameW function doesn't seem to be
limited to MAX_PATH (at least not on Win7), so we can use it to do the
heavy lifting of the conversion (translate '/' to '\', eliminate '.' and
'..', and make an absolute path).

Add long path error checking to xutftowcs_path for APIs with hard MAX_PATH
limit.

Add a new MAX_LONG_PATH constant and xutftowcs_long_path function for APIs
that support long paths.

While improved error checking is always active, long paths support must be
explicitly enabled via 'core.longpaths' option. This is to prevent end
users to shoot themselves in the foot by checking out files that Windows
Explorer, cmd/bash or their favorite IDE cannot handle.

Test suite:
Test the case is when the full pathname length of a dir is close
to 260 (MAX_PATH).
Bug report and an original reproducer by Andrey Rogozhnikov:
https://github.com/msysgit/git/pull/122#issuecomment-43604199

[jes: adjusted test number to avoid conflicts, reinstated && chain]

Thanks-to: Martin W. Kirst <maki@bitkings.de>
Thanks-to: Doug Kelly <dougk.ff7@gmail.com>
Signed-off-by: Karsten Blees <blees@dcon.de>
Original-test-by: Andrey Rogozhnikov <rogozhnikov.andrey@gmail.com>
Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:20 +02:00
Johannes Schindelin
4a7f848d9c Win32: support long paths
Windows paths are typically limited to MAX_PATH = 260 characters, even
though the underlying NTFS file system supports paths up to 32,767 chars.
This limitation is also evident in Windows Explorer, cmd.exe and many
other applications (including IDEs).

Particularly annoying is that most Windows APIs return bogus error codes
if a relative path only barely exceeds MAX_PATH in conjunction with the
current directory, e.g. ERROR_PATH_NOT_FOUND / ENOENT instead of the
infinitely more helpful ERROR_FILENAME_EXCED_RANGE / ENAMETOOLONG.

Many Windows wide char APIs support longer than MAX_PATH paths through the
file namespace prefix ('\\?\' or '\\?\UNC\') followed by an absolute path.
Notable exceptions include functions dealing with executables and the
current directory (CreateProcess, LoadLibrary, Get/SetCurrentDirectory) as
well as the entire shell API (ShellExecute, SHGetSpecialFolderPath...).

Introduce a handle_long_path function to check the length of a specified
path properly (and fail with ENAMETOOLONG), and to optionally expand long
paths using the '\\?\' file namespace prefix. Short paths will not be
modified, so we don't need to worry about device names (NUL, CON, AUX).

Contrary to MSDN docs, the GetFullPathNameW function doesn't seem to be
limited to MAX_PATH (at least not on Win7), so we can use it to do the
heavy lifting of the conversion (translate '/' to '\', eliminate '.' and
'..', and make an absolute path).

Add long path error checking to xutftowcs_path for APIs with hard MAX_PATH
limit.

Add a new MAX_LONG_PATH constant and xutftowcs_long_path function for APIs
that support long paths.

While improved error checking is always active, long paths support must be
explicitly enabled via 'core.longpaths' option. This is to prevent end
users to shoot themselves in the foot by checking out files that Windows
Explorer, cmd/bash or their favorite IDE cannot handle.

Test suite:
Test the case is when the full pathname length of a dir is close
to 260 (MAX_PATH).
Bug report and an original reproducer by Andrey Rogozhnikov:
https://github.com/msysgit/git/pull/122#issuecomment-43604199

[jes: adjusted test number to avoid conflicts]

Thanks-to: Martin W. Kirst <maki@bitkings.de>
Thanks-to: Doug Kelly <dougk.ff7@gmail.com>
Signed-off-by: Karsten Blees <blees@dcon.de>
Original-test-by: Andrey Rogozhnikov <rogozhnikov.andrey@gmail.com>
Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:20 +02:00
Doug Kelly
295bcb9f10 Add a test demonstrating a problem with long submodule paths
[jes: adusted test number to avoid conflicts, fixed non-portable use of
the 'export' statement]

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:19 +02:00
Karsten Blees
8fbc5bb3ec fscache: load directories only once
If multiple threads access a directory that is not yet in the cache, the
directory will be loaded by each thread. Only one of the results is added
to the cache, all others are leaked. This wastes performance and memory.

On cache miss, add a future object to the cache to indicate that the
directory is currently being loaded. Subsequent threads register themselves
with the future object and wait. When the first thread has loaded the
directory, it replaces the future object with the result and notifies
waiting threads.

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:18 +02:00
Karsten Blees
f16b677633 Win32: add a cache below mingw's lstat and dirent implementations
Checking the work tree status is quite slow on Windows, due to slow lstat
emulation (git calls lstat once for each file in the index). Windows
operating system APIs seem to be much better at scanning the status
of entire directories than checking single files.

Add an lstat implementation that uses a cache for lstat data. Cache misses
read the entire parent directory and add it to the cache. Subsequent lstat
calls for the same directory are served directly from the cache.

Also implement opendir / readdir / closedir so that they create and use
directory listings in the cache.

The cache doesn't track file system changes and doesn't plug into any
modifying file APIs, so it has to be explicitly enabled for git functions
that don't modify the working copy.

Note: in an earlier version of this patch, the cache was always active and
tracked file system changes via ReadDirectoryChangesW. However, this was
much more complex and had negative impact on the performance of modifying
git commands such as 'git checkout'.

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:17 +02:00
Karsten Blees
7f9a6c2fde add infrastructure for read-only file system level caches
Add a macro to mark code sections that only read from the file system,
along with a config option and documentation.

This facilitates implementation of relatively simple file system level
caches without the need to synchronize with the file system.

Enable read-only sections for 'git status' and preload_index.

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:16 +02:00
Karsten Blees
b2a0ca071a Win32: make the lstat implementation pluggable
Emulating the POSIX lstat API on Windows via GetFileAttributes[Ex] is quite
slow. Windows operating system APIs seem to be much better at scanning the
status of entire directories than checking single files. A caching
implementation may improve performance by bulk-reading entire directories
or reusing data obtained via opendir / readdir.

Make the lstat implementation pluggable so that it can be switched at
runtime, e.g. based on a config option.

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:16 +02:00
Karsten Blees
eb2a2311c9 Win32: Make the dirent implementation pluggable
Emulating the POSIX dirent API on Windows via FindFirstFile/FindNextFile is
pretty staightforward, however, most of the information provided in the
WIN32_FIND_DATA structure is thrown away in the process. A more
sophisticated implementation may cache this data, e.g. for later reuse in
calls to lstat.

Make the dirent implementation pluggable so that it can be switched at
runtime, e.g. based on a config option.

Define a base DIR structure with pointers to readdir/closedir that match
the opendir implementation (i.e. similar to vtable pointers in OOP).
Define readdir/closedir so that they call the function pointers in the DIR
structure. This allows to choose the opendir implementation on a
call-by-call basis.

Move the fixed sized dirent.d_name buffer to the dirent-specific DIR
structure, as d_name may be implementation specific (e.g. a caching
implementation may just set d_name to point into the cache instead of
copying the entire file name string).

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:15 +02:00
Karsten Blees
009513ec02 Win32: dirent.c: Move opendir down
Move opendir down in preparation for the next patch.

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:14 +02:00
Karsten Blees
b5f2d54f0d Win32: make FILETIME conversion functions public
Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:14 +02:00
Jakub Bereżański
685d808ea9 wincred: handle empty username/password correctly
Empty (length 0) usernames and/or passwords, when saved in the Windows
Credential Manager, come back as null when reading the credential.

One use case for such empty credentials is with NTLM authentication, where
empty username and password instruct libcurl to authenticate using the
credentials of the currently logged-on user (single sign-on).

When locating the relevant credentials, make empty username match null.
When outputting the credentials, handle nulls correctly.

Signed-off-by: Jakub Bereżański <kuba@berezanscy.pl>
2016-04-04 08:02:13 +02:00
Jakub Bereżański
24b53a880e t0302: check helper can handle empty credentials
Make sure the helper does not crash when blank username and password is
provided. If the helper can save such credentials, it should be able to
read them back.

Signed-off-by: Jakub Bereżański <kuba@berezanscy.pl>
2016-04-04 08:02:12 +02:00
Sebastian Schuberth
4171ce62b7 gitk: Use an external icon file on Windows
Git for Windows now ships with the new Git icon from git-scm.com. Use that
icon file if it exists instead of the old procedurally drawn one.

This patch was sent upstream but so far no decision on its inclusion was
made, so commit it to our fork.

Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
2016-04-04 08:02:10 +02:00
Chris West (Faux)
665532813c Fix another invocation of git from gitk with an overly long command-line
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
2016-04-04 08:02:10 +02:00
Johannes Schindelin
aba83ae552 Work around the command line limit on Windows
On Windows, there are dramatic problems when a command line grows
beyond PATH_MAX, which is restricted to 8191 characters on XP and
later (according to http://support.microsoft.com/kb/830473).

Work around this by just cutting off the command line at that length
(actually, at a space boundary) in the hope that only negative
refs are chucked: gitk will then do unnecessary work, but that is
still better than flashing the gitk window and exiting with exit
status 5 (which no Windows user is able to make sense of).

The first fix caused Tcl to fail to compile the regexp, see msysGit issue
427. Here is another fix without using regexp, and using a more relaxed
command line length limit to fix the original issue 387.

Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:09 +02:00
Johannes Schindelin
6a56c78f3c git gui: set GIT_ASKPASS=git-gui--askpass if not set yet
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:08 +02:00
Heiko Voigt
e3ec40b4c8 git-gui: provide question helper for retry fallback on Windows
Make use of the new environment variable GIT_ASK_YESNO to support the
recently implemented fallback in case unlink, rename or rmdir fail for
files in use on Windows. The added dialog will present a yes/no question
to the the user which will currently be used by the windows compat layer
to let the user retry a failed file operation.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
2016-04-04 08:02:07 +02:00
Heiko Voigt
bb9f65befd Revert "git-gui: set GIT_DIR and GIT_WORK_TREE after setup"
This reverts commit a9fa11fe5b.
2016-04-04 08:02:06 +02:00
Pat Thoyts
3bcdaecf84 mingw: add tests for the hidden attribute on the git directory
With msysGit the .git directory is supposed to be hidden, unless it is
a bare git repository. Test this.

Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
2016-04-04 08:02:05 +02:00
Johannes Schindelin
16ca5c88ed When initializing .git/, record the current setting of core.hideDotFiles
This is on Windows only, of course.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:05 +02:00
Erik Faye-Lund
0abc989443 core.hideDotFiles: hide '.git' dir by default
At least for cross-platform projects, it makes sense to hide the
files starting with a dot, as this is the behavior on Unix/MacOSX.

However, at least Eclipse has problems interpreting the hidden flag
correctly, so the default is to hide only the .git/ directory.

The config setting core.hideDotFiles therefore supports not only
'true' and 'false', but also 'dotGitOnly'.

[jes: clarified the commit message, made git init respect the setting
by marking the .git/ directory only after reading the config, and added
documentation, and rebased on top of current junio/next]

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:04 +02:00
Karsten Blees
12a64cba5f git-gui:handle the encoding of Git's output correctly
If we use 'eval exec $opt $cmdp $args' to execute git command,
tcl engine will convert the output of the git comand with the rule
system default code page to unicode.

But cp936 -> unicode conversion implicitly done by exec is not reversible.
So we have to use git_read instead.

Bug report and an original reproducer by Cloud Chou:
https://github.com/msysgit/git/issues/302

Karsten Blees writes this code patch.
Cloud Chou find the reason of the bug.

Thanks-to: dscho
Thanks-to: patthoyts
Signed-off-by: Karsten Blees <blees@dcon.de>
Original-test-by: Cloud Chou <515312382@qq.com>
Signed-off-by: Cloud Chou <515312382@qq.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:03 +02:00
Karsten Blees
c14829f992 Unicode file name support (gitk and git-gui)
Assumes file names in git tree objects are UTF-8 encoded.

On most unix systems, the system encoding (and thus the TCL system
encoding) will be UTF-8, so file names will be displayed correctly.

On Windows, it is impossible to set the system encoding to UTF-8. Changing
the TCL system encoding (via 'encoding system ...', e.g. in the startup
code) is explicitly discouraged by the TCL docs.

Change gitk and git-gui functions dealing with file names to always convert
from and to UTF-8.

Signed-off-by: Karsten Blees <blees@dcon.de>
2016-04-04 08:02:02 +02:00
Johannes Schindelin
d80fc90904 mingw: mark t9100's test cases with appropriate prereqs
Many a test requires either POSIXPERM (to change the executable bit) or
SYMLINKS, and neither are available on Windows.

This lets t9100-git-svn-basic.sh pass in Git for Windows' SDK.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 08:02:01 +02:00
Johannes Schindelin
47571a6769 Start the merging-rebase to v2.8.1
This commit starts the rebase of 5840b06 to fdeee3d
2016-04-04 08:02:00 +02:00
Johannes Schindelin
dfa7d5a9aa fixup! DEBUG
This was a commit not intended for `master`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-04 07:59:36 +02:00
Junio C Hamano
6a269e52a5 First batch for post 2.8 cycle
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-03 10:55:36 -07:00
Junio C Hamano
9494c396f3 Sync with Git 2.8.1 2016-04-03 10:54:38 -07:00
Junio C Hamano
05bf1cdccd Merge branch 'jk/startup-info'
The startup_info data, which records if we are working inside a
repository (among other things), are now uniformly available to Git
subcommand implementations, and Git avoids attempting to touch
references when we are not in a repository.

* jk/startup-info:
  use setup_git_directory() in test-* programs
  grep: turn off gitlink detection for --no-index
  mailmap: do not resolve blobs in a non-repository
  remote: don't resolve HEAD in non-repository
  setup: set startup_info->have_repository more reliably
  setup: make startup_info available everywhere
2016-04-03 10:29:36 -07:00
Junio C Hamano
7ce0bee4c4 Merge branch 'es/test-gpg-tags'
A test for tags has been restructured so that more parts of it can
easily be run on a platform without a working GnuPG.

* es/test-gpg-tags:
  t6302: skip only signed tags rather than all tests when GPG is missing
  t6302: also test annotated in addition to signed tags
  t6302: normalize names and descriptions of signed tags
  lib-gpg: drop unnecessary "missing GPG" warning
2016-04-03 10:29:35 -07:00
Junio C Hamano
087f171f14 Merge branch 'jk/getwholeline-getdelim-empty'
strbuf_getwholeline() did not NUL-terminate the buffer on certain
corner cases in its error codepath.

* jk/getwholeline-getdelim-empty:
  strbuf_getwholeline: NUL-terminate getdelim buffer on error
2016-04-03 10:29:34 -07:00
Junio C Hamano
aa3a2c2af6 Merge branch 'rj/xdiff-prepare-plug-leak-on-error-codepath'
A small memory leak in an error codepath has been plugged in xdiff
code.

* rj/xdiff-prepare-plug-leak-on-error-codepath:
  xdiff/xprepare: fix a memory leak
  xdiff/xprepare: use the XDF_DIFF_ALG() macro to access flag bits
2016-04-03 10:29:33 -07:00
Junio C Hamano
3583bf594d Merge branch 'jc/index-pack'
Code clean-up.

* jc/index-pack:
  index-pack: add a helper function to derive .idx/.keep filename
2016-04-03 10:29:31 -07:00
Junio C Hamano
9081cffd1e Merge branch 'gf/fetch-pack-direct-object-fetch'
Fetching of history by naming a commit object name directly didn't
work across remote-curl transport.

* gf/fetch-pack-direct-object-fetch:
  fetch-pack: update the documentation for "<refs>..." arguments
  fetch-pack: fix object_id of exact sha1
2016-04-03 10:29:29 -07:00
Junio C Hamano
d4a22303ab Merge branch 'jc/maint-index-pack-keep'
"git index-pack --keep[=<msg>] pack-$name.pack" simply did not work.

* jc/maint-index-pack-keep:
  index-pack: correct --keep[=<msg>]
2016-04-03 10:29:29 -07:00
Junio C Hamano
3b8c4b727f Merge branch 'mm/lockfile-error-message'
* mm/lockfile-error-message:
  lockfile: improve error message when lockfile exists
  lockfile: mark strings for translation
2016-04-03 10:29:27 -07:00
Junio C Hamano
fbebb5cd07 Merge branch 'jk/rev-parse-local-env-vars'
The "--local-env-vars" and "--resolve-git-dir" options of "git
rev-parse" failed to work outside a repository when the command's
option parsing was rewritten in 1.8.5 era.

* jk/rev-parse-local-env-vars:
  rev-parse: let some options run outside repository
  t1515: add tests for rev-parse out-of-repo helpers
2016-04-03 10:29:27 -07:00
Junio C Hamano
c832cef8aa Merge branch 'jk/config-get-urlmatch'
"git config --get-urlmatch", unlike other variants of the "git
config --get" family, did not signal error with its exit status
when there was no matching configuration.

* jk/config-get-urlmatch:
  Documentation/git-config: fix --get-all description
  Documentation/git-config: use bulleted list for exit codes
  config: fail if --get-urlmatch finds no value
2016-04-03 10:29:26 -07:00
Junio C Hamano
2052c52d9a Merge branch 'jk/add-i-highlight'
* jk/add-i-highlight:
  add--interactive: allow custom diff highlighting programs
2016-04-03 10:29:25 -07:00
Junio C Hamano
1b68962b29 Merge branch 'jk/credential-clear-config'
The credential.helper configuration variable is cumulative and
there is no good way to override it from the command line.  As
a special case, giving an empty string as its value now serves
as the signal to clear the values specified in various files.

* jk/credential-clear-config:
  credential: let empty credential specs reset helper list
2016-04-03 10:29:24 -07:00
Junio C Hamano
e13de0bdd8 Merge branch 'mp/upload-pack-use-embedded-args'
The embedded args argv-array in the child process is used to build
the command line to run pack-objects instead of using a separate
array of strings.

* mp/upload-pack-use-embedded-args:
  upload-pack: use argv_array for pack_objects
2016-04-03 10:29:24 -07:00
Junio C Hamano
5d2a30d7d8 Merge branch 'mm/diff-renames-default'
The end-user facing Porcelain level commands like "diff" and "log"
now enables the rename detection by default.

* mm/diff-renames-default:
  diff: activate diff.renames by default
  log: introduce init_log_defaults()
  t: add tests for diff.renames (true/false/unset)
  t4001-diff-rename: wrap file creations in a test
  Documentation/diff-config: fix description of diff.renames
2016-04-03 10:29:22 -07:00
Junio C Hamano
f66a5bd923 Merge branch 'mm/readme-markdown'
Fix a few broken links in README.md and also teach rpmbuild
that there is no README.

* mm/readme-markdown:
  README.md: don't take 'commandname' literally
  git.spec.in: use README.md, not README
2016-04-03 10:27:22 -07:00
Junio C Hamano
d95553a6b8 Git 2.8.1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
v2.8.1
2016-04-03 10:14:12 -07:00
Junio C Hamano
6e4de7fca3 Merge branch 'mm/readme-markdown' into maint
* 'mm/readme-markdown':
  git.spec.in: use README.md, not README
2016-04-03 10:13:09 -07:00
Matthieu Moy
c9a014e38e README.md: don't take 'commandname' literally
The link to Documentation/git-commandname.txt was obviously broken.
Remove the link and make it clear that it is not a literal path name by
using *italics* in makdown.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-03 10:12:48 -07:00
Matthieu Moy
c7089e0ee9 git.spec.in: use README.md, not README
The file was renamed in 4ad21f5 (README: use markdown syntax,
2016-02-25), but that commit forgot to update git.spec.in, which
caused the rpmbuild target in the Makefile to fail.

Reported-by: Ron Isaacson <isaacson.ljits@gmail.com>
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-03 10:12:48 -07:00
Johannes Schindelin
71c3301cac Merge pull request #661 from shiftkey/patch-1
Update CONTRIBUTING.md to Contributor Covenant v1.4
2016-04-02 14:12:11 +02:00
Johannes Schindelin
af5a5e06e5 Merge branch 'spawn-with-spaces'
This change lets us spawn .bat scripts whose paths contain spaces.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-02 13:51:48 +02:00
Johannes Schindelin
8086988cd7 mingw: support spawning programs containing spaces in their names
The CreateProcessW() function does not really support spaces in its
first argument, lpApplicationName. But it supports passing NULL as
lpApplicationName, which makes it figure out the application from the
(possibly quoted) first argument of lpCommandLine.

Let's use that trick (if we are certain that the first argument matches
the executable's path) to support launching programs whose path contains
spaces.

This fixes https://github.com/git-for-windows/git/issue/692

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2016-04-02 13:07:13 +02:00