Skip to content

[DO NOT MERGE] Tentative vfs-2.25.1 branch #248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 160 commits into from
Feb 21, 2020

Conversation

derrickstolee
Copy link

@derrickstolee derrickstolee commented Feb 20, 2020

Here is a rebase of vfs-2.25.0 onto v2.25.1.windows.1. There were only a few issues along the way. I dropped our reverts of some dir.c commits that we took in the v2.25.0 update because they have been fixed (supposedly) in v2.25.1. VFS for Git and Scalar tests should demonstrate if these are truly fixed.

Range diff:

113:  d622c34396 =   2:  d622c34396 t1091: improve here-docs
114:  3c754067a1 =   3:  3c754067a1 sparse-checkout: create leading directories
115:  47dbf10d8a =   4:  47dbf10d8a clone: fix --sparse option with URLs
116:  7aa9ef2fca =   5:  7aa9ef2fca sparse-checkout: fix documentation typo for core.sparseCheckoutCone
117:  41de0c6fbc =   6:  41de0c6fbc sparse-checkout: cone mode does not recognize "**"
118:  9e6d3e6417 =   7:  9e6d3e6417 sparse-checkout: detect short patterns
119:  9abc60f801 =   8:  9abc60f801 sparse-checkout: warn on globs in cone patterns
120:  4f52c2ce6c =   9:  4f52c2ce6c sparse-checkout: properly match escaped characters
121:  d585f0e799 =  10:  d585f0e799 sparse-checkout: write escaped patterns in cone mode
122:  bd64de42de =  11:  bd64de42de sparse-checkout: unquote C-style strings over --stdin
123:  e55682ea26 =  12:  e55682ea26 sparse-checkout: use C-style quotes in 'list' subcommand
124:  e53ffe2704 =  13:  e53ffe2704 sparse-checkout: escape all glob characters on write
125:  d2e65f4c90 =  14:  d2e65f4c90 sparse-checkout: improve docs around 'set' in cone mode
126:  f998a3f1e5 =  15:  f998a3f1e5 sparse-checkout: fix cone mode behavior mismatch
130:  6fb705abcb =  16:  6fb705abcb sparse-checkout: extract add_patterns_from_input()
131:  4bf0c06c71 =  17:  4bf0c06c71 sparse-checkout: extract pattern update from 'set' subcommand
132:  2631dc879d =  18:  2631dc879d sparse-checkout: create 'add' subcommand
133:  ef07659926 =  19:  ef07659926 sparse-checkout: work with Windows paths
  1:  21f524c5ac =  20:  aec00fb6d2 reset --stdin: trim carriage return from the paths
  2:  007e3b76f6 !  21:  ddae419f00 gvfs: start by adding the -gvfs suffix to the version
    @@ GIT-VERSION-GEN
      #!/bin/sh
      
      GVF=GIT-VERSION-FILE
    --DEF_VER=v2.25.0
    -+DEF_VER=v2.25.0.vfs.1.1
    +-DEF_VER=v2.25.1
    ++DEF_VER=v2.25.1.vfs.1.1
      
      LF='
      '
  3:  b84ed5db2d =  22:  35222f0a05 gvfs: ensure that the version is based on a GVFS tag
  4:  281dd65821 =  23:  553b86fd98 gvfs: add a GVFS-specific header file
  5:  91a7f1fb37 =  24:  c6ab81b481 gvfs: add the core.gvfs config setting
  6:  70b4dc4ad4 =  25:  ca9383b610 gvfs: add the feature to skip writing the index' SHA-1
  7:  5e5e1e8ec9 =  26:  f030eb86e4 gvfs: add the feature that blobs may be missing
  8:  60a637a94f =  27:  1259c93fe4 gvfs: prevent files to be deleted outside the sparse checkout
  9:  52a4cfa1c7 =  28:  518cc2cad8 gvfs: optionally skip reachability checks/upload pack during fetch
 10:  edcfc9df8c =  29:  5d0d824db6 gvfs: ensure all filters and EOL conversions are blocked
 11:  73b32c42ed =  30:  c9984b7562 Add a new run_hook_argv() function
 12:  bad623023e !  31:  5703d80417 gvfs: allow "virtualizing" objects
    @@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct obj
      		oi = &blank_oi;
      
     +retry:
    - 	if (!(flags & OBJECT_INFO_SKIP_CACHED)) {
    - 		struct cached_object *co = find_cached_object(real);
    - 		if (co) {
    + 	co = find_cached_object(real);
    + 	if (co) {
    + 		if (oi->typep)
     @@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
      			reprepare_packed_git(r);
      			if (find_pack_entry(r, real, &e))
 13:  4e74c191d2 =  32:  60b95f24c4 Hydrate missing loose objects in check_and_freshen()
 14:  425c1571a5 =  33:  00c1a61fae Add support for read-object as a background process to retrieve missing objects
 15:  b90204f9df =  34:  5e513a18f4 sha1_file: when writing objects, skip the read_object_hook
 16:  6ee953bee7 =  35:  8aa1a54317 gvfs: add global command pre and post hook procs
 17:  22c4659a45 =  36:  f42366ef1e Allow hooks to be run before setup_git_directory()
 18:  91291005db =  37:  50a7858b17 gvfs: introduce pre/post command hooks
 19:  665d8a0771 =  38:  38d8dc46cb sparse-checkout: update files with a modify/delete conflict
 20:  da43a06898 =  39:  c6a4f50b97 t0400: verify that the hook is called correctly from a subdirectory
 21:  71383272cb =  40:  6774bf9482 sparse-checkout: avoid writing entries with the skip-worktree bit
 22:  6f4062d600 =  41:  abe3c84396 Pass PID of git process to hooks.
 23:  eb9bcc7626 =  42:  abce59c890 Fix reset when using the sparse-checkout feature.
 24:  27b8f6d795 =  43:  251a28ab3d pre-command: always respect core.hooksPath
 25:  6f1c19016c =  44:  ee592f65e9 Do not remove files outside the sparse-checkout
 26:  fa5d4abca0 =  45:  1c0c811bfd gvfs: refactor loading the core.gvfs config value
 27:  ba96ed82bf =  46:  630ecb7d6a cache-tree: remove use of strbuf_addf in update_one
 28:  db3c3fc3cd =  47:  bbf87397d0 status: add status serialization mechanism
 29:  e18a0aa695 =  48:  f555d493d7 Teach ahead-behind and serialized status to play nicely together
 30:  b7a47a3992 =  49:  d4336edc6d status: serialize to path
 31:  c11afa2df8 =  50:  c9e80e2154 status: reject deserialize in V2 and conflicts
 44:  7c9dca420b =  51:  b7d8c5802a fsck: use ERROR_MULTI_PACK_INDEX
 70:  3f74d141fc =  52:  3eae1576e8 t5516: relax error message pattern
 71:  4c035cda7e =  53:  694acebed5 upload-pack: fix race condition in error messages
  -:  ---------- >  54:  6c11c6a124 sparse-checkout: allow one-character directories in cone mode
 32:  c827fd2eb7 !  55:  0fab055dc8 Add virtual file system settings and hook proc
    @@ dir.c: enum pattern_match_result path_matches_pattern_list(
     +	 * else fall through to the regular excludes logic as it may further exclude.
     +	 */
     +	if (*dtype == DT_UNKNOWN)
    -+		*dtype = get_dtype(NULL, istate, pathname, pathlen);
    ++		*dtype = resolve_dtype(DT_UNKNOWN, istate, pathname, pathlen);
     +	if (is_excluded_from_virtualfilesystem(pathname, pathlen, *dtype) > 0)
     +		return 1;
     +
    @@ dir.c: struct path_pattern *last_matching_pattern(struct dir_struct *dir,
     +	 * else fall through to the regular excludes logic as it may further exclude.
     +	 */
     +	if (*dtype_p == DT_UNKNOWN)
    -+		*dtype_p = get_dtype(NULL, istate, pathname, strlen(pathname));
    ++		*dtype_p = resolve_dtype(DT_UNKNOWN, istate, pathname, strlen(pathname));
     +	if (is_excluded_from_virtualfilesystem(pathname, strlen(pathname), *dtype_p) > 0)
     +		return 1;
     +
 33:  527e28e21c =  56:  162ac55ecf Update the virtualfilesystem support
 34:  96ba4eadec =  57:  85aef2e9da virtualfilesystem: don't run the virtual file system hook if the index has been redirected
 35:  949b596eae =  58:  42230ccc52 virtualfilesystem: fix bug with symlinks being ignored
 36:  06187e1845 =  59:  f41adf20a6 virtualfilesystem: check if directory is included
 37:  53136aa648 =  60:  4a54e81089 vfs: fix case where directories not handled correctly
 38:  6f32da2dbe =  61:  c5bf92afc4 commit: add generation to pop_most_recent_commit()
 39:  2acc657e20 =  62:  92e1e13388 status: fix rename reporting when using serialization cache
 40:  fbf83a36e3 =  63:  3c674868e9 status: add comments for ahead_behind_flags in serialization
 41:  607ed43623 =  64:  81921ed70a serialize-status: serialize global and repo-local exclude file metadata
 42:  c9f635c8dd =  65:  c5ef02ae1a status: deserialization wait
 43:  bcba7d3adf =  66:  0636e7b621 rebase/stash: make post-command hook work again
 45:  c17eb7cc21 =  67:  64f57427b9 send-pack: do not check for sha1 file when GVFS_MISSING_OK set
 46:  5b05fa082a =  68:  d34347add0 gvfs: block unsupported commands when running in a GVFS repo
 47:  2009015df8 =  69:  720a07ab7e BRANCHES.md: Add explanation of branches and using forks
 48:  28e93dfc6c =  70:  db1cc6d0e0 gvfs:trace2:data: add trace2 tracing around read_object_process
 49:  0961a9b46d =  71:  aae47c6876 gvfs:trace2:data: status deserialization information
 50:  13a32d2ec1 =  72:  0e538f6fcd gvfs:trace2:data: status serialization
 51:  2f67571a79 =  73:  d906aaf7e5 gvfs:trace2:data: add vfs stats
 52:  8a21c5bf4d =  74:  fc0fe94b6b trace2: refactor setting process starting time
 53:  e5b8e5c3bc =  75:  597a455020 trace2:gvfs:experiment: clear_ce_flags_1
 54:  2fe4d62587 =  76:  997365974d trace2:gvfs:experiment: traverse_trees
 55:  bd77e92559 =  77:  375785868d trace2:gvfs:experiment: report_tracking
 56:  bc8c2f5519 =  78:  72284e22c6 trace2:gvfs:experiment: read_cache: annotate thread usage in read-cache
 57:  7b30b3d24a =  79:  c57a07b913 trace2:gvfs:experiment: read-cache: time read/write of cache-tree extension
 58:  e0cd39d381 =  80:  b77de01106 trace2:gvfs:experiment: add prime_cache_tree region
 59:  65211e263a =  81:  adf312780f trace2:gvfs:experiment: add region to apply_virtualfilesystem()
 60:  43a83ea781 =  82:  16a1faf04e trace2:gvfs:experiment: add region around unpack_trees()
 61:  095e83bef4 =  83:  304c14e15b trace2:gvfs:experiment: add region to cache_tree_fully_valid()
 62:  0b900bc336 =  84:  cc2047bc95 trace2:gvfs:experiment: add unpack_entry() counter to unpack_trees() and report_tracking()
 63:  a06f59b2cd =  85:  a82ad4f692 trace2:gvfs:experiment: increase default event depth for unpack-tree data
 64:  8b26800393 =  86:  14195c4b77 trace2:gvfs:experiment: add data for check_updates() in unpack_trees()
 65:  81d3a78431 =  87:  b4fa3688a2 Trace2:gvfs:experiment: capture more 'tracking' details
 66:  03f4d2b2c3 =  88:  35413cb1b9 merge-recursive: avoid confusing logic in was_dirty()
 67:  3df82fa345 =  89:  5bb9f62128 merge-recursive: add some defensive coding to was_dirty()
 68:  f4d43a1ff1 =  90:  5efdc2b3c2 merge-recursive: teach was_dirty() about the virtualfilesystem
 69:  46dba7d08a =  91:  ee729c17b0 status: deserialize with -uno does not print correct hint
 72:  59fd64e17c =  92:  fd06941436 backwards-compatibility: support the post-indexchanged hook
 73:  c54c4615a1 =  93:  8b34a15414 credential: set trace2_child_class for credential manager children
 74:  1e584fe0f6 =  94:  b3be97256f sub-process: do not borrow cmd pointer from caller
 75:  93452626c1 =  95:  2967d91b39 sub-process: add subprocess_start_argv()
 76:  e18f4c8a14 =  96:  5563586b01 sha1-file: add function to update existing loose object cache
 77:  1dcbb84ed3 =  97:  79c1edae31 packfile: add install_packed_git_and_mru()
 78:  a710a93136 =  98:  67adc16e36 index-pack: avoid immediate object fetch while parsing packfile
 79:  f629b0e0d1 =  99:  1f41b15703 gvfs-helper: create tool to fetch objects using the GVFS Protocol
 80:  d4370304a2 = 100:  4d4a8e1aa7 gvfs-helper: fix race condition when creating loose object dirs
 81:  9a93c9ad17 = 101:  b54ed3fe80 sha1-file: create shared-cache directory if it doesn't exist
 82:  aac7a3bb5a = 102:  38fcee6f25 gvfs-helper-client: rename ghs__ symbols to gh_server__
 83:  a7f1e5e251 = 103:  5237d68277 gvfs-helper-client: rename ghs__chosen_odb to gh_client__chosen_odb for clarity
 84:  a6c494e822 = 104:  bcc85ea670 gvfs-helper-client: rename ghc__ symbols to gh_client__ for clarity
 85:  4afb0d1a68 = 105:  fe54533728 gvfs-helper: better handling of network errors
 86:  7a1e574ede = 106:  6cad4c108d gvfs-helper-client: properly update loose cache with fetched OID
 87:  f7dce93635 = 107:  5003eb28b2 gvfs-helper: V2 robust retry and throttling
 88:  e765163b60 = 108:  7719fc201c gvfs-helper: expose gvfs/objects GET and POST semantics
 89:  c35b525322 = 109:  d7b4a7d557 gvfs-helper: dramatically reduce progress noise
 90:  69d9dffd8c = 110:  29ae8cd119 gvfs-helper-client.h: define struct object_id
 91:  c25566ee67 = 111:  0dc4f22c6e gvfs-helper: handle pack-file after single POST request
 92:  ee2d76fe85 = 112:  3291a04b7e test-gvfs-prococol, t5799: tests for gvfs-helper
 93:  955e2df361 = 113:  b5b927e058 t/helper/.gitignore: add test-gvfs-procotol
 94:  f096355753 = 114:  c8e59895ac gvfs-helper: move result-list construction into install functions
 95:  4d18c7721d = 115:  3b1481d27f t5799: add support for POST to return either a loose object or packfile
 96:  3d7cfb5cbf = 116:  6553313f2c t5799: cleanup wc-l and grep-c lines
 97:  e9b05d56c3 = 117:  bfe1b52cd3 fsmonitor: check CE_FSMONITOR_VALID in ce_uptodate
 98:  49b47a0b4f = 118:  9279532952 fsmonitor: add script for debugging and update script for tests
 99:  3452d42d46 ! 119:  80f9676a66 gvfs-helper: add prefetch support
    @@ gvfs-helper.c: static int create_loose_pathname_in_odb(struct strbuf *buf_path,
     +		 * TODO just the checksum ?
     +		 */
     +		strbuf_trim_trailing_newline(&ip_stdout);
    ++
    ++		strbuf_addbuf(packfile_checksum, &ip_stdout);
    ++	}
      
     -	/*
     -	 * Build a unique tempfile pathname based upon it.  We avoid
    @@ gvfs-helper.c: static int create_loose_pathname_in_odb(struct strbuf *buf_path,
     -	 * crashes.
     -	 */
     -	strbuf_addf(&buf_path, ".%08u.%.06u.temp", getpid(), nth++);
    -+		strbuf_addbuf(packfile_checksum, &ip_stdout);
    -+	}
    ++cleanup:
    ++	strbuf_release(&ip_stdout);
    ++	child_process_clear(&ip);
    ++}
      
     -	params->tempfile = create_tempfile(buf_path.buf);
     -	if (!params->tempfile) {
    @@ gvfs-helper.c: static int create_loose_pathname_in_odb(struct strbuf *buf_path,
     -			      "could not create tempfile for loose object");
     -		status->ec = GH__ERROR_CODE__COULD_NOT_CREATE_TEMPFILE;
     -		goto cleanup;
    -+cleanup:
    -+	strbuf_release(&ip_stdout);
    -+	child_process_clear(&ip);
    -+}
    -+
     +static void my_finalize_packfile(struct gh__request_params *params,
     +				 struct gh__response_status *status,
     +				 const struct strbuf *temp_path_pack,
    @@ gvfs-helper.c: static enum gh__error_code do_sub_cmd__post(int argc, const char
     +	static const char *since_str;
     +	static struct option prefetch_options[] = {
     +		OPT_STRING(0, "since", &since_str, N_("since"), N_("seconds since epoch")),
    ++		OPT_END(),
     +	};
     +
     +	struct gh__response_status status = GH__RESPONSE_STATUS_INIT;
100:  adb6ce7a0a = 120:  f4ba34b583 gvfs-helper: add prefetch .keep file for last packfile
101:  ae319fa922 = 121:  11e55eb731 gvfs-helper: do one read in my_copy_fd_len_tail()
102:  dabc2c38a1 = 122:  9c1efcad18 gvfs-helper: move content-type warning for prefetch packs
103:  84b1aa8b2d = 123:  79e92304b1 fetch: use gvfs-helper prefetch under config
104:  61def50d4f <   -:  ---------- fetch: add --no-update-remote-refs
105:  dd08b256be = 124:  0469f1dcbb gvfs-helper: better support for concurrent packfile fetches
106:  1c677fdfdb = 125:  94fa1d0541 gvfs-helper: retry when creating temp files
107:  a67b734f41 = 126:  c861919bac Revert "sparse-checkout: check for dirty status"
108:  13e731aef8 <   -:  ---------- Revert "dir: synchronize treat_leading_path() and read_directory_recursive()"
109:  ff1c1f502c <   -:  ---------- Revert "dir: fix checks on common prefix directory"
110:  1c00d4901a <   -:  ---------- msvc: accommodate for vcpkg's upgrade to OpenSSL v1.1.x
111:  5f63115800 <   -:  ---------- fixup! fetch: add --no-update-remote-refs
127:  0aac91ca25 = 127:  0b9369dbfd remote-curl: do not call fetch-pack when using gvfs-helper
128:  b114c34159 = 128:  3c7066eecf vfs: disable `git update-git-for-windows`
129:  be59f1826a <   -:  ---------- ci: ignore rubygems warning in the "Documentation" job

derrickstolee and others added 30 commits January 24, 2020 13:26
When testing the sparse-checkout feature, we need to compare the
contents of the working-directory against some expected output.
Using here-docs was useful in the beginning, but became repetetive
as the test script grew.

Create a check_files helper to make the tests simpler and easier
to extend. It also reduces instances of bad here-doc whitespace.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
t1091-sparse-checkout-builtin.sh uses here-docs to populate the
expected contents of the sparse-checkout file. These do not use
shell interpolation, so use "-\EOF" instead of "-EOF". Also use
proper tabbing.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
The 'git init' command creates the ".git/info" directory and fills it
with some default files. However, 'git worktree add' does not create
the info directory for that worktree. This causes a problem when running
"git sparse-checkout init" inside a worktree. While care was taken to
allow the sparse-checkout config to be specific to a worktree, this
initialization was untested.

Safely create the leading directories for the sparse-checkout file. This
is the safest thing to do even without worktrees, as a user could delete
their ".git/info" directory and expect Git to recover safely.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
The --sparse option was added to the clone builtin in d89f09c (clone:
add --sparse mode, 2019-11-21) and was tested with a local path clone
in t1091-sparse-checkout-builtin.sh. However, due to a difference in
how local paths are handled versus URLs, this mechanism does not work
with URLs.

Modify the test to use a "file://" URL, which would output this error
before the code change:

  Cloning into 'clone'...
  fatal: cannot change to 'file://.../repo': No such file or directory
  error: failed to initialize sparse-checkout

These errors are due to using a "-C <path>" option to call 'git -C
<path> sparse-checkout init' but the URL is being given instead of
the target directory.

Update that target directory to evaluate this correctly. I have also
manually tested that https:// URLs are handled correctly as well.

Acked-by: Taylor Blau <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
Signed-off-by: Jeff King <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
When core.sparseCheckoutCone is enabled, the 'git sparse-checkout set'
command creates a restricted set of possible patterns that are used
by a custom algorithm to quickly match those patterns.

If a user manually edits the sparse-checkout file, then they could
create patterns that do not match these expectations. The cone-mode
matching algorithm can return incorrect results. The solution is to
detect these incorrect patterns, warn that we do not recognize them,
and revert to the standard algorithm.

Check each pattern for the "**" substring, and revert to the old
logic if seen. While technically a "/<dir>/**" pattern matches
the meaning of "/<dir>/", it is not one that would be written by
the sparse-checkout builtin in cone mode. Attempting to accept that
pattern change complicates the logic and instead we punt and do
not accept any instance of "**".

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
In cone mode, the shortest pattern the sparse-checkout command will
write into the sparse-checkout file is "/*". This is handled carefully
in add_pattern_to_hashsets(), so warn if any other pattern is this
short. This will assist future pattern checks by allowing us to assume
there are at least three characters in the pattern.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
In cone mode, the sparse-checkout commmand will write patterns that
allow faster pattern matching. This matching only works if the patterns
in the sparse-checkout file are those written by that command. Users
can edit the sparse-checkout file and create patterns that cause the
cone mode matching to fail.

The cone mode patterns may end in "/*" but otherwise an un-escaped
asterisk or other glob character is invalid. Add checks to disable
cone mode when seeing these values.

A later change will properly handle escaped globs.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
In cone mode, the sparse-checkout feature uses hashset containment
queries to match paths. Make this algorithm respect escaped asterisk
(*) and backslash (\) characters.

Create dup_and_filter_pattern() method to convert a pattern by
removing escape characters and dropping an optional "/*" at the end.
This method is available in dir.h as we will use it in
builtin/sparse-checkout.c in a later change.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
If a user somehow creates a directory with an asterisk (*) or backslash
(\), then the "git sparse-checkout set" command will struggle to provide
the correct pattern in the sparse-checkout file. When not in cone mode,
the provided pattern is written directly into the sparse-checkout file.
However, in cone mode we expect a list of paths to directories and then
we convert those into patterns.

However, there is some care needed for the timing of these escapes. The
in-memory pattern list is used to update the working directory before
writing the patterns to disk. Thus, we need the command to have the
unescaped names in the hashsets for the cone comparisons, then escape
the patterns later.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
If a user somehow creates a directory with an asterisk (*) or backslash
(\), then the "git sparse-checkout set" command will struggle to provide
the correct pattern in the sparse-checkout file. When not in cone mode,
the provided pattern is written directly into the sparse-checkout file.
However, in cone mode we expect a list of paths to directories and then
we convert those into patterns.

Even more specifically, the goal is to always allow the following from
the root of a repo:

  git ls-tree --name-only -d HEAD | git sparse-checkout set --stdin

The ls-tree command provides directory names with an unescaped asterisk.
It also quotes the directories that contain an escaped backslash. We
must remove these quotes, then keep the escaped backslashes.

Use unquote_c_style() when parsing lines from stdin. Command-line
arguments will be parsed as-is, assuming the user can do the correct
level of escaping from their environment to match the exact directory
names.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
When in cone mode, the 'git sparse-checkout list' subcommand lists
the directories included in the sparse cone. When these directories
contain odd characters, such as a backslash, then we need to use
C-style quotes similar to 'git ls-tree'.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
The sparse-checkout patterns allow special globs according to
fnmatch(3). When writing cone-mode patterns for paths containing
these characters, they must be escaped.

Use is_glob_special() to check which characters must be escaped
this way, and add a path to the tests that contains all glob
characters at once. Note that ']' is not special, since the
initial bracket '[' is escaped.

Reported-by: Jeff King <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
The existing documentation does not clarify how the 'set' subcommand
changes when core.sparseCheckoutCone is enabled. Correct this by
changing some language around the "A/B/C" example. Also include a
description of the input format matching the output of 'git ls-tree
--name-only'.

Helped-by: Jeff King <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
The intention of the special "cone mode" in the sparse-checkout
feature is to always match the same patterns that are matched by the
same sparse-checkout file as when cone mode is disabled.

When a file path is given to "git sparse-checkout set" in cone mode,
then the cone mode improperly matches the file as a recursive path.
When setting the skip-worktree bits, files were not expecting the
MATCHED_RECURSIVE response, and hence these were left out of the
matched cone.

Fix this bug by checking for MATCHED_RECURSIVE in addition to MATCHED
and add a test that prevents regression.

Reported-by: Finn Bryant <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
In anticipation of extending the sparse-checkout builtin with "add"
and "remove" subcommands, extract the code that fills a pattern list
based on the input values. The input changes depending on the
presence of "--stdin" or the value of core.sparseCheckoutCone.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
In anticipation of adding "add" and "remove" subcommands to the
sparse-checkout builtin, extract a modify_pattern_list() method from the
sparse_checkout_set() method. This command will read input from the
command-line or stdin to construct a set of patterns, then modify the
existing sparse-checkout patterns after a successful update of the
working directory.

Currently, the only way to modify the patterns is to replace all of the
patterns. This will be extended in a later update.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
When using the sparse-checkout feature, a user may want to incrementally
grow their sparse-checkout pattern set. Allow adding patterns using a
new 'add' subcommand. This is not much different from the 'set'
subcommand, because we still want to allow the '--stdin' option and
interpret inputs as directories when in cone mode and patterns
otherwise.

When in cone mode, we are growing the cone. This may actually reduce the
set of patterns when adding directory A when A/B is already a directory
in the cone. Test the different cases: siblings, parents, ancestors.

When not in cone mode, we can only assume the patterns should be
appended to the sparse-checkout file.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
When using Windows, a user may run 'git sparse-checkout set A\B\C'
to add the Unix-style path A/B/C to their sparse-checkout patterns.
Normalizing the input path converts the backslashes to slashes before we
add the string 'A/B/C' to the recursive hashset.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
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 <[email protected]>
This header file will accumulate GVFS-specific definitions.

Signed-off-by: Kevin Willford <[email protected]>
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 <[email protected]>
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 <[email protected]>
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.

Signed-off-by: Kevin Willford <[email protected]>
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 <[email protected]>
The two existing members of the run_hook*() family, run_hook_ve() and
run_hook_le(), are good for callers that know the precise number of
parameters already. Let's introduce a new sibling that takes an argv
array for callers that want to pass a variable number of parameters.

Signed-off-by: Johannes Schindelin <[email protected]>
jeffhostetler and others added 18 commits February 21, 2020 10:38
The fsmonitor script that can be used for running all the git tests
using watchman was causing some of the tests to fail because it wrote
to stderr and created some files for debugging purposes.

Add a new debug script to use with debugging and modify the other script
to remove the code that would cause tests to fail.

Signed-off-by: Kevin Willford <[email protected]>
test-gvfs-prococol, t5799: tests for gvfs-helper
fsmonitor updates for improved performance
The gvfs-helper allows us to download prefetch packs using a simple
subprocess call. The gvfs-helper-client.h method will automatically
compute the timestamp if passing 0, and passing NULL for the number
of downloaded packs is valid.

Signed-off-by: Derrick Stolee <[email protected]>
This replaces #223. There was a strangely-subtle issue about reading
the trailing hash from the downloaded packs that caused issues when
reading from the origin remote.

Add `gvfs-helper prefetch` command line option
and `objects.prefetch` mode in `gvfs-helper server`.

Sorry, but this contains a major refactor of the packfile and loose file handling
to let me share it with the prefetch code.  As a side benefit, I collapsed the
tempfile creation before the request goes out and merged the install_ code
after the result is returned.

I also changed packfile code to use the packfile-checksum rather than a
timestamp so that we look more like normal Git.

More details are in the commit message.
Teach gvfs-helper to better support the concurrent fetching of the
same packfile by multiple instances.

If 2 instances of gvfs-helper did a POST and requested the same set of
OIDs, they might receive the exact same packfile (same checksum SHA).
Both processes would then race to install their copy of the .pack and
.idx files into the ODB/pack directory.

This is not a problem on Unix (because of filesystem semantics).

On Windows, this can cause an EBUSY/EPERM problem for the loser while
the winner is holding a handle to the target files.  (The existing
packfile code already handled simple the existence and/or replacement
case.)

The solution presented here is to silently let the loser claim
victory IIF the .pack and .idx are already present in the ODB.
(We can't check this in advance because we don't know the packfile
SHA checksum until after we receive it and run index-pack.)

We avoid using a per-packfile lockfile (or a single lockfile for
the `vfs-` prefix) to avoid the usual issues with stale lockfiles.

Signed-off-by: Jeff Hostetler <[email protected]>
This is a follow-up to #227.

1. When a new flag is added to our Git config, we can run `gvfs-helper prefetch` inside of our `git fetch` calls. This will help ensure we have updated commits and trees even if the background prefetches have fallen behind (or are not running).

2. With a new `--no-update-remote-refs` we can avoid updating the `refs/remotes` namespace. This will allow us to run `git fetch --all --no-update-remote-refs +refs/heads/*:refs/hidden/*` and we will get the new refs into a local folder (that doesn't appear anywhere). The most important thing is that users will still see when their remote refs update.
When we create temp files for downloading packs, we use a name
based on the current timestamp. There is no randomness in the
name, so we can have collisions in the same second.

Retry the temp pack names using a new "-<retry>" suffix to the
name before the ".temp".

Signed-off-by: Derrick Stolee <[email protected]>
gvfs-helper: better support for concurrent packfile fetches
When we create temp files for downloading packs, we use a name
based on the current timestamp. There is no randomness in the
name, so we can have collisions in the same second.

Retry the temp pack names using a new "-<retry>" suffix to the
name before the ".temp".

This is a follow-up to #229.
When using the GVFS protocol, we should _never_ call "git fetch-pack"
to attempt downloading a pack-file via the regular Git protocol. It
appears that the mechanism that prevented this in the VFS for Git
world is due to the read-object hook populating the commits at the
new ref tips in a different way than the gvfs-helper does.

By acting as if the fetch-pack succeeds here in remote-curl, we
prevent a failed fetch.

Signed-off-by: Derrick Stolee <[email protected]>
This reverts commit cff4e91.

This is temporary until we fix this behavior upstream. For now,
we need to allow the sparse-checkout command to run when the
status is not clean.

Signed-off-by: Derrick Stolee <[email protected]>
If a user runs git update-git-for-windows, then they will upgrade to a
version that does not support microsoft/vfsforgit or microsoft/scalar.

Therefore, let's prevent this.

This addresses #241
…g gvfs helper

The `gvfs-helper` is supposed to avoid calling `git fetch-pack` by downloading objects through the GVFS protocol instead. For some reason, some `git fetch` calls still end up calling `git fetch-pack` which gets a complaint from the remote because it does not support that kind of fetch.

Put a hard stop in the `fetch_git()` method to prevent this process run.
Disable `git update-git-for-windows`
When computing changed-path Bloom filters or performing a name-only
diff, we do not need the blob contents before completing the diff
values. Thus, we do not need to download a pack containing the blobs
we do not have on-disk before completing our diff calculation.

This prevents downloading every blob in a partial clone during
"git log --raw" and "git diff --name-only" commands.

Signed-off-by: Derrick Stolee <[email protected]>
@derrickstolee
Copy link
Author

/azp run microsoft.git

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@derrickstolee derrickstolee marked this pull request as ready for review February 21, 2020 19:31
@derrickstolee derrickstolee merged commit 397006e into vfs-2.25.1 Feb 21, 2020
derrickstolee added a commit to microsoft/scalar that referenced this pull request Feb 21, 2020
derrickstolee added a commit to microsoft/VFSForGit that referenced this pull request Feb 21, 2020
@derrickstolee derrickstolee deleted the tentative/vfs-2.25.1 branch March 6, 2020 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants