Browse Source

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
maint
Junio C Hamano 3 years ago
parent
commit
3c0e417827
  1. 5
      Documentation/git-ls-files.txt
  2. 2
      builtin/fetch.c
  3. 12
      builtin/ls-files.c
  4. 2
      builtin/pull.c
  5. 64
      t/helper/test-read-cache.c
  6. 25
      t/t1091-sparse-checkout-builtin.sh
  7. 132
      t/t1092-sparse-checkout-compatibility.sh
  8. 8
      t/t3705-add-sparse-checkout.sh

5
Documentation/git-ls-files.txt

@ -187,6 +187,11 @@ Both the <eolinfo> in the index ("i/<eolinfo>") @@ -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.


2
builtin/fetch.c

@ -2009,6 +2009,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) @@ -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);

12
builtin/ls-files.c

@ -37,6 +37,7 @@ static int debug_mode; @@ -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) @@ -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) @@ -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) @@ -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);

2
builtin/pull.c

@ -994,6 +994,8 @@ int cmd_pull(int argc, const char **argv, const char *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);


64
t/helper/test-read-cache.c

@ -1,83 +1,39 @@ @@ -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;
}

25
t/t1091-sparse-checkout-builtin.sh

@ -234,12 +234,27 @@ test_expect_success 'sparse-index enabled and disabled' ' @@ -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
)

132
t/t1092-sparse-checkout-compatibility.sh

@ -206,45 +206,42 @@ test_sparse_unstaged () { @@ -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' ' @@ -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' ' @@ -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' ' @@ -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' ' @@ -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' ' @@ -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
'


8
t/t3705-add-sparse-checkout.sh

@ -181,13 +181,13 @@ test_expect_success 'git add fails outside of sparse-checkout definition' ' @@ -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…
Cancel
Save