Merge branch 'bp/fsmonitor'
We learned to talk to watchman to speed up "git status" and other operations that need to see which paths have been modified. * bp/fsmonitor: fsmonitor: preserve utf8 filenames in fsmonitor-watchman log fsmonitor: read entirety of watchman output fsmonitor: MINGW support for watchman integration fsmonitor: add a performance test fsmonitor: add a sample integration script for Watchman fsmonitor: add test cases for fsmonitor extension split-index: disable the fsmonitor extension when running the split index test fsmonitor: add a test tool to dump the index extension update-index: add fsmonitor support to update-index ls-files: Add support in ls-files to display the fsmonitor valid bit fsmonitor: add documentation for the fsmonitor extension. fsmonitor: teach git to optionally utilize a file system monitor to speed up detecting new or changed files. update-index: add a new --force-write-index option preload-index: add override to enable testing preload-index bswap: add 64 bit endianness helper get_be64
This commit is contained in:
45
read-cache.c
45
read-cache.c
@ -19,6 +19,7 @@
|
||||
#include "varint.h"
|
||||
#include "split-index.h"
|
||||
#include "utf8.h"
|
||||
#include "fsmonitor.h"
|
||||
|
||||
/* Mask for the name length in ce_flags in the on-disk index */
|
||||
|
||||
@ -38,11 +39,12 @@
|
||||
#define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */
|
||||
#define CACHE_EXT_LINK 0x6c696e6b /* "link" */
|
||||
#define CACHE_EXT_UNTRACKED 0x554E5452 /* "UNTR" */
|
||||
#define CACHE_EXT_FSMONITOR 0x46534D4E /* "FSMN" */
|
||||
|
||||
/* changes that can be kept in $GIT_DIR/index (basically all extensions) */
|
||||
#define EXTMASK (RESOLVE_UNDO_CHANGED | CACHE_TREE_CHANGED | \
|
||||
CE_ENTRY_ADDED | CE_ENTRY_REMOVED | CE_ENTRY_CHANGED | \
|
||||
SPLIT_INDEX_ORDERED | UNTRACKED_CHANGED)
|
||||
SPLIT_INDEX_ORDERED | UNTRACKED_CHANGED | FSMONITOR_CHANGED)
|
||||
|
||||
struct index_state the_index;
|
||||
static const char *alternate_index_output;
|
||||
@ -62,6 +64,7 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
|
||||
free(old);
|
||||
set_index_entry(istate, nr, ce);
|
||||
ce->ce_flags |= CE_UPDATE_IN_BASE;
|
||||
mark_fsmonitor_invalid(istate, ce);
|
||||
istate->cache_changed |= CE_ENTRY_CHANGED;
|
||||
}
|
||||
|
||||
@ -150,8 +153,10 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
|
||||
if (assume_unchanged)
|
||||
ce->ce_flags |= CE_VALID;
|
||||
|
||||
if (S_ISREG(st->st_mode))
|
||||
if (S_ISREG(st->st_mode)) {
|
||||
ce_mark_uptodate(ce);
|
||||
mark_fsmonitor_valid(ce);
|
||||
}
|
||||
}
|
||||
|
||||
static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
|
||||
@ -301,7 +306,7 @@ int match_stat_data_racy(const struct index_state *istate,
|
||||
return match_stat_data(sd, st);
|
||||
}
|
||||
|
||||
int ie_match_stat(const struct index_state *istate,
|
||||
int ie_match_stat(struct index_state *istate,
|
||||
const struct cache_entry *ce, struct stat *st,
|
||||
unsigned int options)
|
||||
{
|
||||
@ -309,7 +314,10 @@ int ie_match_stat(const struct index_state *istate,
|
||||
int ignore_valid = options & CE_MATCH_IGNORE_VALID;
|
||||
int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
|
||||
int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY;
|
||||
int ignore_fsmonitor = options & CE_MATCH_IGNORE_FSMONITOR;
|
||||
|
||||
if (!ignore_fsmonitor)
|
||||
refresh_fsmonitor(istate);
|
||||
/*
|
||||
* If it's marked as always valid in the index, it's
|
||||
* valid whatever the checked-out copy says.
|
||||
@ -320,6 +328,8 @@ int ie_match_stat(const struct index_state *istate,
|
||||
return 0;
|
||||
if (!ignore_valid && (ce->ce_flags & CE_VALID))
|
||||
return 0;
|
||||
if (!ignore_fsmonitor && (ce->ce_flags & CE_FSMONITOR_VALID))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Intent-to-add entries have not been added, so the index entry
|
||||
@ -357,7 +367,7 @@ int ie_match_stat(const struct index_state *istate,
|
||||
return changed;
|
||||
}
|
||||
|
||||
int ie_modified(const struct index_state *istate,
|
||||
int ie_modified(struct index_state *istate,
|
||||
const struct cache_entry *ce,
|
||||
struct stat *st, unsigned int options)
|
||||
{
|
||||
@ -778,6 +788,7 @@ int chmod_index_entry(struct index_state *istate, struct cache_entry *ce,
|
||||
}
|
||||
cache_tree_invalidate_path(istate, ce->name);
|
||||
ce->ce_flags |= CE_UPDATE_IN_BASE;
|
||||
mark_fsmonitor_invalid(istate, ce);
|
||||
istate->cache_changed |= CE_ENTRY_CHANGED;
|
||||
|
||||
return 0;
|
||||
@ -1229,10 +1240,13 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
|
||||
int ignore_valid = options & CE_MATCH_IGNORE_VALID;
|
||||
int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
|
||||
int ignore_missing = options & CE_MATCH_IGNORE_MISSING;
|
||||
int ignore_fsmonitor = options & CE_MATCH_IGNORE_FSMONITOR;
|
||||
|
||||
if (!refresh || ce_uptodate(ce))
|
||||
return ce;
|
||||
|
||||
if (!ignore_fsmonitor)
|
||||
refresh_fsmonitor(istate);
|
||||
/*
|
||||
* CE_VALID or CE_SKIP_WORKTREE means the user promised us
|
||||
* that the change to the work tree does not matter and told
|
||||
@ -1246,6 +1260,10 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
|
||||
ce_mark_uptodate(ce);
|
||||
return ce;
|
||||
}
|
||||
if (!ignore_fsmonitor && (ce->ce_flags & CE_FSMONITOR_VALID)) {
|
||||
ce_mark_uptodate(ce);
|
||||
return ce;
|
||||
}
|
||||
|
||||
if (has_symlink_leading_path(ce->name, ce_namelen(ce))) {
|
||||
if (ignore_missing)
|
||||
@ -1283,8 +1301,10 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
|
||||
* because CE_UPTODATE flag is in-core only;
|
||||
* we are not going to write this change out.
|
||||
*/
|
||||
if (!S_ISGITLINK(ce->ce_mode))
|
||||
if (!S_ISGITLINK(ce->ce_mode)) {
|
||||
ce_mark_uptodate(ce);
|
||||
mark_fsmonitor_valid(ce);
|
||||
}
|
||||
return ce;
|
||||
}
|
||||
}
|
||||
@ -1392,6 +1412,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
|
||||
*/
|
||||
ce->ce_flags &= ~CE_VALID;
|
||||
ce->ce_flags |= CE_UPDATE_IN_BASE;
|
||||
mark_fsmonitor_invalid(istate, ce);
|
||||
istate->cache_changed |= CE_ENTRY_CHANGED;
|
||||
}
|
||||
if (quiet)
|
||||
@ -1554,6 +1575,9 @@ static int read_index_extension(struct index_state *istate,
|
||||
case CACHE_EXT_UNTRACKED:
|
||||
istate->untracked = read_untracked_extension(data, sz);
|
||||
break;
|
||||
case CACHE_EXT_FSMONITOR:
|
||||
read_fsmonitor_extension(istate, data, sz);
|
||||
break;
|
||||
default:
|
||||
if (*ext < 'A' || 'Z' < *ext)
|
||||
return error("index uses %.4s extension, which we do not understand",
|
||||
@ -1729,6 +1753,7 @@ static void post_read_index_from(struct index_state *istate)
|
||||
check_ce_order(istate);
|
||||
tweak_untracked_cache(istate);
|
||||
tweak_split_index(istate);
|
||||
tweak_fsmonitor(istate);
|
||||
}
|
||||
|
||||
/* remember to discard_cache() before reading a different cache! */
|
||||
@ -2320,6 +2345,16 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
|
||||
if (err)
|
||||
return -1;
|
||||
}
|
||||
if (!strip_extensions && istate->fsmonitor_last_update) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
write_fsmonitor_extension(&sb, istate);
|
||||
err = write_index_ext_header(&c, newfd, CACHE_EXT_FSMONITOR, sb.len) < 0
|
||||
|| ce_write(&c, newfd, sb.buf, sb.len) < 0;
|
||||
strbuf_release(&sb);
|
||||
if (err)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ce_flush(&c, newfd, istate->sha1))
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user