Using git clone -mirror with --filter blob:none

35 Views Asked by At

How do I do programatically do a bare blobless clone of a remote repository, and then later clone that to a working (non-bare) repository?

Why would I want to do this?

makepkg (Arch Linux's package builder) clones (and keeps) a (bare) mirror of the package's repo (including remote-tracking branches, tags, and notes). makepkg then checks out an ephemeral non-bare copy of the repository to build the latest version of a package.

I'm trying to reduce disk and network usage by using a blobless clone for the mirrored repository, scratching a personal itch, and resolving some GitHub AUR helper issues at the same time.

Here's the blobless bare clone:

% git clone --mirror --filter=blob:none https://github.com/ccontavalli/ssh-ident.git bare-repo
Cloning into bare repository 'bare-repo'...
remote: Enumerating objects: 224, done.
remote: Counting objects: 100% (68/68), done.
remote: Compressing objects: 100% (20/20), done.
remote: Total 224 (delta 57), reused 48 (delta 48), pack-reused 156
Receiving objects: 100% (224/224), 38.17 KiB | 136.00 KiB/s, done.
Resolving deltas: 100% (84/84), done.

And now create one working copy of it:

% git clone bare-repo working-repo
Cloning into 'working-repo'...
done.
error: cannot read object 7567c09cb430f5af21fdde5db260a91a7a084a89 '.gitignore'
error: cannot read object 88133d7666c17b65bb2288dca4d31558e5bfb715 'LICENSE'
error: cannot read object 1b7f7192202a93d3c6416ee768d1308a54f1cbea 'README'
error: cannot read object d5c8306cf058131693268609b0a9a023dd7fd454 'debian/changelog'
error: cannot read object f11c82a4cb6cc2e8f3bdf52b5cdeaad4d5bb214e 'debian/compat'
error: cannot read object 08ffe3bde19df4b9198fce44d622875b6f92d75c 'debian/control'
error: cannot read object 54ef9c6b6422257355ffcebcb43a9fb68aa189c1 'debian/copyright'
error: cannot read object 2d33f6ac8992b7da84b39a5bca0742c4962d3349 'debian/rules'
error: cannot read object 89ae9db8f88b823b6a7eabf55e203658739da122 'debian/source/format'
error: cannot read object e845566c06f9bf557d35e8292c37cf05d97a9769 'debian/ssh-ident.docs'
error: cannot read object 3db76f47ff032f602f1a06ddf20e3d66e2de312f 'debian/ssh-ident.install'
error: cannot read object 911680f8a3b3d19cabde86e4ec3903511859a48c 'ssh-ident'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'

Trying the suggested git restore --source=HEAD :/ within working-repo repeats the exact same list of errors.

Creating the initial clone with --bare instead of --mirror produces the same errors.

1

There are 1 best solutions below

0
On

When you make a partial clone (that is, with the --filter option), the repository is incomplete, and objects that you need are downloaded on demand when you work with that repository. However, making a clone of a repository doesn't cause those objects to be downloaded, because that could invoke additional external processes (such as credential helpers) and Git specifies that cloning from an untrusted repository is safe. Thus, as a practical matter, it's not safe to clone from a partial clone, since it may fail due to missing objects (as you've seen).

If, in the second case, instead of a clone, you added a worktree with git worktree add, that would be valid and it wouldn't create a new repository, so you'd continue to download the objects you need on demand without causing any problems.