`git survey` exposes its `--top` default via `survey.top` so that a
site or per-repository operator can switch the detail tables on once
and have every subsequent invocation include them. Mirror that
ergonomics for `git repo structure` so that, as `git survey`'s
functionality is folded into `git repo structure`, the configuration
side of the migration story stays equivalent.
Add a small `git_config_int` callback bound to `repo.structure.top`
and invoke it before `parse_options()`, so a `--top=<N>` on the
command line cleanly overrides the configured default (including
`--top=0` to opt out of the detail tables when configuration enables
them). Reject negative configured values with the same wording as the
command-line guard, since `git_config_int()` happily returns negative
integers.
Document the new variable in a fresh `Documentation/config/repo.adoc`
and wire it into the alphabetical includes in `Documentation/config.adoc`
between `repack.adoc` and `rerere.adoc`. Cover the precedence
behaviour with a t1901 test: a configured value enables the tables by
default, and a command-line `--top=0` suppresses them again.
Note that the reported paths respect the `core.quotePath` setting.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The preceding commit added `--top=<n>` to `git repo structure`,
reporting the top-N paths per type ranked by count, on-disk size, and
inflated size. Cover the three behaviors that matter for that option:
* Without `--top`, the key-value output emits no `top.*` keys, so
existing parsers stay unaffected.
* `--top=N` produces exactly N ranked entries on each of the six
`objects.<type>.top.by_<axis>` axes (count/disk_size/inflated_size
crossed with trees/blobs), and a constructed input where one blob
is several orders of magnitude bigger than the other lets us
assert the ordering on the disk-size and inflated-size axes.
* A negative `--top` is rejected with a non-zero exit and a message
naming the constraint, so a typo cannot silently degrade into the
default zero.
Avoid grep patterns starting with `--`; grep would parse the leading
double dash as an option terminator.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
`git survey` distinguishes itself from `git repo structure` largely by
its path-level reporting: in addition to whole-repo totals it lists the
paths whose object histories dominate the repository, ranked by raw
count, on-disk size, and inflated size, separately for trees and blobs.
That is often the most actionable output from `git survey`, since it
points an operator at the directories and files that should be reviewed
for cleanup, sparse-checkout exclusion, or rewriting.
`git repo structure` already drives the same path-walk traversal that
`git survey` uses to gather its per-path numbers; the callback simply
discards the path. Aggregate per-(path, type) summaries inside that
existing callback and add a bounded, descending-sorted "top-N" table
keyed by each of the three axes. Gate the feature behind a new
`--top=<n>` option, defaulting to 0, so unadorned invocations are
unaffected and pay no extra work for the top-N tracking.
Mirror the sort and eviction strategy from `builtin/survey.c`: keep an
array of at most N entries sorted from largest to smallest, walk it
from the bottom on each candidate, and shift entries down when a new
one belongs. Compared to `builtin/survey.c`, drop the void-pointer
indirection in the table data, type the comparator's arguments, and
fold the trivial comparators into the `(a > b) - (a < b)` idiom.
For the human-readable `table` output, extend the existing nested
bullet layout with two new top-level sections, `* Top trees` and
`* Top blobs`, each containing three sub-tables (`Top by count`,
`Top by disk size`, `Top by inflated size`). The path becomes the row
name and the relevant scalar becomes the value, reusing
`stats_table_count_addf` and `stats_table_size_addf` so units and
column alignment match the rest of the table.
For the `lines`/`nul` key-value formats, emit one
`objects.<type>.top.by_<axis>.<rank>.path=<path>` entry alongside an
`objects.<type>.top.by_<axis>.<rank>.<axis>=<value>` entry per ranked
path, so consumers can dispatch by axis without parsing the schema.
The root tree's path is the empty string as produced by the path-walk
machinery; preserve that as-is to stay faithful to the upstream
representation rather than fabricating a placeholder.
This is the first piece of folding `git survey`'s functionality into
`git repo structure`. Subsequent commits will add the corresponding
configuration knob and, eventually, turn `git survey` into a thin
deprecated shim over `git repo structure`.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
`git repo structure` walks every reference enumerated by
`refs_for_each_ref()` and feeds each reference's tip into the path
walk that produces the object counts. There is no way to scope the
inquiry to a subset of refs, even though that is the most common
need when an operator is investigating what part of the history is
driving cost: only branches, only release tags, only one remote's
view, etc.
Add a single `--ref-filter=<pattern>` option that, when given,
restricts both the reference count and the object walk to refs whose
full name matches one of the patterns. The option is repeatable;
multiple patterns form a union, so `--ref-filter='refs/heads/*'
--ref-filter='refs/tags/v*'` includes local branches and tags whose
short name starts with `v`. Patterns use `wildmatch()` with
`WM_PATHNAME` semantics so a `*` does not cross `/`, matching the
convention used by `git for-each-ref` positional arguments.
Choosing a single flexible filter, rather than a proliferation of
per-kind flags like `--branches`, `--tags`, `--remotes`, keeps the
option surface small and lets the same mechanism express
narrow selections the per-kind flags could not, such as "only release
tags" (`'refs/tags/v*'`) or "only one remote's branches"
(`'refs/remotes/origin/*'`). Without `--ref-filter`, behaviour is
unchanged: every ref `refs_for_each_ref()` enumerates contributes.
Both the reference counter and the path-walk seeding (via
`add_pending_oid()`) sit on the same callback, so an early return
when no pattern matches naturally excludes a ref from both. No
separate object-walk machinery is needed.
Cover the two interesting code paths with tests in t1901: a single
filter narrowing to branches, and two filters unioning to include
both branches and tags.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Mirror what git survey already reports: lightweight tags
(pointing straight at a commit/tree/blob) and annotated tags
(pointing at an OBJ_TAG that is itself stored as a separate
object) are different things in many monorepo contexts, and one
of the differences git survey users routinely care about. Add
an annotated_tags counter to struct ref_stats, populate it in
count_references() by peeking at the ref OID's object type, and
expose it as a sub-row under Tags in the table output and as
references.tags.annotated.count in the machine-readable formats.
Step toward pivoting the standalone git survey command onto
git repo structure; this fills the first of the four feature
gaps documented in the assessment.
Tests in t1901 widened to assert the new row and key.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Originally introduced as `core.useBuiltinFSMonitor` in Git for Windows
and developed, improved and stabilized there, the built-in FSMonitor
only made it into upstream Git (after unnecessarily long hemming and
hawing and throwing overly perfectionist style review sticks into the
spokes) as `core.fsmonitor = true`.
In Git for Windows, with this topic branch, we re-introduce the
now-obsolete config setting, with warnings suggesting to existing users
how to switch to the new config setting, with the intention to
ultimately drop the patch at some stage.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This topic branch re-adds the deprecated --stdin/-z options to `git
reset`. Those patches were overridden by a different set of options in
the upstream Git project before we could propose `--stdin`.
We offered this in MinGit to applications that wanted a safer way to
pass lots of pathspecs to Git, and these applications will need to be
adjusted.
Instead of `--stdin`, `--pathspec-from-file=-` should be used, and
instead of `-z`, `--pathspec-file-nul`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
A fix for calling `vim` in Windows Terminal caused a regression and was
reverted. We partially un-revert this, to get the fix again.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Upstream Git does not test their tags with the expensive set of tests,
so a couple of them seem quite broken for now, even so much as hanging
indefinitely.
It is outside of the responsibility of the Git for Windows project to
fix upstream's own tests for platforms other than Windows, so let's not
exercise them.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Reintroduce the 'core.useBuiltinFSMonitor' config setting (originally added
in 0a756b2a25 (fsmonitor: config settings are repository-specific,
2021-03-05)) after its removal from the upstream version of FSMonitor.
Upstream, the 'core.useBuiltinFSMonitor' setting was rendered obsolete by
"overloading" the 'core.fsmonitor' setting to take a boolean value. However,
several applications (e.g., 'scalar') utilize the original config setting,
so it should be preserved for a deprecation period before complete removal:
* if 'core.fsmonitor' is a boolean, the user is correctly using the new
config syntax; do not use 'core.useBuiltinFSMonitor'.
* if 'core.fsmonitor' is unspecified, use 'core.useBuiltinFSMonitor'.
* if 'core.fsmonitor' is a path, override and use the builtin FSMonitor if
'core.useBuiltinFSMonitor' is 'true'; otherwise, use the FSMonitor hook
indicated by the path.
Additionally, for this deprecation period, advise users to switch to using
'core.fsmonitor' to specify their use of the builtin FSMonitor.
Signed-off-by: Victoria Dye <vdye@github.com>
The `--stdin` option was a well-established paradigm in other commands,
therefore we implemented it in `git reset` for use by Visual Studio.
Unfortunately, upstream Git decided that it is time to introduce
`--pathspec-from-file` instead.
To keep backwards-compatibility for some grace period, we therefore
reinstate the `--stdin` option on top of the `--pathspec-from-file`
option, but mark it firmly as deprecated.
Helped-by: Victoria Dye <vdye@github.com>
Helped-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In e3f7e01b50 (Revert "editor: save and reset terminal after calling
EDITOR", 2021-11-22), we reverted the commit wholesale where the
terminal state would be saved and restored before/after calling an
editor.
The reverted commit was intended to fix a problem with Windows Terminal
where simply calling `vi` would cause problems afterwards.
To fix the problem addressed by the revert, but _still_ keep the problem
with Windows Terminal fixed, let's revert the revert, with a twist: we
restrict the save/restore _specifically_ to the case where `vi` (or
`vim`) is called, and do not do the same for any other editor.
This should still catch the majority of the cases, and will bridge the
time until the original patch is re-done in a way that addresses all
concerns.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
On Windows, the current working directory is pretty much guaranteed to
contain a colon. If we feed that path to CVS, it mistakes it for a
separator between host and port, though.
This has not been a problem so far because Git for Windows uses MSYS2's
Bash using a POSIX emulation layer that also pretends that the current
directory is a Unix path (at least as long as we're in a shell script).
However, that is rather limiting, as Git for Windows also explores other
ports of other Unix shells. One of those is BusyBox-w32's ash, which is
a native port (i.e. *not* using any POSIX emulation layer, and certainly
not emulating Unix paths).
So let's just detect if there is a colon in $PWD and punt in that case.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This is the recommended way on GitHub to describe policies revolving around
security issues and about supported versions.
Helped-by: Sven Strickroth <email@cs-ware.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Rather than using private IFTTT Applets that send mails to this
maintainer whenever a new version of a Git for Windows component was
released, let's use the power of GitHub workflows to make this process
publicly visible.
This workflow monitors the Atom/RSS feeds, and opens a ticket whenever a
new version was released.
Note: Bash sometimes releases multiple patched versions within a few
minutes of each other (i.e. 5.1p1 through 5.1p4, 5.0p15 and 5.0p16). The
MSYS2 runtime also has a similar system. We can address those patches as
a group, so we shouldn't get multiple issues about them.
Note further: We're not acting on newlib releases, OpenSSL alphas, Perl
release candidates or non-stable Perl releases. There's no need to open
issues about them.
Co-authored-by: Matthias Aßhauer <mha1993@live.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
These are Git for Windows' Git GUI and gitk patches. We will have to
decide at some point what to do about them, but that's a little lower
priority (as Git GUI seems to be unmaintained for the time being, and
the gitk maintainer keeps a very low profile on the Git mailing list,
too).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git for Windows uses MSYS2's Bash to run the test suite, which comes
with benefits but also at a heavy price: on the plus side, MSYS2's
POSIX emulation layer allows us to continue pretending that we are on a
Unix system, e.g. use Unix paths instead of Windows ones, yet this is
bought at a rather noticeable performance penalty.
There *are* some more native ports of Unix shells out there, though,
most notably BusyBox-w32's ash. These native ports do not use any POSIX
emulation layer (or at most a *very* thin one, choosing to avoid
features such as fork() that are expensive to emulate on Windows), and
they use native Windows paths (usually with forward slashes instead of
backslashes, which is perfectly legal in almost all use cases).
And here comes the problem: with a $PWD looking like, say,
C:/git-sdk-64/usr/src/git/t/trash directory.t5813-proto-disable-ssh
Git's test scripts get quite a bit confused, as their assumptions have
been shattered. Not only does this path contain a colon (oh no!), it
also does not start with a slash.
This is a problem e.g. when constructing a URL as t5813 does it:
ssh://remote$PWD. Not only is it impossible to separate the "host" from
the path with a $PWD as above, even prefixing $PWD by a slash won't
work, as /C:/git-sdk-64/... is not a valid path.
As a workaround, detect when $PWD does not start with a slash on
Windows, and simply strip the drive prefix, using an obscure feature of
Windows paths: if an absolute Windows path starts with a slash, it is
implicitly prefixed by the drive prefix of the current directory. As we
are talking about the current directory here, anyway, that strategy
works.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git for Windows accepts pull requests; Core Git does not. Therefore we
need to adjust the template (because it only matches core Git's
project management style, not ours).
Also: direct Git for Windows enhancements to their contributions page,
space out the text for easy reading, and clarify that the mailing list
is plain text, not HTML.
Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When t5605 tries to verify that files are hardlinked (or that they are
not), it uses the `-links` option of the `find` utility.
BusyBox' implementation does not support that option, and BusyBox-w32's
lstat() does not even report the number of hard links correctly (for
performance reasons).
So let's just switch to a different method that actually works on
Windows.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
While it may seem super convenient to some old Unix hands to simpy
require Perl to be available when running the test suite, this is a
major hassle on Windows, where we want to verify that Perl is not,
actually, required in a NO_PERL build.
As a super ugly workaround, we "install" a script into /usr/bin/perl
reading like this:
#!/bin/sh
# We'd much rather avoid requiring Perl altogether when testing
# an installed Git. Oh well, that's why we cannot have nice
# things.
exec c:/git-sdk-64/usr/bin/perl.exe "$@"
The problem with that is that BusyBox assumes that the #! line in a
script refers to an executable, not to a script. So when it encounters
the line #!/usr/bin/perl in t5532's proxy-get-cmd, it barfs.
Let's help this situation by simply executing the Perl script with the
"interpreter" specified explicitly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
At some stage, t5003-archive-zip wants to add a file that is not ASCII.
To that end, it uses /bin/sh. But that file may actually not exist (it
is too easy to forget that not all the world is Unix/Linux...)! Besides,
we already have perfectly fine binary files intended for use solely by
the tests. So let's use one of them instead.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Getting started contributing to Git can be difficult on a Windows
machine. CONTRIBUTING.md contains a guide to getting started, including
detailed steps for setting up build tools, running tests, and
submitting patches to upstream.
[includes an example by Pratik Karki how to submit v2, v3, v4, etc.]
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
When running with BusyBox, we will want to avoid calling executables on
the PATH that are implemented in BusyBox itself.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The Git project followed Git for Windows' lead and added their Code of
Conduct, based on the Contributor Covenant v1.4, later updated to v2.0.
We adapt it slightly to Git for Windows.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The -W option is only understood by MSYS2 Bash's pwd command. We already
make sure to override `pwd` by `builtin pwd -W` for MINGW, so let's not
double the effort here.
This will also help when switching the shell to another one (such as
BusyBox' ash) whose pwd does *not* understand the -W option.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In this time and age, AI is everywhere. However, it's sometimes not very
easy to use. For green-field projects it works quite a bit better than
for existing legacy projects. And Git's source code is _quite_ as legacy
code as they come... 😁
Now, the only way how AI can be used efficiently with legacy code
is by providing enough information by way of prompt context for the
AI to have a chance to make any sense of the code. The structure and
the architecture is, after all, not designed for AI, but rather the
opposite: By virtue of having grown organically over two decades, there
is no design that AI coding models would readily grasp.
So here is a document that describes all kinds of aspects about this
project. The idea is to help AI by providing information that it does
not have ingrained in its weights. The idea is to provide information
that a human prompter might take for granted, but no coding model will
have been trained on specifically.
Assisted-by: Claude Opus 4.5
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Traditionally, Git for Windows' SDK uses Bash as its default shell.
However, other Unix shells are available, too. Most notably, the Win32
port of BusyBox comes with `ash` whose `pwd` command already prints
Windows paths as Git for Windows wants them, while there is not even a
`builtin` command.
Therefore, let's be careful not to override `pwd` unless we know that
the `builtin` command is available.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The Git for Windows project has grown quite complex over the years,
certainly much more complex than during the first years where the
`msysgit.git` repository was abusing Git for package management purposes
and the `git/git` fork was called `4msysgit.git`.
Let's describe the status quo in a thorough way.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
BusyBox-w32 is a true Win32 application, i.e. it does not come with a
POSIX emulation layer.
That also means that it does *not* use the Unix convention of separating
the entries in the PATH variable using colons, but semicolons.
However, there are also BusyBox ports to Windows which use a POSIX
emulation layer such as Cygwin's or MSYS2's runtime, i.e. using colons
as PATH separators.
As a tell-tale, let's use the presence of semicolons in the PATH
variable: on Unix, it is highly unlikely that it contains semicolons,
and on Windows (without POSIX emulation), it is virtually guaranteed, as
everybody should have both $SYSTEMROOT and $SYSTEMROOT/system32 in their
PATH.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The idea is to allow running the test suite on MinGit with BusyBox
installed in /mingw64/bin/sh.exe. In that case, we will want to exclude
sort & find (and other Unix utilities) from being bundled.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
On Windows, git repositories may have extra files which need cleaned
(e.g., a build directory) that may be arbitrarily deep. Suggest using
`core.longPaths` if such situations are encountered.
Fixes: #2715
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
We already have a directory where we store files intended for use by
multiple test scripts. The same directory is a better home for the
test-binary-*.png files than t/.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Update wchar_t buffers to use MAX_LONG_PATH instead of MAX_PATH and call
xutftowcs_long_path() in the Win32 backend source files.
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
When trying to ensure that long paths are handled correctly, we
first normalize absolute paths as we encounter them.
However, if the path is a so-called "drive-less" absolute path, i.e. if
it is relative to the current drive but _does_ start with a directory
separator, we would want the normalized path to be such a drive-less
absolute path, too.
Let's do that, being careful to still include the drive prefix when we
need to go through the `\\?\` dance (because there, the drive prefix is
absolutely required).
This fixes https://github.com/git-for-windows/git/issues/4586.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Windows paths are typically limited to MAX_PATH = 260 characters, even
though the underlying NTFS file system supports paths up to 32,767 chars.
This limitation is also evident in Windows Explorer, cmd.exe and many
other applications (including IDEs).
Particularly annoying is that most Windows APIs return bogus error codes
if a relative path only barely exceeds MAX_PATH in conjunction with the
current directory, e.g. ERROR_PATH_NOT_FOUND / ENOENT instead of the
infinitely more helpful ERROR_FILENAME_EXCED_RANGE / ENAMETOOLONG.
Many Windows wide char APIs support longer than MAX_PATH paths through the
file namespace prefix ('\\?\' or '\\?\UNC\') followed by an absolute path.
Notable exceptions include functions dealing with executables and the
current directory (CreateProcess, LoadLibrary, Get/SetCurrentDirectory) as
well as the entire shell API (ShellExecute, SHGetSpecialFolderPath...).
Introduce a handle_long_path function to check the length of a specified
path properly (and fail with ENAMETOOLONG), and to optionally expand long
paths using the '\\?\' file namespace prefix. Short paths will not be
modified, so we don't need to worry about device names (NUL, CON, AUX).
Contrary to MSDN docs, the GetFullPathNameW function doesn't seem to be
limited to MAX_PATH (at least not on Win7), so we can use it to do the
heavy lifting of the conversion (translate '/' to '\', eliminate '.' and
'..', and make an absolute path).
Add long path error checking to xutftowcs_path for APIs with hard MAX_PATH
limit.
Add a new MAX_LONG_PATH constant and xutftowcs_long_path function for APIs
that support long paths.
While improved error checking is always active, long paths support must be
explicitly enabled via 'core.longpaths' option. This is to prevent end
users from shooting themselves in the foot by checking out files that Windows
Explorer, cmd/bash or their favorite IDE cannot handle.
Test suite:
Test the case is when the full pathname length of a dir is close
to 260 (MAX_PATH).
Bug report and an original reproducer by Andrey Rogozhnikov:
https://github.com/msysgit/git/pull/122#issuecomment-43604199
[jes: adjusted test number to avoid conflicts, added support for
chdir(), etc]
Thanks-to: Martin W. Kirst <maki@bitkings.de>
Thanks-to: Doug Kelly <dougk.ff7@gmail.com>
Original-test-by: Andrey Rogozhnikov <rogozhnikov.andrey@gmail.com>
Signed-off-by: Karsten Blees <blees@dcon.de>
Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Josh Soref <jsoref@gmail.com>
It is convenient to assume that everybody who wants to build & test Git
has access to a working `iconv` executable (after all, we already pretty
much require libiconv).
However, that limits esoteric test scenarios such as Git for Windows',
where an end user installation has to ship with `iconv` for the sole
purpose of being testable. That payload serves no other purpose.
So let's just have a test helper (to be able to test Git, the test
helpers have to be available, after all) to act as `iconv` replacement.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
There is a problem in the way 9ac3f0e5b3 (pack-objects: fix
performance issues on packing large deltas, 2018-07-22) initializes that
mutex in the `packing_data` struct. The problem manifests in a
segmentation fault on Windows, when a mutex (AKA critical section) is
accessed without being initialized. (With pthreads, you apparently do
not really have to initialize them?)
This was reported in https://github.com/git-for-windows/git/issues/1839.
Signed-off-by: Doug Kelly <dougk.ff7@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
BusyBox comes with a ton of applets ("applet" being the identical
concept to Git's "builtins"). And similar to Git's builtins, the applets
can be called via `busybox <command>`, or the BusyBox executable can be
copied/hard-linked to the command name.
The similarities do not end here. Just as with Git's builtins, it is
problematic that BusyBox' hard-linked applets cannot easily be put into
a .zip file: .zip archives have no concept of hard-links and therefore
would store identical copies (and also extract identical copies,
"inflating" the archive unnecessarily).
To counteract that issue, MinGit already ships without hard-linked
copies of the builtins, and the plan is to do the same with BusyBox'
applets: simply ship busybox.exe as single executable, without
hard-linked applets.
To accommodate that, Git is being taught by this commit a very special
trick, exploiting the fact that it is possible to call an executable
with a command-line whose argv[0] is different from the executable's
name: when `sh` is to be spawned, and no `sh` is found in the PATH, but
busybox.exe is, use that executable (with unchanged argv).
Likewise, if any executable to be spawned is not on the PATH, but
busybox.exe is found, parse the output of `busybox.exe --help` to find
out what applets are included, and if the command matches an included
applet name, use busybox.exe to execute it.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
We already avoid traversing NTFS junction points in `git clean -dfx`.
With this topic branch, we do that when the FSCache is enabled, too.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>