worktree: allow in Scalar repositories

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>
This commit is contained in:
Derrick Stolee 2022-09-30 12:59:40 -04:00 коммит произвёл Johannes Schindelin
Родитель 8d46c8e0f6
Коммит 6508076132
3 изменённых файлов: 20 добавлений и 1 удалений

Просмотреть файл

@ -1,4 +1,5 @@
#include "cache.h"
#include "gvfs.h"
#include "checkout.h"
#include "config.h"
#include "builtin.h"
@ -1127,6 +1128,13 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
git_config(git_worktree_config, NULL);
/*
* git-worktree is special-cased to work in Scalar repositories
* even when they use the GVFS Protocol.
*/
if (core_gvfs & GVFS_USE_VIRTUAL_FILESYSTEM)
die("'git %s' is not supported on a GVFS repo", "worktree");
if (!prefix)
prefix = "";

2
git.c
Просмотреть файл

@ -703,7 +703,7 @@ static struct cmd_struct commands[] = {
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
{ "version", cmd_version },
{ "whatchanged", cmd_whatchanged, RUN_SETUP },
{ "worktree", cmd_worktree, RUN_SETUP | BLOCK_ON_GVFS_REPO },
{ "worktree", cmd_worktree, RUN_SETUP },
{ "write-tree", cmd_write_tree, RUN_SETUP },
};

11
gvfs.h
Просмотреть файл

@ -14,7 +14,18 @@
#define GVFS_SKIP_SHA_ON_INDEX (1 << 0)
#define GVFS_BLOCK_COMMANDS (1 << 1)
#define GVFS_MISSING_OK (1 << 2)
/*
* This behavior of not deleting outside of the sparse-checkout
* is specific to the virtual filesystem support. It is only
* enabled by VFS for Git, and so can be used as an indicator
* that we are in a virtualized filesystem environment and not
* in a Scalar environment. This bit has two names to reflect
* that.
*/
#define GVFS_NO_DELETE_OUTSIDE_SPARSECHECKOUT (1 << 3)
#define GVFS_USE_VIRTUAL_FILESYSTEM (1 << 3)
#define GVFS_FETCH_SKIP_REACHABILITY_AND_UPLOADPACK (1 << 4)
#define GVFS_BLOCK_FILTERS_AND_EOL_CONVERSIONS (1 << 6)
#define GVFS_PREFETCH_DURING_FETCH (1 << 7)