Commit Graph

97372 Commits

Author SHA1 Message Date
Johannes Schindelin
30bd97c01f mingw: demonstrate that all file handles are inherited by child processes
When spawning child processes, we really should be careful which file
handles we let them inherit.

This is doubly important on Windows, where we cannot rename, delete, or
modify files if there is still a file handle open.

Sadly, we have to guard this test inside #ifdef WIN32: we need to use
the value of the HANDLE directly, and that concept does not exist on
Linux/Unix.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:52 +02:00
Johannes Schindelin
d74aea3590 Merge branch 'address-coverity-reports'
Coverity pointed out a couple of bugs, and here are fixes for some of
them.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:42 +02:00
Johannes Schindelin
c9e71d9960 Merge pull request #2185 from dscho/fix-status-with-rebase-ir
Fix `git status`' display of `git rebase -ir`'s `label` commands
2019-05-13 22:56:42 +02:00
Johannes Schindelin
5cdba4600a Merge pull request #2127 from dscho/fix-fsmonitor
Do query the fsmonitor again after the index has been discarded
2019-05-13 22:56:42 +02:00
Johannes Schindelin
b6121bfd61 Merge branch 'difftool-no-index-extra'
This patch addresses the segmentation faults in `git difftool --no-index
--dir-diff`: surprisingly, those two options don't make no sense
together.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:41 +02:00
Johannes Schindelin
32735d7932 Merge branch 'difftool-no-index'
This fixes https://github.com/git-for-windows/git/issues/2123

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:41 +02:00
Johannes Schindelin
be6f5eb57f Merge pull request #2121 from dscho/fix-rereading-todo-list
rebase -i: fix re-reading the todo list when newly created objects are referenced
2019-05-13 22:56:41 +02:00
Johannes Schindelin
eb62c912ff Merge pull request #2182 from dscho/untracked-cache-off-by-one
Backport "untracked cache: fix off-by-one"
2019-05-13 22:56:41 +02:00
Johannes Schindelin
ebd23acd6e Merge pull request #2170 from dscho/gitk-long-cmdline
Fix gitk (long cmdline)
2019-05-13 22:56:41 +02:00
Johannes Schindelin
8100cee16c Merge pull request #2180 from dscho/t6500-and-msys2-runtime-v3.x
Prepare the gc tests for v3.x of the MSYS2 runtime
2019-05-13 22:56:40 +02:00
Johannes Schindelin
3badbc69dc Merge pull request #2160 from dscho/skip-t9822-on-apfs-gfw
Prepare our git-p4 tests for running on APFS; This is necessary to fix the CI builds since Azure Pipelines' macOS agents were upgraded to Mojave.
2019-05-13 22:56:40 +02:00
Johannes Schindelin
e8a8f2861d Merge pull request #2115 from dscho/gfw/msys2-3.x
mingw: allow building with an MSYS2 runtime v3.x
2019-05-13 22:56:40 +02:00
Johannes Schindelin
1ec6757da2 Merge pull request #2111 from gitgitgadget/jk/no-sigpipe-during-network-transport
Fix t5570 flakiness on macOS
2019-05-13 22:56:40 +02:00
Johannes Schindelin
269ac52c38 Merge pull request #2110 from dscho/avoid-find-in-makefile
Accelerate startup time of `make`
2019-05-13 22:56:40 +02:00
Johannes Schindelin
e7e650ed96 Merge pull request #2112 from dscho/gfw/rebase-am-and-orig-head
built-in rebase: pick up the ORIG_HEAD fix early
2019-05-13 22:56:39 +02:00
Johannes Schindelin
e0e6c1533f Merge pull request #2101 from yashb5/typo-gitattributes
gitattributes.txt: fix typo
2019-05-13 22:56:39 +02:00
Johannes Schindelin
011074d690 Merge branch 'fsync-object-files-always'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:39 +02:00
Johannes Schindelin
b4d4224333 Merge branch 'spawn-with-spaces'
This topic branch conflicts with the next change that will change the
way we call `CreateProcessW()`. So let's merge it early, to avoid merge
conflicts during a merge (because we would have to resolve this with
every single merging-rebase).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:39 +02:00
Johannes Schindelin
936dedab34 Merge branch 'clean-long-paths'
This addresses https://github.com/git-for-windows/git/issues/521

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:39 +02:00
Johannes Schindelin
bfd75434a2 Merge branch 'mingw-home'
The environment variable `HOME` is not exactly a native concept on
Windows, but Git and its scripts rely heavily on it. Make sure that it
is set (using a default that is sensible in most cases, and can easily
be overridden by setting the user-wide environment variable `HOME`
explicitly, before starting Git).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:38 +02:00
Johannes Schindelin
97d076fbdf Merge branch 'gettext-force-utf-8-on-windows'
The idea of the C runtime on Windows as to what a locale is does not
mesh well with the idea Git has. So let's just ignore the C runtime.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:38 +02:00
Johannes Schindelin
6e18964f7e Merge branch 'mingw-avoid-illegal-filenames'
MSYS2 inherits the trick from Cygwin to pretend that filenames can
contain characters that are illegal on Windows (by mapping them to a
private Unicode page). As long as we stay safely within the MSYS2 realm
(Bash, GNU make, Perl) that is fine, so technically this change is not
needed. But it is a lot more elegant not to rely on this.

Besides, the suffix `.new` is a lot more intuitive than the suffix
`+`...

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:38 +02:00
Johannes Schindelin
2f6a9a6410 Merge branch 'mingw-stack-smashing-protector'
This is GCC's attempt at making things less predictable and thereby
reduce the attack surface for malware.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:38 +02:00
Johannes Schindelin
fe4dab9615 Merge branch 'mingw-manifest'
Windows executables can be configured to make use of certain Windows
features only via a so-called "manifest", i.e. a specific, embedded
resource. This manifest is also necessary to determine the Windows
version reliably.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:38 +02:00
Johannes Schindelin
5821566185 Merge branch 'msys2-htmldir'
Git for Windows ships with a subset of MSYS2, and tries to integrate
smoothly, so we want to install the documentation in the location that
is recommended by MSYS2.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:38 +02:00
Johannes Schindelin
900e2ef83f Merge branch 'munmap-before-ext-diff'
This topic branch fixes the usage pattern where files are still held
open with an exclusive lock when an external program is asked to open
those very same files.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:37 +02:00
Johannes Schindelin
7089566306 Merge pull request #1958 from dscho/ansi-unicode
mingw: safeguard against compiling with `-DUNICODE`
2019-05-13 22:56:37 +02:00
Johannes Schindelin
e60be5146f Merge branch 'program-data-config'
This branch introduces support for reading the "Windows-wide" Git
configuration from `%PROGRAMDATA%\Git\config`. As these settings are
intended to be shared between *all* Git-related software, that config
file takes an even lower precedence than `$(prefix)/etc/gitconfig`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:37 +02:00
Johannes Schindelin
e9e9d75d5a Merge branch 'no-perl-makemaker'
We no longer use MakeMaker, so let's not state in the MINGW section that
we do not want to use it...

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:37 +02:00
Johannes Schindelin
9d66e0812c Merge pull request #2148 from dscho/azure-pipelines-msvc
Let the MSVC build also be tested in the Azure Pipeline
2019-05-13 22:56:37 +02:00
Jeff Hostetler
b4c0acce65 Merge branch 'visual-studio'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:36 +02:00
Jeff Hostetler
1169e1e82d Merge branch 'msvc'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:36 +02:00
Johannes Schindelin
573dbb132b Merge remote-tracking branch 'dscho/add-p' into add-p-g4w
Let's test this for a while.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:36 +02:00
Johannes Schindelin
b279b3a1b2 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-05-13 22:56:28 +02:00
Johannes Schindelin
e5f6204b71 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-05-13 22:56:28 +02:00
Johannes Schindelin
10b1eb3538 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-05-13 22:56:28 +02:00
Johannes Schindelin
67bcd45de1 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-05-13 22:56:28 +02:00
Johannes Schindelin
e8650dcef5 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-05-13 22:56:27 +02:00
Johannes Schindelin
01f25b9d01 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-05-13 22:56:27 +02:00
Johannes Schindelin
7e033a8853 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-05-13 22:56:27 +02:00
Johannes Schindelin
f22d698853 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-05-13 22:56:27 +02:00
Johannes Schindelin
c4832c4af3 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-05-13 22:56:27 +02:00
Johannes Schindelin
2efc3ff1cd built-in add -p: respect the interactive.singlekey config setting
The Perl version of `git add -p` supports this config setting to allow
users to input commands via single characters (as opposed to having to
press the <Enter> key afterwards).

This is an opt-in feature because it requires Perl packages
(Term::ReadKey and Term::Cap, where it tries to handle an absence of the
latter package gracefully) to work. Note that at least on Ubuntu, that
Perl package is not installed by default (it needs to be installed via
`sudo apt-get install libterm-readkey-perl`), so this feature is
probably not used a whole lot.

In C, we obviously do not have these packages available, but we just
introduced `read_single_keystroke()` that is similar to what
Term::ReadKey provides, and we use that here.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:27 +02:00
Johannes Schindelin
52a7357351 terminal: add a new function to read a single keystroke
Typically, input on the command-line is line-based. It is actually not
really easy to get single characters (or better put: keystrokes).

We provide two implementations here:

- One that handles `/dev/tty` based systems as well as native Windows.
  The former uses the `tcsetattr()` function to put the terminal into
  "raw mode", which allows us to read individual keystrokes, one by one.
  The latter uses `stty.exe` to do the same, falling back to direct
  Win32 Console access.

  Thanks to the refactoring leading up to this commit, this is a single
  function, with the platform-specific details hidden away in
  conditionally-compiled code blocks.

- A fall-back which simply punts and reads back an entire line.

Note that the function writes the keystroke into an `strbuf` rather than
a `char`, in preparation for reading Escape sequences (e.g. when the
user hit an arrow key). This is also required for UTF-8 sequences in
case the keystroke corresponds to a non-ASCII letter.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:27 +02:00
Johannes Schindelin
a9cf0d89db terminal: accommodate Git for Windows' default terminal
Git for Windows' Git Bash runs in MinTTY by default, which does not have
a Win32 Console instance, but uses MSYS2 pseudo terminals instead.

This is a problem, as Git for Windows does not want to use the MSYS2
emulation layer for Git itself, and therefore has no direct way to
interact with that pseudo terminal.

As a workaround, use the `stty` utility (which is included in Git for
Windows, and which *is* an MSYS2 program, so it knows how to deal with
the pseudo terminal).

Note: If Git runs in a regular CMD or PowerShell window, there *is* a
regular Win32 Console to work with. This is not a problem for the MSYS2
`stty`: it copes with this scenario just fine.

Also note that we introduce support for more bits than would be
necessary for a mere `disable_echo()` here, in preparation for the
upcoming `enable_non_canonical()` function.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:27 +02:00
Johannes Schindelin
2f51f7fe52 terminal: make the code of disable_echo() reusable
We are about to introduce the function `enable_non_canonical()`, which
shares almost the complete code with `disable_echo()`.

Let's prepare for that, by refactoring out that shared code.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:27 +02:00
Johannes Schindelin
32b56d5a81 built-in add -p: handle diff.algorithm
The Perl version of `git add -p` reads the config setting
`diff.algorithm` and if set, uses it to generate the diff using the
specified algorithm.

This patch ports that functionality to the C version.

To make sure that this works as intended, we add a regression test case
that tries to specify a bogus diff algorithm and then verifies that `git
diff-files` produced the expected error message.

Note: In that new test case, we actually ignore the exit code of `git
add -p`. The reason is that the C version exits with failure (as one
might expect), but the Perl version does not.

In fact, the Perl version continues happily after the uncolored diff
failed, trying to generate the colored diff, still not catching the
problem, and then it pretends to have succeeded (with exit code 0).

This is arguably a bug in the Perl version, and fixing it is safely
outside the scope of this patch.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:27 +02:00
Johannes Schindelin
88d5e66079 built-in add -p: support interactive.diffFilter
The Perl version supports post-processing the colored diff (that is
generated in addition to the uncolored diff, intended to offer a
prettier user experience) by a command configured via that config
setting, and now the built-in version does that, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:56:27 +02:00
Johannes Schindelin
f780dae1d3 Merge pull request #2119 from dscho/update-stash-to-current
Update the built-in `git stash` to the latest version
2019-05-13 22:36:56 +02:00
Johannes Schindelin
bd5938339b Merge branch 'dont-spawn-gzip-in-archive'
This topic branch avoids spawning `gzip` when asking `git archive` to
create `.tar.gz` files.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-05-13 22:36:56 +02:00