Commit Graph

69585 Commits

Author SHA1 Message Date
Johannes Schindelin
b41fd4c3a1 gettext: avoid initialization if the locale dir is not present
The runtime of a simple `git.exe version` call on Windows is currently
dominated by the gettext setup, adding a whopping ~150ms to the ~210ms
total.

Given that this cost is added to each and every git.exe invocation goes
through common-main's invocation of git_setup_gettext(), and given that
scripts have to call git.exe dozens, if not hundreds, of times, this is
a substantial performance penalty.

This is particularly pointless when considering that Git for Windows
ships without localization (to keep the installer's size to a bearable
~34MB): all that time setting up gettext is for naught.

So let's be smart about it and skip setting up gettext if the locale
directory is not even present.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-15 12:09:43 +01:00
Johannes Schindelin
0b81bf408c gettext: use a GIT_LOCALE_PATH relative to $(prefix)
On Windows, we simply pass a POSIX path to bindtextdomain(), relying on
the current libintl-8.dll implementation to handle that gracefully by
resolving the path relative to the "root" directory inferred from the
location of the .dll file itself.

However, not only does this rely on the custom patches of the gettext
library as shipped with MSYS2 (gettext's own source code is not prepared
to handle POSIX paths on Windows), it also means that Git itself cannot
use the `podir` variable at all because it does not handle absolute
POSIX paths in system_path() correctly, leaving them as-is.

This patch fixes that behavior by always using a GIT_LOCALE_PATH
relative to the (runtime) prefix.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-15 12:09:42 +01:00
Johannes Schindelin
15edb002c6 gettext: handle GIT_TEXTDOMAINDIR relative to $(prefix)
On Windows, there is no single root directory. And what Git thinks is a
root directory is not a root directory at all: everything is relative to
the location where Git is installed.

To handle this situation better, let's just allow for GIT_TEXTDOMAINDIR
to be a path relative to the (runtime) prefix.

To that end, we have to switch the order in which common-main handles
argv0 and sets up gettext: in order to have access to the runtime
prefix, we need it to be inferred from argv0 already.

This patch also prepares for GIT_LOCALE_PATH to be relative to prefix,
which is the even more important fix.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-15 12:09:42 +01:00
Johannes Schindelin
599fd1d4ab fixup! mingw: remove 248-char limit when creating directories
Actually, this commit was totally misguided. The path length limit for
non-long paths (at least before Windows 10 build 1067 with long paths
opted in) *is* 248, and we still want to convert to Root Local Device
Path if that limit is reached.

I misread the intention of the code when I made that patch to "remove
the 248-char limit", thinking that there was a hard limit to 248
characters even in the long path case, which was incorrect.

Simply revert that commit and be done.

This fixes https://github.com/git-for-windows/git/issues/1084

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-10 15:53:36 +01:00
Johannes Schindelin
94dafc3b12 fixup! test-strcmp-offset: created test for strcmp_offset 2017-03-03 17:19:22 +01:00
Johannes Schindelin
7503ca808a fixup! git: avoid calling aliased builtins via their dashed form
When copy-pasting from execv_dashed_external(), the array index was
left unchanged even if we now have an array with `git` shifted in.

Instead of adjusting the array index, simply use the original array.

While at it, also reorder the loop until after the potential early
exit.

Pointed out by Akinori Hattori in

https://github.com/git-for-windows/git/issues/1077#issuecomment-283905530

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-03 17:05:08 +01:00
Johannes Schindelin
ce4c6ca554 mingw: fix isatty() after dup2()
We newly handle isatty() by special-casing the stdin/stdout/stderr file
descriptors, caching the return value. However, we missed the case where
dup2() overrides the respective file descriptor.

That poses a problem e.g. where the `show` builtin asks for a pager very
early, the `setup_pager()` function sets the pager depending on the
return value of `isatty()` and then redirects stdout. Subsequently,
`cmd_log_init_finish()` calls `setup_pager()` *again*. What should
happen now is that `isatty()` reports that stdout is *not* a TTY and
consequently stdout should be left alone.

Let's override dup2() to handle this appropriately.

This fixes https://github.com/git-for-windows/git/issues/1077

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-02 16:01:21 +01:00
Johannes Schindelin
eaae98ef59 fixup! msvc: convert environment from/to UTF-16 on the fly
Note: make_environment_block()'s code is a little tricky, as the same
deltaenv may very well add *and* remove the same variable.

This patch fixes t7814 when building with MSVC. The breakage was
reported by Ben Peart.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-03-01 01:27:43 +01:00
Johannes Schindelin
8a117c4824 Merge branch 'emptyauth-auto-fixup'
Let's go with the version that made it into upstream Git's `pu` branch.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-28 11:14:26 +01:00
Jeff King
8fd79507b8 http: add an "auto" mode for http.emptyauth
This variable needs to be specified to make some types of
non-basic authentication work, but ideally this would just
work out of the box for everyone.

However, simply setting it to "1" by default introduces an
extra round-trip for cases where it _isn't_ useful. We end
up sending a bogus empty credential that the server rejects.

Instead, let's introduce an automatic mode, that works like
this:

  1. We won't try to send the bogus credential on the first
     request. We'll wait to get an HTTP 401, as usual.

  2. After seeing an HTTP 401, the empty-auth hack will kick
     in only when we know there is an auth method available
     that might make use of it (i.e., something besides
     "Basic" or "Digest").

That should make it work out of the box, without incurring
any extra round-trips for people hitting Basic-only servers.

This _does_ incur an extra round-trip if you really want to
use "Basic" but your server advertises other methods (the
emptyauth hack will kick in but fail, and then Git will
actually ask for a password).

The auto mode may incur an extra round-trip over setting
http.emptyauth=true, because part of the emptyauth hack is
to feed this blank password to curl even before we've made a
single request.

Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-28 11:12:59 +01:00
Johannes Schindelin
5056380c32 fixup! http: add an "auto" mode for http.emptyauth
In preparation of picking the patch that *actually* made it into
upstream's `pu` branch, let's revert the previous version along with the
proposed fixup.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-28 11:11:05 +01:00
Johannes Schindelin
d4baef1cdf Merge branch 'emptyauth-auto'
An earlier attempt to support NTLM authentication better (by setting
http.emptyauth=true always) failed to take into account that some
servers that support only Basic authentication may be very unhappy
about those "empty credentials".

Jeff King came up with a beautiful fix; this topic branch reverts our
earlier attempt at fixing the problem and applies those patches
instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 12:57:03 +01:00
Johannes Schindelin
44ae0bcae5 fixup! http: add an "auto" mode for http.emptyauth
Note: we keep a "black list" of authentication methods for which we do
not want to enable http.emptyAuth automatically. A white list would be
nicer, but less robust, as we want to support linking to several cURL
versions and the list of authentication methods (as well as their names)
changed over time.

[jes: actually added the "auto" handling, excluded Digest, too]

This fixes https://github.com/git-for-windows/git/issues/1034

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 12:35:59 +01:00
Jeff King
0f93447a1c http: add an "auto" mode for http.emptyauth
This variable needs to be specified to make some types of
non-basic authentication work, but ideally this would just
work out of the box for everyone.

However, simply setting it to "1" by default introduces an
extra round-trip for cases where it _isn't_ useful. We end
up sending a bogus empty credential that the server rejects.

Instead, let's introduce an automatic mode, that works like
this:

  1. We won't try to send the bogus credential on the first
     request. We'll wait to get an HTTP 401, as usual.

  2. After seeing an HTTP 401, the empty-auth hack will kick
     in only when we know there is an auth method beyond
     "Basic" to be tried.

That should make it work out of the box, without incurring
any extra round-trips for people hitting Basic-only servers.

This _does_ incur an extra round-trip if you really want to
use "Basic" but your server advertises other methods (the
emptyauth hack will kick in but fail, and then Git will
actually ask for a password).

The auto mode may incur an extra round-trip over setting
http.emptyauth=true, because part of the emptyauth hack is
to feed this blank password to curl even before we've made a
single request.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 12:35:09 +01:00
Jeff King
4574329e16 http: restrict auth methods to what the server advertises
By default, we tell curl to use CURLAUTH_ANY, which does not
limit its set of auth methods. However, this results in an
extra round-trip to the server when authentication is
required. After we've fed the credential to curl, it wants
to probe the server to find its list of available methods
before sending an Authorization header.

We can shortcut this by limiting our http_auth_methods by
what the server told us it supports. In some cases (such as
when the server only supports Basic), that lets curl skip
the extra probe request.

The end result should look the same to the user, but you can
use GIT_TRACE_CURL to verify the sequence of requests:

  GIT_TRACE_CURL=1 \
  git ls-remote https://example.com/repo.git \
  2>&1 >/dev/null |
  egrep '(Send|Recv) header: (GET|HTTP|Auth)'

Before this patch, hitting a Basic-only server like
github.com results in:

  Send header: GET /repo.git/info/refs?service=git-upload-pack HTTP/1.1
  Recv header: HTTP/1.1 401 Authorization Required
  Send header: GET /repo.git/info/refs?service=git-upload-pack HTTP/1.1
  Recv header: HTTP/1.1 401 Authorization Required
  Send header: GET /repo.git/info/refs?service=git-upload-pack HTTP/1.1
  Send header: Authorization: Basic <redacted>
  Recv header: HTTP/1.1 200 OK

And after:

  Send header: GET /repo.git/info/refs?service=git-upload-pack HTTP/1.1
  Recv header: HTTP/1.1 401 Authorization Required
  Send header: GET /repo.git/info/refs?service=git-upload-pack HTTP/1.1
  Send header: Authorization: Basic <redacted>
  Recv header: HTTP/1.1 200 OK

The possible downsides are:

  - This only helps for a Basic-only server; for a server
    with multiple auth options, curl may still send a probe
    request to see which ones are available (IOW, there's no
    way to say "don't probe, I already know what the server
    will say").

  - The http_auth_methods variable is global, so this will
    apply to all further requests. That's acceptable for
    Git's usage of curl, though, which also treats the
    credentials as global. I.e., in any given program
    invocation we hit only one conceptual server (we may be
    redirected at the outset, but in that case that's whose
    auth_avail field we'd see).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 12:34:49 +01:00
Johannes Schindelin
e2905f4a84 Revert "http(s): automatically try NTLM authentication first"
Turning on http.emptyAuth globally turned out to cause a regression
in case of some servers that support Basic authentication but do not
respond with *yet* another 401 upon receiving the empty user/password:

	https://github.com/git-for-windows/git/issues/1034

Jeff King came up with a superior approach. Let's revert our change in
preparation for including those patches.

This reverts commit de4b3c5efa.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 12:31:54 +01:00
Johannes Schindelin
ed710b967b Merge branch 'dup-gui' of PhilipOakley/git-gui.git
This resolves a couple of Git GUI issues that seem not to have been
picked up from https://github.com/patthoyts/git-gui/pull/10 yet.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:38 +01:00
Johannes Schindelin
be501cc541 Merge branch 'strg-t-in-git-gui'
This does not (yet) resolve the problem that Strg+T with multiple
selected lines fails to (un)stage them all, but it addresses one of
the reported Ctrl+T issues.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:37 +01:00
Philip Oakley
efc9cb5ed4 git gui: allow for a long recentrepo list
The gui.recentrepo list may be longer than the maxrecent setting.
Allow extra space to show any extra entries.

In an ideal world, the git gui would limit the number of entries
to the maxrecent setting, however the recentrepo config list may
have been extended outwith the gui, or the maxrecent setting changed
to a reduced value. Further, when testing the gui's recentrepo
logic it is useful to show these extra, but valid, entries.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
2017-02-25 06:52:36 +01:00
Philip Oakley
03bf5f504f git gui: de-dup selected repo from recentrepo history
When the gui/user selects a repo for display, that repo is brought to
the end of the recentrepo config list. The logic can fail if there are
duplicate old entries for the repo (you cannot unset a single config
entry when duplicates are present).

Similarly, the maxrecentrepo logic could fail if older duplicate entries
are present.

The first commit of this series ({this}~2) fixed the config unsetting
issue. Rather than manipulating a local copy of the $recent list (one
cannot know how many entries were removed), simply re-read it.

We must also catch the error when the attempt to remove the second copy
from the re-read list is performed.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
2017-02-25 06:52:34 +01:00
Philip Oakley
77a74bfc46 git gui: cope with duplicates in _get_recentrepo
_get_recentrepo will fail if duplicate invalid entries are present
in the recentrepo config list. The previous commit fixed the
'git config' limitations in _unset_recentrepo by unsetting all config
entries, however this code would fail on the second attempt to unset it.

Refactor the code to pre-sort and de-duplicate the recentrepo list to
avoid a potential second unset attempt.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
2017-02-25 06:52:33 +01:00
Philip Oakley
2641bc7a0f git-gui: remove duplicate entries from .gitconfig's gui.recentrepo
The git gui's recent repo list may become contaminated with duplicate
entries. The git gui would barf when attempting to remove one entry.
Remove them all - there is no option within 'git config' to selectively
remove one of the entries.

This issue was reported on the 'Git User' list
(https://groups.google.com/forum/#!topic/git-users/msev4KsQGFc,
Warning: gui.recentrepo has multiply values while executing).

And also by zosrothko as a Git-for-Windows issue
https://github.com/git-for-windows/git/issues/1014.

On startup the gui checks that entries in the recentrepo list are still
valid repos and deletes thoses that are not. If duplicate entries are
present the 'git config --unset' will barf and this prevents the gui
from starting.

Subsequent patches fix other parts of recentrepo logic used for syncing
internal lists with the external .gitconfig.

Reported-by: Alexey Astakhov <asstv7@gmail.com>
Signed-off-by: Philip Oakley <philipoakley@iee.org>
2017-02-25 06:52:32 +01:00
Johannes Schindelin
d36c60e4af git-gui: avoid exception upon Ctrl+T in an empty list
Previously unstaged files can be staged by clicking on them and then
pressing Ctrl+T. Conveniently, the next unstaged file is selected
automatically so that the unstaged files can be staged by repeatedly
pressing Ctrl+T.

When a user hits Ctrl+T one time too many, though, Git GUI used to throw
this exception:

	expected number but got ""
	expected number but got ""
	    while executing
	"expr {int([lindex [$w tag ranges in_diff] 0])}"
	    (procedure "toggle_or_diff" line 13)
	    invoked from within
	"toggle_or_diff toggle .vpane.files.workdir.list "
	    (command bound to event)

Let's just avoid that by skipping the operation when there are no more
files to stage.

This fixes https://github.com/git-for-windows/git/issues/1060

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:30 +01:00
Johannes Schindelin
67987948c6 mingw: make is_hidden tests in t0001/t5611 more robust
We should not actually expect the first `attrib.exe` in the PATH to
be the one we are looking for. Or that it is in the PATH, for that
matter.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:29 +01:00
Johannes Schindelin
1869af5c4f mingw: ensure valid CTYPE
A change between versions 2.4.1 and 2.6.0 of the MSYS2 runtime modified
how Cygwin's runtime (and hence Git for Windows' MSYS2 runtime
derivative) handles locales: d16a56306d (Consolidate wctomb/mbtowc calls
for POSIX-1.2008, 2016-07-20).

An unintended side-effect is that "cold-calling" into the POSIX
emulation will start with a locale based on the current code page,
something that Git for Windows is very ill-prepared for, as it expects
to be able to pass a command-line containing non-ASCII characters to the
shell without having those characters munged.

One symptom of this behavior: when `git clone` or `git fetch` shell out
to call `git-upload-pack` with a path that contains non-ASCII
characters, the shell tried to interpret the entire command-line
(including command-line parameters) as executable path, which obviously
must fail.

This fixes https://github.com/git-for-windows/git/issues/1036

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:29 +01:00
Johannes Schindelin
e2c9203b8c Merge pull request #994 from jeffhostetler/jeffhostetler/fscache_nfd
fscache: add not-found directory cache to fscache
2017-02-25 06:52:29 +01:00
Johannes Schindelin
f0dde54029 Merge pull request #1032 from max630/gitgui_GIT_GIT_unset
git-gui: correctly restore GIT_DIR after invoking commands
2017-02-25 06:52:28 +01:00
Johannes Schindelin
529a27cdfb Merge branch 'test-unc-alternates'
The fix we introduced in Git for Windows will be made obsolete by a more
general fix that has been already accepted into upstream Git's `next`
branch.

But we still can introduce a regression test that verifies that this bug
will be caught very quickly, if reintroduced.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:27 +01:00
Johannes Schindelin
a6505b77e0 fscache: add a test for the dir-not-found optimization
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:26 +01:00
Jeff Hostetler
f793665392 fscache: remember not-found directories
Teach FSCACHE to remember "not found" directories.

This is a performance optimization.

FSCACHE is a performance optimization available for Windows.  It
intercepts Posix-style lstat() calls into an in-memory directory
using FindFirst/FindNext.  It improves performance on Windows by
catching the first lstat() call in a directory, using FindFirst/
FindNext to read the list of files (and attribute data) for the
entire directory into the cache, and short-cut subsequent lstat()
calls in the same directory.  This gives a major performance
boost on Windows.

However, it does not remember "not found" directories.  When STATUS
runs and there are missing directories, the lstat() interception
fails to find the parent directory and simply return ENOENT for the
file -- it does not remember that the FindFirst on the directory
failed. Thus subsequent lstat() calls in the same directory, each
re-attempt the FindFirst.  This completely defeats any performance
gains.

This can be seen by doing a sparse-checkout on a large repo and
then doing a read-tree to reset the skip-worktree bits and then
running status.

This change reduced status times for my very large repo by 60%.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:26 +01:00
Jeff Hostetler
3ae2954f0a fscache: add key for GIT_TRACE_FSCACHE
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:25 +01:00
Johannes Schindelin
bc0c34a778 Merge branch 'long-paths'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:25 +01:00
Max Kirillov
dfd475760a git-gui: correctly restore GIT_DIR after invoking gitk
git-gui tries to temporary set GIT_DIR for starting gitk and restore
it back after they are started. But in case of GIT_DIR which was not set
prior to invocation it is not unset after it. This affects commands
which can be later started from that git gui, for example "Git Bash".

Fix it.

Signed-off-by: Max Kirillov <max@max630.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:24 +01:00
Johannes Schindelin
97109377fe Merge branch 'git-gui'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:23 +01:00
Johannes Schindelin
c9edcf21f5 t5580: verify that alternates can be UNC paths
On Windows, UNC paths are a very convenient way to share data, and
alternates are all about sharing data.

We fixed a bug where alternates specifying UNC paths were not handled
properly, and it is high time that we add a regression test to ensure
that this bug is not reintroduced.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:22 +01:00
Johannes Schindelin
a21a527f71 t9001: work around hard-to-debug hangs
Just like the workaround we added for t9116, t9001.83 hangs sometimes --
but not always! -- when being run in the Git for Windows SDK.

The issue seems to be related to redirection via a pipe, but it is really
hard to diagnose, what with git.exe (a non-MSYS2 program) calling a Perl
script (which is executed by an MSYS2 Perl), piping into another MSYS2
program.

As hunting time is scarce these days, simply work around this for now and
leave the real diagnosis and resolution for later.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:21 +01:00
Johannes Schindelin
3ad715ab92 t9116: work around hard-to-debug hangs
As of a couple of weeks ago, t9116 hangs sometimes -- but not always! --
when being run in the Git for Windows SDK.

The issue seems to be related to redirection via a pipe, but it is really
hard to diagnose, what with git.exe (a non-MSYS2 program) calling a Perl
script (which is executed by an MSYS2 Perl), piping into another MSYS2
program.

As hunting time is scarce these days, simply work around this for now and
leave the real diagnosis and resolution for later.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:21 +01:00
Johannes Schindelin
f6aec09365 Merge branch 'interactive-rebase-current'
This series of branches introduces the git-rebase--helper, a builtin
helping to accelerate the interactive rebase dramatically.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:21 +01:00
Johannes Schindelin
83a668dcb8 Merge pull request #1006 from segevfiner/git-ssh-command-putty
connect: recognize [tortoise]plink in GIT_SSH_COMMAND
2017-02-25 06:52:19 +01:00
Johannes Schindelin
a0e7c895f0 Merge 'rebase-i-extra' into HEAD 2017-02-25 06:52:18 +01:00
Johannes Schindelin
f12c2cb9ef Merge 'rebase--helper' into HEAD 2017-02-25 06:52:17 +01:00
Johannes Schindelin
4bf13ccdf9 rebase -i: rearrange fixup/squash lines using the rebase--helper
This operation has quadratic complexity, which is especially painful
on Windows, where shell scripts are *already* slow (mainly due to the
overhead of the POSIX emulation layer).

Let's reimplement this with linear complexity (using a hash map to
match the commits' subject lines) for the common case; Sadly, the
fixup/squash feature's design neglected performance considerations,
allowing arbitrary prefixes (read: `fixup! hell` will match the
commit subject `hello world`), which means that we are stuck with
quadratic performance in the worst case.

The reimplemented logic also happens to fix a bug where commented-out
lines (representing empty patches) were dropped by the previous code.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:15 +01:00
Johannes Schindelin
3548685edd t3415: test fixup with wrapped oneline
The `git commit --fixup` command unwraps wrapped onelines when
constructing the commit message, without wrapping the result.

We need to make sure that `git rebase --autosquash` keeps handling such
cases correctly, in particular since we are about to move the autosquash
handling into the rebase--helper.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:15 +01:00
Johannes Schindelin
813e1b1237 rebase -i: skip unnecessary picks using the rebase--helper
In particular on Windows, where shell scripts are even more expensive
than on MacOSX or Linux, it makes sense to move a loop that forks
Git at least once for every line in the todo list into a builtin.

Note: The original code did not try to skip unnecessary picks of root
commits but punts instead (probably --root was not considered common
enough of a use case to bother optimizing). We do the same, for now.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:15 +01:00
Johannes Schindelin
8de55809b5 rebase -i: check for missing commits in the rebase--helper
In particular on Windows, where shell scripts are even more expensive
than on MacOSX or Linux, it makes sense to move a loop that forks
Git at least once for every line in the todo list into a builtin.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:15 +01:00
Johannes Schindelin
1020534ccc t3404: relax rebase.missingCommitsCheck tests
These tests were a bit anal about the *exact* warning/error message
printed by git rebase. But those messages are intended for the *end
user*, therefore it does not make sense to test so rigidly for the
*exact* wording.

In the following, we will reimplement the missing commits check in
the sequencer, with slightly different words.

So let's just test for the parts in the warning/error message that
we *really* care about, nothing more, nothing less.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:15 +01:00
Johannes Schindelin
106fca1f18 rebase -i: also expand/collapse the SHA-1s via the rebase--helper
This is crucial to improve performance on Windows, as the speed is now
mostly dominated by the SHA-1 transformation (because it spawns a new
rev-parse process for *every* line, and spawning processes is pretty
slow from Git for Windows' MSYS2 Bash).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:15 +01:00
Johannes Schindelin
7e3338eed9 rebase -i: do not invent onelines when expanding/collapsing SHA-1s
To avoid problems with short SHA-1s that become non-unique during the
rebase, we rewrite the todo script with short/long SHA-1s before and
after letting the user edit the script. Since SHA-1s are not intuitive
for humans, rebase -i also provides the onelines (commit message
subjects) in the script, purely for the user's convenience.

It is very possible to generate a todo script via different means than
rebase -i and then to let rebase -i run with it; In this case, these
onelines are not required.

And this is where the expand/collapse machinery has a bug: it *expects*
that oneline, and failing to find one reuses the previous SHA-1 as
"oneline".

It was most likely an oversight, and made implementation in the (quite
limiting) shell script language less convoluted. However, we are about
to reimplement performance-critical parts in C (and due to spawning a
git.exe process for every single line of the todo script, the
expansion/collapsing of the SHA-1s *is* performance-hampering on
Windows), therefore let's fix this bug to make cross-validation with the
C version of that functionality possible.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:14 +01:00
Johannes Schindelin
55be0e20a3 rebase -i: remove useless indentation
The commands used to be indented, and it is nice to look at, but when we
transform the SHA-1s, the indentation is removed. So let's do away with it.

For the moment, at least: when we will use the upcoming rebase--helper
to transform the SHA-1s, we *will* keep the indentation and can
reintroduce it. Yet, to be able to validate the rebase--helper against
the output of the current shell script version, we need to remove the
extra indentation.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:14 +01:00
Johannes Schindelin
2c6c838cce rebase -i: generate the script via rebase--helper
The first step of an interactive rebase is to generate the so-called "todo
script", to be stored in the state directory as "git-rebase-todo" and to
be edited by the user.

Originally, we adjusted the output of `git log <options>` using a simple
sed script. Over the course of the years, the code became more
complicated. We now use shell scripting to edit the output of `git log`
conditionally, depending whether to keep "empty" commits (i.e. commits
that do not change any files).

On platforms where shell scripting is not native, this can be a serious
drag. And it opens the door for incompatibilities between platforms when
it comes to shell scripting or to Unix-y commands.

Let's just re-implement the todo script generation in plain C, using the
revision machinery directly.

This is substantially faster, improving the speed relative to the
shell script version of the interactive rebase from 2x to 3x on Windows.

Note that the rearrange_squash() function in git-rebase--interactive
relied on the fact that we set the "format" variable to the config setting
rebase.instructionFormat. Relying on a side effect like this is no good,
hence we explicitly perform that assignment (possibly again) in
rearrange_squash().

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-02-25 06:52:14 +01:00