Skip to content

Conversation

@derrickstolee
Copy link

@derrickstolee derrickstolee commented Mar 6, 2020

Currently based on v2.26.0-rc2.windows.1.

Here is the range-diff:

  1:  522e641748 <   -:  ---------- t1091: use check_files to reduce boilerplate
  2:  d622c34396 <   -:  ---------- t1091: improve here-docs
  3:  3c754067a1 <   -:  ---------- sparse-checkout: create leading directories
  4:  47dbf10d8a <   -:  ---------- clone: fix --sparse option with URLs
  5:  7aa9ef2fca <   -:  ---------- sparse-checkout: fix documentation typo for core.sparseCheckoutCone
  6:  41de0c6fbc <   -:  ---------- sparse-checkout: cone mode does not recognize "**"
  7:  9e6d3e6417 <   -:  ---------- sparse-checkout: detect short patterns
  8:  9abc60f801 <   -:  ---------- sparse-checkout: warn on globs in cone patterns
  9:  4f52c2ce6c <   -:  ---------- sparse-checkout: properly match escaped characters
 10:  d585f0e799 <   -:  ---------- sparse-checkout: write escaped patterns in cone mode
 11:  bd64de42de <   -:  ---------- sparse-checkout: unquote C-style strings over --stdin
 12:  e55682ea26 <   -:  ---------- sparse-checkout: use C-style quotes in 'list' subcommand
 13:  e53ffe2704 <   -:  ---------- sparse-checkout: escape all glob characters on write
 14:  d2e65f4c90 <   -:  ---------- sparse-checkout: improve docs around 'set' in cone mode
 15:  f998a3f1e5 <   -:  ---------- sparse-checkout: fix cone mode behavior mismatch
 16:  6fb705abcb <   -:  ---------- sparse-checkout: extract add_patterns_from_input()
 17:  4bf0c06c71 <   -:  ---------- sparse-checkout: extract pattern update from 'set' subcommand
 18:  2631dc879d <   -:  ---------- sparse-checkout: create 'add' subcommand
 19:  ef07659926 <   -:  ---------- sparse-checkout: work with Windows paths
 20:  aec00fb6d2 =   1:  151a6fd4a1 reset --stdin: trim carriage return from the paths
 21:  ddae419f00 !   2:  1f5a65d4b9 gvfs: start by adding the -gvfs suffix to the version
    @@ GIT-VERSION-GEN
      #!/bin/sh
      
      GVF=GIT-VERSION-FILE
    --DEF_VER=v2.25.1
    -+DEF_VER=v2.25.1.vfs.1.1
    +-DEF_VER=v2.26.0
    ++DEF_VER=v2.26.0.vfs.1.1
      
      LF='
      '
 22:  35222f0a05 =   3:  b00b12c7ab gvfs: ensure that the version is based on a GVFS tag
 23:  553b86fd98 =   4:  6e4134d142 gvfs: add a GVFS-specific header file
 24:  c6ab81b481 =   5:  ee42b60b0c gvfs: add the core.gvfs config setting
 25:  ca9383b610 =   6:  5b2464cf18 gvfs: add the feature to skip writing the index' SHA-1
 26:  f030eb86e4 =   7:  d807b2074d gvfs: add the feature that blobs may be missing
 27:  1259c93fe4 =   8:  d7e1f19ac1 gvfs: prevent files to be deleted outside the sparse checkout
 28:  518cc2cad8 =   9:  435be2e5c3 gvfs: optionally skip reachability checks/upload pack during fetch
 29:  5d0d824db6 =  10:  8ccff72fa4 gvfs: ensure all filters and EOL conversions are blocked
 30:  c9984b7562 =  11:  8396af71ab Add a new run_hook_argv() function
 31:  5703d80417 !  12:  f1f796f6d9 gvfs: allow "virtualizing" objects
    @@ environment.c: int core_gvfs;
      #ifndef PROTECT_HFS_DEFAULT
     
      ## sha1-file.c ##
    -@@ sha1-file.c: static int loose_object_info(struct repository *r,
    - 	return (status < 0) ? status : 0;
    +@@ sha1-file.c: void disable_obj_read_lock(void)
    + 	pthread_mutex_destroy(&obj_read_mutex);
      }
      
     +static int run_read_object_hook(const struct object_id *oid)
    @@ sha1-file.c: static int loose_object_info(struct repository *r,
     +
      int fetch_if_missing = 1;
      
    - int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    -@@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    + static int do_oid_object_info_extended(struct repository *r,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      	int rtype;
      	const struct object_id *real = oid;
      	int already_retried = 0;
     +	int tried_hook = 0;
      
    + 
      	if (flags & OBJECT_INFO_LOOKUP_REPLACE)
    - 		real = lookup_replace_object(r, oid);
    -@@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      	if (!oi)
      		oi = &blank_oi;
      
    @@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct obj
      	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,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      			reprepare_packed_git(r);
      			if (find_pack_entry(r, real, &e))
      				break;
 32:  60b95f24c4 !  13:  751b9711dc Hydrate missing loose objects in check_and_freshen()
    @@ sha1-file.c: static int check_and_freshen_nonlocal(const struct object_id *oid,
      }
      
      int has_loose_object_nonlocal(const struct object_id *oid)
    -@@ sha1-file.c: static int loose_object_info(struct repository *r,
    - 	return (status < 0) ? status : 0;
    +@@ sha1-file.c: void disable_obj_read_lock(void)
    + 	pthread_mutex_destroy(&obj_read_mutex);
      }
      
     -static int run_read_object_hook(const struct object_id *oid)
    @@ sha1-file.c: static int loose_object_info(struct repository *r,
     -
      int fetch_if_missing = 1;
      
    - int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    + static int do_oid_object_info_extended(struct repository *r,
     
      ## t/t0411-read-object.sh (new) ##
     @@
 33:  00c1a61fae !  14:  8d92e3758e Add support for read-object as a background process to retrieve missing objects
    @@ sha1-file.c: static int check_and_freshen(const struct object_id *oid, int fresh
      			goto retry;
      	}
      
    -@@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      				break;
      			if (core_virtualize_objects && !tried_hook) {
      				tried_hook = 1;
 34:  5e513a18f4 !  15:  7e5b996560 sha1_file: when writing objects, skip the read_object_hook
    @@ sha1-file.c: static int write_loose_object(const struct object_id *oid, char *hd
      
      static int freshen_packed_object(const struct object_id *oid)
     @@ sha1-file.c: int write_object_file(const void *buf, unsigned long len, const char *type,
    - 	 * it out into .git/objects/??/?{38} file.
      	 */
    - 	write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen);
    + 	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
    + 				  &hdrlen);
     -	if (freshen_packed_object(oid) || freshen_loose_object(oid))
     +	if (freshen_packed_object(oid) || freshen_loose_object(oid, 1))
      		return 0;
 35:  8aa1a54317 =  16:  a156dc72fa gvfs: add global command pre and post hook procs
 36:  f42366ef1e =  17:  f231582391 Allow hooks to be run before setup_git_directory()
 37:  50a7858b17 =  18:  7127b5bbe4 gvfs: introduce pre/post command hooks
 39:  c6a4f50b97 =  19:  ad6d21d5cd t0400: verify that the hook is called correctly from a subdirectory
 38:  38d8dc46cb =  20:  fc961801c2 sparse-checkout: update files with a modify/delete conflict
 40:  6774bf9482 =  21:  743d05cacc sparse-checkout: avoid writing entries with the skip-worktree bit
 41:  abe3c84396 =  22:  4a0851a5e3 Pass PID of git process to hooks.
 42:  abce59c890 =  23:  69a2d504d0 Fix reset when using the sparse-checkout feature.
 43:  251a28ab3d =  24:  4475dfbd8c pre-command: always respect core.hooksPath
 44:  ee592f65e9 =  25:  f000f1281d Do not remove files outside the sparse-checkout
 45:  1c0c811bfd =  26:  f2532500c9 gvfs: refactor loading the core.gvfs config value
 46:  630ecb7d6a =  27:  bf5d479012 cache-tree: remove use of strbuf_addf in update_one
 47:  bbf87397d0 =  28:  4873f397d4 status: add status serialization mechanism
 48:  f555d493d7 =  29:  a363d336b1 Teach ahead-behind and serialized status to play nicely together
 49:  d4336edc6d =  30:  8de43dbc26 status: serialize to path
 50:  c9e80e2154 =  31:  d721b7602a status: reject deserialize in V2 and conflicts
 55:  0fab055dc8 !  32:  4059f12b5c Add virtual file system settings and hook proc
    @@ Commit message
         Signed-off-by: Ben Peart <benpeart@microsoft.com>
     
      ## Documentation/config/core.txt ##
    -@@ Documentation/config/core.txt: core.fsmonitor::
    - 	avoiding unnecessary processing of files that have not changed.
    - 	See the "fsmonitor-watchman" section of linkgit:githooks[5].
    +@@ Documentation/config/core.txt: core.fsmonitorHookVersion::
    + 	something that can be used to determine what files have changed
    + 	without race conditions.
      
     +core.virtualFilesystem::
     +	If set, the value of this variable is used as a command which
 56:  162ac55ecf =  33:  895fe5e3d2 Update the virtualfilesystem support
 57:  85aef2e9da =  34:  2148bb0457 virtualfilesystem: don't run the virtual file system hook if the index has been redirected
 58:  42230ccc52 =  35:  3bd29cb0b4 virtualfilesystem: fix bug with symlinks being ignored
 59:  f41adf20a6 =  36:  78e717d29d virtualfilesystem: check if directory is included
 60:  4a54e81089 =  37:  52d774059f vfs: fix case where directories not handled correctly
 61:  c5bf92afc4 =  38:  10daf3c37b commit: add generation to pop_most_recent_commit()
 62:  92e1e13388 =  39:  e6c9336e0c status: fix rename reporting when using serialization cache
 63:  3c674868e9 =  40:  98140ad161 status: add comments for ahead_behind_flags in serialization
 64:  81921ed70a =  41:  0cc87e8422 serialize-status: serialize global and repo-local exclude file metadata
 65:  c5ef02ae1a =  42:  01d5d88321 status: deserialization wait
 66:  0636e7b621 =  43:  e299835d3f rebase/stash: make post-command hook work again
 51:  b7d8c5802a =  44:  169bfebb1c fsck: use ERROR_MULTI_PACK_INDEX
 67:  64f57427b9 =  45:  ef9c1332a9 send-pack: do not check for sha1 file when GVFS_MISSING_OK set
 68:  d34347add0 =  46:  8bdfdd7d02 gvfs: block unsupported commands when running in a GVFS repo
 69:  720a07ab7e =  47:  d7ee1a7422 BRANCHES.md: Add explanation of branches and using forks
 70:  db1cc6d0e0 =  48:  2bae4005fc gvfs:trace2:data: add trace2 tracing around read_object_process
 71:  aae47c6876 =  49:  9110266124 gvfs:trace2:data: status deserialization information
 72:  0e538f6fcd =  50:  5bb3b37531 gvfs:trace2:data: status serialization
 73:  d906aaf7e5 =  51:  b46dbcb620 gvfs:trace2:data: add vfs stats
 74:  fc0fe94b6b =  52:  1826c2182a trace2: refactor setting process starting time
 75:  597a455020 =  53:  57a1c77122 trace2:gvfs:experiment: clear_ce_flags_1
 76:  997365974d =  54:  0225e8102a trace2:gvfs:experiment: traverse_trees
 77:  375785868d =  55:  2f0407cb0c trace2:gvfs:experiment: report_tracking
 78:  72284e22c6 =  56:  dd8830f18c trace2:gvfs:experiment: read_cache: annotate thread usage in read-cache
 79:  c57a07b913 =  57:  f7b1bf9f83 trace2:gvfs:experiment: read-cache: time read/write of cache-tree extension
 80:  b77de01106 =  58:  8107736e00 trace2:gvfs:experiment: add prime_cache_tree region
 81:  adf312780f =  59:  1744c520d1 trace2:gvfs:experiment: add region to apply_virtualfilesystem()
 82:  16a1faf04e =  60:  9a04644e14 trace2:gvfs:experiment: add region around unpack_trees()
 83:  304c14e15b =  61:  ff72101463 trace2:gvfs:experiment: add region to cache_tree_fully_valid()
 84:  cc2047bc95 =  62:  900d0a2db5 trace2:gvfs:experiment: add unpack_entry() counter to unpack_trees() and report_tracking()
 85:  a82ad4f692 =  63:  106957a9fa trace2:gvfs:experiment: increase default event depth for unpack-tree data
 86:  14195c4b77 !  64:  b24a7c78d0 trace2:gvfs:experiment: add data for check_updates() in unpack_trees()
    @@ Commit message
     
         Give proper category name to all events in unpack-trees.c and eliminate "exp".
     
    +    This is modified slightly from the original version due to interactions with 26f924d
    +    (unpack-trees: exit check_updates() early if updates are not wanted, 2020-01-07).
    +
         Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
    +    Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
     
      ## unpack-trees.c ##
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
    @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      	state.quiet = 1;
      	state.refresh_cache = 1;
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
    - 
      		if (ce->ce_flags & CE_WT_REMOVE) {
      			display_progress(progress, ++cnt);
    --			if (o->update && !o->dry_run)
    -+			if (o->update && !o->dry_run) {
    - 				unlink_entry(ce);
    -+				sum_unlink++;
    -+			}
    + 			unlink_entry(ce);
    ++			sum_unlink++;
      		}
      	}
    - 	remove_marked_cache_entries(index, 0);
    + 
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      				continue;
      			oid_array_append(&to_fetch, &ce->oid);
    @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      			promisor_remote_get_direct(the_repository,
      						   to_fetch.oid, to_fetch.nr);
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
    + 			display_progress(progress, ++cnt);
      			ce->ce_flags &= ~CE_UPDATE;
    - 			if (o->update && !o->dry_run) {
    - 				errs |= checkout_entry(ce, &state, NULL, NULL);
    -+				sum_checkout++;
    - 			}
    + 			errs |= checkout_entry(ce, &state, NULL, NULL);
    ++			sum_checkout++;
      		}
      	}
    + 	stop_progress(&progress);
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      	if (o->clone)
      		report_collided_checkout(index);
 87:  b4fa3688a2 =  65:  45efaa3088 Trace2:gvfs:experiment: capture more 'tracking' details
 88:  35413cb1b9 =  66:  29927d9d47 merge-recursive: avoid confusing logic in was_dirty()
 89:  5bb9f62128 =  67:  09ca36beb5 merge-recursive: add some defensive coding to was_dirty()
 90:  5efdc2b3c2 =  68:  fcc1e452ec merge-recursive: teach was_dirty() about the virtualfilesystem
 91:  ee729c17b0 =  69:  052c036e84 status: deserialize with -uno does not print correct hint
 52:  3eae1576e8 !  70:  26d594b083 t5516: relax error message pattern
    @@ Commit message
      ## t/t5516-fetch-push.sh ##
     @@ t/t5516-fetch-push.sh: do
      			git cat-file commit $SHA1_2 &&
    - 			test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
    + 			test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
      				git fetch ../testrepo/.git $SHA1_3 2>err &&
     -			test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
     +			test_i18ngrep "not our ref.*$SHA1_3" err
 53:  694acebed5 =  71:  64aaeb4200 upload-pack: fix race condition in error messages
 54:  6c11c6a124 <   -:  ---------- sparse-checkout: allow one-character directories in cone mode
 92:  fd06941436 =  72:  b281fa681e backwards-compatibility: support the post-indexchanged hook
 93:  8b34a15414 =  73:  c335c6057a credential: set trace2_child_class for credential manager children
 94:  b3be97256f =  74:  a1a53f1111 sub-process: do not borrow cmd pointer from caller
 95:  2967d91b39 =  75:  6dc242dd01 sub-process: add subprocess_start_argv()
 96:  5563586b01 =  76:  a90d8aa84f sha1-file: add function to update existing loose object cache
 97:  79c1edae31 =  77:  1bc5c4c2ff packfile: add install_packed_git_and_mru()
 98:  67adc16e36 =  78:  0dd9d84593 index-pack: avoid immediate object fetch while parsing packfile
 99:  1f41b15703 !  79:  9f6a8f6c9f gvfs-helper: create tool to fetch objects using the GVFS Protocol
    @@ sha1-file.c
      
      /* The maximum size for an object header. */
      #define MAX_HEADER_LEN 32
    -@@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      	const struct object_id *real = oid;
      	int already_retried = 0;
      	int tried_hook = 0;
    +-
     +	int tried_gvfs_helper = 0;
      
      	if (flags & OBJECT_INFO_LOOKUP_REPLACE)
      		real = lookup_replace_object(r, oid);
    -@@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      		if (!loose_object_info(r, real, oi, flags))
      			return 0;
      
100:  4d4a8e1aa7 =  80:  0dd734c778 gvfs-helper: fix race condition when creating loose object dirs
101:  b54ed3fe80 =  81:  1f28ede3b0 sha1-file: create shared-cache directory if it doesn't exist
102:  38fcee6f25 =  82:  35ccb65dca gvfs-helper-client: rename ghs__ symbols to gh_server__
103:  5237d68277 =  83:  8dd82e113b gvfs-helper-client: rename ghs__chosen_odb to gh_client__chosen_odb for clarity
104:  bcc85ea670 !  84:  3b5b873093 gvfs-helper-client: rename ghc__ symbols to gh_client__ for clarity
    @@ gvfs-helper-client.h: int ghc__get_immediate(const struct object_id *oid, enum g
      #endif /* GVFS_HELPER_CLIENT_H */
     
      ## sha1-file.c ##
    -@@ sha1-file.c: int oid_object_info_extended(struct repository *r, const struct object_id *oid,
    +@@ sha1-file.c: static int do_oid_object_info_extended(struct repository *r,
      			return 0;
      
      		if (core_use_gvfs_helper && !tried_gvfs_helper) {
105:  fe54533728 =  85:  e8368a9040 gvfs-helper: better handling of network errors
106:  6cad4c108d =  86:  92a38d1984 gvfs-helper-client: properly update loose cache with fetched OID
107:  5003eb28b2 =  87:  a0f5456e3c gvfs-helper: V2 robust retry and throttling
108:  7719fc201c =  88:  2a3dbe7100 gvfs-helper: expose gvfs/objects GET and POST semantics
109:  d7b4a7d557 =  89:  98eeef9219 gvfs-helper: dramatically reduce progress noise
110:  29ae8cd119 =  90:  59b28ef04b gvfs-helper-client.h: define struct object_id
111:  0dc4f22c6e =  91:  11a513d5f2 gvfs-helper: handle pack-file after single POST request
112:  3291a04b7e =  92:  76cc36ada0 test-gvfs-prococol, t5799: tests for gvfs-helper
113:  b5b927e058 =  93:  f0f7cfc326 t/helper/.gitignore: add test-gvfs-procotol
114:  c8e59895ac =  94:  6c3e99719d gvfs-helper: move result-list construction into install functions
115:  3b1481d27f =  95:  f9d9fc09ac t5799: add support for POST to return either a loose object or packfile
116:  6553313f2c =  96:  afe1f2a2c1 t5799: cleanup wc-l and grep-c lines
117:  bfe1b52cd3 =  97:  fedd7a0531 fsmonitor: check CE_FSMONITOR_VALID in ce_uptodate
118:  9279532952 =  98:  8eb82167ab fsmonitor: add script for debugging and update script for tests
119:  80f9676a66 =  99:  1da3d9d33d gvfs-helper: add prefetch support
120:  f4ba34b583 = 100:  3fa2346cae gvfs-helper: add prefetch .keep file for last packfile
121:  11e55eb731 = 101:  f1580cfb62 gvfs-helper: do one read in my_copy_fd_len_tail()
122:  9c1efcad18 = 102:  11034864d2 gvfs-helper: move content-type warning for prefetch packs
123:  79e92304b1 = 103:  a654a18335 fetch: use gvfs-helper prefetch under config
124:  0469f1dcbb = 104:  cdacb9b176 gvfs-helper: better support for concurrent packfile fetches
125:  94fa1d0541 = 105:  396182d71f gvfs-helper: retry when creating temp files
126:  c861919bac ! 106:  79dc6584cd Revert "sparse-checkout: check for dirty status"
    @@ builtin/sparse-checkout.c
      #include "resolve-undo.h"
      #include "unpack-trees.h"
     -#include "wt-status.h"
    + #include "quote.h"
      
      static const char *empty_base = "";
    - 
     @@ builtin/sparse-checkout.c: static int sparse_checkout_init(int argc, const char **argv)
      		OPT_END(),
      	};
    @@ builtin/sparse-checkout.c: static int sparse_checkout_init(int argc, const char
      	argc = parse_options(argc, argv, NULL,
      			     builtin_sparse_checkout_init_options,
      			     builtin_sparse_checkout_init_usage, 0);
    -@@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
    +@@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char **argv, const char *prefix,
      		OPT_END(),
      	};
      
    @@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char *
     -	require_clean_work_tree(the_repository,
     -				N_("set sparse-checkout patterns"), NULL, 1, 0);
     -
    - 	memset(&pl, 0, sizeof(pl));
    - 
      	argc = parse_options(argc, argv, prefix,
    + 			     builtin_sparse_checkout_set_options,
    + 			     builtin_sparse_checkout_set_usage,
     @@ builtin/sparse-checkout.c: static int sparse_checkout_disable(int argc, const char **argv)
      	struct pattern_list pl;
      	struct strbuf match_all = STRBUF_INIT;
    @@ builtin/sparse-checkout.c: static int sparse_checkout_disable(int argc, const ch
      	hashmap_init(&pl.parent_hashmap, pl_hashmap_cmp, NULL, 0);
     
      ## t/t1091-sparse-checkout-builtin.sh ##
    -@@ t/t1091-sparse-checkout-builtin.sh: test_expect_success 'cone mode: set with nested folders' '
    - '
    - 
    - test_expect_success 'revert to old sparse-checkout on bad update' '
    --	test_when_finished git -C repo reset --hard &&
    +@@ t/t1091-sparse-checkout-builtin.sh: test_expect_success 'revert to old sparse-checkout on bad update' '
      	echo update >repo/deep/deeper2/a &&
      	cp repo/.git/info/sparse-checkout expect &&
      	test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err &&
     -	test_i18ngrep "cannot set sparse-checkout patterns" err &&
     +	test_i18ngrep "Cannot update sparse checkout" err &&
      	test_cmp repo/.git/info/sparse-checkout expect &&
    - 	list_files repo/deep >dir &&
    - 	cat >expect <<-EOF &&
    + 	check_files repo/deep a deeper1 deeper2
    + '
     @@ t/t1091-sparse-checkout-builtin.sh: test_expect_success '.gitignore should not warn about cone mode' '
      	test_i18ngrep ! "disabling cone patterns" err
      '
127:  0b9369dbfd = 107:  7983e855f6 remote-curl: do not call fetch-pack when using gvfs-helper
128:  3c7066eecf = 108:  b678529b33 vfs: disable `git update-git-for-windows`
129:  397006ee55 = 109:  51b804b57b diff: skip batch object download when possible
130:  d0badf8797 <   -:  ---------- partial-clone: demonstrate bugs in partial fetch
131:  3e96c66805 <   -:  ---------- partial-clone: avoid fetching when looking for objects
132:  7ee8175ca8 <   -:  ---------- ci: prevent `perforce` from being quarantined
133:  36738d9891 <   -:  ---------- t/lib-httpd: avoid using BSD's sed
  -:  ---------- > 110:  fd45198ca2 fetch: reprepare packs before checking connectivity

@dscho
Copy link
Member

dscho commented Mar 9, 2020

Looks pretty good except for one commit:

86:  14195c4b77 !  64:  1d62837ce0 trace2:gvfs:experiment: add data for check_updates() in unpack_trees()
    @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      
      		if (ce->ce_flags & CE_WT_REMOVE) {
      			display_progress(progress, ++cnt);
    --			if (o->update && !o->dry_run)
    +-			unlink_entry(ce);
     +			if (o->update && !o->dry_run) {
    - 				unlink_entry(ce);
    ++				unlink_entry(ce);
     +				sum_unlink++;
     +			}
      		}
      	}
    - 	remove_marked_cache_entries(index, 0);
    + 
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      				continue;
      			oid_array_append(&to_fetch, &ce->oid);
    @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
      			promisor_remote_get_direct(the_repository,
      						   to_fetch.oid, to_fetch.nr);
     @@ unpack-trees.c: static int check_updates(struct unpack_trees_options *o)
    + 				    ce->name);
    + 			display_progress(progress, ++cnt);
      			ce->ce_flags &= ~CE_UPDATE;
    - 			if (o->update && !o->dry_run) {
    - 				errs |= checkout_entry(ce, &state, NULL, NULL);
    +-			errs |= checkout_entry(ce, &state, NULL, NULL);
    ++			if (o->update && !o->dry_run) {
    ++				errs |= checkout_entry(ce, &state, NULL, NULL);
     +				sum_checkout++;
    - 			}
    ++			}
      		}
      	}
    + 	stop_progress(&progress);

That one looks incorrect, as 26f924d explicitly got rid of those conditional blocks guarded by o->update && !o->dry_run.

In other words, I think this hunk of 1d62837ce08053b18fb9ad774ed2867590494991:

@@ -396,7 +400,10 @@ static int check_updates(struct unpack_trees_options *o)

                if (ce->ce_flags & CE_WT_REMOVE) {
                        display_progress(progress, ++cnt);
-                       unlink_entry(ce);
+                       if (o->update && !o->dry_run) {
+                               unlink_entry(ce);
+                               sum_unlink++;
+                       }
                }
        }

should be replaced by

@@ -396,7 +400,8 @@ static int check_updates(struct unpack_trees_options *o)

                if (ce->ce_flags & CE_WT_REMOVE) {
                        display_progress(progress, ++cnt);
                        unlink_entry(ce);
+                       sum_unlink++;
                }
        }

For comparison, in the pre-rebase commit 14195c4, that hunk looked like this:

@@ -391,8 +395,10 @@ static int check_updates(struct unpack_trees_options *o)

                if (ce->ce_flags & CE_WT_REMOVE) {
                        display_progress(progress, ++cnt);
-                       if (o->update && !o->dry_run)
+                       if (o->update && !o->dry_run) {
                                unlink_entry(ce);
+                               sum_unlink++;
+                       }
                }
        }
        remove_marked_cache_entries(index, 0);

And likewise, also in 1d62837ce08053b18fb9ad774ed2867590494991, the hunk

@@ -439,7 +447,10 @@ static int check_updates(struct unpack_trees_options *o)
                                    ce->name);
                        display_progress(progress, ++cnt);
                        ce->ce_flags &= ~CE_UPDATE;
-                       errs |= checkout_entry(ce, &state, NULL, NULL);
+                       if (o->update && !o->dry_run) {
+                               errs |= checkout_entry(ce, &state, NULL, NULL);
+                               sum_checkout++;
+                       }
                }
        }
        stop_progress(&progress);

should be replaced by

@@ -439,7 +447,8 @@ static int check_updates(struct unpack_trees_options *o)
                                    ce->name);
                        display_progress(progress, ++cnt);
                        ce->ce_flags &= ~CE_UPDATE;
                        errs |= checkout_entry(ce, &state, NULL, NULL);
+                       sum_checkout++;
        }
        stop_progress(&progress);

For comparison, in the pre-rebase commit 14195c4, that hunk looked like this:

@@ -436,6 +443,7 @@ static int check_updates(struct unpack_trees_options *o)
                        ce->ce_flags &= ~CE_UPDATE;
                        if (o->update && !o->dry_run) {
                                errs |= checkout_entry(ce, &state, NULL, NULL);
+                               sum_checkout++;
                        }
                }
        }

Copy link
Member

@dscho dscho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As pointed out, I would like to have two changes in 1d62837ce0. Otherwise the PR looks good to go.

@derrickstolee
Copy link
Author

Looks pretty good except for one commit:

Thanks for the extremely thorough description, @dscho! I'll make the suggested changes and try again.

@derrickstolee derrickstolee force-pushed the tentative/vfs-2.26.0 branch 4 times, most recently from 554ecfe to c805465 Compare March 17, 2020 11:35
Kevin Willford and others added 20 commits March 23, 2020 13:41
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>
Signed-off-by: Saeed Noursalehi <sanoursa@microsoft.com>
Signed-off-by: Johannes Schindelin <johasc@microsoft.com>
This header file will accumulate GVFS-specific definitions.

Signed-off-by: Kevin Willford <kewillf@microsoft.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>
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 <johannes.schindelin@gmx.de>
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>
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>
Signed-off-by: Kevin Willford <kewillf@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.

Signed-off-by: Ben Peart <Ben.Peart@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>
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 <kewillf@microsoft.com>
The use case here is to allow usage statistics to be gathered by
running hooks before and after every hook, and to make that
configurable via hooks.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…ng objects

This commit converts the existing read_object hook proc model for
downloading missing blobs to use a background process that is started
the first time git encounters a missing blob and stays running until git
exits.  Git and the read-object process communicate via stdin/stdout and
a versioned, capability negotiated interface as documented in
Documentation/technical/read-object-protocol.txt.  The advantage of this
over the previous hook proc is that it saves the overhead of spawning a
new hook process for every missing blob.

The model for the background process was refactored from the recent git
LFS work.  I refactored that code into a shared module (sub-process.c/h)
and then updated convert.c to consume the new library.  I then used the
same sub-process module when implementing the read-object background
process.

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>
GVFS Git introduced pre-command and post-command hooks, to gather usage
statistics and to be able to adjust the worktree if necessary.

As run_hooks() implicitly calls setup_git_directory(), and that
function does surprising things to the global state (sometimes even
changing the current working directory), it cannot be used here.

This commit introduces the pre-command/post-command hooks, based on
the previous patches that culminate in support for running hooks early,
i.e. before setup_git_directory() was called.

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>
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>
Suggested by Ben Peart.

Signed-off-by: Johannes Schindelin <johasc@microsoft.com>
derrickstolee and others added 25 commits March 23, 2020 13:41
…OST request

If our POST request includes a commit ID, then the the remote will
send a pack-file containing the commit and all trees reachable from
its root tree. With the current implementation, this causes a
failure since we call install_loose() when asking for one object.

Modify the condition to check for install_pack() when the response
type changes.
Earlier versions of the test always returned a packfile in response to a POST.
Now we look at the number of objects in the POST request.

If > 1, always send a packfile.

If = 1 and it is a commit, send a packfile.
Otherwise, send a loose object.

This is to better model the behavior of the GVFS server/protocol which
treats commits differently.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Teach gvfs-helper to support "/gvfs/prefetch" REST API.
This includes a new `gvfs-helper prefetch --since=<t>` command line option.
And a new `objects.prefetch` verb in `gvfs-helper server` mode.

If `since` argument is omitted, `gvfs-helper` will search the local
shared-cache for the most recent prefetch packfile and start from
there.

The <t> is usually a seconds-since-epoch, but may also be a "friendly"
date -- such as "midnight", "yesterday" and etc. using the existing
date selection mechanism.

Add `gh_client__prefetch()` API to allow `git.exe` to easily call
prefetch (and using the same long-running process as immediate and
queued object fetches).

Expanded t5799 unit tests to include prefetch tests.  Test setup now
also builds some commits-and-trees packfiles for testing purposes with
well-known timestamps.

Expanded t/helper/test-gvfs-protocol.exe to support "/gvfs/prefetch"
REST API.

Massive refactor of existing packfile handling in gvfs-helper.c to
reuse more code between "/gvfs/objects POST" and "/gvfs/prefetch".
With this we now properly name packfiles with the checksum SHA1
rather than a date string.

Refactor also addresses some of the confusing tempfile setup and
install_<result> code processing (introduced to handle the ambiguity
of how POST works with commit objects).

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
When using fsmonitor the CE_FSMONITOR_VALID flag should be checked when
wanting to know if the entry has been updated. If the flag is set the
entry should be considered up to date and the same as if the CE_UPTODATE
is set.

In order to trust the CE_FSMONITOR_VALID flag, the fsmonitor data needs to
be refreshed when the fsmonitor bitmap is applied to the index in
tweak_fsmonitor. Since the fsmonitor data is kept up to date for every
command, some tests needed to be updated to take that into account.

istate->untracked->use_fsmonitor was set in tweak_fsmonitor when the
fsmonitor bitmap data was loaded and is now in refresh_fsmonitor since
that is being called in tweak_fsmonitor. refresh_fsmonitor will only be
called once and any other callers should be setting it when refreshing
the fsmonitor data so that code can use the fsmonitor data when checking
untracked files.

When writing the index, fsmonitor_last_update is used to determine if
the fsmonitor bitmap should be created and the extension data written to
the index. When running through unpack-trees this is not copied to the
result index. This makes the next time a git command is ran do all the
work of lstating all files to determine what is clean since all entries
in the index are marked as dirty since there wasn't any fsmonitor data
saved in the index extension.

Copying the fsmonitor_last_update to the result index will cause the
extension data for fsmonitor to be in the index for the next git command
to use.

Signed-off-by: Kevin Willford <Kevin.Willford@microsoft.com>
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
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 <Kevin.Willford@microsoft.com>
test-gvfs-prococol, t5799: tests for gvfs-helper
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
fsmonitor updates for improved performance
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
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 <dstolee@microsoft.com>
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 <jeffhost@microsoft.com>
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 <dstolee@microsoft.com>
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 <dstolee@microsoft.com>
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 <dstolee@microsoft.com>
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 <dstolee@microsoft.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
@derrickstolee derrickstolee merged commit fd45198 into vfs-2.26.0 Mar 23, 2020
derrickstolee added a commit to microsoft/scalar that referenced this pull request Mar 24, 2020
See microsoft/git#251 for details.

A few reaction items needed to happen:

1. We need to ignore whitespace lines when verifying Git commands. Some added an extra whitespace line.
2. The rebase backend changed, and it causes `git rebase --continue` to open an editor if the commit had conflicts. By changing `core.editor=true`, we can no-op the editor portion instead of running forever with an open `vi` editor.
3. With the updated rebase backend, the commit OID is written to output. This causes our output between the control repo and the Scalar repo to be different. Set `GIT_COMMITTER_DATE` to be constant to avoid this problem.
4. The `fsmonitor` hook version was updated, so we need to update our hook along with Git. By copying from the templates directory instead of the samples initialized in `.git/hooks`, we are future-proof and will always get the latest copy recommended by Git. Resolves #301.
derrickstolee added a commit to microsoft/VFSForGit that referenced this pull request Mar 24, 2020
See microsoft/git#251 for details.

This required an update to our test infrastructure. The rebase merge backend changed in a way that it would now open an editor during `git rebase --continue`, causing a test to wait for `vim` to close. Set the editor to be a no-op. This also changes the output to include the commit oid, so use `GIT_COMMITTER_TIME` to be a constant to keep the commits the same.
@derrickstolee derrickstolee deleted the tentative/vfs-2.26.0 branch March 30, 2021 16:33
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