-
Notifications
You must be signed in to change notification settings - Fork 141
fsmonitor: don't fill bitmap with entries to be removed #372
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,8 +14,13 @@ struct trace_key trace_fsmonitor = TRACE_KEY_INIT(FSMONITOR); | |
static void fsmonitor_ewah_callback(size_t pos, void *is) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, SZEDER Gábor wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, SZEDER Gábor wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, William Baker wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Junio C Hamano wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, William Baker wrote (reply to this):
|
||
{ | ||
struct index_state *istate = (struct index_state *)is; | ||
struct cache_entry *ce = istate->cache[pos]; | ||
struct cache_entry *ce; | ||
|
||
if (pos >= istate->cache_nr) | ||
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" >= %u)", | ||
(uintmax_t)pos, istate->cache_nr); | ||
|
||
ce = istate->cache[pos]; | ||
ce->ce_flags &= ~CE_FSMONITOR_VALID; | ||
} | ||
|
||
|
@@ -50,17 +55,24 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data, | |
} | ||
istate->fsmonitor_dirty = fsmonitor_dirty; | ||
|
||
if (istate->fsmonitor_dirty->bit_size > istate->cache_nr) | ||
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", | ||
(uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr); | ||
|
||
trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful"); | ||
return 0; | ||
} | ||
|
||
void fill_fsmonitor_bitmap(struct index_state *istate) | ||
{ | ||
unsigned int i; | ||
unsigned int i, skipped = 0; | ||
istate->fsmonitor_dirty = ewah_new(); | ||
for (i = 0; i < istate->cache_nr; i++) | ||
if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) | ||
ewah_set(istate->fsmonitor_dirty, i); | ||
for (i = 0; i < istate->cache_nr; i++) { | ||
if (istate->cache[i]->ce_flags & CE_REMOVE) | ||
skipped++; | ||
else if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) | ||
ewah_set(istate->fsmonitor_dirty, i - skipped); | ||
} | ||
} | ||
|
||
void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate) | ||
|
@@ -71,6 +83,10 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate) | |
uint32_t ewah_size = 0; | ||
int fixup = 0; | ||
|
||
if (istate->fsmonitor_dirty->bit_size > istate->cache_nr) | ||
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", | ||
(uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr); | ||
|
||
put_be32(&hdr_version, INDEX_EXTENSION_VERSION); | ||
strbuf_add(sb, &hdr_version, sizeof(uint32_t)); | ||
|
||
|
@@ -236,6 +252,9 @@ void tweak_fsmonitor(struct index_state *istate) | |
} | ||
|
||
/* Mark all previously saved entries as dirty */ | ||
if (istate->fsmonitor_dirty->bit_size > istate->cache_nr) | ||
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", | ||
(uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr); | ||
ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate); | ||
|
||
/* Now mark the untracked cache for fsmonitor usage */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -354,4 +354,21 @@ test_expect_success 'discard_index() also discards fsmonitor info' ' | |
test_cmp expect actual | ||
' | ||
|
||
# Test staging/unstaging files that appear at the end of the index. Test | ||
# file names begin with 'z' so that they are sorted to the end of the index. | ||
test_expect_success 'status succeeds after staging/unstaging ' ' | ||
test_create_repo fsmonitor-stage-unstage && | ||
( | ||
cd fsmonitor-stage-unstage && | ||
test_commit initial && | ||
git update-index --fsmonitor && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interestingly, without this line:
This test would only catch the bug when run with |
||
removed=$(test_seq 1 100 | sed "s/^/z/") && | ||
touch $removed && | ||
git add $removed && | ||
git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" && | ||
FSMONITOR_LIST="$removed" git restore -S $removed && | ||
FSMONITOR_LIST="$removed" git status | ||
) | ||
' | ||
|
||
test_done |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/sh | ||
# | ||
# An test hook script to integrate with git to test fsmonitor. | ||
# | ||
# The hook is passed a version (currently 1) and a time in nanoseconds | ||
# formatted as a string and outputs to stdout all files that have been | ||
# modified since the given time. Paths must be relative to the root of | ||
# the working tree and separated by a single NUL. | ||
# | ||
#echo "$0 $*" >&2 | ||
|
||
if test "$#" -ne 2 | ||
then | ||
echo "$0: exactly 2 arguments expected" >&2 | ||
exit 2 | ||
fi | ||
|
||
if test "$1" != 1 | ||
then | ||
echo "Unsupported core.fsmonitor hook version." >&2 | ||
exit 1 | ||
fi | ||
|
||
printf '%s\n' $FSMONITOR_LIST |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Junio C Hamano wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, William Baker wrote (reply to this):