Граф коммитов

99931 Коммитов

Автор SHA1 Сообщение Дата
Philip Oakley b14716e9bc .gitignore: touch up the entries regarding Visual Studio
Add the Microsoft .manifest pattern, and do not anchor the 'Debug'
and 'Release' entries at the top-level directory, to allow for
multiple projects (one per target).

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:28 +02:00
Johannes Schindelin fcfabc9e57 vcxproj: also link-or-copy builtins
The problem with not having, say, git-receive-pack.exe after a full
build is that the test suite will then happily use the *installed*
git-receive-pack.exe because it finds nothing else.

Absolutely not what we want. We want to have confidence that our test
covers the MSVC-built Git executables, and not some random stuff.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:28 +02:00
Johannes Schindelin da18d69356 msvc: add a Makefile target to pre-generate the VS solution
The entire idea of generating the VS solution makes only sense if we
generate it via Continuous Integration; otherwise potential users would
still have to download the entire Git for Windows SDK.

So let's just add a target in the Makefile that can be used to generate
said solution; The generated files will then be committed so that they
can be pushed to a branch ready to check out by Visual Studio users.

To make things even more useful, we also generate and commit other files
that are required to run the test suite, such as templates and
bin-wrappers: with this, developers can run the test suite in a regular
Git Bash (that is part of a regular Git for Windows installation) after
building the solution in Visual Studio.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:28 +02:00
Johannes Schindelin a13c9e5f06 contrib/buildsystems: add a backend for modern Visual Studio versions
Based on the previous patch series to be able to compile Git using
Visual C++ from the command-line, this patch offers to generate project
definitions for Visual Studio, so that Git can be developed in a modern
IDE.

Based on the generator for Visual Studio versions <= 2008 (which used
.sln/.vcproj files), this patch copy-edits the generator of the .vcproj
files to a new generator that produces .vcxproj files ready for Visual
Studio 2010 and later (or MSBuild).

As the vcpkg system (which is used to build Git's dependencies) cannot
run in parallel (it does not lock, wreaking havoc with files being
accessed and written at the same time, letting the vcpkg processes
stumble over each others' toes), we make libgit the root of the project
dependency tree and initialize the vcpkg system in this project's
PreBuildEvent.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Johannes Schindelin df173b6f13 contrib/buildsystems: error out on unknown option
One time too many did this developer call the `generate` script passing
a `--make-out=<PATH>` option that was happily ignored (because there
should be a space, not an equal sign, between `--make-out` and the
path).

And one time too many, this script not only ignored it but did not even
complain. Let's fix that.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Johannes Schindelin 4fc25102aa contrib/buildsystems: handle options starting with a slash
With the recent changes to allow building with MSVC=1, we now pass the
/OPT:REF option to the compiler. This confuses the parser that wants to
turn the output of a dry run into project definitions for QMake and Visual
Studio:

	Unhandled link option @ line 213: /OPT:REF at [...]

Let's just extend the code that passes through options that start with a
dash, so that it passes through options that start with a slash, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Johannes Schindelin 901a28b607 contrib/buildsystems: handle libiconv, too
Git's test suite shows tons of breakages unless Git is compiled
*without* NO_ICONV. That means, in turn, that we need to generate
build definitions *with* libiconv, which in turn implies that we
have to handle the -liconv option properly.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley 090f9bd484 contrib/buildsystems: handle the curl library option
Upon seeing the '-lcurl' option, point to the libcurl.lib.

While there, fix the elsif indentation.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley 4904efd463 contrib/buildsystems: optionally capture the dry-run in a file
Add an option for capturing the output of the make dry-run used in
determining the msvc-build structure for easy debugging.

You can use the output of `--make-out <path>` in subsequent runs via the
`--in <path>` option.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley 17b48257f2 contrib/buildsystems: redirect errors of the dry run into a log file
Rather than swallowing the errors, it is better to have them in a file.

To make it obvious what this is about, use the file name
'msvc-build-makedryerrors.txt'.

Further, if the output is empty, simply delete that file. As we target
Git for Windows' SDK (which, unlike its predecessor msysGit, offers Perl
versions newer than 5.8), we can use the quite readable syntax `if -f -z
$ErrsFile` (available in Perl >=5.10).

Note that the file will contain the new values of the GIT_VERSION and
GITGUI_VERSION if they were generated by the make file. They are omitted
if the release is tagged and indentically defined in their respective
GIT_VERSION_GEN file DEF_VER variables.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley 32f9913108 contrib/buildsystems: ignore gettext stuff
Git's build contains steps to handle internationalization. This caused
hiccups in the parser used to generate QMake/Visual Studio project files.

As those steps are irrelevant in this context, let's just ignore them.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley fb32eac393 contrib/buildsystems: handle quoted spaces in filenames
The engine.pl script expects file names not to contain spaces. However,
paths with spaces are quite prevalent on Windows. Use shellwords() rather
than split() to parse them correctly.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley 38e18625fc contrib/buildsystems: fix misleading error message
The error message talked about a "lib option", but it clearly referred
to a link option.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Johannes Schindelin 7eb09700f1 contrib/buildsystems: ignore irrelevant files in Generators/
The Generators/ directory can contain spurious files such as editors'
backup files. Even worse, there could be .swp files which are not even
valid Perl scripts.

Let's just ignore anything but .pm files in said directory.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley e9951330bf contrib/buildsystems: ignore invalidcontinue.obj
Since 4b623d8 (MSVC: link in invalidcontinue.obj for better POSIX
compatibility, 2014-03-29), invalidcontinue.obj is linked in the MSVC
build, but it was not parsed correctly by the buildsystem. Ignore it, as
it is known to Visual Studio and will be handled elsewhere.

Also only substitute filenames ending with .o when generating the
source .c filename, otherwise we would start to expect .cbj files to
generate .obj files (which are not generated by our build)...

In the future there may be source files that produce .obj files
so keep the two issues (.obj files with & without source files)
separate.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Duncan Smart <duncan.smart@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Johannes Schindelin b6c7a67931 Vcproj.pm: urlencode '<' and '>' when generating VC projects
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Johannes Schindelin bc3eec6e8d Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool
It is not necessary, and Visual Studio 2015 no longer supports it, anyway.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:27 +02:00
Philip Oakley 6ac55011bc Vcproj.pm: list git.exe first to be startup project
Visual Studio takes the first listed application/library as the default
startup project [1].

Detect the 'git' project and place it the head of the apps list, rather
than the tail.

Export the apps list before libs list for both the projects and global
structures of the .sln file.

[1] http://stackoverflow.com/questions/1238553/
vs2008-where-is-the-startup-project-setting-stored-for-a-solution
    "In the solution file, there are a list of pseudo-XML "Project"
    entries. It turns out that whatever is the first one ends up as
    the Startup Project, unless it’s overridden in the suo file. Argh.
    I just rearranged the order in the file and it’s good."

    "just moving the pseudo-xml isn't enough. You also have to move the
    group of entries in the "GlobalSection(ProjectConfigurationPlatforms)
    = postSolution" group that has the GUID of the project you moved to
    the top. So there are two places to move lines."

Signed-off-by: Philip Oakley <philipoakley@iee.org>
2019-06-03 22:59:27 +02:00
Jeff Hostetler 2db49eecd3 msvc: ignore .dll and incremental compile output
Ignore .dll files copied into the top-level directory.
Ignore MSVC incremental compiler output files.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Johannes Schindelin e69639ac67 Vcproj.pm: auto-generate GUIDs
We ran out GUIDs. Again. But there is no need to: we can generate them
semi-randomly from the target file name of the project.

Note: the Vcproj generator is probably only interesting for historical
reasons; nevertheless, the upcoming Vcxproj generator (to support modern
Visual Studio versions) is based on the Vcproj generator and it is
better to fix this here first.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Johannes Schindelin c60f733328 msvc: avoid debug assertion windows in Debug Mode
For regular debugging, it is pretty helpful when a debug assertion in a
running application triggers a window that offers to start the debugger.

However, when running the test suite, it is not so helpful, in
particular when the debug assertions are then suppressed anyway because
we disable the invalid parameter checking (via invalidcontinue.obj, see
the comment in config.mak.uname about that object for more information).

So let's simply disable that window in Debug Mode (it is already
disabled in Release Mode).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Jeff Hostetler 87d61a771a msvc: support building Git using MS Visual C++
With this patch, Git can be built using the Microsoft toolchain, via:

	make MSVC=1 [DEBUG=1]

Third party libraries are built from source using the open source
"vcpkg" tool set. See https://github.com/Microsoft/vcpkg

On a first build, the vcpkg tools and the third party libraries are
automatically downloaded and built. DLLs for the third party libraries
are copied to the top-level (and t/helper) directory to facilitate
debugging. See compat/vcbuild/README.

A series of .bat files are invoked by the Makefile to find the location
of the installed version of Visual Studio and the associated compiler
tools (essentially replicating the environment setup performed by a
"Developer Command Prompt"). This should find the most recent VS2015 or
VS2017 installation. Output from these scripts are used by the Makefile
to define compiler and linker pathnames and -I and -L arguments.

The build produces .pdb files for both debug and release builds.

Note: This commit was squashed from an organic series of commits
developed between 2016 and 2018 in Git for Windows' `master` branch.
This combined commit eliminates the obsolete commits related to fetching
NuGet packages for third party libraries. It is difficult to use NuGet
packages for C/C++ sources because they may be built by earlier versions
of the MSVC compiler and have CRT version and linking issues.
Additionally, the C/C++ NuGet packages that were using tended to not be
updated concurrently with the sources.  And in the case of cURL and
OpenSSL, this could expose us to security issues.

Helped-by: Yue Lin Ho <b8732003@student.nsysu.edu.tw>
Helped-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Jeff Hostetler 2fc1f455b7 msvc: do not pretend to support all signals
This special-cases various signals that are not supported on Windows,
such as SIGPIPE. These cause the UCRT to throw asserts (at least in
debug mode).

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
2019-06-03 22:59:26 +02:00
Philip Oakley 62f84cd4fd msvc: add pragmas for common warnings
MSVC can be overzealous about some warnings. Disable them.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
2019-06-03 22:59:26 +02:00
Jeff Hostetler 4d9345ae3e msvc: fix detect_msys_tty()
The ntstatus.h header is only available in MINGW.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
2019-06-03 22:59:26 +02:00
Jeff Hostetler a3733ebe74 msvc: define ftello()
It is just called differently in MSVC's headers.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Jeff Hostetler 582dcd3de1 msvc: do not re-declare the timespec struct
VS2015's headers already declare that struct.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
2019-06-03 22:59:26 +02:00
Jeff Hostetler 01d6ad1054 msvc: mark a variable as non-const
VS2015 complains when using a const pointer in memcpy()/free().

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
2019-06-03 22:59:26 +02:00
Philip Oakley 660c418ca4 msvc: define O_ACCMODE
This constant is not defined in MSVC's headers.

In UCRT's fcntl.h, _O_RDONLY, _O_WRONLY and _O_RDWR are defined as 0, 1
and 2, respectively. Yes, that means that UCRT breaks with the tradition
that O_RDWR == O_RDONLY | O_WRONLY.

It is a perfectly legal way to define those constants, though, therefore
we need to take care of defining O_ACCMODE accordingly.

This is particularly important in order to keep our "open() can set
errno to EISDIR" emulation working: it tests that (flags & O_ACCMODE) is
not identical to O_RDONLY before going on to test specifically whether
the file for which open() reported EACCES is, in fact, a directory.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Philip Oakley 80863fa0db msvc: include sigset_t definition
On MSVC (VS2008) sigset_t is not defined.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
2019-06-03 22:59:26 +02:00
Johannes Schindelin d44df8c9a5 msvc: fix dependencies of compat/msvc.c
The file compat/msvc.c includes compat/mingw.c, which means that we have
to recompile compat/msvc.o if compat/mingw.c changes.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:26 +02:00
Johannes Schindelin bc0e986220 Merge branch 'stash-p-corner-case'
This topic branch fixes a corner case that is amazingly common in this
developer's workflow: in a `git stash -p`, splitting a hunk and stashing
only part of it runs into a (known) bug where the partial hunk cannot be
applied in reverse.

It is one of those "good enough" fixes, not a full fix, though, as the
full fix would require a 3-way merge between `stash^` and the *worktree*
(not `HEAD`), with `stash` as merge base (i.e. a `git revert`, but on
top of the current worktree).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Johannes Schindelin 9e67d88adc mingw: replace mingw_startup() hack
Git for Windows has special code to retrieve the command-line parameters
(and even the environment) in UTF-16 encoding, so that they can be
converted to UTF-8. This is necessary because Git for Windows wants to
use UTF-8 encoded strings throughout its code, and the main() function
does not get the parameters in that encoding.

To do that, we used the __wgetmainargs() function, which is not even a
Win32 API function, but provided by the MINGW "runtime" instead.

Obviously, this method would not work with any other compiler than GCC,
and in preparation for compiling with Visual C++, we would like to avoid
that.

Lucky us, there is a much more elegant way: we simply implement wmain()
and link with -municode. The command-line parameters are passed to
wmain() encoded in UTF-16, as desired, and this method also works with
Visual C++ after adjusting the MSVC linker flags to force it to use
wmain().

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Johannes Schindelin d74f3ee394 Merge branch 'add-p-in-c-config-settings'
This is the final leg of the journey to a fully built-in `git add`: the
`git add -i` and `git add -p` modes were re-implemented in C, but they
lacked support for a couple of config settings.

The one that sticks out most is the `interactive.singleKey` setting: it
was not only particularly hard to get to work, especially on Windows. It
is also the setting that seems to be incomplete already in the Perl
version: while the name suggests that it applies to the main loop of
`git add --interactive`, or to the file selections in that command, it
does not. Only the `git add --patch` mode respects that setting.

As it is outside the purpose of the conversion of
`git-add--interactive.perl` to C, we will leave that loose end for some
future date.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Johannes Schindelin 770444a2bb obstack: fix compiler warning
MS Visual C suggests that the construct

	condition ? (int) i : (ptrdiff_t) d

is incorrect. Let's fix this by casting to ptrdiff_t also for the
positive arm of the conditional.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Johannes Schindelin 8af7a2842b Merge branch 'other-command-p-in-c'
At this stage on the journey to a fully built-in `git add`, we already
have everything we need, including the `--interactive` and `--patch`
options, as long as the `add.interactive.useBuiltin` setting is set to
`true` (kind of a "turned off feature flag", which it will be for a
while, until we get confident enough that the built-in version does the
job, and retire the Perl script).

However, the internal `add--interactive` helper is also used to back the
`--patch` option of `git stash`, `git reset` and `git checkout`.

This patch series brings them "online".

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Jeff Hostetler 018fb6305f cache-tree.c: avoid reusing the DEBUG constant
In MSVC, the DEBUG constant is set automatically whenever compiling with
debug information.

This is clearly not what was intended in cache-tree.c, so let's use a less
ambiguous constant there.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
2019-06-03 22:59:25 +02:00
Johannes Schindelin 89c0a446a6 t0001 (mingw): do not expect specific order of stdout/stderr
When redirecting stdout/stderr to the same file, we cannot guarantee
that stdout will come first.

In fact, in this test case, it seems that an MSVC build always prints
stderr first.

In any case, this test case does not want to verify the *order* but
the *presence* of both outputs, so let's relax the test a little.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Johannes Schindelin 2452f5f9b8 Mark .bat files as requiring CR/LF endings
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:25 +02:00
Johannes Schindelin 7a65ed051e stash -p: (partially) fix bug concerning split hunks
When trying to stash part of the worktree changes by splitting a hunk
and then only partially accepting the split bits and pieces, the user
is presented with a rather cryptic error:

	error: patch failed: <file>:<line>
	error: test: patch does not apply
	Cannot remove worktree changes

and the command would fail to stash the desired parts of the worktree
changes (even if the `stash` ref was actually updated correctly).

We even have a test case demonstrating that failure, carrying it for
four years already.

The explanation: when splitting a hunk, the changed lines are no longer
separated by more than 3 lines (which is the amount of context lines
Git's diffs use by default), but less than that. So when staging only
part of the diff hunk for stashing, the resulting diff that we want to
apply to the worktree in reverse will contain those changes to be
dropped surrounded by three context lines, but since the diff is
relative to HEAD rather than to the worktree, these context lines will
not match.

Example time. Let's assume that the file README contains these lines:

	We
	the
	people

and the worktree added some lines so that it contains these lines
instead:

	We
	are
	the
	kind
	people

and the user tries to stash the line containing "are", then the command
will internally stage this line to a temporary index file and try to
revert the diff between HEAD and that index file. The diff hunk that
`git stash` tries to revert will look somewhat like this:

	@@ -1776,3 +1776,4
	 We
	+are
	 the
	 people

It is obvious, now, that the trailing context lines overlap with the
part of the original diff hunk that the user did *not* want to stash.

Keeping in mind that context lines in diffs serve the primary purpose of
finding the exact location when the diff does not apply precisely (but
when the exact line number in the file to be patched differs from the
line number indicated in the diff), we work around this by reducing the
amount of context lines: the diff was just generated.

Note: this is not a *full* fix for the issue. Just as demonstrated in
t3701's 'add -p works with pathological context lines' test case, there
are ambiguities in the diff format. It is very rare in practice, of
course, to encounter such repeated lines.

The full solution for such cases would be to replace the approach of
generating a diff from the stash and then applying it in reverse by
emulating `git revert` (i.e. doing a 3-way merge). However, in `git
stash -p` it would not apply to `HEAD` but instead to the worktree,
which makes this non-trivial to implement as long as we also maintain a
scripted version of `add -i`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:24 +02:00
Johannes Schindelin 64ae766f50 Merge branch 'add-p-in-c'
Out of all the patch series on the journey to provide `git add
--interactive` and `git add --patch` in a built-in versions, this is the
big one, as can be expected from the fact that the `git add --patch`
functionality makes up over half of the 1,800+ lines of
`git-add--interactive.perl`.

The two patches that stick out are of course the ones to implement hunk
splitting and hunk editing: these operations are fundamentally more
complicated, and less obvious, than the rest of the operations.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:24 +02:00
Johannes Schindelin b8ffeee25f Merge branch 'add-i-fixes'
While re-implementing `git add -i` and `git add -p` in C, I tried to
make sure that there is test coverage for all of the features I convert
from Perl to C, to give me some confidence in the correctness from
running the test suite both with `GIT_TEST_ADD_I_USE_BUILTIN=true` and
with `GIT_TEST_ADD_I_USE_BUILTIN=false`.

However, I discovered that there are a couple of gaps. This patch series
intends to close them.

The first patch might actually not be considered a gap by some: it
basically removes the need for the `TTY` prerequisite in the `git add
-i` tests to verify that the output is colored all right. This change is
rather crucial for me, though: on Windows, where the conversion to a
built-in shows the most obvious benefits, there are no pseudo terminals
(yet), therefore `git.exe` cannot work with them (even if the MSYS2 Perl
interpreter used by Git for Windows knows about some sort of pty
emulation). And I *really* wanted to make sure that the colors work on
Windows, as I personally get a lot out of those color cues.

The patch series ends by addressing two issues that are not exactly
covering testing gaps:

- While adding a test case, I noticed that `git add -p` exited with
  *success* when it could not even generate a diff. This is so obviously
  wrong that I had to fix it right away (I noticed, actually, because my
  in-progress built-in `git add -p` failed, and the Perl version did
  not), and I used the same test case to verify that this is fixed once
  and for all.

- While working on covering those test gaps, I noticed a problem in an
  early version of the built-in version of `git add -p` where the `git
  apply --allow-overlap` mode failed to work properly, for little
  reason, and I fixed it real quick.

  It would seem that the `--allow-overlap` function is not only
  purposefully under-documented, but also purposefully under-tested,
  probably to discourage its use. I do not quite understand what I
  perceive to be Junio's aversion to that option, but I did not feel
  like I should put up a battle here, so I did not accompany this fix
  with a new test script.

  In the end, the built-in version of `git add -p` does not use the
  `--allow-overlap` function at all, anyway. Which should make everybody
  a lot happier.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:24 +02:00
Johannes Schindelin 8726c508b0 Merge branch 'add-i-in-c-all-except-patch'
This patch series implements the rest of the commands in `git add -i`'s
main loop: `update`, `revert`, `add_untracked`, `patch`, `diff`, and
`quit`. Apart from `quit`, these commands are all very similar in that
they first build a list of files, display it, let the user choose which
ones to act on, and then perform the action.

Note that the `patch` command is not actually converted to C, not
completely at least: the built-in version simply hands off to `git
add--interactive` after letting the user select which files to act on.

The reason for this omission is practicality. Out of the 1,800+ lines of
`git-add--interactive.perl`, over a thousand deal *just* with the `git
add -p` part. I did convert that functionality already (to be
contributed in a separate patch series), discovering that there is so
little overlap between the `git add --patch` part and the rest of `git
add --interactive` that I could put the former into a totally different
file: `add-patch.c`. Just a teaser ;-)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:24 +02:00
Johannes Schindelin ac11fe8abc Merge branch 'add-i-in-c-status-and-help'
The first part of the long journey to a fully built-in `git add -i`.

It reflects the part that was submitted a couple of times (see
https://github.com/gitgitgadget/git/pull/103) during the Outreachy
project by Slavica Đukić that continued the journey based on an initial
patch series by Daniel Ferreira.

This part only implements the `status` and the `help` part, like
Slavica's last iteration did, in the interest of making the review
remotely more reviewable. I fear that this attempt of making it a bit
more reviewable is pretty futile, as so many things changed. So I will
ask the reviewers for forgiveness: please be kind, and give this sort of
a fresh review.

I threw in a couple of major changes on top of that iteration, though:

- The original plan was to add a helper (`git add--helper`) that takes
  over more and more responsibility from the Perl script over the course
  of the conversion.

  This plan is no longer in effect, as I encountered a serious problem
  with that: the MSYS2 runtime used by the Perl interpreter which Git
  for Windows employs to run `git add -i` has a curious bug (that is
  safely outside the purview of this here patch series) where it fails
  to read from standard input after it spawned a non-MSYS2 program that
  reads from standard input. To keep my `git add -i` in a working state,
  I therefore adopted a different strategy:

  Just like `git difftool` was converted by starting with a built-in
  that did nothing but handing off to the scripted version, guarded by
  the (opt-in) `difftool.useBuiltin` config setting, I start this patch
  series by a built-in `add -i` that does nothing else but state that it
  is not implemented yet, guarded by the (opt-in)
  `add.interactive.useBuiltin` config setting.

  In contrast to the `git difftool` situation, it is quite a bit easier
  here, as we do not even have to rename the script to
  `git-legacy-add--interactive.perl`: the `add--interactive` command is
  an implementation detail that users are not even supposed to know
  about. Therefore, we can implement that road fork between the built-in
  and the scripted version in `builtin/add.c`, i.e. in the user-facing
  `git add` command.

  This will also naturally help with the transition to a fully built-in
  `git add -i`/`git add -p`, as we saw with the built-in `git rebase`
  how important it is for end users to have an escape hatch (and for
  that reason, tried our best to provide the same with the built-in `git
  stash`).

- The `help` command was actually not hooked up in `git add -i`, but was
  only available as a special option of the `git add--helper` command.
  As that command no longer exists, I kind of *had* to implement
  some way to let the built-in `git add -i` show the help text.

- The main loop of `git add -i` (i.e. the thing that lets you choose
  `status` or `help`) is now implemented (but only lists `status` and
  `help`, of course), as it makes use of that feature that took the main
  chunk of the Outreachy project: the function to determine unique
  prefixes of a list of strings.

- Speaking of the unique prefixes: the functionality to determine those
  is now encapsulated in the `prefix-map.c` file, and I also added a
  regression test.

- Speaking of the tests: I also implemented support for the environment
  variable `GIT_TEST_ADD_I_USE_BUILTIN`: by setting it, the test suite
  can be forced to use the built-in, or the Perl script, version of `git
  add -i`. Needless to say: by the end of this patch series, running the
  test suite with `GIT_TEST_ADD_I_USE_BUILTIN=true` will still result in
  a ton of test failures due to not-yet-implemented commands, but it
  will also demonstrate what *already* works.

- Since the main loop starts not only by showing the status, but
  refreshes the index before that, I added that, and I actually
  refactored that code into a new function
  (`repo_refresh_and_write_index()`), as it will be used a couple of
  times by the end of the complete conversion of `git add -i` into a
  built-in command.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:24 +02:00
Johannes Schindelin a2afcc18fb ci: include the built-in `git add -i` in the `linux-gcc` job
This job runs the test suite twice, once in regular mode, and once with
a whole slew of `GIT_TEST_*` variables set.

Now that the built-in version of `git add --interactive` is
feature-complete, let's also throw `GIT_TEST_MULTI_PACK_INDEX` into that
fray.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:23 +02:00
Johannes Schindelin 49f24d59f4 built-in stash: use the built-in `git add -p` if so configured
The scripted version of `git stash` called directly into the Perl script
`git-add--interactive.perl`, and this was faithfully converted to C.

However, we have a much better way to do this now: call `git add
--patch=<mode>`, which incidentally also respects the config setting
`add.interactive.useBuiltin`.

Let's do this.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:23 +02:00
Johannes Schindelin 38218480c6 t3904: fix incorrect demonstration of a bug
In 7e9e048661 (stash -p: demonstrate failure of split with mixed y/n,
2015-04-16), a regression test for a known breakage that was added to
the test script `t3904-stash-patch.sh` that demonstrated that splitting
a hunk and trying to stash only part of that split hunk fails (but
shouldn't).

As expected, it still fails, but for the wrong reason: once the bug is
fixed, we would expect stderr to show nothing, yet the regression test
expects stderr to show something.

Let's fix that by telling that regression test case to expect nothing to
be printed to stderr.

While at it, also drop the obvious left-over from debugging where the
regression test did not mind `git stash -p` to return a non-zero exit
status.

Of course, the regression test still fails, but this time for the
correct reason.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:23 +02:00
Johannes Schindelin 0ea33a5875 built-in add -p: handle Escape sequences more efficiently
When `interactive.singlekey = true`, we react immediately to keystrokes,
even to Escape sequences (e.g. when pressing a cursor key).

The problem with Escape sequences is that we do not really know when
they are done, and as a heuristic we poll standard input for half a
second to make sure that we got all of it.

While waiting half a second is not asking for a whole lot, it can become
quite annoying over time, therefore with this patch, we read the
terminal capabilities (if available) and extract known Escape sequences
from there, then stop polling immediately when we detected that the user
pressed a key that generated such a known sequence.

This recapitulates the remaining part of b5cc003253 (add -i: ignore
terminal escape sequences, 2011-05-17).

Note: We do *not* query the terminal capabilities directly. That would
either require a lot of platform-specific code, or it would require
linking to a library such as ncurses.

Linking to a library in the built-ins is something we try very hard to
avoid (we even kicked the libcurl dependency to a non-built-in remote
helper, just to shave off a tiny fraction of a second from Git's startup
time). And the platform-specific code would be a maintenance nightmare.

Even worse: in Git for Windows' case, we would need to query MSYS2
pseudo terminals, which `git.exe` simply cannot do (because it is
intentionally *not* an MSYS2 program).

To address this, we simply spawn `infocmp -L -1` and parse its output
(which works even in Git for Windows, because that helper is included in
the end-user facing installations).

This is done only once, as in the Perl version, but it is done only when
the first Escape sequence is encountered, not upon startup of `git add
-i`; This saves on startup time, yet makes reacting to the first Escape
sequence slightly more sluggish. But it allows us to keep the
terminal-related code encapsulated in the `compat/terminal.c` file.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:23 +02:00
Johannes Schindelin a5eac709b2 commit --interactive: make it work with the built-in `add -i`
The built-in `git add -i` machinery obviously has its `the_repository`
structure initialized at the point where `cmd_commit()` calls it, and
therefore does not look at the environment variable `GIT_INDEX_FILE`.

But it has to, because the index was already locked, and we want to ask
the interactive add machinery to work on the `index.lock` file instead
of the `index` file.

Technically, we could teach `run_add_i()` (and `run_add_p()`) to look
specifically at that environment variable, but the entire idea of
passing in a parameter of type `struct repository *` is to allow working
on multiple repositories (and their index files) independently.

So let's instead override the `index_file` field of that structure
temporarily.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:23 +02:00
Johannes Schindelin 400d6dc517 built-in add -p: handle Escape sequences in interactive.singlekey mode
This recapitulates part of b5cc003253 (add -i: ignore terminal escape
sequences, 2011-05-17):

    add -i: ignore terminal escape sequences

    On the author's terminal, the up-arrow input sequence is ^[[A, and
    thus fat-fingering an up-arrow into 'git checkout -p' is quite
    dangerous: git-add--interactive.perl will ignore the ^[ and [
    characters and happily treat A as "discard everything".

    As a band-aid fix, use Term::Cap to get all terminal capabilities.
    Then use the heuristic that any capability value that starts with ^[
    (i.e., \e in perl) must be a key input sequence.  Finally, given an
    input that starts with ^[, read more characters until we have read a
    full escape sequence, then return that to the caller.  We use a
    timeout of 0.5 seconds on the subsequent reads to avoid getting stuck
    if the user actually input a lone ^[.

    Since none of the currently recognized keys start with ^[, the net
    result is that the sequence as a whole will be ignored and the help
    displayed.

Note that we leave part for later which uses "Term::Cap to get all
terminal capabilities", for several reasons:

1. it is actually not really necessary, as the timeout of 0.5 seconds
   should be plenty sufficient to catch Escape sequences,

2. it is cleaner to keep the change to special-case Escape sequences
   separate from the change that reads all terminal capabilities to
   speed things up, and

3. in practice, relying on the terminal capabilities is a bit overrated,
   as the information could be incomplete, or plain wrong. For example,
   in this developer's tmux sessions, the terminal capabilities claim
   that the "cursor up" sequence is ^[M, but the actual sequence
   produced by the "cursor up" key is ^[[A.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-06-03 22:59:23 +02:00