threads / bug / 62978

Bug or just a mistake : --shallow-exclude parameter behavior anomalies in Git 2.45.2: "no commits selected" and "ambiguous deepen-not" errors

Subject: Bug or just a mistake : --shallow-exclude parameter behavior anomalies in Git 2.45.2: "no commits selected" and "ambiguous deepen-not" errors

## tl;dr

8 messages between Feb 20, 2025 and Oct 21, 2025.

replies: 7people: 5as markdown or json

bolide2005@163.com· Feb 20, 2025, 08:26 UTC · lore
When using git clone with --shallow-exclude parameter (specifying branch name or existing commit SHA-1), two different errors occur:
Case 1: git clone --shallow-exclude=master <repo-url>
Error: fatal: no commits selected for shallow requests
Case 2: git clone --shallow-exclude=ef5974fc470ad7a08f9b58dcd78724e9329910db <repo-url>
Error: git upload-pack: ambiguous deepen-not: deepen-not ef5974fc470ad7a08f9b58dcd78724e9329910db
Git Version: 2.45.2 (Confirmed on Centos 7)
bolide2005@163.com
Elijah Newren· Feb 24, 2025, 15:27 UTC · re: bolide2005@163.com · lore

Re: Bug or just a mistake : --shallow-exclude parameter behavior anomalies in Git 2.45.2: "no commits selected" and "ambiguous deepen-not" errors

On Thu, Feb 20, 2025 at 12:27 AM bolide2005@163.com <bolide2005@163.com> wrote:
Show 19 quoted lines
>
> When using git clone with --shallow-exclude parameter (specifying branch name or existing commit SHA-1), two different errors occur:
>
>
>
>
> Case 1: git clone --shallow-exclude=master <repo-url>
>
>
>
> Error: fatal: no commits selected for shallow requests
>
>
>
> Case 2: git clone --shallow-exclude=ef5974fc470ad7a08f9b58dcd78724e9329910db <repo-url>
>
>
>
> Error: git upload-pack: ambiguous deepen-not: deepen-not ef5974fc470ad7a08f9b58dcd78724e9329910db

They actually should give different error messages, but the one given by the second case, in the version of Git you are using, is broken.

The error message for case 2 was fixed in 5a875ff7fbd ("upload-pack: fix ambiguous error message", 2024-11-04).

The documentation was fixed for case 2 in 00e10e07510 ("doc: correct misleading descriptions for --shallow-exclude", 2024-11-04) to point out that this usage is flawed.

Both are part of Git 2.48 and newer.
Philipp Hahn· Sep 16, 2025, 14:50 UTC · re: Elijah Newren · lore

Re: --shallow-exclude=ref -> "ambiguous deepen-not" error

Hello Elijah,
On Mon, 24 Feb 2025 at 07:27:55 -0800 Elijah Newren <newren@gmail.com> wrote:
Show 6 quoted lines
> On Thu, Feb 20, 2025 at 12:27 AM bolide2005@163.com <bolide2005@163.com> wrote:
> > Case 2: git clone --shallow-exclude=<rev> <repo-url>
>
> The documentation was fixed for case 2 in 00e10e07510 ("doc: correct
> misleading descriptions for --shallow-exclude", 2024-11-04) to point
> out that this usage is flawed.

I have searched the archive and git repository, but found no explanation, why that usage - shallow-exclude by REV - is considered "flawed": I understand, that the current implementation does not support this, but is there any technical reason why that is not possible or undesirable?

                     A---B---C topic
                    /
               D---E---F---G master

I have a use-case for this, where we use GitLab to run some linters on our merge requests (MRs): They examine the commits since the fork-point "E", for which they need access to the commits + trees + blobs. Some MRs are larger, some smaller, so there is no fixed maximum depth I can give to `--depth X` and be sure to have gotten all commits. Same for `--shallow-since=` as some are dormant for a year and many other MRs by-pass them.

GitLab gives me the `CI_MERGE_REQUEST_DIFF_BASE_SHA`[1] (The base SHA of the merge request diff) for free, which I would like to use with `--shallow-exclude=`, but that does not work as `deepen-not` does not like REVs.

For now I'm using `CI_MERGE_REQUEST_TARGET_BRANCH_NAME`[1] (The target branch name of the merge request.), but there is a different problem with this:

GitLab supports a 2nd variant of "MR Pipelines", called "Merged Result Pipelines"[2]: Instead of running on "topic" GitLab does a temporary merge of "topic" into "master" (X) and runs the pipeline on that merge commit "X". As "master" is a parent of that commit "X", the trick of using `--shallow-exclude=master` fails as the linters then run only on the merge commit "X", but not on the individual commits A-B-C, which is what I need:

                     A---B---C topic
                    /         \
               D---E---F---G---X master

Sadly there is no "ref" on "E" any longer, so I only can specify "E" via its "rev", which GitLab provides as `CI_MERGE_REQUEST_DIFF_BASE_SHA`.

Any idea on how to solve this?

The GitLab runners do not have persistent storage, so they clone the git repository anew each time. That includes the Linux Kernel git, which sometimes takes 13m to clone the 1.4e6 commits, from which only the top 1-100 have to be checked. The build on the other hand only needs `--depth 1`. That makes the build way faster than running out linters.

Philipp

[1]: https://docs.gitlab.com/ci/variables/predefined_variables/#predefined-variables-for-merge-request-pipelines [2]: https://docs.gitlab.com/ci/pipelines/merged_results_pipelines/

D. Ben Knoble· Sep 16, 2025, 17:03 UTC · re: Philipp Hahn · lore

Re: --shallow-exclude=ref -> "ambiguous deepen-not" error

On Tue, Sep 16, 2025 at 10:58 AM Philipp Hahn <phahn-oss@avm.de> wrote:
Show 27 quoted lines
>
> Hello Elijah,
>
> On Mon, 24 Feb 2025 at 07:27:55 -0800 Elijah Newren <newren@gmail.com> wrote:
> > On Thu, Feb 20, 2025 at 12:27 AM bolide2005@163.com <bolide2005@163.com> wrote:
> > > Case 2: git clone --shallow-exclude=<rev> <repo-url>
> >
> > The documentation was fixed for case 2 in 00e10e07510 ("doc: correct
> > misleading descriptions for --shallow-exclude", 2024-11-04) to point
> > out that this usage is flawed.
>
> I have searched the archive and git repository, but found no explanation, why
> that usage - shallow-exclude by REV - is considered "flawed": I understand,
> that the current implementation does not support this, but is there any
> technical reason why that is not possible or undesirable?
>
>                      A---B---C topic
>                     /
>                D---E---F---G master
>
> I have a use-case for this, where we use GitLab to run some linters on our
> merge requests (MRs): They examine the commits since the fork-point "E", for
> which they need access to the commits + trees + blobs. Some MRs are larger,
> some smaller, so there is no fixed maximum depth I can give to `--depth X` and
> be sure to have gotten all commits.
> Same for `--shallow-since=` as some are dormant for a year and many other MRs
> by-pass them.

I might have misunderstood, but aren't the commits you're interested in here the ones named by

    git rev-list master..topic
?

I see a mention of git-clone in the quoted reply, so perhaps you're trying to avoid cloning too much history. I wonder if a blobless clone would suffice, which you can then add to once you have the list of commits produced above? That would fetch more commits than necessary, but should still be significantly cheaper.

-- 
D. Ben Knoble
Philipp Hahn· Sep 16, 2025, 17:57 UTC · re: D. Ben Knoble · lore

Re: --shallow-exclude=ref -> "ambiguous deepen-not" error

Hello Ben,
Thank you for your reply.
On Tue, 16 Sep 2025 at 13:03:41 -0400 D. Ben Knoble <ben.knoble@gmail.com> wrote:
> On Tue, Sep 16, 2025 at 10:58 AM Philipp Hahn <phahn-oss@avm.de> wrote:
> >                      A---B---C topic
> >                     /
> >                D---E---F---G master
Show 6 quoted lines
> I might have misunderstood, but aren't the commits you're interested
> in here the ones named by
> 
>     git rev-list master..topic
> 
> ?

Yes, which is I have described using `CI_MERGE_REQUEST_TARGET_BRANCH_NAME := master`.

But as also described this fails for those "merged regsult pipelines", where GitLab creates a temporary merge "X" and then runs its pipeline on "X":
Show 5 quoted lines
>                      A---B---C topic
>                     /         \
>                     /        __X temp
>                     /       /
>                D---E---F---G master
Here `master..temp` becomes just "X", but not "A-B-C".

I have played with this some more and found another blocker: When using `--shallow-exclude=E` "A" becomes the new _root_-commit, which is then a _crafted_-commit containing *all* files up until "A". What I would need here is to make "E" the _crafted_-commit, so that "A-B-C" remain exactly the same to the not-shallow-clone.

> I see a mention of git-clone in the quoted reply, so perhaps you're
> trying to avoid cloning too much history.
Yes
> I wonder if a blobless clone would suffice, which you can then add to once
> you have the list of commits produced above? That would fetch more commits
> than necessary, but should still be significantly cheaper.

That also would be an option – I have not yet tried it out here, but `--filter=tree:0` already worked wonders in one other case.

Philipp
Ben Knoble· Sep 16, 2025, 20:34 UTC · re: Philipp Hahn · lore

Re: --shallow-exclude=ref -> "ambiguous deepen-not" error

Show 31 quoted lines
> Le 16 sept. 2025 à 13:59, Philipp Hahn <phahn-oss@avm.de> a écrit :
> 
> Hello Ben,
> 
> Thank you for your reply.
> 
>> On Tue, 16 Sep 2025 at 13:03:41 -0400 D. Ben Knoble <ben.knoble@gmail.com> wrote:
>>> On Tue, Sep 16, 2025 at 10:58 AM Philipp Hahn <phahn-oss@avm.de> wrote:
>>>                     A---B---C topic
>>>                    /
>>>               D---E---F---G master
> 
>> I might have misunderstood, but aren't the commits you're interested
>> in here the ones named by
>> 
>>    git rev-list master..topic
>> 
>> ?
> 
> Yes, which is I have described using `CI_MERGE_REQUEST_TARGET_BRANCH_NAME :=
> master`.
> 
> But as also described this fails for those "merged regsult pipelines", where GitLab creates a temporary merge "X" and then runs its pipeline on "X":
> 
>>                     A---B---C topic
>>                    /         \
>>                    /        __X temp
>>                    /       /
>>               D---E---F---G master
> 
> Here `master..temp` becomes just "X", but not "A-B-C".
Here you should still use master..topic if you want to lint each individual commit, plus include temp if you want to lint the merge. 
Elijah Newren· Sep 17, 2025, 02:54 UTC · re: Philipp Hahn · lore

Re: --shallow-exclude=ref -> "ambiguous deepen-not" error

On Tue, Sep 16, 2025 at 7:52 AM Philipp Hahn <phahn-oss@avm.de> wrote:
Show 15 quoted lines
>
> Hello Elijah,
>
> On Mon, 24 Feb 2025 at 07:27:55 -0800 Elijah Newren <newren@gmail.com> wrote:
> > On Thu, Feb 20, 2025 at 12:27 AM bolide2005@163.com <bolide2005@163.com> wrote:
> > > Case 2: git clone --shallow-exclude=<rev> <repo-url>
> >
> > The documentation was fixed for case 2 in 00e10e07510 ("doc: correct
> > misleading descriptions for --shallow-exclude", 2024-11-04) to point
> > out that this usage is flawed.
>
> I have searched the archive and git repository, but found no explanation, why
> that usage - shallow-exclude by REV - is considered "flawed": I understand,
> that the current implementation does not support this, but is there any
> technical reason why that is not possible or undesirable?

I'd honestly rather not touch shallow clones, I only did so because of user reports and their obvious confusion from the misleading documentation and error message that existed at the time.

Anyway, I wasn't making any judgement call on what might be a desirable implementation. I was just noting that the current implementation is guaranteed to do nothing useful with such a flag, and thus that passing such a flag with the current code is flawed, and sadly that our documentation misled users and our code gave a less than helpful error message in such cases. I fixed up the documentation and error messages to fit the current implementation.

Hope that helps clarify my intent and focus at the time.
Erik Cervin Edin· Oct 21, 2025, 12:08 UTC · re: Elijah Newren · lore

Re: --shallow-exclude=ref -> "ambiguous deepen-not" error

Hi!
I just wanted to add some personal experiences to this thread.
On Tue, Sep 16, 2025 at 4:58 PM Philipp Hahn <phahn-oss@avm.de> wrote:
Show 8 quoted lines
>
> I have a use-case for this, where we use GitLab to run some linters on our
> merge requests (MRs): They examine the commits since the fork-point "E", for
> which they need access to the commits + trees + blobs. Some MRs are larger,
> some smaller, so there is no fixed maximum depth I can give to `--depth X` and
> be sure to have gotten all commits.
> Same for `--shallow-since=` as some are dormant for a year and many other MRs
> by-pass them.

I have a very similar use-case to Philipp. Except my forge is GitHub and not quite the same challenges w. temporary merge commits. Basically we run commitlinter on origin/master..HEAD in each PR. The GitHub action does a shallow clone with depth=1 and it looks like commitlinter uses git log under the hood, and as a consequence ends up only running the linter on HEAD. I found --shallow-exclude and thought I would give that a try (to make sure we have the commits origin/master..HEAD). However I encounter a different issue when running the command

  # Test 1: shallow-exclude=master FAILS
  cd /tmp
  git clone --depth=1 https://github.com/git/git.git test-master
  cd test-master
  git rev-list --count --all  # Shows: 1 commit
  git fetch --shallow-exclude=master origin
  # Result: fatal: the remote end hung up unexpectedly ❌
  # Test 2: shallow-exclude=maint WORKS
  cd /tmp
  git clone --depth=1 https://github.com/git/git.git test-maint
  cd test-maint
  git rev-list --count --all  # Shows: 1 commit
  git fetch --shallow-exclude=maint origin
  # Result: SUCCESS, now has 43 commits ✅

Originally I thought deepen-not wasn't supported by the GitHub server but I was very surprised seeing it work for maint. No idea of what's going wrong here actually. Some searches pointed in the direction of changing the postBuffer configuration (which seems odd).

I'll probably go a different route but I wanted to share my experiences in the thread as there was not a lot of information around which helped me understand what was going wrong.

← back to recent threads