Skip to content

Commit f906482

Browse files
Merge tb/codex/fsmonitor-hardlink-inodes-unstable into codex-unstable
Integrate the current tb/codex/fsmonitor-hardlink-inodes-unstable topic into the internally distributed codex-unstable branch. Codex-Integration: tb/codex/fsmonitor-hardlink-inodes-unstable@4b3b7478e8fde214835049c4f24e517c4f71947a
2 parents 77416c7 + 4b3b747 commit f906482

86 files changed

Lines changed: 19593 additions & 577 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Documentation/config/core.adoc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,10 @@ but may cost more than normal preload depending on filesystem and cache
738738
state. Inconclusive scans are discarded before continuing with the normal
739739
preload. Currently this is supported on APFS, ext-family filesystems, and
740740
XFS, and only has an effect when `core.preloadIndex` is enabled. Defaults
741-
to false.
741+
to false, except that a whole-worktree, read-only `git status` may use it
742+
after the native file system monitor discards a legacy
743+
untracked cache. Setting this option explicitly to false also disables
744+
that recovery optimization.
742745

743746
core.unsetenvvars::
744747
Windows-only: comma-separated list of environment variables'

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,7 @@ CLAR_TEST_SUITES += u-clean-status-history-store
15791579
CLAR_TEST_SUITES += u-clean-status-identity
15801580
CLAR_TEST_SUITES += u-clean-status-index
15811581
CLAR_TEST_SUITES += u-clean-status-manifest
1582+
CLAR_TEST_SUITES += u-clean-status-progress
15821583
CLAR_TEST_SUITES += u-clean-status-sidecar
15831584
CLAR_TEST_SUITES += u-clean-status-store
15841585
CLAR_TEST_SUITES += u-ctype

add-interactive.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "git-compat-util.h"
44
#include "add-interactive.h"
5+
#include "clean-status.h"
56
#include "color.h"
67
#include "diffcore.h"
78
#include "gettext.h"
@@ -1123,6 +1124,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps,
11231124
_("staged"), _("unstaged"), _("path"));
11241125
opts.list_opts.header = header.buf;
11251126

1127+
clean_status_prepare_main_index_history(r);
11261128
discard_index(r->index);
11271129
if (repo_read_index(r) < 0 ||
11281130
repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,

add-patch.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "git-compat-util.h"
55
#include "add-patch.h"
66
#include "advice.h"
7+
#include "clean-status.h"
78
#include "commit.h"
89
#include "config.h"
910
#include "diff.h"
@@ -2080,6 +2081,7 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
20802081
s.mode = &patch_mode_add;
20812082
s.revision = revision;
20822083

2084+
clean_status_prepare_main_index_history(r);
20832085
discard_index(r->index);
20842086
if (repo_read_index(r) < 0 ||
20852087
(!s.mode->index_only &&

apply.c

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@
1313
#include "git-compat-util.h"
1414
#include "abspath.h"
1515
#include "base85.h"
16+
#include "clean-status.h"
17+
#include "clean-status-index.h"
1618
#include "config.h"
1719
#include "odb.h"
1820
#include "delta.h"
1921
#include "diff.h"
2022
#include "dir.h"
2123
#include "environment.h"
24+
#include "fsmonitor-settings.h"
2225
#include "gettext.h"
2326
#include "hex.h"
2427
#include "xdiff-interface.h"
@@ -31,6 +34,7 @@
3134
#include "path.h"
3235
#include "quote.h"
3336
#include "read-cache.h"
37+
#include "replace-object.h"
3438
#include "repository.h"
3539
#include "rerere.h"
3640
#include "apply.h"
@@ -4440,9 +4444,79 @@ static void patch_stats(struct apply_state *state, struct patch *patch)
44404444
}
44414445
}
44424446

4447+
static int patch_preserves_clean_history(struct apply_state *state,
4448+
struct patch *patch)
4449+
{
4450+
struct index_state *istate = state->repo->index;
4451+
const struct cache_entry *old;
4452+
int suspended = clean_status_fsmonitor_backoff_suspended(istate);
4453+
int pos;
4454+
4455+
if (!state->update_index || state->ita_only || state->threeway ||
4456+
state->apply_with_reject || state->fake_ancestor ||
4457+
state->index_file || !fstat_is_reliable() ||
4458+
(getenv(INDEX_ENVIRONMENT) &&
4459+
!clean_status_index_path_is_main(istate->repo,
4460+
istate->repo->index_file)) ||
4461+
getenv(GIT_WORK_TREE_ENVIRONMENT) ||
4462+
getenv(GIT_COMMON_DIR_ENVIRONMENT) ||
4463+
getenv(DB_ENVIRONMENT) || getenv(ALTERNATE_DB_ENVIRONMENT) ||
4464+
istate != istate->repo->index || istate->split_index ||
4465+
istate->sparse_index != INDEX_EXPANDED ||
4466+
repo_config_values(istate->repo)->apply_sparse_checkout ||
4467+
!istate->repo->config_values_private_.trust_ctime ||
4468+
!istate->repo->config_values_private_.check_stat ||
4469+
(fsm_settings__get_mode(istate->repo) != FSMONITOR_MODE_IPC &&
4470+
!suspended) ||
4471+
repo_has_replace_refs_uncached(istate->repo) ||
4472+
patch->is_new > 0 || patch->is_delete > 0 || patch->is_copy ||
4473+
patch->is_rename || patch->conflicted_threeway ||
4474+
!patch->old_name || !patch->new_name ||
4475+
strcmp(patch->old_name, patch->new_name) ||
4476+
!S_ISREG(patch->old_mode) || !S_ISREG(patch->new_mode) ||
4477+
create_ce_mode(patch->old_mode) !=
4478+
create_ce_mode(patch->new_mode) ||
4479+
!clean_status_external_history_enabled(istate) ||
4480+
!istate->untracked ||
4481+
!istate->untracked->root)
4482+
return 0;
4483+
if (suspended) {
4484+
/* Keep only the authenticated historical boundary during backoff. */
4485+
if (!clean_status_fsmonitor_semantic_baseline_pending(istate) ||
4486+
!istate->untracked->root->valid ||
4487+
!istate->untracked->fsmonitor_revalidation)
4488+
return 0;
4489+
} else if (!clean_status_has_persistent_fsmonitor_semantic_history(istate) ||
4490+
!clean_status_revalidated_token_matches(istate) ||
4491+
!istate->fsmonitor_token_valid ||
4492+
!istate->fsmonitor_untracked_valid ||
4493+
!istate->fsmonitor_untracked_extension_seen ||
4494+
istate->fsmonitor_untracked_extension_invalid ||
4495+
!istate->fsmonitor_last_update ||
4496+
!istate->fsmonitor_untracked_token ||
4497+
strcmp(istate->fsmonitor_last_update,
4498+
istate->fsmonitor_untracked_token) ||
4499+
!istate->untracked->use_fsmonitor) {
4500+
return 0;
4501+
}
4502+
4503+
pos = index_name_pos(istate, patch->old_name,
4504+
strlen(patch->old_name));
4505+
if (pos < 0)
4506+
return 0;
4507+
old = istate->cache[pos];
4508+
return S_ISREG(old->ce_mode) &&
4509+
old->ce_mode == create_ce_mode(patch->new_mode) &&
4510+
clean_status_index_entry_is_semantically_safe(
4511+
istate, old, old);
4512+
}
4513+
44434514
static int remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)
44444515
{
4445-
if (state->update_index && !state->ita_only) {
4516+
if (state->update_index && !state->ita_only &&
4517+
!patch_preserves_clean_history(state, patch)) {
4518+
if (clean_status_external_history_enabled(state->repo->index))
4519+
clean_status_invalidate_current_proof(state->repo->index);
44464520
if (remove_file_from_index(state->repo->index, patch->old_name) < 0)
44474521
return error(_("unable to remove %s from index"), patch->old_name);
44484522
}
@@ -4455,6 +4529,7 @@ static int remove_file(struct apply_state *state, struct patch *patch, int rmdir
44554529
}
44564530

44574531
static int add_index_file(struct apply_state *state,
4532+
struct patch *patch,
44584533
const char *path,
44594534
unsigned mode,
44604535
void *buf,
@@ -4463,6 +4538,7 @@ static int add_index_file(struct apply_state *state,
44634538
struct stat st;
44644539
struct cache_entry *ce;
44654540
int namelen = strlen(path);
4541+
int options = ADD_CACHE_OK_TO_ADD;
44664542

44674543
ce = make_empty_cache_entry(state->repo->index, namelen);
44684544
memcpy(ce->name, path, namelen);
@@ -4497,7 +4573,13 @@ static int add_index_file(struct apply_state *state,
44974573
"for newly created file %s"), path);
44984574
}
44994575
}
4500-
if (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) {
4576+
if (patch_preserves_clean_history(state, patch)) {
4577+
options |= ADD_CACHE_OK_TO_REPLACE |
4578+
ADD_CACHE_PRESERVE_CLEAN_HISTORY;
4579+
} else if (clean_status_external_history_enabled(state->repo->index)) {
4580+
clean_status_invalidate_current_proof(state->repo->index);
4581+
}
4582+
if (add_index_entry(state->repo->index, ce, options) < 0) {
45014583
discard_cache_entry(ce);
45024584
return error(_("unable to add cache entry for %s"), path);
45034585
}
@@ -4697,7 +4779,7 @@ static int create_file(struct apply_state *state, struct patch *patch)
46974779
if (patch->conflicted_threeway)
46984780
return add_conflicted_stages_file(state, patch);
46994781
else if (state->check_index || (state->ita_only && patch->is_new > 0))
4700-
return add_index_file(state, path, mode, buf, size);
4782+
return add_index_file(state, patch, path, mode, buf, size);
47014783
return 0;
47024784
}
47034785

@@ -4828,6 +4910,18 @@ static int write_out_results(struct apply_state *state, struct patch *list)
48284910
struct patch *l;
48294911
struct string_list cpath = STRING_LIST_INIT_DUP;
48304912

4913+
if (state->update_index &&
4914+
clean_status_external_history_enabled(state->repo->index)) {
4915+
for (l = list; l; l = l->next) {
4916+
if (l->rejected ||
4917+
!patch_preserves_clean_history(state, l)) {
4918+
clean_status_invalidate_current_proof(
4919+
state->repo->index);
4920+
break;
4921+
}
4922+
}
4923+
}
4924+
48314925
for (phase = 0; phase < 2; phase++) {
48324926
l = list;
48334927
while (l) {

builtin/am.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "builtin.h"
1010
#include "abspath.h"
1111
#include "advice.h"
12+
#include "clean-status.h"
1213
#include "config.h"
1314
#include "editor.h"
1415
#include "environment.h"
@@ -2464,6 +2465,8 @@ int cmd_am(int argc,
24642465
/* Ensure a valid committer ident can be constructed */
24652466
git_committer_info(IDENT_STRICT);
24662467

2468+
clean_status_prepare_main_index_history(the_repository);
2469+
24672470
if (repo_read_index_preload(the_repository, NULL, 0) < 0)
24682471
die(_("failed to read the index"));
24692472

builtin/apply.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#define USE_THE_REPOSITORY_VARIABLE
22
#include "builtin.h"
3+
#include "clean-status.h"
34
#include "gettext.h"
45
#include "hash.h"
56
#include "apply.h"
@@ -43,6 +44,11 @@ int cmd_apply(int argc,
4344
if (check_apply_state(&state, force_apply))
4445
exit(128);
4546

47+
if (state.apply && state.check_index && !state.threeway &&
48+
!state.apply_with_reject && !state.ita_only &&
49+
!state.fake_ancestor && !state.index_file)
50+
clean_status_prepare_main_index_history(the_repository);
51+
4652
ret = apply_all_patches(&state, argc, argv, options);
4753

4854
clear_apply_state(&state);

builtin/check-attr.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "config.h"
44
#include "attr.h"
55
#include "environment.h"
6+
#include "fsmonitor.h"
67
#include "gettext.h"
78
#include "object-name.h"
89
#include "quote.h"
@@ -115,6 +116,7 @@ int cmd_check_attr(int argc,
115116
struct attr_check *check;
116117
struct object_id initialized_oid;
117118
int cnt, i, doubledash, filei;
119+
int scoped_bootstrap = 0;
118120

119121
if (!is_bare_repository(the_repository))
120122
setup_work_tree(the_repository);
@@ -127,13 +129,6 @@ int cmd_check_attr(int argc,
127129
prepare_repo_settings(the_repository);
128130
the_repository->settings.command_requires_full_index = 0;
129131

130-
if (repo_read_index(the_repository) < 0) {
131-
die("invalid cache");
132-
}
133-
134-
if (cached_attrs)
135-
git_attr_set_direction(GIT_ATTR_INDEX);
136-
137132
doubledash = -1;
138133
for (i = 0; doubledash < 0 && i < argc; i++) {
139134
if (!strcmp(argv[i], "--"))
@@ -176,6 +171,18 @@ int cmd_check_attr(int argc,
176171
error_with_usage("No file specified");
177172
}
178173

174+
scoped_bootstrap = !stdin_paths && !source &&
175+
argc - filei > 0 && argc - filei <= 64;
176+
if (scoped_bootstrap)
177+
fsmonitor_begin_scoped_bootstrap(the_repository->index);
178+
if (repo_read_index(the_repository) < 0)
179+
die("invalid cache");
180+
if (scoped_bootstrap)
181+
fsmonitor_end_scoped_bootstrap(the_repository->index);
182+
183+
if (cached_attrs)
184+
git_attr_set_direction(GIT_ATTR_INDEX);
185+
179186
check = attr_check_alloc();
180187
if (!all_attrs) {
181188
for (i = 0; i < cnt; i++) {

builtin/checkout-index.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "clean-status-config.h"
1313
#include "config.h"
1414
#include "environment.h"
15+
#include "fsmonitor-settings.h"
1516
#include "gettext.h"
1617
#include "hook.h"
1718
#include "lockfile.h"
@@ -277,13 +278,8 @@ int cmd_checkout_index(int argc,
277278
prepare_repo_settings(repo);
278279
repo->settings.command_requires_full_index = 0;
279280

280-
if (repo_read_index(repo) < 0) {
281-
die("invalid cache");
282-
}
283-
284281
argc = parse_options(argc, argv, prefix, builtin_checkout_index_options,
285282
builtin_checkout_index_usage, 0);
286-
state.istate = repo->index;
287283
state.force = force;
288284
state.quiet = quiet;
289285
state.not_new = not_new;
@@ -298,6 +294,15 @@ int cmd_checkout_index(int argc,
298294
die(_("options '%s' and '%s' cannot be used together"),
299295
"--stage=all", "--no-temp");
300296

297+
if (index_opt && !state.base_dir_len && !to_tempfile &&
298+
!checkout_stage && !getenv(INDEX_ENVIRONMENT) &&
299+
fstat_is_reliable() &&
300+
fsm_settings__get_mode(repo) == FSMONITOR_MODE_IPC)
301+
clean_status_enable_external_history(repo);
302+
if (repo_read_index(repo) < 0)
303+
die("invalid cache");
304+
state.istate = repo->index;
305+
301306
/*
302307
* when --prefix is specified we do not want to update cache.
303308
*/

0 commit comments

Comments
 (0)