When our patches to support that hook were upstreamed, the hook's name
was eliciting some reviewer suggestions, and it was renamed to
`post-index-change`. These patches (with the new name) made it into
v2.22.0.
However, VFSforGit users may very well have checkouts with that hook
installed under the original name.
To support this, let's just introduce a hack where we look a bit more
closely when we just failed to find the `post-index-change` hook, and
allow any `post-indexchanged` hook to run instead (if it exists).
The vfs does not correctly handle the case when there is a file
that begins with the same prefix as a directory. For example, the
following setup would encounter this issue:
A directory contains a file named `dir1.sln` and a directory
named `dir1/`.
The directory `dir1` contains other files.
The directory `dir1` is in the virtual file system list
The contents of `dir1` should be in the virtual file system, but
it is not. The contents of this directory do not have the skip
worktree bit cleared as expected. The problem is in the
`apply_virtualfilesystem(...)` function where it does not include
the trailing slash of the directory name when looking up the
position in the index to start clearing the skip worktree bit.
This fix is it include the trailing slash when finding the first
index entry from `index_name_pos(...)`.
Add check to see if a directory is included in the virtualfilesystem
before checking the directory hashmap. This allows a directory entry
like foo/ to find all untracked files in subdirectories.
The virtual file system code incorrectly treated symlinks as directories
instead of regular files. This meant symlinks were not included even if
they are listed in the list of files returned by the core.virtualFilesystem
hook proc. Fixes#25
Signed-off-by: Ben Peart <Ben.Peart@microsoft.com>
Fixes#13
Some git commands spawn helpers and redirect the index to a different
location. These include "difftool -d" and the sequencer
(i.e. `git rebase -i`, `git cherry-pick` and `git revert`) and others.
In those instances we don't want to update their temporary index with
our virtualization data.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Ben Peart <Ben.Peart@microsoft.com>
On index load, clear/set the skip worktree bits based on the virtual
file system data. Use virtual file system data to update skip-worktree
bit in unpack-trees. Use virtual file system data to exclude files and
folders not explicitly requested.
Update 2022-04-05: disable the "present-despite-SKIP_WORKTREE" file removal
behavior when 'core.virtualfilesystem' is enabled.
Signed-off-by: Ben Peart <benpeart@microsoft.com>
We found a user who had set "core.gvfs = false" in their global
config. This should not have been necessary, but it also should not
have caused a problem. However, it did.
The reason is that gvfs_load_config_value() is called from config.c
when reading config key/value pairs from all the config files. The
local config should override the global config, and this is done by
config.c reading the global config first then reading the local
config. However, our logic only allowed writing the core_gvfs
variable once.
Put the guards against multiple assignments of core_gvfs into
gvfs_config_is_set() instead, because that will fix the problem
_and_ keep multiple calls to gvfs_config_is_set() from slowing down.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
The 'git worktree' command was marked as BLOCK_ON_GVFS_REPO because it
does not interact well with the virtual filesystem of VFS for Git. When
a Scalar clone uses the GVFS protocol, it enables the
GVFS_BLOCK_COMMANDS flag, since commands like 'git gc' do not work well
with the GVFS protocol.
However, 'git worktree' works just fine with the GVFS protocol since it
isn't doing anything special. It copies the sparse-checkout from the
current worktree, so it does not have performance issues.
This is a highly requested option.
The solution is to stop using the BLOCK_ON_GVFS_REPO option and instead
add a special-case check in cmd_worktree() specifically for a particular
bit of the 'core_gvfs' global variable (loaded by very early config
reading) that corresponds to the virtual filesystem. The bit that most
closely resembled this behavior was non-obviously named, but does
provide a signal that we are in a Scalar clone and not a VFS for Git
clone. The error message is copied from git.c, so it will have the same
output as before if a user runs this in a VFS for Git clone.
Signed-off-by: Derrick Stolee <derrickstolee@github.com>
The following commands and options are not currently supported when working
in a GVFS repo. Add code to detect and block these commands from executing.
1) fsck
2) gc
4) prune
5) repack
6) submodule
8) update-index --split-index
9) update-index --index-version (other than 4)
10) update-index --[no-]skip-worktree
11) worktree
Signed-off-by: Ben Peart <benpeart@microsoft.com>
String formatting can be a performance issue when there are
hundreds of thousands of trees.
Change to stop using the strbuf_addf and just add the strings
or characters individually.
There are a limited number of modes so added a switch for the
known ones and a default case if something comes through that
are not a known one for git.
In one scenario regarding a huge worktree, this reduces the
time required for a `git checkout <branch>` from 44 seconds
to 38 seconds, i.e. it is a non-negligible performance
improvement.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
This code change makes sure that the config value for core_gvfs
is always loaded before checking it.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
When using the sparse-checkout feature git should not write to the working
directory for files with the skip-worktree bit on. With the skip-worktree
bit on the file may or may not be in the working directory and if it is
not we don't want or need to create it by calling checkout_entry.
There are two callers of checkout_target. Both of which check that the
file does not exist before calling checkout_target. load_current which
make a call to lstat right before calling checkout_target and
check_preimage which will only run checkout_taret it stat_ret is less than
zero. It sets stat_ret to zero and only if !stat->cached will it lstat
the file and set stat_ret to something other than zero.
This patch checks if skip-worktree bit is on in checkout_target and just
returns so that the entry doesn't not end up in the working directory.
This is so that apply will not create a file in the working directory,
then update the index but not keep the working directory up to date with
the changes that happened in the index.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
When using the sparse-checkout feature, the file might not be on disk
because the skip-worktree bit is on.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
We need to respect that config setting even if we already know that we
have a repository, but have not yet read the config.
The regression test was written by Alejandro Pauly.
2021-10-30: Recent movement of find_hook() into hook.c required moving this
change from run-command.c.
Signed-off-by: Johannes Schindelin <johasc@microsoft.com>
This adds hard-coded call to GVFS.hooks.exe before and after each Git
command runs.
To make sure that this is only called on repositories cloned with GVFS, we
test for the tell-tale .gvfs.
2021-10-30: Recent movement of find_hook() to hook.c required moving these
changes out of run-command.c to hook.c.
Signed-off-by: Ben Peart <Ben.Peart@microsoft.com>
If we are going to write an object there is no use in calling
the read object hook to get an object from a potentially remote
source. We would rather just write out the object and avoid the
potential round trip for an object that doesn't exist.
This change adds a flag to the check_and_freshen() and
freshen_loose_object() functions' signatures so that the hook
is bypassed when the functions are called before writing loose
objects. The check for a local object is still performed so we
don't overwrite something that has already been written to one
of the objects directories.
Based on a patch by Kevin Willford.
Signed-off-by: Johannes Schindelin <johasc@microsoft.com>
Hydrate missing loose objects in check_and_freshen() when running
virtualized. Add test cases to verify read-object hook works when
running virtualized.
This hook is called in check_and_freshen() rather than
check_and_freshen_local() to make the hook work also with alternates.
Helped-by: Kevin Willford <kewillf@microsoft.com>
Signed-off-by: Ben Peart <Ben.Peart@microsoft.com>
The idea is to allow blob objects to be missing from the local repository,
and to load them lazily on demand.
After discussing this idea on the mailing list, we will rename the feature
to "lazy clone" and work more on this.
Signed-off-by: Ben Peart <Ben.Peart@microsoft.com>
Ensure all filters and EOL conversions are blocked when running under
GVFS so that our projected file sizes will match the actual file size
when it is hydrated on the local machine.
Signed-off-by: Ben Peart <Ben.Peart@microsoft.com>
While performing a fetch with a virtual file system we know that there
will be missing objects and we don't want to download them just because
of the reachability of the commits. We also don't want to download a
pack file with commits, trees, and blobs since these will be downloaded
on demand.
This flag will skip the first connectivity check and by returning zero
will skip the upload pack. It will also skip the second connectivity
check but continue to update the branches to the latest commit ids.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
Prevent the sparse checkout to delete files that were marked with
skip-worktree bit and are not in the sparse-checkout file.
This is because everything with the skip-worktree bit turned on is being
virtualized and will be removed with the change of HEAD.
There was only one failing test when running with these changes that was
checking to make sure the worktree narrows on checkout which was
expected since we would no longer be narrowing the worktree.
Update 2022-04-05: temporarily set 'sparse.expectfilesoutsideofpatterns' in
test (until we start disabling the "remove present-despite-SKIP_WORKTREE"
behavior with 'core.virtualfilesystem' in a later commit).
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
This takes a substantial amount of time, and if the user is reasonably
sure that the files' integrity is not compromised, that time can be saved.
Git no longer verifies the SHA-1 by default, anyway.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
Update for 2023-02-27: This feature was upstreamed as the index.skipHash
config option. This resulted in some changes to the struct and some of
the setup code. In particular, the config reading was moved to
prepare_repo_settings(), so the core.gvfs bit check was moved there,
too.
Signed-off-by: Derrick Stolee <derrickstolee@github.com>
This does not do anything yet. The next patches will add various values
for that config setting that correspond to the various features
offered/required by GVFS.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
Since we really want to be based on a `.vfs.*` tag, let's make sure that
there was a new-enough one, i.e. one that agrees with the first three
version numbers of the recorded default version.
This prevents e.g. v2.22.0.vfs.0.<some-huge-number>.<commit> from being
used when the current release train was not yet tagged.
It is important to get the first three numbers of the version right
because e.g. Scalar makes decisions depending on those (such as assuming
that the `git maintenance` built-in is not available, even though it
actually _is_ available).
Signed-off-by: Johannes Schindelin <johasc@microsoft.com>
While using the reset --stdin feature on windows path added may have a
\r at the end of the path that wasn't getting removed so didn't match
the path in the index and wasn't reset.
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
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>
This is the recommended way on GitHub to describe policies revolving around
security issues and about supported versions.
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>