Skip to content

Commit

Permalink
worktree: allow in Scalar repositories
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
derrickstolee authored and vdye committed Jul 19, 2023
1 parent 3078d8c commit 46303ad
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
8 changes: 8 additions & 0 deletions builtin/worktree.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "cache.h"
#include "abspath.h"
#include "gvfs.h"
#include "checkout.h"
#include "config.h"
#include "copy.h"
Expand Down Expand Up @@ -1196,6 +1197,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 = "";

Expand Down
2 changes: 1 addition & 1 deletion git.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
};

Expand Down
11 changes: 11 additions & 0 deletions gvfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 46303ad

Please sign in to comment.