Skip to content

Commit c9fdbca

Browse files
committed
Merge branch 'av/fsmonitor'
Various fixes to bp/fsmonitor topic. * av/fsmonitor: fsmonitor: simplify determining the git worktree under Windows fsmonitor: store fsmonitor bitmap before splitting index fsmonitor: read from getcwd(), not the PWD environment variable fsmonitor: delay updating state until after split index is merged fsmonitor: document GIT_TRACE_FSMONITOR fsmonitor: don't bother pretty-printing JSON from watchman fsmonitor: set the PWD to the top of the working tree
2 parents e05336b + 1fff303 commit c9fdbca

File tree

8 files changed

+77
-48
lines changed

8 files changed

+77
-48
lines changed

Documentation/git.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,10 @@ into it.
595595
Unsetting the variable, or setting it to empty, "0" or
596596
"false" (case insensitive) disables trace messages.
597597

598+
`GIT_TRACE_FSMONITOR`::
599+
Enables trace messages for the filesystem monitor extension.
600+
See `GIT_TRACE` for available trace output options.
601+
598602
`GIT_TRACE_PACK_ACCESS`::
599603
Enables trace messages for all accesses to any packs. For each
600604
access, the pack file name and an offset in the pack is

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ struct index_state {
348348
unsigned char sha1[20];
349349
struct untracked_cache *untracked;
350350
uint64_t fsmonitor_last_update;
351+
struct ewah_bitmap *fsmonitor_dirty;
351352
};
352353

353354
extern struct index_state the_index;

fsmonitor.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
2626
uint32_t hdr_version;
2727
uint32_t ewah_size;
2828
struct ewah_bitmap *fsmonitor_dirty;
29-
int i;
3029
int ret;
3130

3231
if (sz < sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t))
@@ -49,31 +48,25 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
4948
ewah_free(fsmonitor_dirty);
5049
return error("failed to parse ewah bitmap reading fsmonitor index extension");
5150
}
52-
53-
if (git_config_get_fsmonitor()) {
54-
/* Mark all entries valid */
55-
for (i = 0; i < istate->cache_nr; i++)
56-
istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID;
57-
58-
/* Mark all previously saved entries as dirty */
59-
ewah_each_bit(fsmonitor_dirty, fsmonitor_ewah_callback, istate);
60-
61-
/* Now mark the untracked cache for fsmonitor usage */
62-
if (istate->untracked)
63-
istate->untracked->use_fsmonitor = 1;
64-
}
65-
ewah_free(fsmonitor_dirty);
51+
istate->fsmonitor_dirty = fsmonitor_dirty;
6652

6753
trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful");
6854
return 0;
6955
}
7056

57+
void fill_fsmonitor_bitmap(struct index_state *istate)
58+
{
59+
int i;
60+
istate->fsmonitor_dirty = ewah_new();
61+
for (i = 0; i < istate->cache_nr; i++)
62+
if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
63+
ewah_set(istate->fsmonitor_dirty, i);
64+
}
65+
7166
void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
7267
{
7368
uint32_t hdr_version;
7469
uint64_t tm;
75-
struct ewah_bitmap *bitmap;
76-
int i;
7770
uint32_t ewah_start;
7871
uint32_t ewah_size = 0;
7972
int fixup = 0;
@@ -87,12 +80,9 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
8780
strbuf_add(sb, &ewah_size, sizeof(uint32_t)); /* we'll fix this up later */
8881

8982
ewah_start = sb->len;
90-
bitmap = ewah_new();
91-
for (i = 0; i < istate->cache_nr; i++)
92-
if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
93-
ewah_set(bitmap, i);
94-
ewah_serialize_strbuf(bitmap, sb);
95-
ewah_free(bitmap);
83+
ewah_serialize_strbuf(istate->fsmonitor_dirty, sb);
84+
ewah_free(istate->fsmonitor_dirty);
85+
istate->fsmonitor_dirty = NULL;
9686

9787
/* fix up size field */
9888
put_be32(&ewah_size, sb->len - ewah_start);
@@ -121,6 +111,7 @@ static int query_fsmonitor(int version, uint64_t last_update, struct strbuf *que
121111
argv[3] = NULL;
122112
cp.argv = argv;
123113
cp.use_shell = 1;
114+
cp.dir = get_git_work_tree();
124115

125116
return capture_command(&cp, query_result, 1024);
126117
}
@@ -238,7 +229,29 @@ void remove_fsmonitor(struct index_state *istate)
238229

239230
void tweak_fsmonitor(struct index_state *istate)
240231
{
241-
switch (git_config_get_fsmonitor()) {
232+
int i;
233+
int fsmonitor_enabled = git_config_get_fsmonitor();
234+
235+
if (istate->fsmonitor_dirty) {
236+
if (fsmonitor_enabled) {
237+
/* Mark all entries valid */
238+
for (i = 0; i < istate->cache_nr; i++) {
239+
istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID;
240+
}
241+
242+
/* Mark all previously saved entries as dirty */
243+
ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate);
244+
245+
/* Now mark the untracked cache for fsmonitor usage */
246+
if (istate->untracked)
247+
istate->untracked->use_fsmonitor = 1;
248+
}
249+
250+
ewah_free(istate->fsmonitor_dirty);
251+
istate->fsmonitor_dirty = NULL;
252+
}
253+
254+
switch (fsmonitor_enabled) {
242255
case -1: /* keep: do nothing */
243256
break;
244257
case 0: /* false */

fsmonitor.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ extern struct trace_key trace_fsmonitor;
1010
extern int read_fsmonitor_extension(struct index_state *istate, const void *data, unsigned long sz);
1111

1212
/*
13-
* Write the CE_FSMONITOR_VALID state into the fsmonitor index extension.
13+
* Fill the fsmonitor_dirty ewah bits with their state from the index,
14+
* before it is split during writing.
15+
*/
16+
extern void fill_fsmonitor_bitmap(struct index_state *istate);
17+
18+
/*
19+
* Write the CE_FSMONITOR_VALID state into the fsmonitor index
20+
* extension. Reads from the fsmonitor_dirty ewah in the index.
1421
*/
1522
extern void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate);
1623

read-cache.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,6 +2535,9 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
25352535
int new_shared_index, ret;
25362536
struct split_index *si = istate->split_index;
25372537

2538+
if (istate->fsmonitor_last_update)
2539+
fill_fsmonitor_bitmap(istate);
2540+
25382541
if (!si || alternate_index_output ||
25392542
(istate->cache_changed & ~EXTMASK)) {
25402543
if (si)

t/t7519-status-fsmonitor.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,17 @@ do
301301
done
302302
done
303303

304+
# test that splitting the index dosn't interfere
305+
test_expect_success 'splitting the index results in the same state' '
306+
write_integration_script &&
307+
dirty_repo &&
308+
git update-index --fsmonitor &&
309+
git ls-files -f >expect &&
310+
test-dump-fsmonitor >&2 && echo &&
311+
git update-index --fsmonitor --split-index &&
312+
test-dump-fsmonitor >&2 && echo &&
313+
git ls-files -f >actual &&
314+
test_cmp expect actual
315+
'
316+
304317
test_done

t/t7519/fsmonitor-watchman

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,13 @@ if ($version == 1) {
2929
"Falling back to scanning...\n";
3030
}
3131

32-
# Convert unix style paths to escaped Windows style paths when running
33-
# in Windows command prompt
34-
35-
my $system = `uname -s`;
36-
$system =~ s/[\r\n]+//g;
3732
my $git_work_tree;
38-
39-
if ($system =~ m/^MSYS_NT/ || $system =~ m/^MINGW/) {
40-
$git_work_tree = `cygpath -aw "\$PWD"`;
41-
$git_work_tree =~ s/[\r\n]+//g;
42-
$git_work_tree =~ s,\\,/,g;
33+
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
34+
$git_work_tree = Win32::GetCwd();
35+
$git_work_tree =~ tr/\\/\//;
4336
} else {
44-
$git_work_tree = $ENV{'PWD'};
37+
require Cwd;
38+
$git_work_tree = Cwd::cwd();
4539
}
4640

4741
my $retry = 1;

templates/hooks--fsmonitor-watchman.sample

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,13 @@ if ($version == 1) {
2828
"Falling back to scanning...\n";
2929
}
3030

31-
# Convert unix style paths to escaped Windows style paths when running
32-
# in Windows command prompt
33-
34-
my $system = `uname -s`;
35-
$system =~ s/[\r\n]+//g;
3631
my $git_work_tree;
37-
38-
if ($system =~ m/^MSYS_NT/ || $system =~ m/^MINGW/) {
39-
$git_work_tree = `cygpath -aw "\$PWD"`;
40-
$git_work_tree =~ s/[\r\n]+//g;
41-
$git_work_tree =~ s,\\,/,g;
32+
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
33+
$git_work_tree = Win32::GetCwd();
34+
$git_work_tree =~ tr/\\/\//;
4235
} else {
43-
$git_work_tree = $ENV{'PWD'};
36+
require Cwd;
37+
$git_work_tree = Cwd::cwd();
4438
}
4539

4640
my $retry = 1;
@@ -49,7 +43,7 @@ launch_watchman();
4943

5044
sub launch_watchman {
5145

52-
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j')
46+
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
5347
or die "open2() failed: $!\n" .
5448
"Falling back to scanning...\n";
5549

0 commit comments

Comments
 (0)