Skip to content

Commit 8d2c373

Browse files
committed
Merge branch 'ld/sparse-diff-blame'
Teach diff and blame to work well with sparse index. * ld/sparse-diff-blame: blame: enable and test the sparse index diff: enable and test the sparse index diff: replace --staged with --cached in t1092 tests repo-settings: prepare_repo_settings only in git repos test-read-cache: set up repo after git directory commit-graph: return if there is no git directory git: ensure correct git directory setup with -h
2 parents 3f9d505 + add4c86 commit 8d2c373

File tree

7 files changed

+131
-37
lines changed

7 files changed

+131
-37
lines changed

builtin/blame.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
939939
revs.diffopt.flags.follow_renames = 0;
940940
argc = parse_options_end(&ctx);
941941

942+
prepare_repo_settings(the_repository);
943+
the_repository->settings.command_requires_full_index = 0;
944+
942945
if (incremental || (output_option & OUTPUT_PORCELAIN)) {
943946
if (show_progress > 0)
944947
die(_("--progress can't be used with --incremental or porcelain formats"));

builtin/diff.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
437437

438438
prefix = setup_git_directory_gently(&nongit);
439439

440+
if (!nongit) {
441+
prepare_repo_settings(the_repository);
442+
the_repository->settings.command_requires_full_index = 0;
443+
}
444+
440445
if (!no_index) {
441446
/*
442447
* Treat git diff with at least one path outside of the

commit-graph.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,13 @@ static int prepare_commit_graph(struct repository *r)
632632
struct object_directory *odb;
633633

634634
/*
635+
* Early return if there is no git dir or if the commit graph is
636+
* disabled.
637+
*
635638
* This must come before the "already attempted?" check below, because
636639
* we want to disable even an already-loaded graph file.
637640
*/
638-
if (r->commit_graph_disabled)
641+
if (!r->gitdir || r->commit_graph_disabled)
639642
return 0;
640643

641644
if (r->objects->commit_graph_attempted)

git.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -421,27 +421,30 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
421421
int status, help;
422422
struct stat st;
423423
const char *prefix;
424+
int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY));
424425

425-
prefix = NULL;
426426
help = argc == 2 && !strcmp(argv[1], "-h");
427-
if (!help) {
428-
if (p->option & RUN_SETUP)
429-
prefix = setup_git_directory();
430-
else if (p->option & RUN_SETUP_GENTLY) {
431-
int nongit_ok;
432-
prefix = setup_git_directory_gently(&nongit_ok);
433-
}
434-
precompose_argv_prefix(argc, argv, NULL);
435-
if (use_pager == -1 && p->option & (RUN_SETUP | RUN_SETUP_GENTLY) &&
436-
!(p->option & DELAY_PAGER_CONFIG))
437-
use_pager = check_pager_config(p->cmd);
438-
if (use_pager == -1 && p->option & USE_PAGER)
439-
use_pager = 1;
440-
441-
if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) &&
442-
startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
443-
trace_repo_setup(prefix);
427+
if (help && (run_setup & RUN_SETUP))
428+
/* demote to GENTLY to allow 'git cmd -h' outside repo */
429+
run_setup = RUN_SETUP_GENTLY;
430+
431+
if (run_setup & RUN_SETUP) {
432+
prefix = setup_git_directory();
433+
} else if (run_setup & RUN_SETUP_GENTLY) {
434+
int nongit_ok;
435+
prefix = setup_git_directory_gently(&nongit_ok);
436+
} else {
437+
prefix = NULL;
444438
}
439+
precompose_argv_prefix(argc, argv, NULL);
440+
if (use_pager == -1 && run_setup &&
441+
!(p->option & DELAY_PAGER_CONFIG))
442+
use_pager = check_pager_config(p->cmd);
443+
if (use_pager == -1 && p->option & USE_PAGER)
444+
use_pager = 1;
445+
if (run_setup && startup_info->have_repository)
446+
/* get_git_dir() may set up repo, avoid that */
447+
trace_repo_setup(prefix);
445448
commit_pager_choice();
446449

447450
if (!help && get_super_prefix()) {

repo-settings.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ void prepare_repo_settings(struct repository *r)
1717
char *strval;
1818
int manyfiles;
1919

20+
if (!r->gitdir)
21+
BUG("Cannot add settings for uninitialized repository");
22+
2023
if (r->settings.initialized++)
2124
return;
2225

t/perf/p2000-sparse-operations.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,9 @@ test_perf_on_all git checkout -f -
113113
test_perf_on_all git reset
114114
test_perf_on_all git reset --hard
115115
test_perf_on_all git reset -- does-not-exist
116+
test_perf_on_all git diff
117+
test_perf_on_all git diff --cached
118+
test_perf_on_all git blame $SPARSE_CONE/a
119+
test_perf_on_all git blame $SPARSE_CONE/f3/a
116120

117121
test_done

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ test_expect_success 'checkout and reset --hard' '
415415
test_all_match git reset --hard update-folder2
416416
'
417417

418-
test_expect_success 'diff --staged' '
418+
test_expect_success 'diff --cached' '
419419
init_repos &&
420420
421421
write_script edit-contents <<-\EOF &&
@@ -424,10 +424,10 @@ test_expect_success 'diff --staged' '
424424
run_on_all ../edit-contents &&
425425
426426
test_all_match git diff &&
427-
test_all_match git diff --staged &&
427+
test_all_match git diff --cached &&
428428
test_all_match git add README.md &&
429429
test_all_match git diff &&
430-
test_all_match git diff --staged
430+
test_all_match git diff --cached
431431
'
432432

433433
# NEEDSWORK: sparse-checkout behaves differently from full-checkout when
@@ -444,8 +444,8 @@ test_expect_success 'diff with renames and conflicts' '
444444
test_all_match git checkout rename-base &&
445445
test_all_match git checkout $branch -- . &&
446446
test_all_match git status --porcelain=v2 &&
447-
test_all_match git diff --staged --no-renames &&
448-
test_all_match git diff --staged --find-renames || return 1
447+
test_all_match git diff --cached --no-renames &&
448+
test_all_match git diff --cached --find-renames || return 1
449449
done
450450
'
451451

@@ -464,8 +464,8 @@ test_expect_success 'diff with directory/file conflicts' '
464464
test_all_match git checkout $branch &&
465465
test_all_match git checkout rename-base -- . &&
466466
test_all_match git status --porcelain=v2 &&
467-
test_all_match git diff --staged --no-renames &&
468-
test_all_match git diff --staged --find-renames || return 1
467+
test_all_match git diff --cached --no-renames &&
468+
test_all_match git diff --cached --find-renames || return 1
469469
done
470470
'
471471

@@ -486,21 +486,36 @@ test_expect_success 'log with pathspec outside sparse definition' '
486486
test_expect_success 'blame with pathspec inside sparse definition' '
487487
init_repos &&
488488
489-
test_all_match git blame a &&
490-
test_all_match git blame deep/a &&
491-
test_all_match git blame deep/deeper1/a &&
492-
test_all_match git blame deep/deeper1/deepest/a
489+
for file in a \
490+
deep/a \
491+
deep/deeper1/a \
492+
deep/deeper1/deepest/a
493+
do
494+
test_all_match git blame $file
495+
done
493496
'
494497

495-
# TODO: blame currently does not support blaming files outside of the
496-
# sparse definition. It complains that the file doesn't exist locally.
497-
test_expect_failure 'blame with pathspec outside sparse definition' '
498+
# Without a revision specified, blame will error if passed any file that
499+
# is not present in the working directory (even if the file is tracked).
500+
# Here we just verify that this is also true with sparse checkouts.
501+
test_expect_success 'blame with pathspec outside sparse definition' '
498502
init_repos &&
503+
test_sparse_match git sparse-checkout set &&
499504
500-
test_all_match git blame folder1/a &&
501-
test_all_match git blame folder2/a &&
502-
test_all_match git blame deep/deeper2/a &&
503-
test_all_match git blame deep/deeper2/deepest/a
505+
for file in a \
506+
deep/a \
507+
deep/deeper1/a \
508+
deep/deeper1/deepest/a
509+
do
510+
test_sparse_match test_must_fail git blame $file &&
511+
cat >expect <<-EOF &&
512+
fatal: Cannot lstat '"'"'$file'"'"': No such file or directory
513+
EOF
514+
# We compare sparse-checkout-err and sparse-index-err in
515+
# `test_sparse_match`. Given we know they are the same, we
516+
# only check the content of sparse-index-err here.
517+
test_cmp expect sparse-index-err
518+
done
504519
'
505520

506521
test_expect_success 'checkout and reset (mixed)' '
@@ -936,6 +951,64 @@ test_expect_success 'sparse-index is not expanded: merge conflict in cone' '
936951
)
937952
'
938953

954+
test_expect_success 'sparse index is not expanded: diff' '
955+
init_repos &&
956+
957+
write_script edit-contents <<-\EOF &&
958+
echo text >>$1
959+
EOF
960+
961+
# Add file within cone
962+
test_sparse_match git sparse-checkout set deep &&
963+
run_on_all ../edit-contents deep/testfile &&
964+
test_all_match git add deep/testfile &&
965+
run_on_all ../edit-contents deep/testfile &&
966+
967+
test_all_match git diff &&
968+
test_all_match git diff --cached &&
969+
ensure_not_expanded diff &&
970+
ensure_not_expanded diff --cached &&
971+
972+
# Add file outside cone
973+
test_all_match git reset --hard &&
974+
run_on_all mkdir newdirectory &&
975+
run_on_all ../edit-contents newdirectory/testfile &&
976+
test_sparse_match git sparse-checkout set newdirectory &&
977+
test_all_match git add newdirectory/testfile &&
978+
run_on_all ../edit-contents newdirectory/testfile &&
979+
test_sparse_match git sparse-checkout set &&
980+
981+
test_all_match git diff &&
982+
test_all_match git diff --cached &&
983+
ensure_not_expanded diff &&
984+
ensure_not_expanded diff --cached &&
985+
986+
# Merge conflict outside cone
987+
# The sparse checkout will report a warning that is not in the
988+
# full checkout, so we use `run_on_all` instead of
989+
# `test_all_match`
990+
run_on_all git reset --hard &&
991+
test_all_match git checkout merge-left &&
992+
test_all_match test_must_fail git merge merge-right &&
993+
994+
test_all_match git diff &&
995+
test_all_match git diff --cached &&
996+
ensure_not_expanded diff &&
997+
ensure_not_expanded diff --cached
998+
'
999+
1000+
test_expect_success 'sparse index is not expanded: blame' '
1001+
init_repos &&
1002+
1003+
for file in a \
1004+
deep/a \
1005+
deep/deeper1/a \
1006+
deep/deeper1/deepest/a
1007+
do
1008+
ensure_not_expanded blame $file
1009+
done
1010+
'
1011+
9391012
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
9401013
# in this scenario, but it shouldn't.
9411014
test_expect_success 'reset mixed and checkout orphan' '

0 commit comments

Comments
 (0)