[PATCH] Fixed --shallow-since generating descendant borders
- From
Samo Pogačnik via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Nov 22, 2025, 10:38 UTC
- Message-ID
- <pull.2107.git.git.1763807914242.gitgitgadget@gmail.com>
From: =?UTF-8?q?Samo=20Poga=C4=8Dnik?= <samo_pogacnik@t-2.net>
When shallow cloning based on a date, it happens that a list of commits is received, where some of the list border commits actually descend one from another. In such cases borders need to be expanded by additional parents and excluding the child as border.
Signed-off-by: Samo Pogačnik <samo_pogacnik@t-2.net>
---
Fixed --shallow-since generating descendant borders
When shallow cloning based on a date, it happens that a list of commits
is received, where some of the list border commits actually descend one
from another. In such cases borders need to be expanded by additional
parents and excluding the child as border.Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2107%2Fspog%2Ffix-shallow-since-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2107/spog/fix-shallow-since-v1 Pull-Request: https://github.com/git/git/pull/2107
shallow.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/shallow.c b/shallow.c index 55b9cd9d3f..37079a0bf1 100644 --- a/shallow.c +++ b/shallow.c @@ -251,21 +251,50 @@ struct commit_list *get_shallow_commits_by_rev_list(struct strvec *argv, * commit A is processed first, then commit B, whose parent is * A, later. If NOT_SHALLOW on A is cleared at step 1, B * itself is considered border at step 2, which is incorrect. + * We must also consider that B has multiple parents, some of + * them not being in the not_shallow_list, but must be added + * as border commits to the result. + * + * The general processing goes like this: + * 1. Above we've coloured the whole not_shallow_list of commits + * with 'not_shallow'. + * 2. For each commit from the not_shallow_list (the code below) + * we colour 'shallow' the commit and its parents, which are not + * already coloured 'not_shallow'. + * 3. Commits with all parents being coloured only 'shallow' remain + * shallow and are being added to result list. + * 4. Commits without all parents being coloured only 'shallow' are + * being excluded as borders, however their parents coloured only + * 'shallow' are being added to the result borders list. */ for (p = not_shallow_list; p; p = p->next) { struct commit *c = p->item; struct commit_list *parent; + int must_not_be_shallow = 0; if (repo_parse_commit(the_repository, c)) die("unable to parse commit %s", oid_to_hex(&c->object.oid)); for (parent = c->parents; parent; parent = parent->next) - if (!(parent->item->object.flags & not_shallow_flag)) { + if (parent->item->object.flags & not_shallow_flag) { + must_not_be_shallow = 1; + } else { c->object.flags |= shallow_flag; - commit_list_insert(c, &result); - break; + parent->item->object.flags |= shallow_flag; } + if (must_not_be_shallow) { + c->object.flags &= ~shallow_flag; + for (parent = c->parents; parent; parent = parent->next) + if (parent->item->object.flags & shallow_flag) { + parent->item->object.flags |= not_shallow_flag; + commit_list_insert(parent->item, &result); + } + } else { + for (parent = c->parents; parent; parent = parent->next) + parent->item->object.flags &= ~shallow_flag; + commit_list_insert(c, &result); + } } free_commit_list(not_shallow_list); base-commit: debbc87557487aa9a8ed8a35367d17f8b4081c76
-- gitgitgadget