Skip to content

Commit

Permalink
Merge sparse-index work into vfs-2.32.0
Browse files Browse the repository at this point in the history
  • Loading branch information
derrickstolee committed Jun 10, 2021
2 parents 656bba7 + 8608476 commit e70be92
Show file tree
Hide file tree
Showing 15 changed files with 555 additions and 54 deletions.
3 changes: 3 additions & 0 deletions builtin/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));

prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;

hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);

/*
Expand Down
8 changes: 3 additions & 5 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,6 @@ static int checkout_worktree(const struct checkout_opts *opts,
if (pc_workers > 1)
init_parallel_checkout();

/* TODO: audit for interaction with sparse-index. */
ensure_full_index(&the_index);

enable_fscache(active_nr);
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
Expand Down Expand Up @@ -533,8 +530,6 @@ static int checkout_paths(const struct checkout_opts *opts,
* Make sure all pathspecs participated in locating the paths
* to be checked out.
*/
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(&the_index);
for (pos = 0; pos < active_nr; pos++)
if (opts->overlay_mode)
mark_ce_for_checkout_overlay(active_cache[pos],
Expand Down Expand Up @@ -1604,6 +1599,9 @@ static int checkout_main(int argc, const char **argv, const char *prefix,

git_config(git_checkout_config, opts);

prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;

opts->track = BRANCH_TRACK_UNSPECIFIED;

if (!opts->accept_pathspec && !opts->accept_ref)
Expand Down
6 changes: 6 additions & 0 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_status_usage, builtin_status_options);

prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;

status_init_config(&s, git_status_config);
argc = parse_options(argc, argv, prefix,
builtin_status_options,
Expand Down Expand Up @@ -1937,6 +1940,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_commit_usage, builtin_commit_options);

prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;

status_init_config(&s, git_commit_config);
s.commit_template = 1;
status_format = STATUS_FORMAT_NONE; /* Ignore status.short */
Expand Down
2 changes: 0 additions & 2 deletions cache-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,6 @@ int cache_tree_update(struct index_state *istate, int flags)
if (i)
return i;

ensure_full_index(istate);

if (!istate->cache_tree)
istate->cache_tree = cache_tree();

Expand Down
32 changes: 32 additions & 0 deletions diff-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,13 @@ static int get_stat_data(const struct index_state *istate,
return 0;
}

static void show_directory(struct rev_info *revs,
const struct cache_entry *new_dir,
int added)
{
diff_tree_oid(NULL, &new_dir->oid, new_dir->name, &revs->diffopt);
}

static void show_new_file(struct rev_info *revs,
const struct cache_entry *new_file,
int cached, int match_missing)
Expand All @@ -325,6 +332,11 @@ static void show_new_file(struct rev_info *revs,
unsigned dirty_submodule = 0;
struct index_state *istate = revs->diffopt.repo->index;

if (new_file && S_ISSPARSEDIR(new_file->ce_mode)) {
show_directory(revs, new_file, /*added */ 1);
return;
}

/*
* New file in the index: it might actually be different in
* the working tree.
Expand All @@ -336,6 +348,15 @@ static void show_new_file(struct rev_info *revs,
diff_index_show_file(revs, "+", new_file, oid, !is_null_oid(oid), mode, dirty_submodule);
}

static void show_modified_sparse_directory(struct rev_info *revs,
const struct cache_entry *old_entry,
const struct cache_entry *new_entry,
int report_missing,
int cached, int match_missing)
{
diff_tree_oid(&old_entry->oid, &new_entry->oid, new_entry->name, &revs->diffopt);
}

static int show_modified(struct rev_info *revs,
const struct cache_entry *old_entry,
const struct cache_entry *new_entry,
Expand All @@ -347,6 +368,17 @@ static int show_modified(struct rev_info *revs,
unsigned dirty_submodule = 0;
struct index_state *istate = revs->diffopt.repo->index;

/*
* If both are sparse directory entries, then expand the
* modifications to the file level.
*/
if (old_entry && new_entry &&
S_ISSPARSEDIR(old_entry->ce_mode) &&
S_ISSPARSEDIR(new_entry->ce_mode)) {
show_modified_sparse_directory(revs, old_entry, new_entry, report_missing, cached, match_missing);
return 0;
}

if (get_stat_data(istate, new_entry, &oid, &mode, cached, match_missing,
&dirty_submodule, &revs->diffopt) < 0) {
if (report_missing)
Expand Down
11 changes: 11 additions & 0 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,17 @@ enum pattern_match_result path_matches_pattern_list(
strbuf_addch(&parent_pathname, '/');
strbuf_add(&parent_pathname, pathname, pathlen);

/*
* Directory entries are matched if and only if a file
* contained immediately within them is matched. For the
* case of a directory entry, modify the path to create
* a fake filename within this directory, allowing us to
* use the file-base matching logic in an equivalent way.
*/
if (parent_pathname.len > 0 &&
parent_pathname.buf[parent_pathname.len - 1] == '/')
strbuf_add(&parent_pathname, "-", 1);

if (hashmap_contains_path(&pl->recursive_hashmap,
&parent_pathname)) {
result = MATCHED_RECURSIVE;
Expand Down
2 changes: 0 additions & 2 deletions pathspec.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,
num_unmatched++;
if (!num_unmatched)
return;
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(istate);
for (i = 0; i < istate->cache_nr; i++) {
const struct cache_entry *ce = istate->cache[i];
if (sw_action == PS_IGNORE_SKIP_WORKTREE && ce_skip_worktree(ce))
Expand Down
10 changes: 8 additions & 2 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1598,8 +1598,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
*/
preload_index(istate, pathspec, 0);
trace2_region_enter("index", "refresh", NULL);
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(istate);

for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce, *new_entry;
int cache_errno = 0;
Expand All @@ -1614,6 +1613,13 @@ int refresh_index(struct index_state *istate, unsigned int flags,
if (ignore_skip_worktree && ce_skip_worktree(ce))
continue;

/*
* If this entry is a sparse directory, then there isn't
* any stat() information to update. Ignore the entry.
*/
if (S_ISSPARSEDIR(ce->ce_mode))
continue;

if (pathspec && !ce_path_match(istate, ce, pathspec, seen))
filtered = 1;

Expand Down
27 changes: 26 additions & 1 deletion sparse-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ int set_sparse_index_config(struct repository *repo, int enable)
return res;
}

static int index_has_unmerged_entries(struct index_state *istate)
{
int i;
for (i = 0; i < istate->cache_nr; i++) {
if (ce_stage(istate->cache[i]))
return 1;
}

return 0;
}

int convert_to_sparse(struct index_state *istate)
{
int test_env;
Expand Down Expand Up @@ -152,6 +163,13 @@ int convert_to_sparse(struct index_state *istate)
return -1;
}

/*
* NEEDSWORK: If we have unmerged entries, then stay full.
* Unmerged entries prevent the cache-tree extension from working.
*/
if (index_has_unmerged_entries(istate))
return 0;

if (cache_tree_update(istate, 0)) {
warning(_("unable to update cache-tree, staying full"));
return -1;
Expand All @@ -168,6 +186,10 @@ int convert_to_sparse(struct index_state *istate)
cache_tree_free(&istate->cache_tree);
cache_tree_update(istate, 0);

istate->fsmonitor_has_run_once = 0;
FREE_AND_NULL(istate->fsmonitor_dirty);
FREE_AND_NULL(istate->fsmonitor_last_update);

istate->sparse_index = 1;
trace2_region_leave("index", "convert_to_sparse", istate->repo);
return 0;
Expand Down Expand Up @@ -195,7 +217,7 @@ static int add_path_to_index(const struct object_id *oid,
strbuf_addstr(base, path);

ce = make_cache_entry(istate, mode, oid, base->buf, 0, 0);
ce->ce_flags |= CE_SKIP_WORKTREE;
ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED;
set_index_entry(istate, istate->cache_nr++, ce);

strbuf_setlen(base, len);
Expand Down Expand Up @@ -264,6 +286,9 @@ void ensure_full_index(struct index_state *istate)
istate->cache = full->cache;
istate->cache_nr = full->cache_nr;
istate->cache_alloc = full->cache_alloc;
istate->fsmonitor_has_run_once = 0;
FREE_AND_NULL(istate->fsmonitor_dirty);
FREE_AND_NULL(istate->fsmonitor_last_update);

strbuf_release(&base);
free(full);
Expand Down
47 changes: 30 additions & 17 deletions t/perf/p2000-sparse-operations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test_description="test performance of Git operations using the index"

test_perf_default_repo

SPARSE_CONE=f2/f4/f1
SPARSE_CONE=f2/f4

test_expect_success 'setup repo and indexes' '
git reset --hard HEAD &&
Expand All @@ -27,7 +27,7 @@ test_expect_success 'setup repo and indexes' '
OLD_COMMIT=$(git rev-parse HEAD) &&
OLD_TREE=$(git rev-parse HEAD^{tree}) &&
for i in $(test_seq 1 4)
for i in $(test_seq 1 3)
do
cat >in <<-EOF &&
100755 blob $BLOB a
Expand All @@ -43,45 +43,57 @@ test_expect_success 'setup repo and indexes' '
done &&
git sparse-checkout init --cone &&
git branch -f wide $OLD_COMMIT &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-index-v3 &&
git sparse-checkout set $SPARSE_CONE &&
git checkout -b wide $OLD_COMMIT &&
for l2 in f1 f2 f3 f4
do
echo more bogus >>$SPARSE_CONE/$l2/a &&
git commit -a -m "edit $SPARSE_CONE/$l2/a" || return 1
done &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-v3 &&
(
cd full-index-v3 &&
cd full-v3 &&
git sparse-checkout init --cone &&
git sparse-checkout set $SPARSE_CONE &&
git config index.version 3 &&
git update-index --index-version=3
git update-index --index-version=3 &&
git checkout HEAD~4
) &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-index-v4 &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-v4 &&
(
cd full-index-v4 &&
cd full-v4 &&
git sparse-checkout init --cone &&
git sparse-checkout set $SPARSE_CONE &&
git config index.version 4 &&
git update-index --index-version=4
git update-index --index-version=4 &&
git checkout HEAD~4
) &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-index-v3 &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-v3 &&
(
cd sparse-index-v3 &&
cd sparse-v3 &&
git sparse-checkout init --cone --sparse-index &&
git sparse-checkout set $SPARSE_CONE &&
git config index.version 3 &&
git update-index --index-version=3
git update-index --index-version=3 &&
git checkout HEAD~4
) &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-index-v4 &&
git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-v4 &&
(
cd sparse-index-v4 &&
cd sparse-v4 &&
git sparse-checkout init --cone --sparse-index &&
git sparse-checkout set $SPARSE_CONE &&
git config index.version 4 &&
git update-index --index-version=4
git update-index --index-version=4 &&
git checkout HEAD~4
)
'

test_perf_on_all () {
command="$@"
for repo in full-index-v3 full-index-v4 \
sparse-index-v3 sparse-index-v4
for repo in full-v3 full-v4 \
sparse-v3 sparse-v4
do
test_perf "$command ($repo)" "
(
Expand All @@ -97,5 +109,6 @@ test_perf_on_all git status
test_perf_on_all git add -A
test_perf_on_all git add .
test_perf_on_all git commit -a -m A
test_perf_on_all git checkout -f -

test_done
Loading

0 comments on commit e70be92

Please sign in to comment.