Skip to content
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

[DO NOT MERGE] Rebase to v2.21.0 #122

Closed
wants to merge 151 commits into from
Closed

Conversation

dscho
Copy link
Member

@dscho dscho commented Feb 27, 2019

The full output of git range-diff v2.20.1.windows.1..vfs-2.20.1 v2.21.0.windows.1..tentative/vfs-2.21.0 is at the end of this description.

The easiest-to-explain changes first: the dropped patches

"pager: fix order of atexit() calls"

This drops a no-longer used patch: the idea of the patch was broken, and we do not need it any longer, anyway. See PR #119 benpeart/revert-pager-atexit for the full explanation.

7: 3f58806 < -: ------------ pager: fix order of atexit() calls
153: 79dca30 < -: ------------ fixup! pager: fix order of atexit() calls

PR #96 A new sparse algorithm for walking trees in push

The sparse push made it (in slightly different form) into v2.21.0 as 5fda343321f3^...5fda343321f3^2:

1: 817e30a < -: ------------ revision: add mark_tree_uninteresting_sparse
2: 39dc89b < -: ------------ list-objects: consume sparse tree walk
3: ab733da < -: ------------ pack-objects: add --sparse option
4: c44172c < -: ------------ revision: implement sparse algorithm
5: f386f6c < -: ------------ pack-objects: create pack.useSparse setting
6: d011a9c < -: ------------ pack-objects: create GIT_TEST_PACK_SPARSE

PR #97 commit-graph: writing missing parents is a BUG

This made it into v2.21.0 as cce99cd unchanged:

74: 907a24d < -: ------------ commit-graph: writing missing parents is a BUG

trace2

v1, (PR #34 as a fixup to v1), v3, v4 and v5 were all merged, then reverted and superseded, with v7 being the only survivor.

gvfs-trace2-v1 + #34:

55: 1354d73 < -: ------------ trace2: create new combined trace facility
56: 00bac7b < -: ------------ trace2: add trace2 tracing of major regions in wt-status
57: 95597bd < -: ------------ trace2: classify some child processes
58: d83778f < -: ------------ trace2: add child classification for transport processes
59: 918f51b < -: ------------ trace2: instrument reading and writing the index
60: c7f9cb3 < -: ------------ gvfs:trace2: add region/data events for status deserialization
62: e15d3e9 < -: ------------ gvfs:trace2: add trace2 tracing around read_object_process
63: d5c1e3b < -: ------------ pack-objects: add trace2 regions

gvfs-trace2-v3:

82: 81291af < -: ------------ Revert "pack-objects: add trace2 regions"
83: b837111 < -: ------------ Revert "gvfs:trace2: add trace2 tracing around read_object_process"
84: 089a0c7 < -: ------------ Revert "gvfs:trace2: add region/data events for status deserialization"
85: eebf43a < -: ------------ Revert "trace2: instrument reading and writing the index"
86: 2dc5fab < -: ------------ Revert "trace2: add child classification for transport processes"
87: 39fa714 < -: ------------ Revert "trace2: classify some child processes"
88: fed7162 < -: ------------ Revert "trace2: add trace2 tracing of major regions in wt-status"
89: 095fc20 < -: ------------ Revert "trace2: create new combined trace facility"
91: c849c28 < -: ------------ trace2: (V3) create new combined trace facility
92: 3adeefc < -: ------------ trace2: collect platform-specific process information
93: ef2f927 < -: ------------ trace2:data: add trace2 regions to wt-status
94: 0b2eb68 < -: ------------ trace2:data: add editor/pager child classification
95: a1ab077 < -: ------------ trace2:data: add trace2 sub-process classification
96: cba8ef2 < -: ------------ trace2:data: add trace2 transport child classification
97: 9afaef2 < -: ------------ trace2:data: add trace2 hook classification
98: 517c6d8 < -: ------------ trace2:data: add trace2 instrumentation to index read/write
99: d9bbeed < -: ------------ pack-objects: add trace2 regions
100: 0bfdd41 < -: ------------ trace2:data: add subverb to checkout command
101: b006aff < -: ------------ trace2:data: add subverb to reset command
102: 68d0a78 < -: ------------ trace2:data: add subverb for rebase
103: 7336c10 < -: ------------ trace2:data: add vfs stats
104: ba1e59f < -: ------------ trace2: t/helper/test-trace2
105: a495882 < -: ------------ DROPME: keep inherited GIT_TR2 env vars when running test suite
106: dc8019e < -: ------------ gvfs:trace2:data: add trace2 tracing around read_object_process
107: f4e9264 < -: ------------ gvfs:trace2:data add status serialization/deserialization information

gvfs-trace2-v4:

109: 7e4387a < -: ------------ gvfs:trace2:data fixup: add region/data around actual serialization
110: d9cbade < -: ------------ trace2:data: add trace2 data/region around status printing

gvfs-trace2-v5:

111: cefc83a < -: ------------ trace2: fixup: remove warning message when opening trace file

The part of gvfs-trace2-v7 that reverts previous iterations:

112: 4487587 < -: ------------ Revert "trace2: fixup: remove warning message when opening trace file"
113: 15ba903 < -: ------------ Revert "trace2:data: add trace2 data/region around status printing"
114: c4aadf8 < -: ------------ Revert "gvfs:trace2:data fixup: add region/data around actual serialization"
115: 89c9e22 < -: ------------ Revert "gvfs:trace2:data add status serialization/deserialization information"
116: 0cee6e1 < -: ------------ Revert "gvfs:trace2:data: add trace2 tracing around read_object_process"
117: e0ff5c4 < -: ------------ Revert "DROPME: keep inherited GIT_TR2 env vars when running test suite"
118: 4e11a5f < -: ------------ Revert "trace2: t/helper/test-trace2"
119: 1829cd7 < -: ------------ Revert "trace2:data: add vfs stats"
120: f2bd703 < -: ------------ Revert "trace2:data: add subverb for rebase"
121: ff815f1 < -: ------------ Revert "trace2:data: add subverb to reset command"
122: 3fb5d50 < -: ------------ Revert "trace2:data: add subverb to checkout command"
123: b06eaff < -: ------------ Revert "pack-objects: add trace2 regions"
124: b9ef989 < -: ------------ Revert "trace2:data: add trace2 instrumentation to index read/write"
125: 605946b < -: ------------ Revert "trace2:data: add trace2 hook classification"
126: 60363bf < -: ------------ Revert "trace2:data: add trace2 transport child classification"
127: d4af6ba < -: ------------ Revert "trace2:data: add trace2 sub-process classification"
128: 7085285 < -: ------------ Revert "trace2:data: add editor/pager child classification"
129: b607158 < -: ------------ Revert "trace2:data: add trace2 regions to wt-status"
130: 14fc29d < -: ------------ Revert "trace2: collect platform-specific process information"
131: 0b7ba67 < -: ------------ Revert "trace2: (V3) create new combined trace facility"

Next up: reordered commits

I coalesced all the virtual-filesystem related patches into virtual-file-system-support: virtual-file-system-support, update/virtual-file-system, PR #15 benpeart/difftool, PR #27 benpeart/virtualprojectionlinks, PR #33 virtualfilesystem - check if directory is included and PR #70 jamill/jamill/virtual_filesystem_directories

Changed patches

There are a ton of patches that show up as changed in the range-diff by virtue of their diff context being changed, i.e. the surrounding code changed, but not our code changes.

In the remainder of this description, I will only list those patches where the code modifications are different from vfs-2.20.1. In the following, I simply ignore the patches where only the context changed (as well as the patches with unchanged diffs).

In other words, this section explains the lines of the range-diff that start with --, -+, +- or ++.

gvfs: start by adding the -gvfs suffix to the version

As with every vfs- rebase, 1166b21 was changed to reflect the new version 8fb171b

fsck: use ERROR_MULTI_PACK_INDEX

While 39250a8 changed two instances of ERROR_COMMIT_GRAPH to ERROR_MULTI_PACK_INDEX, 5f8e102 changes only one. The reason is that f0eaf63 enhanced the code so that the first one (which was outside the loop) was handled by the second one (which is in the loop that was extended).

Fix reset when using the sparse-checkout feature.

5d2a5fc added a call to checkout_entry(), and since that function's signature changed in 0f086e6 to accept a 4th parameter called nr_checkouts, that line had to be changed in 94e5d2a to pass an extra NULL for that parameter.

status: add status serialization mechanism

The implicit and explicit use of the_repository and the_index in fae0da4 is no longer allowed; we use s->repo and s->repo->index in 6defbaa for that reason.

Additionally, coccicheck (which is now run as part of the CI build, thanks to the Azure Pipeline that made it into v2.21.0) pointed out one use of hashcmp() where hasheq() should be used, and one use of xstrdup() guarded behind an if (arg) which has been converted to xstrdup_or_null().

status: serialize to path

There was an xstrdup() call guarded by an if (arg) in a74a553, which coccicheck (run as part of the Azure Pipeline definition that made it into v2.21.0) frowns upon. It was changed to xstrdup_or_null() in 60518e7.

Add virtual file system settings and hook proc

In 322557a, we added documentation for the gvfs.virtualfilesystem setting, but it mentioned a link to githooks that used the wrong section number (which was pointed out by the lint-docs target that is now run as part of the CI build, thanks to the Azure Pipeline definition that made it into v2.21.0). This was fixed in fc02dcf.

send-pack: do not check for sha1 file when GVFS_MISSING_OK set

The condition that is changed in c9ceb5a contained !has_sha1_file(oid->hash), which had changed to !has_object_file(oid) in 98374a0, therefore 2be79c3 has a different pre and post image. But both patches simply insert !gvfs_config_is_set(GVFS_MISSING_OK) && into the condition.

trace2: collect Windows-specific process information

The fixup! commit dcbd5a1 from PR #117 jeffhostetler/gvfs-trace2-next-fixup was squashed into 6a86993, resulting in df00b65 (which as a consequence has a different diff from the pre-rebase commit).

The full range-diff

As promised in the beginning, the full changes between vfs-2.20.1 and this branch:

  1:  817e30a287e1 <   -:  ------------ revision: add mark_tree_uninteresting_sparse
  2:  39dc89beb91a <   -:  ------------ list-objects: consume sparse tree walk
  3:  ab733daff539 <   -:  ------------ pack-objects: add --sparse option
  4:  c44172c35ece <   -:  ------------ revision: implement sparse algorithm
  5:  f386f6c3c9db <   -:  ------------ pack-objects: create pack.useSparse setting
  6:  d011a9c1b1c1 <   -:  ------------ pack-objects: create GIT_TEST_PACK_SPARSE
  7:  3f588065b018 <   -:  ------------ pager: fix order of atexit() calls
  8:  ac04954b7e92 =   1:  a2de79ddeb16 reset --stdin: trim carriage return from the paths
  9:  1166b213a26b !   2:  8fb171b2f7fc gvfs: start by adding the -gvfs suffix to the version
    @@ -11,8 +11,8 @@
      #!/bin/sh
      
      GVF=GIT-VERSION-FILE
    --DEF_VER=v2.20.1
    -+DEF_VER=v2.20.1.vfs.1.1
    +-DEF_VER=v2.21.0
    ++DEF_VER=v2.21.0.vfs.1.1
      
      LF='
      '
 10:  26eb0e399f03 =   3:  9fc99b086a1c gvfs: ensure that the version is based on a GVFS tag
 11:  1aade282063a =   4:  7e3102069053 gvfs: add a GVFS-specific header file
 12:  788870a5cb1d =   5:  7305e3856500 gvfs: add the core.gvfs config setting
 13:  44122be121d2 =   6:  ee378e46705e gvfs: add the feature to skip writing the index' SHA-1
 14:  8383f5c4f450 =   7:  dea359752a5b gvfs: add the feature that blobs may be missing
 15:  11da98050f2b =   8:  cd7014a3bb41 gvfs: prevent files to be deleted outside the sparse checkout
 27:  d28bbdcee00d =   9:  e439e6a3a27b sparse-checkout: update files with a modify/delete conflict
 29:  a42b69aa25db !  10:  9e94a98e8299 sparse-checkout: avoid writing entries with the skip-worktree bit
    @@ -49,4 +49,4 @@
     +
      	costate.refresh_cache = 1;
      	costate.istate = istate;
    - 	if (checkout_entry(ce, &costate, NULL) || lstat(ce->name, st))
    + 	if (checkout_entry(ce, &costate, NULL, NULL) ||
 65:  39250a8760e2 !  11:  5f8e1023e071 fsck: use ERROR_MULTI_PACK_INDEX
    @@ -24,16 +24,8 @@
      static const char *describe_object(struct object *obj)
      {
     @@
    - 		midx_verify.argv = midx_argv;
    - 		midx_verify.git_cmd = 1;
    - 		if (run_command(&midx_verify))
    --			errors_found |= ERROR_COMMIT_GRAPH;
    -+			errors_found |= ERROR_MULTI_PACK_INDEX;
    - 
    - 		prepare_alt_odb(the_repository);
    - 		for (alt =  the_repository->objects->alt_odb_list; alt; alt = alt->next) {
      			midx_argv[2] = "--object-dir";
    - 			midx_argv[3] = alt->path;
    + 			midx_argv[3] = odb->path;
      			if (run_command(&midx_verify))
     -				errors_found |= ERROR_COMMIT_GRAPH;
     +				errors_found |= ERROR_MULTI_PACK_INDEX;
 76:  a697df120c9a =  12:  e06eb8e8ec6f repack: refactor pack deletion for future use
 77:  55df6b20ffda =  13:  13e95e66f755 Docs: rearrange subcommands for multi-pack-index
 78:  2529afe89e79 =  14:  05443a544034 multi-pack-index: prepare for 'expire' subcommand
 79:  0c29a242fec3 =  15:  c9772d2430f0 midx: refactor permutation logic
 80:  1c4af93f5e98 =  16:  6e5954710283 multi-pack-index: implement 'expire' verb
 81:  af08e21c974f =  17:  aeadfe89a37a multi-pack-index: prepare 'repack' subcommand
 90:  f067cd46d7b2 =  18:  f295fe686ced midx: implement midx_repack()
108:  5e95f49218e7 =  19:  57a505d5e0db midx: use more structured data for expire
 16:  332ed29c07ba !  20:  0253f8058701 gvfs: optionally skip reachability checks/upload pack during fetch
    @@ -83,10 +83,10 @@
      static inline int gvfs_config_is_set(int mask) {
      	return (core_gvfs & mask) == mask;
     
    - diff --git a/t/t5581-gvfs.sh b/t/t5581-gvfs.sh
    + diff --git a/t/t5582-vfs.sh b/t/t5582-vfs.sh
      new file mode 100755
      --- /dev/null
    - +++ b/t/t5581-gvfs.sh
    + +++ b/t/t5582-vfs.sh
     @@
     +#!/bin/sh
     +
 17:  627bb8b010b2 !  21:  a82642bd984e gvfs: ensure all filters and EOL conversions are blocked
    @@ -50,7 +50,7 @@
      	if (strbuf_avail(buf) + buf->len < len)
      		strbuf_grow(buf, len - buf->len);
     @@
    - 	if (!will_convert_lf_to_crlf(len, &stats, crlf_action))
    + 	if (!will_convert_lf_to_crlf(&stats, crlf_action))
      		return 0;
      
     +	if (gvfs_config_is_set(GVFS_BLOCK_FILTERS_AND_EOL_CONVERSIONS))
 18:  3dd70448a3a2 =  22:  4493e88df7e7 Add a new run_hook_argv() function
 19:  9cd4a6d00d1e =  23:  8addd6aad65c gvfs: allow "virtualizing" objects
 20:  d6eaacef8eb5 !  24:  0e0a1ffb7517 Hydrate missing loose objects in check_and_freshen()
    @@ -16,7 +16,7 @@
      --- a/sha1-file.c
      +++ b/sha1-file.c
     @@
    - 	read_info_alternates(r, r->objects->objectdir, 0);
    + 	r->objects->loaded_alternates = 1;
      }
      
     +static int run_read_object_hook(const struct object_id *oid)
 21:  1e9f9ed75523 !  25:  c15368e9d6f6 Add support for read-object as a background process to retrieve missing objects
    @@ -261,7 +261,7 @@
      /* The maximum size for an object header. */
      #define MAX_HEADER_LEN 32
     @@
    - 	read_info_alternates(r, r->objects->objectdir, 0);
    + 	r->objects->loaded_alternates = 1;
      }
      
     -static int run_read_object_hook(const struct object_id *oid)
 22:  cec3c33636bd =  26:  ec1fd01a4cf1 sha1_file: when writing objects, skip the read_object_hook
 23:  4356dd15dcfa !  27:  de554642931a gvfs: add global command pre and post hook procs
    @@ -155,10 +155,10 @@
     +
      	trace_argv_printf(argv, "trace: built-in: git");
      
    - 	validate_cache_entries(&the_index);
    + 	validate_cache_entries(the_repository->index);
     -	status = p->fn(argc, argv, prefix);
     +	exit_code = status = p->fn(argc, argv, prefix);
    - 	validate_cache_entries(&the_index);
    + 	validate_cache_entries(the_repository->index);
      
      	if (status)
      		return status;
    @@ -194,8 +194,8 @@
      
      static int run_argv(int *argcp, const char ***argv)
     @@
    - 	 */
    - 	atexit(wait_for_pager_atexit);
    + 	}
    + 
      	trace_command_performance(argv);
     +	atexit(post_command_hook_atexit);
      
    @@ -207,7 +207,7 @@
      		commit_pager_choice();
     +		if (run_pre_command_hook(argv))
     +			die("pre-command hook aborted command");
    - 		printf("usage: %s\n\n", git_usage_string);
    + 		printf(_("usage: %s\n\n"), git_usage_string);
      		list_common_cmds_help();
      		printf("\n%s\n", _(git_more_info_string));
     -		exit(1);
 24:  688c31c2802e =  28:  5c74423c80b4 Allow hooks to be run before setup_git_directory()
 25:  bc483c5775b2 =  29:  ca6584f7ddcc gvfs: introduce pre/post command hooks
 26:  cb57e9f7a0d6 =  30:  2d07ab6cd197 t0400: verify that the hook is called correctly from a subdirectory
 28:  d3c7dc7ffd77 =  31:  e2af1546aa04 Pass PID of git process to hooks.
 30:  1e08be2d1e64 =  32:  2fe63cb1a649 pre-command: always respect core.hooksPath
 31:  5d2a5fc58adb !  33:  94e5d2a74405 Fix reset when using the sparse-checkout feature.
    @@ -70,7 +70,7 @@
     +					die(_("make_cache_entry failed for path '%s'"),
     +						two->path);
     +
    -+				checkout_entry(ceBefore, &state, NULL);
    ++				checkout_entry(ceBefore, &state, NULL, NULL);
     +			}
     +		}
      
 32:  b30acf9736f6 =  34:  551acd0c8651 Do not remove files outside the sparse-checkout
 33:  662357421d07 =  35:  0a34c2e1bcab gvfs: refactor loading the core.gvfs config value
 34:  092882f322ea =  36:  1c63bb258557 cache-tree: remove use of strbuf_addf in update_one
 35:  fae0da404ac1 !  37:  6defbaa9abc7 status: add status serialization mechanism
    @@ -261,8 +261,8 @@
     +	} else {
     +		if (do_serialize)
     +			die("cannot mix --serialize and --deserialize");
    -+		if (arg) /* override config or stdin */
    -+			deserialize_path = xstrdup(arg);
    ++		/* override config or stdin */
    ++		deserialize_path = xstrdup_or_null(arg);
     +		if (deserialize_path && *deserialize_path
     +		    && (access(deserialize_path, R_OK) != 0))
     +			die("cannot find serialization file '%s'",
    @@ -1136,7 +1136,7 @@
     +		return DESERIALIZE_ERR;
     +	}
     +	/* status_format */
    -+	if (hashcmp(cmd_s->sha1_commit, des_s->sha1_commit)) {
    ++	if (!hasheq(cmd_s->sha1_commit, des_s->sha1_commit)) {
     +		trace_printf_key(&trace_deserialize, "reject: sha1_commit");
     +		return DESERIALIZE_ERR;
     +	}
    @@ -1201,7 +1201,7 @@
     +	}
     +
     +	if (result == DESERIALIZE_OK) {
    -+		wt_status_get_state(&des_s.state, des_s.branch &&
    ++		wt_status_get_state(cmd_s->repo, &des_s.state, des_s.branch &&
     +				    !strcmp(des_s.branch, "HEAD"));
     +		wt_status_print(&des_s);
     +	}
    @@ -1230,8 +1230,8 @@
     +	 * the deserializer recognize a stale data set.
     +	 */
     +	packet_write_fmt(fd, "index_mtime %d %d\n",
    -+			 the_index.timestamp.sec,
    -+			 the_index.timestamp.nsec);
    ++			 s->repo->index->timestamp.sec,
    ++			 s->repo->index->timestamp.nsec);
     +
     +	/*
     +	 * Write data from wt_status to qualify this status report.
    @@ -1462,7 +1462,7 @@
     +#include "pkt-line.h"
      #include "remote.h"
      
    - struct worktree;
    + struct repository;
     @@
      enum untracked_status_type {
      	SHOW_NO_UNTRACKED_FILES,
    @@ -1482,8 +1482,8 @@
      	STATUS_FORMAT_UNSPECIFIED
      };
     @@
    - int require_clean_work_tree(const char *action, const char *hint,
    - 	int ignore_submodules, int gently);
    + 			    int ignore_submodules,
    + 			    int gently);
      
     +#define DESERIALIZE_OK  0
     +#define DESERIALIZE_ERR 1
 36:  0f9a27e205f1 =  38:  dc898810b6c5 status: add status.aheadbehind setting
 37:  9b162e190720 =  39:  8a68bdf1a7d7 Teach ahead-behind and serialized status to play nicely together
 38:  dfb20164c834 !  40:  f0986157749f status: add warning when a/b calculation takes too long for long/normal format
    @@ -8,7 +8,7 @@
      --- a/advice.c
      +++ b/advice.c
     @@
    - int advice_push_needs_force = 1;
    + int advice_push_unqualified_ref_name = 1;
      int advice_status_hints = 1;
      int advice_status_u_option = 1;
     +int advice_status_ahead_behind_warning = 1;
    @@ -16,7 +16,7 @@
      int advice_reset_quiet_warning = 1;
      int advice_resolve_conflict = 1;
     @@
    - 	{ "pushNeedsForce", &advice_push_needs_force },
    + 	{ "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
      	{ "statusHints", &advice_status_hints },
      	{ "statusUoption", &advice_status_u_option },
     +	{ "statusAheadBehindWarning", &advice_status_ahead_behind_warning },
    @@ -28,7 +28,7 @@
      --- a/advice.h
      +++ b/advice.h
     @@
    - extern int advice_push_needs_force;
    + extern int advice_push_unqualified_ref_name;
      extern int advice_status_hints;
      extern int advice_status_u_option;
     +extern int advice_status_ahead_behind_warning;
 39:  ffc0fb8ebfec =  41:  94e7e1f3e808 status: ignore status.aheadbehind in porcelain formats
 40:  a74a553794ea !  42:  60518e71dd31 status: serialize to path
    @@ -75,8 +75,7 @@
     -	else
     -		die("unsupported serialize version '%s'", arg);
     +
    -+	if (arg)
    -+		serialize_path = xstrdup(arg);
    ++	serialize_path = xstrdup_or_null(arg);
      
      	if (do_explicit_deserialize)
      		die("cannot mix --serialize and --deserialize");
 41:  2ab3909560df =  43:  6d85c1ea6d03 status: reject deserialize in V2 and conflicts
 42:  933f6b028474 =  44:  69f45e694525 fetch: Add --[no-]show-forced-updates argument
 43:  62dea1a397aa =  45:  cad1db2c98bc fetch: Warn about forced updates after branch list
 44:  bbc5e9e76cb2 =  46:  399ca6a747ef push: add --[no-]show-forced-updates passthrough to fetch
 45:  3e24efdd7c4b =  47:  61e9e80aa980 fetch: add documentation for --[no-]show-forced-updates
 46:  322557ac7686 !  48:  fc02dcfe51ff Add virtual file system settings and hook proc
    @@ -22,7 +22,7 @@
     +	the working directory.  Git will only track and update files
     +	listed in the virtual file system.  Using the virtual file system
     +	will supersede the sparse-checkout settings which will be ignored.
    -+	See the "virtual file system" section of linkgit:githooks[6].
    ++	See the "virtual file system" section of linkgit:githooks[5].
     +
      core.trustctime::
      	If false, the ctime differences between the index and the
 47:  2a5ff6be12f8 =  49:  2ea2362947c4 Update the virtualfilesystem support
 53:  dfe5be1a53a6 =  50:  74e6a9c3be6a virtualfilesystem: don't run the virtual file system hook if the index has been redirected
 54:  c3e50d87c177 =  51:  6cdefbc3692a virtualfilesystem: fix bug with symlinks being ignored
 61:  ff3b38819ea9 =  52:  a6997b7993fb virtualfilesystem: check if directory is included
 71:  a7cfd2af8ebf =  53:  9405d8886b1e vfs: fix case where directories not handled correctly
 48:  5de80715d569 =  54:  01a182b5c8a7 commit: add generation to pop_most_recent_commit()
 49:  d994cd9ff8d1 =  55:  3b152af7f94a status: fix rename reporting when using serialization cache
 50:  c3ee8f99eb03 =  56:  fe6fb0bdc969 status: add comments for ahead_behind_flags in serialization
 51:  c483b6d52224 !  57:  01ce7f3f3667 serialize-status: serialize global and repo-local exclude file metadata
    @@ -263,8 +263,8 @@
       */
     @@
      	packet_write_fmt(fd, "index_mtime %d %d\n",
    - 			 the_index.timestamp.sec,
    - 			 the_index.timestamp.nsec);
    + 			 s->repo->index->timestamp.sec,
    + 			 s->repo->index->timestamp.nsec);
     +	append_core_excludes_file_info(fd);
     +	append_repo_excludes_file_info(fd);
      
 52:  2aa6acc349a3 =  58:  113144d06ef3 status: deserialization wait
 55:  1354d7301ec3 <   -:  ------------ trace2: create new combined trace facility
 56:  00bac7b6f678 <   -:  ------------ trace2: add trace2 tracing of major regions in wt-status
 57:  95597bd7fc7d <   -:  ------------ trace2: classify some child processes
 58:  d83778f2ee71 <   -:  ------------ trace2: add child classification for transport processes
 59:  918f51b86667 <   -:  ------------ trace2: instrument reading and writing the index
 60:  c7f9cb3355cb <   -:  ------------ gvfs:trace2: add region/data events for status deserialization
 62:  e15d3e9795a2 <   -:  ------------ gvfs:trace2: add trace2 tracing around read_object_process
 63:  d5c1e3b80b88 <   -:  ------------ pack-objects: add trace2 regions
 64:  81f397c01669 =  59:  fb1a595b819d rebase/stash: make post-command hook work again
 66:  04cd4198b9f7 =  60:  2ca002fcfb54 read-cache: add post-indexchanged hook
 67:  7454daddc4f3 =  61:  b110df9ba094 read-cache: post-indexchanged hook add skip-worktree bit changing support
 69:  c9ceb5a5a5eb !  62:  2be79c33011b send-pack: do not check for sha1 file when GVFS_MISSING_OK set
    @@ -17,8 +17,8 @@
      
      static void feed_object(const struct object_id *oid, FILE *fh, int negative)
      {
    --	if (negative && !has_sha1_file(oid->hash))
    -+	if (negative && !gvfs_config_is_set(GVFS_MISSING_OK) && !has_sha1_file(oid->hash))
    +-	if (negative && !has_object_file(oid))
    ++	if (negative && !gvfs_config_is_set(GVFS_MISSING_OK) && !has_object_file(oid))
      		return;
      
      	if (negative)
 68:  5e370406b955 =  63:  d907392a887e read-cache: add test for post-indexchanged hook
 70:  66887e1c0359 =  64:  5e2d9fe87296 Add documentation for the post-indexchanged hook
 72:  c566104f6e1f =  65:  20bc4bed2fda update the reset --quiet path codepath to pass the correct flags to the post-indexchanged hook
 73:  1d8453eec4f9 =  66:  5244829f2b76 gvfs: block unsupported commands when running in a GVFS repo
 74:  907a24d2c45a <   -:  ------------ commit-graph: writing missing parents is a BUG
 75:  20bc81a9a606 =  67:  b0af3a8b83ef BRANCHES.md: Add explanation of branches and using forks
 82:  81291afa3fe2 <   -:  ------------ Revert "pack-objects: add trace2 regions"
 83:  b837111feec0 <   -:  ------------ Revert "gvfs:trace2: add trace2 tracing around read_object_process"
 84:  089a0c7e6445 <   -:  ------------ Revert "gvfs:trace2: add region/data events for status deserialization"
 85:  eebf43af34fc <   -:  ------------ Revert "trace2: instrument reading and writing the index"
 86:  2dc5fabf38ed <   -:  ------------ Revert "trace2: add child classification for transport processes"
 87:  39fa7147cea0 <   -:  ------------ Revert "trace2: classify some child processes"
 88:  fed716200779 <   -:  ------------ Revert "trace2: add trace2 tracing of major regions in wt-status"
 89:  095fc201d03a <   -:  ------------ Revert "trace2: create new combined trace facility"
 91:  c849c28e3c35 <   -:  ------------ trace2: (V3) create new combined trace facility
 92:  3adeefcbaffe <   -:  ------------ trace2: collect platform-specific process information
 93:  ef2f9278982e <   -:  ------------ trace2:data: add trace2 regions to wt-status
 94:  0b2eb6888a87 <   -:  ------------ trace2:data: add editor/pager child classification
 95:  a1ab0771a6af <   -:  ------------ trace2:data: add trace2 sub-process classification
 96:  cba8ef2abd01 <   -:  ------------ trace2:data: add trace2 transport child classification
 97:  9afaef252cf5 <   -:  ------------ trace2:data: add trace2 hook classification
 98:  517c6d8e27af <   -:  ------------ trace2:data: add trace2 instrumentation to index read/write
 99:  d9bbeedabb26 <   -:  ------------ pack-objects: add trace2 regions
100:  0bfdd41d7461 <   -:  ------------ trace2:data: add subverb to checkout command
101:  b006aff07a93 <   -:  ------------ trace2:data: add subverb to reset command
102:  68d0a789d2a1 <   -:  ------------ trace2:data: add subverb for rebase
103:  7336c1099cdf <   -:  ------------ trace2:data: add vfs stats
104:  ba1e59f2600c <   -:  ------------ trace2: t/helper/test-trace2
105:  a4958826e1ca <   -:  ------------ DROPME: keep inherited GIT_TR2 env vars when running test suite
106:  dc8019ee1ccc <   -:  ------------ gvfs:trace2:data: add trace2 tracing around read_object_process
107:  f4e9264f1453 <   -:  ------------ gvfs:trace2:data add status serialization/deserialization information
109:  7e4387a94a95 <   -:  ------------ gvfs:trace2:data fixup: add region/data around actual serialization
110:  d9cbade5169c <   -:  ------------ trace2:data: add trace2 data/region around status printing
111:  cefc83a448ae <   -:  ------------ trace2: fixup: remove warning message when opening trace file
112:  44875878ae1b <   -:  ------------ Revert "trace2: fixup: remove warning message when opening trace file"
113:  15ba90384a73 <   -:  ------------ Revert "trace2:data: add trace2 data/region around status printing"
114:  c4aadf8ecae6 <   -:  ------------ Revert "gvfs:trace2:data fixup: add region/data around actual serialization"
115:  89c9e224db5e <   -:  ------------ Revert "gvfs:trace2:data add status serialization/deserialization information"
116:  0cee6e154c00 <   -:  ------------ Revert "gvfs:trace2:data: add trace2 tracing around read_object_process"
117:  e0ff5c4ca9a1 <   -:  ------------ Revert "DROPME: keep inherited GIT_TR2 env vars when running test suite"
118:  4e11a5f9f1d3 <   -:  ------------ Revert "trace2: t/helper/test-trace2"
119:  1829cd7079bd <   -:  ------------ Revert "trace2:data: add vfs stats"
120:  f2bd703075e9 <   -:  ------------ Revert "trace2:data: add subverb for rebase"
121:  ff815f1b2405 <   -:  ------------ Revert "trace2:data: add subverb to reset command"
122:  3fb5d50200f2 <   -:  ------------ Revert "trace2:data: add subverb to checkout command"
123:  b06eaff8d0d7 <   -:  ------------ Revert "pack-objects: add trace2 regions"
124:  b9ef9890f3c7 <   -:  ------------ Revert "trace2:data: add trace2 instrumentation to index read/write"
125:  605946b486cd <   -:  ------------ Revert "trace2:data: add trace2 hook classification"
126:  60363bf83933 <   -:  ------------ Revert "trace2:data: add trace2 transport child classification"
127:  d4af6ba4662e <   -:  ------------ Revert "trace2:data: add trace2 sub-process classification"
128:  7085285789d8 <   -:  ------------ Revert "trace2:data: add editor/pager child classification"
129:  b607158fe3eb <   -:  ------------ Revert "trace2:data: add trace2 regions to wt-status"
130:  14fc29d36638 <   -:  ------------ Revert "trace2: collect platform-specific process information"
131:  0b7ba67000a0 <   -:  ------------ Revert "trace2: (V3) create new combined trace facility"
132:  ce5d1d3ce37e =  68:  0ff703cde1dc trace2: Documentation/technical/api-trace2.txt
133:  e398076fc8e6 !  69:  2a4785aee72d trace2: create new combined trace facility
    @@ -302,7 +302,7 @@
     +	trace2_cmd_name(p->cmd);
     +	trace2_cmd_list_config();
      
    - 	validate_cache_entries(&the_index);
    + 	validate_cache_entries(the_repository->index);
      	exit_code = status = p->fn(argc, argv, prefix);
     @@
      	cmd.clean_on_exit = 1;
    @@ -601,9 +601,9 @@
      --- a/submodule.c
      +++ b/submodule.c
     @@
    - 	/* default value, "--submodule-prefix" and its value are added later */
      
    - 	calculate_changed_submodule_paths(r);
    + 	calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
    + 	string_list_sort(&spf.changed_submodule_names);
     -	run_processes_parallel(max_parallel_jobs,
     -			       get_next_submodule,
     -			       fetch_start_failure,
134:  6a8699310265 !  70:  df00b657ce29 trace2: collect Windows-specific process information
    @@ -35,6 +35,8 @@
     +#include <Psapi.h>
     +#include <tlHelp32.h>
     +
    ++#define NR_PIDS_LIMIT 42
    ++
     +/*
     + * Find the process data for the given PID in the given snapshot
     + * and update the PROCESSENTRY32 data.
    @@ -53,13 +55,17 @@
     +}
     +
     +/*
    -+ * Accumulate JSON array:
    ++ * Accumulate JSON array of our parent processes:
     + *     [
     + *         exe-name-parent,
     + *         exe-name-grand-parent,
     + *         ...
     + *     ]
     + *
    ++ * We artificially limit this to NR_PIDS_LIMIT to quickly guard against cycles
    ++ * in the parent PIDs without a lot of fuss and because we just want some
    ++ * context and don't need an absolute answer.
    ++ *
     + * Note: we only report the filename of the process executable; the
     + *       only way to get its full pathname is to use OpenProcess()
     + *       and GetModuleFileNameEx() or QueryfullProcessImageName()
    @@ -70,16 +76,28 @@
     +{
     +	PROCESSENTRY32 pe32;
     +	DWORD pid;
    ++	DWORD pid_list[NR_PIDS_LIMIT];
    ++	int k, nr_pids = 0;
     +
     +	pid = GetCurrentProcessId();
    ++	while (find_pid(pid, hSnapshot, &pe32)) {
    ++		/* Only report parents. Omit self from the JSON output. */
    ++		if (nr_pids)
    ++			jw_array_string(jw, pe32.szExeFile);
     +
    -+	/* We only want parent processes, so skip self. */
    -+	if (!find_pid(pid, hSnapshot, &pe32))
    -+		return;
    -+	pid = pe32.th32ParentProcessID;
    ++		/* Check for cycle in snapshot. (Yes, it happened.) */
    ++		for (k = 0; k < nr_pids; k++)
    ++			if (pid == pid_list[k]) {
    ++				jw_array_string(jw, "(cycle)");
    ++				return;
    ++			}
     +
    -+	while (find_pid(pid, hSnapshot, &pe32)) {
    -+		jw_array_string(jw, pe32.szExeFile);
    ++		if (nr_pids == NR_PIDS_LIMIT) {
    ++			jw_array_string(jw, "(truncated)");
    ++			return;
    ++		}
    ++
    ++		pid_list[nr_pids++] = pid;
     +
     +		pid = pe32.th32ParentProcessID;
     +	}
    @@ -144,9 +162,9 @@
      	COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DDETECT_MSYS_TTY -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
      	BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -ENTRY:wmainCRTStartup -SUBSYSTEM:CONSOLE
     @@
    - 	COMPAT_CFLAGS += -DNOGDI -Icompat -Icompat/win32
      	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
      	COMPAT_OBJS += compat/mingw.o compat/winansi.o \
    + 		compat/win32/path-utils.o \
     +		compat/win32/trace2_win32_process_info.o \
      		compat/win32/pthread.o compat/win32/syslog.o \
      		compat/win32/dirent.o compat/win32/fscache.o
135:  af8f33cdd657 !  71:  367f8ffb0855 trace2:data: add trace2 regions to wt-status
    @@ -38,7 +38,7 @@
      	wt_status_collect_untracked(s);
     +	trace2_region_leave("status", "untracked", s->repo);
      
    - 	wt_status_get_state(&s->state, s->branch && !strcmp(s->branch, "HEAD"));
    + 	wt_status_get_state(s->repo, &s->state, s->branch && !strcmp(s->branch, "HEAD"));
      	if (s->state.merge_in_progress && !has_unmerged(s))
     @@
      
136:  314c7ed901b2 =  72:  333a79482781 trace2:data: add editor/pager child classification
137:  33d46a78c66f =  73:  0953eb16d41e trace2:data: add trace2 sub-process classification
138:  169737263a76 =  74:  d66c292f10c7 trace2:data: add trace2 transport child classification
139:  138ebf6ea8d2 =  75:  2bf7ef342691 trace2:data: add trace2 hook classification
140:  179a39efeab8 !  76:  16c3c1a8b328 trace2:data: add trace2 instrumentation to index read/write
    @@ -55,7 +55,7 @@
     +	trace2_region_leave_printf("index", "shared/do_read_index",
     +				   the_repository, "%s", base_path);
      	if (!oideq(&split_index->base_oid, &split_index->base->oid))
    - 		die("broken index, expect %s in %s, got %s",
    + 		die(_("broken index, expect %s in %s, got %s"),
      		    base_oid_hex, base_path,
     @@
      	istate->timestamp.sec = (unsigned int)st.st_mtime;
141:  7aa40e1dc9f4 !  77:  e5bd98083f06 trace2:data: pack-objects: add trace2 regions
    @@ -34,7 +34,7 @@
      
     +	trace2_region_enter("pack-objects", "enumerate-objects",
     +			    the_repository);
    - 	prepare_packing_data(&to_pack);
    + 	prepare_packing_data(the_repository, &to_pack);
      
      	if (progress)
     @@
142:  6c7ff986e059 !  78:  3a6e9f70d3e7 trace2:data: add subverb to checkout command
    @@ -9,8 +9,8 @@
      --- a/builtin/checkout.c
      +++ b/builtin/checkout.c
     @@
    - 	int errs = 0;
      	struct lock_file lock_file = LOCK_INIT;
    + 	int nr_checkouts = 0, nr_unmerged = 0;
      
     +	trace2_cmd_mode(opts->patch_mode ? "patch" : "path");
     +
143:  8ace6f896045 =  79:  01f404c5c867 trace2:data: add subverb to reset command
144:  83de4d3d461e =  80:  8ab45c1c9072 trace2:data: add subverb for rebase
145:  ad23341a7d06 !  81:  511a8b20150a trace2: t/helper/test-trace2, t0210.sh, t0211.sh, t0212.sh
    @@ -16,8 +16,8 @@
      TEST_BUILTINS_OBJS += test-subprocess.o
     +TEST_BUILTINS_OBJS += test-trace2.o
      TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
    + TEST_BUILTINS_OBJS += test-xml-encode.o
      TEST_BUILTINS_OBJS += test-wildmatch.o
    - TEST_BUILTINS_OBJS += test-windows-named-pipe.o
     
      diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
      --- a/t/helper/test-tool.c
    @@ -28,8 +28,8 @@
      	{ "subprocess", cmd__subprocess },
     +	{ "trace2", cmd__trace2 },
      	{ "urlmatch-normalization", cmd__urlmatch_normalization },
    + 	{ "xml-encode", cmd__xml_encode },
      	{ "wildmatch", cmd__wildmatch },
    - #ifdef GIT_WINDOWS_NATIVE
     
      diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
      --- a/t/helper/test-tool.h
    @@ -40,8 +40,8 @@
      int cmd__subprocess(int argc, const char **argv);
     +int cmd__trace2(int argc, const char **argv);
      int cmd__urlmatch_normalization(int argc, const char **argv);
    + int cmd__xml_encode(int argc, const char **argv);
      int cmd__wildmatch(int argc, const char **argv);
    - #ifdef GIT_WINDOWS_NATIVE
     
      diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c
      new file mode 100644
146:  f2ba675acb58 =  82:  6422643c4ef9 trace2: add for_each macros to clang-format
147:  1d7d271d4b5d !  83:  f5e45bad8ce5 DROPME: trace2:status: use the_repository rather than s->repo
    @@ -40,7 +40,7 @@
     -	trace2_region_leave("status", "untracked", s->repo);
     +	trace2_region_leave("status", "untracked", the_repository);
      
    - 	wt_status_get_state(&s->state, s->branch && !strcmp(s->branch, "HEAD"));
    + 	wt_status_get_state(s->repo, &s->state, s->branch && !strcmp(s->branch, "HEAD"));
      	if (s->state.merge_in_progress && !has_unmerged(s))
     @@
      
148:  49484a5ca098 =  84:  79e7b823c91a gvfs:trace2:data: add trace2 tracing around read_object_process
149:  40171a59f4e0 !  85:  99d5ab461c27 gvfs:trace2:data: status deserialization information
    @@ -46,8 +46,8 @@
      static int do_explicit_deserialize = 0;
      static char *deserialize_path = NULL;
     @@
    - 		if (arg) /* override config or stdin */
    - 			deserialize_path = xstrdup(arg);
    + 		/* override config or stdin */
    + 		deserialize_path = xstrdup_or_null(arg);
      		if (deserialize_path && *deserialize_path
     -		    && (access(deserialize_path, R_OK) != 0))
     +		    && (wt_status_deserialize_access(deserialize_path, R_OK) != 0))
    @@ -302,7 +302,7 @@
      		return DESERIALIZE_ERR;
      	}
      	/* status_format */
    - 	if (hashcmp(cmd_s->sha1_commit, des_s->sha1_commit)) {
    + 	if (!hasheq(cmd_s->sha1_commit, des_s->sha1_commit)) {
     +		set_deserialize_reject_reason("args/commit-changed");
      		trace_printf_key(&trace_deserialize, "reject: sha1_commit");
      		return DESERIALIZE_ERR;
    @@ -364,7 +364,7 @@
     +	trace2_region_leave("status", "deserialize", the_repository);
     +
      	if (result == DESERIALIZE_OK) {
    - 		wt_status_get_state(&des_s.state, des_s.branch &&
    + 		wt_status_get_state(cmd_s->repo, &des_s.state, des_s.branch &&
      				    !strcmp(des_s.branch, "HEAD"));
     
      diff --git a/wt-status.h b/wt-status.h
150:  a0751d6ea4e9 =  86:  c7bf8354d031 gvfs:trace2:data: status serialization
151:  9835bc6a95ed =  87:  054f516d880e gvfs:trace2:data: add vfs stats
152:  dcbd5a1763fb <   -:  ------------ fixup! trace2: collect Windows-specific process information
153:  79dca3044599 <   -:  ------------ fixup! pager: fix order of atexit() calls

Kevin Willford and others added 23 commits February 27, 2019 16:35
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>
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>
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.

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>
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>
The multi-pack-index was added to the data verified by git-fsck in
ea5ae6c "fsck: verify multi-pack-index". This implementation was
based on the implementation for verifying the commit-graph, and a
copy-paste error kept the ERROR_COMMIT_GRAPH flag as the bit set
when an error appears in the multi-pack-index.

Add a new flag, ERROR_MULTI_PACK_INDEX, and use that instead.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
The repack builtin deletes redundant pack-files and their
associated .idx, .promisor, .bitmap, and .keep files. We will want
to re-use this logic in the future for other types of repack, so
pull the logic into 'unlink_pack_path()' in packfile.c.

The 'ignore_keep' parameter is enabled for the use in repack, but
will be important for a future caller.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
We will add new subcommands to the multi-pack-index, and that will
make the documentation a bit messier. Clean up the 'verb'
descriptions by renaming the concept to 'subcommand' and removing
the reference to the object directory.

Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Szeder Gábor <szeder.dev@gmail.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
The multi-pack-index tracks objects in a collection of pack-files.
Only one copy of each object is indexed, using the modified time
of the pack-files to determine tie-breakers. It is possible to
have a pack-file with no referenced objects because all objects
have a duplicate in a newer pack-file.

Introduce a new 'expire' subcommand to the multi-pack-index builtin.
This subcommand will delete these unused pack-files and rewrite the
multi-pack-index to no longer refer to those files. More details
about the specifics will follow as the method is implemented.

Add a test that verifies the 'expire' subcommand is correctly wired,
but will still be valid when the verb is implemented. Specifically,
create a set of packs that should all have referenced objects and
should not be removed during an 'expire' operation.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
When writing a multi-pack-index, we keep track of an integer
permutation, tracking the list of pack-files that we know about
(both from the existing multi-pack-index and the new pack-files
being introduced) and converting them into a sorted order for
the new multi-pack-index.

In anticipation of dropping pack-files from the existing multi-
pack-index, refactor the logic around how we track this permutation.

First, insert the permutation into the pack_list structure. This
allows us to grow the permutation dynamically as we add packs.

Second, fill the permutation with values corresponding to their
position in the list of pack-files, sorted as follows:

  1. The pack-files in the existing multi-pack-index,
     sorted lexicographically.

  2. The pack-files not in the existing multi-pack-index,
     sorted as discovered from the filesystem.

There is a subtle thing in how we initialize this permutation,
specifically how we use 'i' for the initial value. This will
matter more when we implement the logic for dropping existing
packs, as we will create holes in the ordering.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
The 'git multi-pack-index expire' command looks at the existing
mult-pack-index, counts the number of objects referenced in each
pack-file, deletes the pack-fils with no referenced objects, and
rewrites the multi-pack-index to no longer reference those packs.

Refactor the write_midx_file() method to call write_midx_internal()
which now takes an existing 'struct multi_pack_index' and a list
of pack-files to drop (as specified by the names of their pack-
indexes). As we write the new multi-pack-index, we drop those
file names from the list of known pack-files.

The expire_midx_packs() method removes the unreferenced pack-files
after carefully closing the packs to avoid open handles.

Test that a new pack-file that covers the contents of two other
pack-files leads to those pack-files being deleted during the
expire command. Be sure to read the multi-pack-index to ensure
it no longer references those packs.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
In an environment where the multi-pack-index is useful, it is due
to many pack-files and an inability to repack the object store
into a single pack-file. However, it is likely that many of these
pack-files are rather small, and could be repacked into a slightly
larger pack-file without too much effort. It may also be important
to ensure the object store is highly available and the repack
operation does not interrupt concurrent git commands.

Introduce a 'repack' subcommand to 'git multi-pack-index' that
takes a '--batch-size' option. The verb will inspect the
multi-pack-index for referenced pack-files whose size is smaller
than the batch size, until collecting a list of pack-files whose
sizes sum to larger than the batch size. Then, a new pack-file
will be created containing the objects from those pack-files that
are referenced by the multi-pack-index. The resulting pack is
likely to actually be smaller than the batch size due to
compression and the fact that there may be objects in the pack-
files that have duplicate copies in other pack-files.

The current change introduces the command-line arguments, and we
add a test that ensures we parse these options properly. Since
we specify a small batch size, we will guarantee that future
implementations do not change the list of pack-files.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
To repack using a multi-pack-index, first sort all pack-files by
their modified time. Second, walk those pack-files from oldest
to newest, adding the packs to a list if they are smaller than the
given pack-size. Finally, collect the objects from the multi-pack-
index that are in those packs and send them to 'git pack-objects'.

While first designing a 'git multi-pack-index repack' operation, I
started by collecting the batches based on the size of the objects
instead of the size of the pack-files. This allows repacking a
large pack-file that has very few referencd objects. However, this
came at a significant cost of parsing pack-files instead of simply
reading the multi-pack-index and getting the file information for
the pack-files. This object-size idea could be a direction for
future expansion in this area.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Derrick Stolee <dstolee@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>
When using the sparse checkout feature the git reset command will add
entries to the index that will have the skip-worktree bit off but will
leave the working directory empty.  File data is lost because the index
version of the files has been changed but there is nothing that is in
the working directory.  This will cause the next status call to show
either deleted for files modified or deleting or nothing for files
added.  The added files should be shown as untracked and modified files
should be shown as modified.

To fix this when the reset is running if there is not a file in the
working directory and if it will be missing with the new index entry or
was not missing in the previous version, we create the previous index
version of the file in the working directory so that status will report
correctly and the files will be availble for the user to deal with.

Signed-off-by: Kevin Willford <kewillf@microsoft.com>
Signed-off-by: Kevin Willford <kewillf@microsoft.com>
@dscho dscho changed the title Tentative/vfs 2.21.0 [DO NOT MERGE] Rebase to v2.21.0 Feb 27, 2019
@dscho
Copy link
Member Author

dscho commented Feb 28, 2019

Note: the Azure Pipeline failed in t0021.16 ident blocked when under GVFS at first, but a re-run "fixed" it. This indicates that this test case is flakey...

@benpeart you seem to have added this in a82642b (gvfs: ensure all filters and EOL conversions are blocked, 2016-06-15). The symptom of a failed run is this:

expecting success:                                                                                                                                                                                [55/1820]
        git add ident.i &&

        git commit -m "added ident.i" &&
        test_config core.gvfs 64 &&
        rm ident.i &&
        git checkout -- ident.i &&

        test_must_fail git status

++ git add ident.i
++ git commit -m 'added ident.i'
[master 57dc091] added ident.i
 Author: A U Thor <author@example.com>
 7 files changed, 7 insertions(+)
 create mode 100644 30MB
 create mode 100644 big
 create mode 100644 empty-in-repo
 create mode 100644 empty-in-worktree
 create mode 100644 ident.i
 create mode 100644 test.fs
 create mode 100644 test.r
++ test_config core.gvfs 64
++ config_dir=
++ test core.gvfs = -C
++ test_when_finished 'test_unconfig  '\''core.gvfs'\'''
++ test 0 = 0
++ test_cleanup='{ test_unconfig  '\''core.gvfs'\''
                } && (exit "$eval_ret"); eval_ret=$?; :'
++ git config core.gvfs 64
++ rm ident.i
++ git checkout -- ident.i
++ test_must_fail git status
++ case "$1" in
++ _test_ok=
++ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   empty-in-repo
        modified:   empty-in-worktree
        modified:   expanded-keywords
        modified:   expanded-keywords-crlf
        modified:   name-no-magic
        deleted:    test.fs
        modified:   test.r

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .gitattributes
        actual
        argc.sh
        expanded-keywords.0
        expect
        expected
        expected-output
        expected-output-crlf
        expected-output.0
        filtered-empty-in-repo
        rot13-filter.pl
        rot13.sh
        test.fc
        test.o
        test2.o
        test3 'sq',$x=.o

no changes added to commit (use "git add" and/or "git commit -a")
++ exit_code=0
++ test 0 -eq 0
++ list_contains '' success
++ case ",$1," in
++ return 1
++ echo 'test_must_fail: command succeeded: git status'
test_must_fail: command succeeded: git status
++ return 1
error: last command exited with $?=1
not ok 16 - ident blocked when under GVFS
#
#               git add ident.i &&
#
#               git commit -m "added ident.i" &&
#               test_config core.gvfs 64 &&
#               rm ident.i &&
#               git checkout -- ident.i &&
#
#               test_must_fail git status
#

It usually passes, though, and the output with --run=1-16 -i -v -x -d looks like this:

expecting success:                                                                                                                                                                               [525/1959]
        git add ident.i &&

        git commit -m "added ident.i" &&
        test_config core.gvfs 64 &&
        rm ident.i &&
        git checkout -- ident.i &&

        test_must_fail git status

++ git add ident.i
++ git commit -m 'added ident.i'
[master 95653ad] added ident.i
 Author: A U Thor <author@example.com>
 7 files changed, 7 insertions(+)
 create mode 100644 30MB
 create mode 100644 big
 create mode 100644 empty-in-repo
 create mode 100644 empty-in-worktree
 create mode 100644 ident.i
 create mode 100644 test.fs
 create mode 100644 test.r
++ test_config core.gvfs 64
++ config_dir=
++ test core.gvfs = -C
++ test_when_finished 'test_unconfig  '\''core.gvfs'\'''
++ test 0 = 0
++ test_cleanup='{ test_unconfig  '\''core.gvfs'\''
                } && (exit "$eval_ret"); eval_ret=$?; :'
++ git config core.gvfs 64
++ rm ident.i
++ git checkout -- ident.i
++ test_must_fail git status
++ case "$1" in
++ _test_ok=
++ git status
fatal: ident conversions not supported when running under GVFS
++ exit_code=128
++ test 128 -eq 0
++ test_match_signal 13 128
++ test 128 = 141
++ test 128 = 269
++ return 1
++ test 128 -gt 129
++ test 128 -eq 127
++ test 128 -eq 126
++ return 0
++ test_unconfig core.gvfs
++ config_dir=
++ test core.gvfs = -C
++ git config --unset-all core.gvfs
++ config_status=0
++ case "$config_status" in
++ return 0
++ exit 0
++ eval_ret=0
++ :
ok 16 - ident blocked when under GVFS

I verified that this is a flakey test locally, by using the new --stress option. It looks like it had to run 16 times here to eventually errors out with the same log as pasted above (and as can be seen here: https://gvfs.visualstudio.com/ci/_build/results?buildId=7487&view=ms.vss-test-web.build-test-results-tab).

I am slightly worried that it is not so much the test case that is flakey, but the actual code that tries to prevent the ident conversion.

Besides, I really wonder why git checkout -- ident.i works after setting core.gvfs to 64: should this not rather error out? I mean, I see the file ident.i has the contents $Id: 055c8729cdcc372500a08db659c045e16c4409fb $ while the index recorded $Id$ for that file. It looks to me like this is a bug, not only in our code to prevent the ident conversion, but also in that test case, as it expects git checkout -- ident.i to succeed (when I think it should fail).

What do you think?

@dscho
Copy link
Member Author

dscho commented Feb 28, 2019

@jeffhostetler I saw you merged #121, and forward-ported the changes. Output of git range-diff 8af1f397ff7a..be59e6fef9ee 5e99cbd87ae6..42da0677004a:

1:  fa4b43c831a9 = 1:  4a7fe712efe4 midx: verify: add midx packfiles to the packed_git list

@dscho
Copy link
Member Author

dscho commented Feb 28, 2019

I saw you merged #121, and forward-ported the changes.

FWIW if you are curious what I did:

git fetch Microsoft # that is the nick name I use for this remote
git checkout Microsoft/vfs-2.20.1
git rebase -ir --onto @{-1} Microsoft/vfs-2.20.1@{yesterday} # @{-1} refers to the branch I had checked out before, which was `tentative/vfs-2.21.0`
git checkout @{-1} # go back to tentative/vfs-2.21.0
git merge --ff-only @{-1} # now, @{-1} refers to the detached HEAD on which I performed the rebase

This is essentially the equivalent of git cherry-pick --rebase-merges Microsoft/vfs-2.20.1@{yesterday}..Microsoft/vfs-2.20.1, except that this command does not work (yet) because cherry-pick does not accept the option --rebase-merges (yet).

jeffhostetler and others added 11 commits May 1, 2019 12:43
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
…iment

Gvfs trace2 checkout and reset experiment
The write_or_die() function has one quirk that a caller might not
expect: when it sees EPIPE from the write() call, it translates that
into a death by SIGPIPE. This doesn't change the overall behavior (the
program exits either way), but it does potentially confuse test scripts
looking for a non-signal exit code.

Let's switch away from using write_or_die() in a few code paths, which
will give us more consistent exit codes. It also gives us the
opportunity to write more descriptive error messages, since we have
context that write_or_die() does not.

Note that this won't do much by itself, since we'd typically be killed
by SIGPIPE before write_or_die() even gets a chance to do its thing.
That will be addressed in the next patch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The default SIGPIPE behavior can be useful for a command that generates
a lot of output: if the receiver of our output goes away, we'll be
notified asynchronously to stop generating it (typically by killing the
program).

But for a command like fetch, which is primarily concerned with
receiving data and writing it to disk, an unexpected SIGPIPE can be
awkward. We're already checking the return value of all of our write()
calls, and dying due to the signal takes away our chance to gracefully
handle the error.

On Linux, we wouldn't generally see SIGPIPE at all during fetch. If the
other side of the network connection hangs up, we'll see ECONNRESET. But
on OS X, we get a SIGPIPE, and the process is killed. This causes t5570
to racily fail, as we sometimes die by signal (instead of the expected
die() call) when the server side hangs up.

Let's ignore SIGPIPE during the network portion of the fetch, which will
cause our write() to return EPIPE, giving us consistent behavior across
platforms.

This fixes the test flakiness, but note that it stops short of fixing
the larger problem. The server side hit a fatal error, sent us an "ERR"
packet, and then hung up. We notice the failure because we're trying to
write to a closed socket. But by dying immediately, we never actually
read the ERR packet and report its content to the user. This is a (racy)
problem on all platforms. So this patch lays the groundwork from which
that problem might be fixed consistently, but it doesn't actually fix
it.

Note the placement of the SIGPIPE handling. The absolute minimal change
would be to ignore SIGPIPE only when we're writing. But twiddling the
signal handler for each write call is inefficient and maintenance
burden. On the opposite end of the spectrum, we could simply declare
that fetch does not need SIGPIPE handling, since it doesn't generate a
lot of output, and we could just ignore it at the start of cmd_fetch().

This patch takes a middle ground. It ignores SIGPIPE during the network
operation (which is admittedly most of the program, since the actual
network operations are all done under the hood by the transport code).
So it's still pretty coarse.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This branch fixes the flakiness of the git-daemon tests on macOS.
In Git for Windows, we use the MSYS2 Bash which inherits a non-standard
PID model from Cygwin's POSIX emulation layer: every MSYS2 process has a
regular Windows PID, and in addition it has an MSYS2 PID (which
corresponds to a shadow process that emulates Unix-style signal
handling).

With the upgrade to the MSYS2 runtime v3.x, this shadow process cannot
be accessed via `OpenProcess()` any longer, and therefore t6500 thought
incorrectly that the process referenced in `gc.pid` (which is not
actually a real `gc` process in this context, but the current shell) no
longer exists.

Let's fix this by making sure that the Windows PID is written into
`gc.pid` in this test script soo that `git.exe` is able to understand
that that process does indeed still exist.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The return type of the `GetProcAddress()` function is `FARPROC` which
evaluates to `long long int (*)()`, i.e. it cannot be cast to the
correct function signature by GCC 8.

To work around that, we first cast to `void *` and go on with our merry
lives.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The kwset functionality makes use of the obstack code, which expects to
be handed a function that can allocate large chunks of data. It expects
that function to accept a `size` parameter of type `long`.

This upsets GCC 8 on Windows, because `long` does not have the same
bit size as `size_t` there.

Now, the proper thing to do would be to switch to `size_t`. But this
would make us deviate from the "upstream" code even further, making it
hard to synchronize with newer versions, and also it would be quite
involved because that `long` type is so invasive in that code.

Let's punt, and instead provide a super small wrapper around
`xmalloc()`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This is needed to make things compile with GCC 8.x and later.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This backports several patch series from Git for Windows' `master` to
make things compile with GCC v8.x, as that will soon be the default for
Git for Windows (and is already the current setup on this developer's
machine).
@dscho
Copy link
Member Author

dscho commented May 13, 2019

I just forward-ported the commits merged into vfs-2.20.1 via adf2904 (most of them are already in v2.21.0.windows.1, but a few are only in Git for Windows' master yet) and pushed the result.

[EDIT] As a consequence, tentative/vfs-2.21.0 is now up to date with vfs-2.20.1 as of the commit adf2904 (Merge pull request #137 Fix the Azure Pipeline (e.g. macOS builds after the upgrade to Mojave), 2019-05-10).

@derrickstolee
Copy link
Collaborator

I queued an installer build and will test taking the update into VFS for Git. Thanks!

@derrickstolee
Copy link
Collaborator

There seems to be a problem with reporting untracked files. Here are some possible related changes I see in your range-diff.

135:  af8f33cdd657 !  71:  367f8ffb0855 trace2:data: add trace2 regions to wt-status
    @@ -38,7 +38,7 @@
      	wt_status_collect_untracked(s);
     +	trace2_region_leave("status", "untracked", s->repo);
      
    - 	wt_status_get_state(&s->state, s->branch && !strcmp(s->branch, "HEAD"));
    + 	wt_status_get_state(s->repo, &s->state, s->branch && !strcmp(s->branch, "HEAD"));
      	if (s->state.merge_in_progress && !has_unmerged(s))
     @@
147:  1d7d271d4b5d !  83:  f5e45bad8ce5 DROPME: trace2:status: use the_repository rather than s->repo
    @@ -40,7 +40,7 @@
     -	trace2_region_leave("status", "untracked", s->repo);
     +	trace2_region_leave("status", "untracked", the_repository);
      
    - 	wt_status_get_state(&s->state, s->branch && !strcmp(s->branch, "HEAD"));
    + 	wt_status_get_state(s->repo, &s->state, s->branch && !strcmp(s->branch, "HEAD"));
      	if (s->state.merge_in_progress && !has_unmerged(s))
     @@

@derrickstolee
Copy link
Collaborator

@dscho: I think the issue is related to 37b65ce (merge-recursive: new function for better colliding conflict resolutions). You are probably the expert in this area, but maybe @jeffhostetler and @kewillford know how this change could be colliding with our fork to cause functional test failures.

Copy link
Collaborator

@derrickstolee derrickstolee left a comment

Choose a reason for hiding this comment

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

(changing vote until we fix the functional tests)

@dscho
Copy link
Member Author

dscho commented May 18, 2019

@derrickstolee do you know perchance the exact operations that are done in

I think the issue is related to 37b65ce (merge-recursive: new function for better colliding conflict resolutions). You are probably the expert in this area, but maybe @jeffhostetler and @kewillford know how this change could be colliding with our fork to cause functional test failures.

Possibly. I tried to reproduce in a regular clone of https://gvfs.visualstudio.com/ci/_git/ForTests and failed to reproduce the issue.

Will continue to investigate on Monday.

dscho added 4 commits May 21, 2019 23:14
It took this developer more than a moment to verify that was_dirty()
really returns 0 (i.e. "false") if the file was not even tracked. In
other words, the `dirty` variable that was initialized to 1 (i.e.
"true") and then negated to be returned was not helping readability.

The same holds for the final return: rather than assigning the value to
return to `dirty` and then *immediately* returning that, we can simplify
it to a single statement.
It took this developer quite a good while to understand why the current
code cannot get a `NULL` returned by `index_file_exists()`. To
un-confuse readers (and future-proof the code), let's just be safe and
check before we dereference the returned pointer.
The idea of the virtual file system really is to tell Git to avoid
accessing certain paths. This fixes the case where a given path is not
yet included in the virtual file system and we are about to write a
conflicted version of it.
The major work on merge-recursive.c that went into v2.21.0 necessitates
an adjustment to work well with VFSforGit's virtualfilesystem hook.
@dscho
Copy link
Member Author

dscho commented May 21, 2019

Okay, I added a topic branch adjusting merge-recursive.c to reconcile the was_dirty() addition with our virtualfilesystem support, and hope that the functional tests would be appeased ;-)

@dscho
Copy link
Member Author

dscho commented May 22, 2019

Addressed by re-tagging, followed by pushing to vfs-2.21.0.

@dscho dscho closed this May 22, 2019
@dscho dscho deleted the tentative/vfs-2.21.0 branch May 22, 2019 14:20
derrickstolee added a commit to microsoft/VFSForGit that referenced this pull request May 22, 2019
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.

10 participants