10000 Merge pull request #6846 from kcsaul/fix/setup_shallow_roots · BenJam/libgit2@db5b9f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit db5b9f5

Browse files
authored
Merge pull request libgit2#6846 from kcsaul/fix/setup_shallow_roots
Fix shallow root maintenance during fetch
2 parents 585210a + 9e40c13 commit db5b9f5

File tree

2 files changed

+146
-3
lines changed

2 files changed

+146
-3
lines changed

src/libgit2/transports/smart_protocol.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ static int setup_shallow_roots(
394394

395395
memcpy(out->ptr, wants->shallow_roots,
396396
sizeof(git_oid) * wants->shallow_roots_len);
397+
out->size = wants->shallow_roots_len;
397398
}
398399

399400
return 0;

tests/libgit2/online/shallow.c

Lines changed: 145 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,15 @@ void test_online_shallow__shorten_four(void)
242242
cl_assert_equal_b(true, git_repository_is_shallow(repo));
243243

244244
cl_git_pass(git_repository__shallow_roots(&roots, &roots_len, repo));
245-
cl_assert_equal_i(3, roots_len);
246-
cl_assert_equal_s("d86a2aada2f5e7ccf6f11880bfb9ab404e8a8864", git_oid_tostr_s(&roots[0]));
247-
cl_assert_equal_s("59706a11bde2b9899a278838ef20a97e8f8795d2", git_oid_tostr_s(&roots[1]));
245+
cl_assert_equal_i(6, roots_len);
246+
/* roots added during initial clone, not removed as not encountered during fetch */
247+
cl_assert_equal_s("c070ad8c08840c8116da865b2d65593a6bb9cd2a", git_oid_tostr_s(&roots[0]));
248+
cl_assert_equal_s("0966a434eb1a025db6b71485ab63a3bfbea520b6", git_oid_tostr_s(&roots[1]));
249+
cl_assert_equal_s("83834a7afdaa1a1260568567f6ad90020389f664", git_oid_tostr_s(&roots[3]));
250+
/* roots added during fetch */
248251
cl_assert_equal_s("bab66b48f836ed950c99134ef666436fb07a09a0", git_oid_tostr_s(&roots[2]));
252+
cl_assert_equal_s("59706a11bde2b9899a278838ef20a97e8f8795d2", git_oid_tostr_s(&roots[4]));
253+
cl_assert_equal_s("d86a2aada2f5e7ccf6f11880bfb9ab404e8a8864", git_oid_tostr_s(&roots[5]));
249254

250255
git_revwalk_new(&walk, repo);
251256
git_revwalk_push_head(walk);
@@ -263,3 +268,140 @@ void test_online_shallow__shorten_four(void)
263268
git_revwalk_free(walk);
264269
git_repository_free(repo);
265270
}
271+
272+
void test_online_shallow__preserve_unrelated_roots(void)
273+
{
274+
git_str path = GIT_STR_INIT;
275+
git_repository *repo;
276+
git_revwalk *walk;
277+
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
278+
git_remote *origin = NULL;
279+
git_strarray refspecs;
280+
git_oid oid;
281+
git_oid *roots;
282+
size_t roots_len;
283+
size_t num_commits = 0;
284+
int error = 0;
285+
git_oid first_oid;
286+
git_oid second_oid;
287+
git_oid third_oid;
288+
char *first_commit = "c070ad8c08840c8116da865b2d65593a6bb9cd2a";
289+
char *second_commit = "6e1475206e57110fcef4b92320436c1e9872a322";
290+
char *third_commit = "7f822839a2fe9760f386cbbbcb3f92c5fe81def7";
291+
292+
#ifdef GIT_EXPERIMENTAL_SHA256
293+
cl_git_pass(git_oid_fromstr(&first_oid, first_commit, GIT_OID_SHA1));
294+
cl_git_pass(git_oid_fromstr(&second_oid, second_commit, GIT_OID_SHA1));
295+
cl_git_pass(git_oid_fromstr(&third_oid, third_commit, GIT_OID_SHA1));
296+
#else
297+
cl_git_pass(git_oid_fromstr(&first_oid, first_commit));
298+
cl_git_pass(git_oid_fromstr(&second_oid, second_commit));
299+
cl_git_pass(git_oid_fromstr(&third_oid, third_commit));
300+
#endif
301+
302+
/* setup empty repository without cloning */
303+
git_str_joinpath(&path, clar_sandbox_path(), "preserve_unrelated_roots");
304+
cl_git_pass(git_repository_init(&repo, git_str_cstr(&path), true));
305+
cl_git_pass(git_remote_create(&origin, repo, "origin", "https://github.com/libgit2/TestGitRepository"));
306+
cl_assert_equal_b(false, git_repository_is_shallow(repo));
307+
308+
/* shallow fetch for first commit */
309+
fetch_opts.depth = 1;
310+
refspecs.strings = &first_commit;
311+
refspecs.count = 1;
312+
cl_git_pass(git_remote_fetch(origin, &refspecs, &fetch_opts, NULL));
313+
cl_assert_equal_b(true, git_repository_is_shallow(repo));
314+
315+
cl_git_pass(git_repository__shallow_roots(&roots, &roots_len, repo));
316+
cl_assert_equal_i(1, roots_len);
317+
cl_assert_equal_s("c070ad8c08840c8116da865b2d65593a6bb9cd2a", git_oid_tostr_s(&roots[0]));
318+
319+
cl_git_pass(git_revwalk_new(&walk, repo));
320+
cl_git_pass(git_revwalk_push(walk, &first_oid));
321+
while ((error = git_revwalk_next(&oid, walk)) == GIT_OK) {
322+
num_commits++;
323+
}
324+
cl_assert_equal_i(num_commits, 1);
325+
cl_assert_equal_i(error, GIT_ITEROVER);
326+
327+
/* shallow fetch for second commit */
328+
fetch_opts.depth = 1;
329+
refspecs.strings = &second_commit;
330+
refspecs.count = 1;
331+
cl_git_pass(git_remote_fetch(origin, &refspecs, &fetch_opts, NULL));
332+
cl_assert_equal_b(true, git_repository_is_shallow(repo));
333+
334+
git__free(roots);
335+
cl_git_pass(git_repository__shallow_roots(&roots, &roots_len, repo));
336+
cl_assert_equal_i(2, roots_len);
337+
cl_assert_equal_s("c070ad8c08840c8116da865b2d65593a6bb9cd2a", git_oid_tostr_s(&roots[0]));
338+
cl_assert_equal_s("6e1475206e57110fcef4b92320436c1e9872a322", git_oid_tostr_s(&roots[1]));
339+
340+
git_revwalk_free(walk);
341+
cl_git_pass(git_revwalk_new(&walk, repo));
342+
cl_git_pass(git_revwalk_push(walk, &second_oid));
343+
num_commits = 0;
344+
while ((error = git_revwalk_next(&oid, walk)) == GIT_OK) {
345+
num_commits++;
346+
}
347+
cl_assert_equal_i(error, GIT_ITEROVER);
348+
cl_assert_equal_i(num_commits, 1);
349+
350+
/* fetch full history for third commit, includes first commit which should be removed from shallow roots */
351+
fetch_opts.depth = 100;
352+
refspecs.strings = &third_commit;
353+
refspecs.count = 1;
354+
cl_git_pass(git_remote_fetch(origin, &refspecs, &fetch_opts, NULL));
355+
cl_assert_equal_b(true, git_repository_is_shallow(repo));
356+
357+
git__free(roots);
358+
cl_git_pass(git_repository__shallow_roots(&roots, &roots_len, repo));
359+
cl_assert_equal_i(1, roots_len);
360+
cl_assert_equal_s("6e1475206e57110fcef4b92320436c1e9872a322", git_oid_tostr_s(&roots[0]));
361+
362+
git_revwalk_free(walk);
363+
cl_git_pass(git_revwalk_new(&walk, repo));
364+
cl_git_pass(git_revwalk_push(walk, &third_oid));
365+
num_commits = 0;
366+
while ((error = git_revwalk_next(&oid, walk)) == GIT_OK) {
367+
num_commits++;
368+
}
369+
cl_assert_equal_i(error, GIT_ITEROVER);
370+
cl_assert_equal_i(num_commits, 12);
371+
372+
cl_git_pass(git_revwalk_reset(walk));
373+
cl_git_pass(git_revwalk_push(walk, &second_oid));
374+
F2A6 num_commits = 0;
375+
while ((error = git_revwalk_next(&oid, walk)) == GIT_OK) {
376+
num_commits++;
377+
}
378+
cl_assert_equal_i(error, GIT_ITEROVER);
379+
cl_assert_equal_i(num_commits, 1);
380+
381+
/* unshallow repository without specifying any refspec */
382+
fetch_opts.depth = GIT_FETCH_DEPTH_UNSHALLOW;
383+
cl_git_pass(git_remote_fetch(origin, NULL, &fetch_opts, NULL));
384+
cl_assert_equal_b(false, git_repository_is_shallow(repo));
385+
386+
git__free(roots);
387+
cl_git_pass(git_repository__shallow_roots(&roots, &roots_len, repo));
388+
cl_assert_equal_i(0, roots_len);
389+
390+
git_revwalk_free(walk);
391+
cl_git_pass(git_revwalk_new(&walk, repo));
392+
cl_git_pass(git_revwalk_push(walk, &first_oid));
393+
cl_git_pass(git_revwalk_push(walk, &second_oid));
394+
cl_git_pass(git_revwalk_push(walk, &third_oid));
395+
num_commits = 0;
396+
while ((error = git_revwalk_next(&oid, walk)) == GIT_OK) {
397+
num_commits++;
398+
}
399+
cl_assert_equal_i(error, GIT_ITEROVER);
400+
cl_assert_equal_i(num_commits, 18);
401+
402+
git__free(roots);
403+
git_remote_free(origin);
404+
git_str_dispose(&path);
405+
git_revwalk_free(walk);
406+
git_repository_free(repo);
407+
}

0 commit comments

Comments
 (0)
0