Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Conversation

@spog
Copy link

@spog spog commented Nov 22, 2025

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.

@gitgitgadget-git
Copy link

Welcome to GitGitGadget

Hi @spog, and welcome to GitGitGadget, the GitHub App to send patch series to the Git mailing list from GitHub Pull Requests.

Please make sure that either:

  • Your Pull Request has a good description, if it consists of multiple commits, as it will be used as cover letter.
  • Your Pull Request description is empty, if it consists of a single commit, as the commit message should be descriptive enough by itself.

You can CC potential reviewers by adding a footer to the PR description with the following syntax:

CC: Revi Ewer <[email protected]>, Ill Takalook <[email protected]>

NOTE: DO NOT copy/paste your CC list from a previous GGG PR's description,
because it will result in a malformed CC list on the mailing list. See
example.

Also, it is a good idea to review the commit messages one last time, as the Git project expects them in a quite specific form:

  • the lines should not exceed 76 columns,
  • the first line should be like a header and typically start with a prefix like "tests:" or "revisions:" to state which subsystem the change is about, and
  • the commit messages' body should be describing the "why?" of the change.
  • Finally, the commit messages should end in a Signed-off-by: line matching the commits' author.

It is in general a good idea to await the automated test ("Checks") in this Pull Request before contributing the patches, e.g. to avoid trivial issues such as unportable code.

Contributing the patches

Before you can contribute the patches, your GitHub username needs to be added to the list of permitted users. Any already-permitted user can do that, by adding a comment to your PR of the form /allow. A good way to find other contributors is to locate recent pull requests where someone has been /allowed:

Both the person who commented /allow and the PR author are able to /allow you.

An alternative is the channel #git-devel on the Libera Chat IRC network:

<newcontributor> I've just created my first PR, could someone please /allow me? https://github.com/gitgitgadget/git/pull/12345
<veteran> newcontributor: it is done
<newcontributor> thanks!

Once on the list of permitted usernames, you can contribute the patches to the Git mailing list by adding a PR comment /submit.

If you want to see what email(s) would be sent for a /submit request, add a PR comment /preview to have the email(s) sent to you. You must have a public GitHub email address for this. Note that any reviewers CC'd via the list in the PR description will not actually be sent emails.

After you submit, GitGitGadget will respond with another comment that contains the link to the cover letter mail in the Git mailing list archive. Please make sure to monitor the discussion in that thread and to address comments and suggestions (while the comments and suggestions will be mirrored into the PR by GitGitGadget, you will still want to reply via mail).

If you do not want to subscribe to the Git mailing list just to be able to respond to a mail, you can download the mbox from the Git mailing list archive (click the (raw) link), then import it into your mail program. If you use GMail, you can do this via:

curl -g --user "<EMailAddress>:<Password>" \
    --url "imaps://imap.gmail.com/INBOX" -T /path/to/raw.txt

To iterate on your change, i.e. send a revised patch or patch series, you will first want to (force-)push to the same branch. You probably also want to modify your Pull Request description (or title). It is a good idea to summarize the revision by adding something like this to the cover letter (read: by editing the first comment on the PR, i.e. the PR description):

Changes since v1:
- Fixed a typo in the commit message (found by ...)
- Added a code comment to ... as suggested by ...
...

To send a new iteration, just add another PR comment with the contents: /submit.

Need help?

New contributors who want advice are encouraged to join [email protected], where volunteers who regularly contribute to Git are willing to answer newbie questions, give advice, or otherwise provide mentoring to interested contributors. You must join in order to post or view messages, but anyone can join.

You may also be able to find help in real time in the developer IRC channel, #git-devel on Libera Chat. Remember that IRC does not support offline messaging, so if you send someone a private message and log out, they cannot respond to you. The scrollback of #git-devel is archived, though.

@gitgitgadget-git
Copy link

There are issues in commit 53f19aa:
Fixed --shallow-since generating descendant borders
Commit not signed off

@Ikke
Copy link
Contributor

Ikke commented Nov 22, 2025

/allow

@gitgitgadget-git
Copy link

User spog is now allowed to use GitGitGadget.

@spog spog force-pushed the fix-shallow-since branch from 53f19aa to aaeff44 Compare November 22, 2025 10:26
@spog
Copy link
Author

spog commented Nov 22, 2025

/preview

@gitgitgadget-git
Copy link

Preview email sent as [email protected]

@spog
Copy link
Author

spog commented Nov 22, 2025

/submit

@gitgitgadget-git
Copy link

Submitted as [email protected]

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2107/spog/fix-shallow-since-v1

To fetch this version to local tag pr-git-2107/spog/fix-shallow-since-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2107/spog/fix-shallow-since-v1

@gitgitgadget-git
Copy link

On the Git mailing list, Junio C Hamano wrote (reply to this):

"Samo Pogačnik via GitGitGadget" <[email protected]> writes:

> Subject: Re: [PATCH] Fixed --shallow-since generating descendant borders

A patch title wants maximum information density, and "Fixed" is a
vague verb in that context, as it does not tell what existing
behaviour was wrong or what is the right alternative behaviour.

As "git log --oneline --no-merges" can show, our patches typically
begins with the area the change pertains to plus a colon.  "git log
--oneline shallow.c" (which is the file this patch touches) shows a
handful ones that are prefixed with "shallow:".

What to write after the "<area>:" prefix for this patch, I am not
sure, as the body of the proposed log message does not discuss the
bad effect of the suboptimal or wrong (I cannot even tell which one
from the proposed log message) behaviour.

> From: =?UTF-8?q?Samo=20Poga=C4=8Dnik?= <[email protected]>
>
> 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.

Missing from the above description are

 - received by whom?

 - the reason why they want such a list is to do what?

 - when there are multiple borders that can be "expanded", and if
   you leave it unexpanded (i.e., the behaviour of the current code)
   what happens and why is it bad?  Is it breaking bad (e.g., clone
   would be aborted, the resulting cloned repository does not pass
   fsck), or is it suboptimal bad (e.g., we told the command that we
   do not want commits older than date X, but we end up having more
   commits)?

 - what is the cost of computing the "expansion", relative to the
   above "badness"?  Fixing a breaking bad behaviour can of course
   afford to spend more cycles than a suboptimal bad behaviour.

The usual way to compose a log message of this project is to

 - Give an observation on how the current system works in the
   present tense (so no need to say "Currently X is Y", or
   "Previously X was Y" to describe the state before your change;
   just "X is Y" is enough), and discuss what you perceive as a
   problem in it.

 - Propose a solution (optional---often, problem description
   trivially leads to an obvious solution in reader's minds).

 - Give commands to somebody editing the codebase to "make it so",
   instead of saying "This commit does X".

in this order.

> 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(-)

We'd want to protect this change from other people accidentally
breaking it in the future, and the best practice we have is to write
a test to observe end-user visible behaviour.  The whole helper
function being touched by the patch came in the 27-patch series
merged at a460ea4a (Merge branch 'nd/shallow-deepen', 2016-10-10),
and it seems to have added to t5500-fetch-pack.sh to cover the
"--shallow-since" feature.  Perhaps this should add a few tests to
demonstrate existing "breakage" (i.e., a "test_expect_success" test
that would fail without the change in the patch to shallow.c we see
below, and would succeed when the patch to shallow.c is applied).

Thanks.

When shallow cloning based on a date, it happens that not all
shallow border commits are reachable.

Original implementation of a generic shallow boundary finder
based on rev-list sets a commit (from the initial list of border
commit candidates) to be the border commit as soon as it finds one
of its parentis that wasn't on the list of initial candidates. This
results in a successful shallow clone, where some of its declared
border commits may not be reachable and they would not actually exist
in the cloned repository. Thus the result may contradict existing
comment in the code, which correctly states that such commmit should
not be considered border.

One can inspect such case by running the added test scenario:
- 'clone shallow since all borders reachable'

The modified implementation of a generic shallow boundary finder
based on rev-list ensures that all shallow border commits are reachable
also after being grafted. This is achieved by inspecting all parents
of each initial border commit candidate. The border commit candidate
is set border only when all its parents wern't on the initial list of
candidates. Otherwise the border commit candidate is not set as border
however its parents that weren't on the list of candidates are set as
borders.

Signed-off-by: Samo Pogačnik <[email protected]>
@spog spog force-pushed the fix-shallow-since branch from aaeff44 to 479692c Compare November 23, 2025 18:55
@spog
Copy link
Author

spog commented Nov 23, 2025

/preview

@gitgitgadget-git
Copy link

Preview email sent as [email protected]

@spog
Copy link
Author

spog commented Nov 23, 2025

/submit

@gitgitgadget-git
Copy link

Submitted as [email protected]

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2107/spog/fix-shallow-since-v2

To fetch this version to local tag pr-git-2107/spog/fix-shallow-since-v2:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2107/spog/fix-shallow-since-v2

@gitgitgadget-git
Copy link

This branch is now known as sp/shallow-time-boundary.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via f8f9bfa.

@gitgitgadget-git
Copy link

On the Git mailing list, Junio C Hamano wrote (reply to this):

"Samo Pogačnik via GitGitGadget" <[email protected]> writes:

> From: =?UTF-8?q?Samo=20Poga=C4=8Dnik?= <[email protected]>
>
> When shallow cloning based on a date, it happens that not all
> shallow border commits are reachable.
>
> Original implementation of a generic shallow boundary finder
> based on rev-list sets a commit (from the initial list of border
> commit candidates) to be the border commit as soon as it finds one
> of its parentis that wasn't on the list of initial candidates. This
> results in a successful shallow clone, where some of its declared
> border commits may not be reachable and they would not actually exist
> in the cloned repository. Thus the result may contradict existing
> comment in the code, which correctly states that such commmit should
> not be considered border.
>
> One can inspect such case by running the added test scenario:
> - 'clone shallow since all borders reachable'
>
> The modified implementation of a generic shallow boundary finder
> based on rev-list ensures that all shallow border commits are reachable
> also after being grafted. This is achieved by inspecting all parents
> of each initial border commit candidate. The border commit candidate
> is set border only when all its parents wern't on the initial list of
> candidates. Otherwise the border commit candidate is not set as border
> however its parents that weren't on the list of candidates are set as
> borders.

It is a minor point, but there are "boundary" and "border" used more
or less interchangeably in the proposed commit log message, and
would make the readers wonder if there are differences (I do not
think we use the word "border" anywhere in our documentation).  It
is minor as we do not have such mixture in the end-user facing part
of the documentation with this patch.

I'll let those (cc'ed) who may be more familiar with, or, at least
have more code than I have in, the shallow infrastructure to comment
on the way the updated code uses the revision machinery.

Thanks.

> diff --git a/shallow.c b/shallow.c
> index 55b9cd9d3f..2929ac90ee 100644
> --- a/shallow.c
> +++ b/shallow.c
> @@ -251,21 +251,57 @@ 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 which may
> +	 * not all be marked NOT_SHALLOW (as they weren't traversed into
> +	 * the not_shallow_list from revs in the first place). Because of
> +	 * that an additional step is required to reconsider B as border.
> +	 * A commit from the not_shallow_list is considered border only
> +	 * when ALL its parents weren't on the not_shallow_list.
> +	 * When one or more parents of a commit from the not_shellow_list
> +	 * also come from that list, the commit is not considered border,
> +	 * but its non-listed parents are considered border commits.
> +	 *
> +	 * The general processing goes like this:
> +	 * 1. Above we've painted the whole not_shallow_list of commits
> +	 *    NOT_SHALLOW.
> +	 * 2. For each commit from the not_shallow_list (the code below)
> +	 *    we paint SHALLOW this commit and its parent for all its
> +	 *    parents that had not yet been painted NOT_SHALLOW.
> +	 * 3. Commits with all parents being painted only SHALLOW remain
> +	 *    shallow and are being added to result list.
> +	 * 4. Commits without all parents being painted only SHALLOW are
> +	 *    being excluded as borders, however their parents painted 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);
>  
> diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
> index 2677cd5faa..12209887fb 100755
> --- a/t/t5500-fetch-pack.sh
> +++ b/t/t5500-fetch-pack.sh
> @@ -904,6 +904,25 @@ test_expect_success 'shallow since with commit graph and already-seen commit' '
>  	)
>  '
>  
> +test_expect_success 'clone shallow since all borders reachable' '
> +	test_create_repo shallow-since-all-borders-reachable &&
> +	(
> +	rm -rf shallow123 &&
> +	cd shallow-since-all-borders-reachable &&
> +	GIT_COMMITTER_DATE="2025-08-19 12:34:56" git commit --allow-empty -m one &&
> +	GIT_COMMITTER_DATE="2025-08-20 12:34:56" git switch -c branch &&
> +	GIT_COMMITTER_DATE="2025-08-21 12:34:56" git commit --allow-empty -m two &&
> +	GIT_COMMITTER_DATE="2025-08-22 12:34:56" git commit --allow-empty -m three &&
> +	GIT_COMMITTER_DATE="2025-08-23 12:34:56" git switch main &&
> +	GIT_COMMITTER_DATE="2025-08-24 12:34:56" git merge branch --no-ff &&
> +	GIT_COMMITTER_DATE="2025-08-26 12:34:56" git clone --shallow-since "2025-08-21 12:34:56" "file://$(pwd)/." ../shallow123 &&
> +	cd ../shallow123 &&
> +	echo "Shallow borders:" &&
> +	cat .git/shallow &&
> +	$(for commit in $(cat .git/shallow); do git rev-list $commit 1>/dev/null || exit 1; done)
> +	)
> +'
> +
>  test_expect_success 'shallow clone exclude tag two' '
>  	test_create_repo shallow-exclude &&
>  	(
>
> base-commit: debbc87557487aa9a8ed8a35367d17f8b4081c76

@gitgitgadget-git
Copy link

This patch series was integrated into seen via a405e8e.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 5e595b0.

@gitgitgadget-git
Copy link

There was a status update in the "New Topics" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via f84cd24.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 630a33a.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 40232be.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via f7e9101.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 4c97afc.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 6d0b8f5.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via cc6a5e5.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 5566427.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 68660f8.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 1ba7d4b.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 16cb942.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 351a485.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 69f9717.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 27b0cab.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 009699f.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via e086939.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 9d2066a.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via a56f76d.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 895c1a3.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 1fcd731.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 3c83ddb.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch sp/shallow-time-boundary on the Git mailing list:

The set of shallow boundary "git clone --shallow-since" leaves
contained commits that are not on the boundary, which has been
corrected.

Comments?
source: <[email protected]>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants