Shallow clones of local directories require file://
as explained at: git clone: warning: --depth is ignored in local clones; use file:// instead
But how to use relative paths with that?
E.g.: if I have a repo myrepo
in the current directory, and then I do:
git clone --depth 1 file://mymodule mymodule2
then it fails with:
Cloning into 'mymodule2'...
fatal: No path specified. See 'man git-pull' for valid url syntax
And if I try:
git clone --depth 1 file://./mymodule mymodule2
It fails with:
Cloning into 'mymodule2'...
fatal: '/./mymodule' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
The only workaround I could find was to convert it to an absolute path starting with /
:
git clone --depth 1 "file://$(pwd)/mymodule" mymodule2
Is there a profound reason for this behavior, or it just buggy?
Maybe file URIs simply don't support relative paths:
git 2.14.1.
But how to use relative paths with that?
This is not supported; file://
expects only absolute paths. There are e.g. RFC1738 and RFC8089 which describe this kind of URIs.
A file URL takes the form:
file://<host>/<path>
where is the fully qualified domain name of the system on
which the is accessible, and is a hierarchical
directory path of the form //.../.
When you write file://mymodule
, the mymodule
can be interpreted as a hostname.
It's neither necessary nor beneficial to shallow clone a local repo. Just git clone ./relative/path
and you are good to go.
I assume you want to shallow copy because you want to save the disk space and save time, but
1. It doesn't save disk space in local cloning.
From Git 2.24.1 manual:
For local repositories, also supported by Git natively, the following syntaxes may be used:
• /path/to/repo.git/
• file:///path/to/repo.git/
These two syntaxes are mostly equivalent, except the former implies --local option.
and
-l, --local
When the repository to clone from is on a local machine, this flag bypasses the normal "Git aware" transport mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under .git/objects/ directory are hardlinked to save space when possible.
So a shallow copy with file:///path/to/repo.git/
syntax should consume more disk space than a full copy with /path/to/repo.git/
syntax because the former has real copies of objects instead of hard links.
(And I believe that hard-linking is the reason why --depth
get ignored when --local
is set.)
2. It doesn't save time either.
Still, Git 2.24.1 manual:
-l, --local
When the repository to clone from is on a local machine, this flag bypasses the normal "Git aware" transport mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under .git/objects/ directory are hardlinked to save space when possible.
"Git aware" transport mechanism is time-consuming even when the URI is file://...
because it includes object compressing:
$ time git clone --depth 1 --local --shallow-submodules file://$(pwd)/../linux
Cloning into 'linux'...
warning: --local is ignored
remote: Enumerating objects: 65607, done.
remote: Counting objects: 100% (65607/65607), done.
remote: Compressing objects: 100% (61137/61137), done.
remote: Total 65607 (delta 4886), reused 39965 (delta 3556)
Receiving objects: 100% (65607/65607), 176.65 MiB | 10.81 MiB/s, done.
Resolving deltas: 100% (4886/4886), done.
Updating files: 100% (61793/61793), done.
git clone --depth 1 --local --shallow-submodules 73.55s user 4.97s system 245% cpu 31.976 total
(I don't know why the receiving speed is 10.81 MiB/s on my NVMe SSD)
And cloning with --local
flag is much quicker:
$ time git clone ../linux
Cloning into 'linux'...
done.
Updating files: 100% (61793/61793), done.
git clone ../linux 4.16s user 1.71s system 100% cpu 5.857 total
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With