When I make a local clone from a repository, the clone fails if the origin repository is shallow.
git clone -l -- . target-dir
As that is not always the case I'd like to find out prior clone but don't know how to do that.
What I tried so far is very little, basically creating error messages on clone. At the moment I just fetch to unshallow and if that fails, I do a plain fetch because if the repo would be shallow, it should be unshallow afterwards:
if ! git fetch --unshallow; then
git fetch
fi
However there is no guarantee for being unshallow afterwards (remote to fetch from can be shallow, too), so a test for the (un)shallowness of a git repository would be much better.
A shallow repository has an incomplete history some of whose commits have parents cauterized away (in other words, Git is told to pretend that these commits do not have the parents, even though they are recorded in the commit object).
Definition. Shallow commits do have parents, but not in the shallow repo, and therefore grafts are introduced pretending that these commits have no parents.
If your Git is 2.15 or later, run:
git rev-parse --is-shallow-repository
which will print false
(not shallow) or true
(shallow):
if $(git rev-parse --is-shallow-repository); then ... repository is shallow ... fi
The answer below dates back to Git versions before 2.15.
If your Git is older than 2.15,1 just test for the file shallow
in the Git repository directory:2
if [ -f "$(git rev-parse --git-dir)"/shallow ]; then echo this is a shallow repository; else echo not a shallow repository; fi
or (shorter):
[ -f "$(git rev-parse --git-dir)"/shallow ] && echo true || echo false
You can turn this into a shell function:
test_shallow() { [ -f "$(git rev-parse --git-dir)"/shallow ] && echo true || echo false }
and even automate the Git version checking:
test_shallow() { set -- $(git rev-parse --is-shallow-repository) if [ x$1 == x--is-shallow-repository ]; then [ -f "$(git rev-parse --git-dir)"/shallow ] && set true || set false fi echo $1 }
1git --version
will print the current version number:
$ git --version 2.14.1 $ git --version git version 2.7.4
etc. (I have multiple versions on different VMs/machines at this point.) You can also run:
git rev-parse --is-shallow-repository
If it just prints --is-shallow-repository
, your Git is pre-2.15 and lacks the option.
2To see why there are double quotes around $(git rev-parse --git-dir)
, see Tom Hale's comment. Note that testing this is a bit tricky since git rev-parse --git-dir
from the top level of, e.g., the repository /tmp/with space
just prints .git
; you must be in a subdirectory, such as /tmp/with space/sub
to observe the problem.
When you don't have access to the remote repository (not the case here, but still a possible scenario), a git clone
is still a good way to test if that remote repository is shallow or not.
The problem is not transfer/create file needlessly when the clone would ultimately fail because of the shallow nature of said remote repository.
This is now fixed with Git 2.32 (Q2 2021): "git clone
"(man) new --reject-shallow
option fails the clone as soon as we notice that we are cloning from a shallow repository.
See commit 4fe788b (01 Apr 2021) by Li Linchao (Cactusinhand
).
(Merged by Junio C Hamano -- gitster
-- in commit 22eee7f, 08 Apr 2021)
builtin/clone.c
: add--reject-shallow
optionSigned-off-by: Li Linchao
In some scenarios, users may want more history than the repository offered for cloning, which happens to be a shallow repository, can give them.
But because users don't know it is a shallow repository until they download it to local, we may want to refuse to clone this kind of repository, without creating any unnecessary files.The '
--depth=x
' option cannot be used as a solution; the source may be deep enough to give us 'x
' commits when cloned, but the user may later need to deepen the history to arbitrary depth.Teach '
--reject-shallow
' option to "git clone
"(man) to abort as soon as we find out that we are cloning from a shallow repository.
No local file created!
The error message will be (with the test clone command):
git -c clone.rejectshallow=true clone --no-local shallow-repo source repository is shallow, reject to clone.
git config
now includes in its man page:
clone.rejectShallow
Reject to clone a repository if it is a shallow one, can be overridden by passing option
--reject-shallow
in command line.
git clone
now includes in its man page:
--[no-]reject-shallow
Fail if the source repository is a shallow repository.
The 'clone.rejectShallow
' configuration variable can be used to specify the default.
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