Skip to content

Commit 39d18fe

Browse files
committed
smart: use push_glob instead of manual filtering
The code worked under the assumption that anything under `refs/tags` are tag objects, and all the rest would be peelable to a commit. As it is completely valid to have tags to blobs under a non `refs/tags` ref, this would cause failures when trying to peel a tag to a commit. Fix the broken filtering by switching to `git_revwalk_push_glob`, which already handles this case.
1 parent 0f40e68 commit 39d18fe

File tree

6 files changed

+16
-54
lines changed

6 files changed

+16
-54
lines changed

src/transports/smart_protocol.c

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -270,50 +270,6 @@ static int store_common(transport_smart *t)
270270
return 0;
271271
}
272272

273-
static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
274-
{
275-
git_revwalk *walk = NULL;
276-
git_strarray refs;
277-
unsigned int i;
278-
git_reference *ref = NULL;
279-
int error;
280-
281-
if ((error = git_reference_list(&refs, repo)) < 0)
282-
return error;
283-
284-
if ((error = git_revwalk_new(&walk, repo)) < 0)
285-
return error;
286-
287-
git_revwalk_sorting(walk, GIT_SORT_TIME);
288-
289-
for (i = 0; i < refs.count; ++i) {
290-
git_reference_free(ref);
291-
ref = NULL;
292-
293-
/* No tags */
294-
if (!git__prefixcmp(refs.strings[i], GIT_REFS_TAGS_DIR))
295-
continue;
296-
297-
if ((error = git_reference_lookup(&ref, repo, refs.strings[i])) < 0)
298-
goto on_error;
299-
300-
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC)
301-
continue;
302-
303-
if ((error = git_revwalk_push(walk, git_reference_target(ref))) < 0)
304-
goto on_error;
305-
}
306-
307-
*out = walk;
308-
309-
on_error:
310-
if (error)
311-
git_revwalk_free(walk);
312-
git_reference_free(ref);
313-
git_strarray_free(&refs);
314-
return error;
315-
}
316-
317273
static int wait_while_ack(gitno_buffer *buf)
318274
{
319275
int error;
@@ -358,7 +314,10 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
358314
if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
359315
return error;
360316

361-
if ((error = fetch_setup_walk(&walk, repo)) < 0)
317+
if ((error = git_revwalk_new(&walk, repo)) < 0)
318+
goto on_error;
319+
320+
if ((error = git_revwalk_push_glob(walk, "refs/*")) < 0)
362321
goto on_error;
363322

364323
/*

tests/network/fetchlocal.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,15 +419,15 @@ void test_network_fetchlocal__multi_remotes(void)
419419
cl_git_pass(git_remote_fetch(test, NULL, &options, NULL));
420420

421421
cl_git_pass(git_reference_list(&refnames, repo));
422-
cl_assert_equal_i(32, (int)refnames.count);
422+
cl_assert_equal_i(33, (int)refnames.count);
423423
git_strarray_free(&refnames);
424424

425425
cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git")));
426426
cl_git_pass(git_remote_lookup(&test2, repo, "test_with_pushurl"));
427427
cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL));
428428

429429
cl_git_pass(git_reference_list(&refnames, repo));
430-
cl_assert_equal_i(44, (int)refnames.count);
430+
cl_assert_equal_i(45, (int)refnames.count);
431431

432432
git_strarray_free(&refnames);
433433
git_remote_free(test);

tests/network/remote/local.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void test_network_remote_local__retrieve_advertised_references(void)
6262

6363
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
6464

65-
cl_assert_equal_i(refs_len, 28);
65+
cl_assert_equal_i(refs_len, 29);
6666
}
6767

6868
void test_network_remote_local__retrieve_advertised_before_connect(void)
@@ -86,7 +86,7 @@ void test_network_remote_local__retrieve_advertised_references_after_disconnect(
8686

8787
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
8888

89-
cl_assert_equal_i(refs_len, 28);
89+
cl_assert_equal_i(refs_len, 29);
9090
}
9191

9292
void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void)
@@ -101,7 +101,7 @@ void test_network_remote_local__retrieve_advertised_references_from_spaced_repos
101101

102102
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
103103

104-
cl_assert_equal_i(refs_len, 28);
104+
cl_assert_equal_i(refs_len, 29);
105105

106106
git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */
107107
remote = NULL;

tests/refs/foreachglob.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ static void assert_retrieval(const char *glob, int expected_count)
4848

4949
void test_refs_foreachglob__retrieve_all_refs(void)
5050
{
51-
/* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags */
52-
assert_retrieval("*", 22);
51+
/* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags + 1 blob */
52+
assert_retrieval("*", 23);
5353
}
5454

5555
void test_refs_foreachglob__retrieve_remote_branches(void)

tests/refs/iterator.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void test_refs_iterator__cleanup(void)
1515
}
1616

1717
static const char *refnames[] = {
18+
"refs/blobs/annotated_tag_to_blob",
1819
"refs/heads/br2",
1920
"refs/heads/cannot-fetch",
2021
"refs/heads/chomped",
@@ -40,6 +41,7 @@ static const char *refnames[] = {
4041
};
4142

4243
static const char *refnames_with_symlink[] = {
44+
"refs/blobs/annotated_tag_to_blob",
4345
"refs/heads/br2",
4446
"refs/heads/cannot-fetch",
4547
"refs/heads/chomped",
@@ -99,7 +101,7 @@ void test_refs_iterator__list(void)
99101
git_vector output;
100102
git_reference *ref;
101103

102-
cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
104+
cl_git_pass(git_vector_init(&output, 33, &refcmp_cb));
103105
cl_git_pass(git_reference_iterator_new(&iter, repo));
104106

105107
while (1) {
@@ -143,7 +145,7 @@ static int refs_foreach_cb(git_reference *reference, void *payload)
143145
void test_refs_iterator__foreach(void)
144146
{
145147
git_vector output;
146-
cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
148+
cl_git_pass(git_vector_init(&output, 33, &refcmp_cb));
147149
cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
148150
assert_all_refnames_match(refnames, &output);
149151
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
521d87c1ec3aef9824daf6d96cc0ae3710766d91

0 commit comments

Comments
 (0)