mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
Merge branch 'ds/fetch-pull-with-sparse-index'
"git fetch" and "git pull" are now declared sparse-index clean. Also "git ls-files" learns the "--sparse" option to help debugging. * ds/fetch-pull-with-sparse-index: test-read-cache: remove --table, --expand options t1091/t3705: remove 'test-tool read-cache --table' t1092: replace 'read-cache --table' with 'ls-files --sparse' ls-files: add --sparse option fetch/pull: use the sparse index
This commit is contained in:
commit
3c0e417827
|
@ -187,6 +187,11 @@ Both the <eolinfo> in the index ("i/<eolinfo>")
|
|||
and in the working tree ("w/<eolinfo>") are shown for regular files,
|
||||
followed by the ("attr/<eolattr>").
|
||||
|
||||
--sparse::
|
||||
If the index is sparse, show the sparse directories without expanding
|
||||
to the contained files. Sparse directories will be shown with a
|
||||
trailing slash, such as "x/" for a sparse directory "x".
|
||||
|
||||
\--::
|
||||
Do not interpret any more arguments as options.
|
||||
|
||||
|
|
|
@ -2009,6 +2009,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
git_config(git_fetch_config, NULL);
|
||||
prepare_repo_settings(the_repository);
|
||||
the_repository->settings.command_requires_full_index = 0;
|
||||
|
||||
argc = parse_options(argc, argv, prefix,
|
||||
builtin_fetch_options, builtin_fetch_usage, 0);
|
||||
|
|
|
@ -37,6 +37,7 @@ static int debug_mode;
|
|||
static int show_eol;
|
||||
static int recurse_submodules;
|
||||
static int skipping_duplicates;
|
||||
static int show_sparse_dirs;
|
||||
|
||||
static const char *prefix;
|
||||
static int max_prefix_len;
|
||||
|
@ -315,8 +316,10 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
|
|||
|
||||
if (!(show_cached || show_stage || show_deleted || show_modified))
|
||||
return;
|
||||
/* TODO: audit for interaction with sparse-index. */
|
||||
ensure_full_index(repo->index);
|
||||
|
||||
if (!show_sparse_dirs)
|
||||
ensure_full_index(repo->index);
|
||||
|
||||
for (i = 0; i < repo->index->cache_nr; i++) {
|
||||
const struct cache_entry *ce = repo->index->cache[i];
|
||||
struct stat st;
|
||||
|
@ -670,6 +673,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
|
|||
OPT_BOOL(0, "debug", &debug_mode, N_("show debugging data")),
|
||||
OPT_BOOL(0, "deduplicate", &skipping_duplicates,
|
||||
N_("suppress duplicate entries")),
|
||||
OPT_BOOL(0, "sparse", &show_sparse_dirs,
|
||||
N_("show sparse directories in the presence of a sparse index")),
|
||||
OPT_END()
|
||||
};
|
||||
int ret = 0;
|
||||
|
@ -677,6 +682,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
|
|||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
usage_with_options(ls_files_usage, builtin_ls_files_options);
|
||||
|
||||
prepare_repo_settings(the_repository);
|
||||
the_repository->settings.command_requires_full_index = 0;
|
||||
|
||||
prefix = cmd_prefix;
|
||||
if (prefix)
|
||||
prefix_len = strlen(prefix);
|
||||
|
|
|
@ -994,6 +994,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
|
|||
set_reflog_message(argc, argv);
|
||||
|
||||
git_config(git_pull_config, NULL);
|
||||
prepare_repo_settings(the_repository);
|
||||
the_repository->settings.command_requires_full_index = 0;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
|
||||
|
||||
|
|
|
@ -1,83 +1,39 @@
|
|||
#include "test-tool.h"
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "blob.h"
|
||||
#include "commit.h"
|
||||
#include "tree.h"
|
||||
#include "sparse-index.h"
|
||||
|
||||
static void print_cache_entry(struct cache_entry *ce)
|
||||
{
|
||||
const char *type;
|
||||
printf("%06o ", ce->ce_mode & 0177777);
|
||||
|
||||
if (S_ISSPARSEDIR(ce->ce_mode))
|
||||
type = tree_type;
|
||||
else if (S_ISGITLINK(ce->ce_mode))
|
||||
type = commit_type;
|
||||
else
|
||||
type = blob_type;
|
||||
|
||||
printf("%s %s\t%s\n",
|
||||
type,
|
||||
oid_to_hex(&ce->oid),
|
||||
ce->name);
|
||||
}
|
||||
|
||||
static void print_cache(struct index_state *istate)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < istate->cache_nr; i++)
|
||||
print_cache_entry(istate->cache[i]);
|
||||
}
|
||||
|
||||
int cmd__read_cache(int argc, const char **argv)
|
||||
{
|
||||
struct repository *r = the_repository;
|
||||
int i, cnt = 1;
|
||||
const char *name = NULL;
|
||||
int table = 0, expand = 0;
|
||||
|
||||
initialize_the_repository();
|
||||
|
||||
for (++argv, --argc; *argv && starts_with(*argv, "--"); ++argv, --argc) {
|
||||
if (skip_prefix(*argv, "--print-and-refresh=", &name))
|
||||
continue;
|
||||
if (!strcmp(*argv, "--table"))
|
||||
table = 1;
|
||||
else if (!strcmp(*argv, "--expand"))
|
||||
expand = 1;
|
||||
if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
cnt = strtol(argv[0], NULL, 0);
|
||||
if (argc == 2)
|
||||
cnt = strtol(argv[1], NULL, 0);
|
||||
setup_git_directory();
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
prepare_repo_settings(r);
|
||||
r->settings.command_requires_full_index = 0;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
repo_read_index(r);
|
||||
|
||||
if (expand)
|
||||
ensure_full_index(r->index);
|
||||
|
||||
read_cache();
|
||||
if (name) {
|
||||
int pos;
|
||||
|
||||
refresh_index(r->index, REFRESH_QUIET,
|
||||
refresh_index(&the_index, REFRESH_QUIET,
|
||||
NULL, NULL, NULL);
|
||||
pos = index_name_pos(r->index, name, strlen(name));
|
||||
pos = index_name_pos(&the_index, name, strlen(name));
|
||||
if (pos < 0)
|
||||
die("%s not in index", name);
|
||||
printf("%s is%s up to date\n", name,
|
||||
ce_uptodate(r->index->cache[pos]) ? "" : " not");
|
||||
ce_uptodate(the_index.cache[pos]) ? "" : " not");
|
||||
write_file(name, "%d\n", i);
|
||||
}
|
||||
if (table)
|
||||
print_cache(r->index);
|
||||
discard_index(r->index);
|
||||
discard_cache();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -234,12 +234,27 @@ test_expect_success 'sparse-index enabled and disabled' '
|
|||
|
||||
git -C repo sparse-checkout init --cone --sparse-index &&
|
||||
test_cmp_config -C repo true index.sparse &&
|
||||
test-tool -C repo read-cache --table >cache &&
|
||||
grep " tree " cache &&
|
||||
|
||||
git -C repo ls-files --sparse >sparse &&
|
||||
git -C repo sparse-checkout disable &&
|
||||
test-tool -C repo read-cache --table >cache &&
|
||||
! grep " tree " cache &&
|
||||
git -C repo ls-files --sparse >full &&
|
||||
|
||||
cat >expect <<-\EOF &&
|
||||
@@ -1,4 +1,7 @@
|
||||
a
|
||||
-deep/
|
||||
-folder1/
|
||||
-folder2/
|
||||
+deep/a
|
||||
+deep/deeper1/a
|
||||
+deep/deeper1/deepest/a
|
||||
+deep/deeper2/a
|
||||
+folder1/a
|
||||
+folder2/a
|
||||
EOF
|
||||
|
||||
diff -u sparse full | tail -n +3 >actual &&
|
||||
test_cmp expect actual &&
|
||||
|
||||
git -C repo config --list >config &&
|
||||
! grep index.sparse config
|
||||
)
|
||||
|
|
|
@ -206,45 +206,42 @@ test_sparse_unstaged () {
|
|||
test_expect_success 'sparse-index contents' '
|
||||
init_repos &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
git -C sparse-index ls-files --sparse --stage >cache &&
|
||||
for dir in folder1 folder2 x
|
||||
do
|
||||
TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
|
||||
grep "040000 tree $TREE $dir/" cache \
|
||||
grep "040000 $TREE 0 $dir/" cache \
|
||||
|| return 1
|
||||
done &&
|
||||
|
||||
git -C sparse-index sparse-checkout set folder1 &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
git -C sparse-index ls-files --sparse --stage >cache &&
|
||||
for dir in deep folder2 x
|
||||
do
|
||||
TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
|
||||
grep "040000 tree $TREE $dir/" cache \
|
||||
grep "040000 $TREE 0 $dir/" cache \
|
||||
|| return 1
|
||||
done &&
|
||||
|
||||
git -C sparse-index sparse-checkout set deep/deeper1 &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
git -C sparse-index ls-files --sparse --stage >cache &&
|
||||
for dir in deep/deeper2 folder1 folder2 x
|
||||
do
|
||||
TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
|
||||
grep "040000 tree $TREE $dir/" cache \
|
||||
grep "040000 $TREE 0 $dir/" cache \
|
||||
|| return 1
|
||||
done &&
|
||||
|
||||
# Disabling the sparse-index removes tree entries with full ones
|
||||
# Disabling the sparse-index replaces tree entries with full ones
|
||||
git -C sparse-index sparse-checkout init --no-sparse-index &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
! grep "040000 tree" cache &&
|
||||
test_sparse_match test-tool read-cache --table
|
||||
test_sparse_match git ls-files --stage --sparse
|
||||
'
|
||||
|
||||
test_expect_success 'expanded in-memory index matches full index' '
|
||||
init_repos &&
|
||||
test_sparse_match test-tool read-cache --expand --table
|
||||
test_sparse_match git ls-files --stage
|
||||
'
|
||||
|
||||
test_expect_success 'status with options' '
|
||||
|
@ -801,9 +798,9 @@ test_expect_success 'submodule handling' '
|
|||
|
||||
# having a submodule prevents "modules" from collapse
|
||||
test_sparse_match git sparse-checkout set deep/deeper1 &&
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
grep "100644 blob .* modules/a" cache &&
|
||||
grep "160000 commit $(git -C initial-repo rev-parse HEAD) modules/sub" cache
|
||||
git -C sparse-index ls-files --sparse --stage >cache &&
|
||||
grep "100644 .* modules/a" cache &&
|
||||
grep "160000 $(git -C initial-repo rev-parse HEAD) 0 modules/sub" cache
|
||||
'
|
||||
|
||||
# When working with a sparse index, some commands will need to expand the
|
||||
|
@ -816,6 +813,12 @@ test_expect_success 'sparse-index is expanded and converted back' '
|
|||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
|
||||
git -C sparse-index reset -- folder1/a &&
|
||||
test_region index convert_to_sparse trace2.txt &&
|
||||
test_region index ensure_full_index trace2.txt &&
|
||||
|
||||
# ls-files expands on read, but does not write.
|
||||
rm trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index ls-files &&
|
||||
test_region index ensure_full_index trace2.txt
|
||||
'
|
||||
|
||||
|
@ -871,6 +874,7 @@ test_expect_success 'sparse-index is not expanded' '
|
|||
init_repos &&
|
||||
|
||||
ensure_not_expanded status &&
|
||||
ensure_not_expanded ls-files --sparse &&
|
||||
ensure_not_expanded commit --allow-empty -m empty &&
|
||||
echo >>sparse-index/a &&
|
||||
ensure_not_expanded commit -a -m a &&
|
||||
|
@ -1009,6 +1013,100 @@ test_expect_success 'sparse index is not expanded: blame' '
|
|||
done
|
||||
'
|
||||
|
||||
test_expect_success 'sparse index is not expanded: fetch/pull' '
|
||||
init_repos &&
|
||||
|
||||
git -C sparse-index remote add full "file://$(pwd)/full-checkout" &&
|
||||
ensure_not_expanded fetch full &&
|
||||
git -C full-checkout commit --allow-empty -m "for pull merge" &&
|
||||
git -C sparse-index commit --allow-empty -m "for pull merge" &&
|
||||
ensure_not_expanded pull full base
|
||||
'
|
||||
|
||||
test_expect_success 'ls-files' '
|
||||
init_repos &&
|
||||
|
||||
# Use a smaller sparse-checkout for reduced output
|
||||
test_sparse_match git sparse-checkout set &&
|
||||
|
||||
# Behavior agrees by default. Sparse index is expanded.
|
||||
test_all_match git ls-files &&
|
||||
|
||||
# With --sparse, the sparse index data changes behavior.
|
||||
git -C sparse-index ls-files --sparse >actual &&
|
||||
|
||||
cat >expect <<-\EOF &&
|
||||
a
|
||||
deep/
|
||||
e
|
||||
folder1-
|
||||
folder1.x
|
||||
folder1/
|
||||
folder10
|
||||
folder2/
|
||||
g
|
||||
x/
|
||||
z
|
||||
EOF
|
||||
|
||||
test_cmp expect actual &&
|
||||
|
||||
# With --sparse and no sparse index, nothing changes.
|
||||
git -C sparse-checkout ls-files >dense &&
|
||||
git -C sparse-checkout ls-files --sparse >sparse &&
|
||||
test_cmp dense sparse &&
|
||||
|
||||
# Set up a strange condition of having a file edit
|
||||
# outside of the sparse-checkout cone. This is just
|
||||
# to verify that sparse-checkout and sparse-index
|
||||
# behave the same in this case.
|
||||
write_script edit-content <<-\EOF &&
|
||||
mkdir folder1 &&
|
||||
echo content >>folder1/a
|
||||
EOF
|
||||
run_on_sparse ../edit-content &&
|
||||
|
||||
# ls-files does not currently notice modified files whose
|
||||
# cache entries are marked SKIP_WORKTREE. This may change
|
||||
# in the future, but here we test that sparse index does
|
||||
# not accidentally create a change of behavior.
|
||||
test_sparse_match git ls-files --modified &&
|
||||
test_must_be_empty sparse-checkout-out &&
|
||||
test_must_be_empty sparse-index-out &&
|
||||
|
||||
git -C sparse-index ls-files --sparse --modified >sparse-index-out &&
|
||||
test_must_be_empty sparse-index-out &&
|
||||
|
||||
# Add folder1 to the sparse-checkout cone and
|
||||
# check that ls-files shows the expanded files.
|
||||
test_sparse_match git sparse-checkout add folder1 &&
|
||||
test_sparse_match git ls-files --modified &&
|
||||
|
||||
test_all_match git ls-files &&
|
||||
git -C sparse-index ls-files --sparse >actual &&
|
||||
|
||||
cat >expect <<-\EOF &&
|
||||
a
|
||||
deep/
|
||||
e
|
||||
folder1-
|
||||
folder1.x
|
||||
folder1/0/0/0
|
||||
folder1/0/1
|
||||
folder1/a
|
||||
folder10
|
||||
folder2/
|
||||
g
|
||||
x/
|
||||
z
|
||||
EOF
|
||||
|
||||
test_cmp expect actual &&
|
||||
|
||||
# Double-check index expansion is avoided
|
||||
ensure_not_expanded ls-files --sparse
|
||||
'
|
||||
|
||||
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
|
||||
# in this scenario, but it shouldn't.
|
||||
test_expect_success 'reset mixed and checkout orphan' '
|
||||
|
@ -1024,13 +1122,13 @@ test_expect_success 'reset mixed and checkout orphan' '
|
|||
# the sparse checkouts skip "adding" the other side of
|
||||
# the conflict.
|
||||
test_sparse_match git reset --mixed HEAD~1 &&
|
||||
test_sparse_match test-tool read-cache --table --expand &&
|
||||
test_sparse_match git ls-files --stage &&
|
||||
test_sparse_match git status --porcelain=v2 &&
|
||||
|
||||
# At this point, sparse-checkouts behave differently
|
||||
# from the full-checkout.
|
||||
test_sparse_match git checkout --orphan new-branch &&
|
||||
test_sparse_match test-tool read-cache --table --expand &&
|
||||
test_sparse_match git ls-files --stage &&
|
||||
test_sparse_match git status --porcelain=v2
|
||||
'
|
||||
|
||||
|
|
|
@ -181,13 +181,13 @@ test_expect_success 'git add fails outside of sparse-checkout definition' '
|
|||
# Avoid munging CRLFs to avoid an error message
|
||||
git -c core.autocrlf=input add --sparse sparse_entry 2>stderr &&
|
||||
test_must_be_empty stderr &&
|
||||
test-tool read-cache --table >actual &&
|
||||
grep "^100644 blob.*sparse_entry\$" actual &&
|
||||
git ls-files --stage >actual &&
|
||||
grep "^100644 .*sparse_entry\$" actual &&
|
||||
|
||||
git add --sparse --chmod=+x sparse_entry 2>stderr &&
|
||||
test_must_be_empty stderr &&
|
||||
test-tool read-cache --table >actual &&
|
||||
grep "^100755 blob.*sparse_entry\$" actual &&
|
||||
git ls-files --stage >actual &&
|
||||
grep "^100755 .*sparse_entry\$" actual &&
|
||||
|
||||
git reset &&
|
||||
|
||||
|
|
Loading…
Reference in a new issue