Skip to content

Commit 098e8c6

Browse files
committed
Merge branch 'jk/disable-commit-graph-during-upload-pack'
The "upload-pack" (the counterpart of "git fetch") needs to disable commit-graph when responding to a shallow clone/fetch request, but the way this was done made Git panic, which has been corrected. * jk/disable-commit-graph-during-upload-pack: upload-pack: disable commit graph more gently for shallow traversal commit-graph: bump DIE_ON_LOAD check to actual load-time
2 parents 37ab7cb + 6abada1 commit 098e8c6

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

commit-graph.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,14 +468,21 @@ static int prepare_commit_graph(struct repository *r)
468468
{
469469
struct object_directory *odb;
470470

471-
if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0))
472-
die("dying as requested by the '%s' variable on commit-graph load!",
473-
GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD);
471+
/*
472+
* This must come before the "already attempted?" check below, because
473+
* we want to disable even an already-loaded graph file.
474+
*/
475+
if (r->commit_graph_disabled)
476+
return 0;
474477

475478
if (r->objects->commit_graph_attempted)
476479
return !!r->objects->commit_graph;
477480
r->objects->commit_graph_attempted = 1;
478481

482+
if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0))
483+
die("dying as requested by the '%s' variable on commit-graph load!",
484+
GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD);
485+
479486
prepare_repo_settings(r);
480487

481488
if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
@@ -2101,3 +2108,8 @@ void free_commit_graph(struct commit_graph *g)
21012108
free(g->filename);
21022109
free(g);
21032110
}
2111+
2112+
void disable_commit_graph(struct repository *r)
2113+
{
2114+
r->commit_graph_disabled = 1;
2115+
}

commit-graph.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,10 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
107107
void close_commit_graph(struct raw_object_store *);
108108
void free_commit_graph(struct commit_graph *);
109109

110+
/*
111+
* Disable further use of the commit graph in this process when parsing a
112+
* "struct commit".
113+
*/
114+
void disable_commit_graph(struct repository *r);
115+
110116
#endif

repository.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ struct repository {
125125
/* A unique-id for tracing purposes. */
126126
int trace2_repo_id;
127127

128+
/* True if commit-graph has been disabled within this process. */
129+
int commit_graph_disabled;
130+
128131
/* Configurations */
129132

130133
/* Indicate if a repository has a different 'commondir' from 'gitdir' */

t/t5500-fetch-pack.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,44 @@ test_expect_success 'clone shallow since selects no commits' '
792792
)
793793
'
794794

795+
# A few subtle things about the request in this test:
796+
#
797+
# - the server must have commit-graphs present and enabled
798+
#
799+
# - the history is such that our want/have share a common ancestor ("base"
800+
# here)
801+
#
802+
# - we send only a single have, which is fewer than a normal client would
803+
# send. This ensures that we don't parse "base" up front with
804+
# parse_object(), but rather traverse to it as a parent while deciding if we
805+
# can stop the "have" negotiation, and call parse_commit(). The former
806+
# sees the actual object data and so always loads the three oid, whereas the
807+
# latter will try to load it lazily.
808+
#
809+
# - we must use protocol v2, because it handles the "have" negotiation before
810+
# processing the shallow directives
811+
#
812+
test_expect_success 'shallow since with commit graph and already-seen commit' '
813+
test_create_repo shallow-since-graph &&
814+
(
815+
cd shallow-since-graph &&
816+
test_commit base &&
817+
test_commit master &&
818+
git checkout -b other HEAD^ &&
819+
test_commit other &&
820+
git commit-graph write --reachable &&
821+
git config core.commitGraph true &&
822+
823+
GIT_PROTOCOL=version=2 git upload-pack . <<-EOF >/dev/null
824+
0012command=fetch
825+
00010013deepen-since 1
826+
0032want $(git rev-parse other)
827+
0032have $(git rev-parse master)
828+
0000
829+
EOF
830+
)
831+
'
832+
795833
test_expect_success 'shallow clone exclude tag two' '
796834
test_create_repo shallow-exclude &&
797835
(

upload-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ static void deepen_by_rev_list(struct packet_writer *writer, int ac,
721721
{
722722
struct commit_list *result;
723723

724-
close_commit_graph(the_repository->objects);
724+
disable_commit_graph(the_repository);
725725
result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
726726
send_shallow(writer, result);
727727
free_commit_list(result);

0 commit comments

Comments
 (0)