Note that Git 1.9/2.0 (Q1 2014) could be more efficient in fetching for a shallow clone.
See commit 82fba2b, from Nguyễn Thái Ngọc Duy (pclouds
):
Now that git supports data transfer from or to a shallow clone, these limitations are not true anymore.
All the details are in "shallow.c
: the 8 steps to select new commits for .git/shallow
".
You can see the consequence in commits like 0d7d285, f2c681c, and c29a7b8 which support clone, send-pack /receive-pack with/from shallow clones.
smart-http now supports shallow fetch/clone too.
You can even clone form a shallow repo.
Update 2015: git 2.5+ (Q2 2015) will even allow for a single commit fetch! See "Pull a specific commit from a remote git repository".
Update 2016 (Oct.): git 2.11+ (Q4 2016) allows for fetching:
You also have git fetch --update-shallow
, with Git v1.9, Q4 2013:
By default when fetching from a shallow repository, git fetch
refuses refs that require updating .git/shallow
.
This option updates .git/shallow
and accepts such refs.
With Git 2.45 (Q2 2024), batch 6, make sure failure return from merge_bases_many()
is properly caught.
See commit 25fd20e, commit 81a34cb (09 Mar 2024), and commit caaf1a2, commit 5317380, commit f87056c, commit 76e2a09, commit 8226e15, commit fb02c52, commit 896a0e1, commit 2d2da17, commit 24876eb, commit 207c40e, commit e67431d (28 Feb 2024) by Johannes Schindelin (dscho
).
(Merged by Junio C Hamano -- gitster
-- in commit 7745f92, 11 Mar 2024)
Signed-off-by: Johannes Schindelin
When git fetch --update-shallow
(man) needs to test for commit ancestry, it can naturally run into a missing object (e.g. if it is a parent of a shallow commit).
For the purpose of --update-shallow
, this needs to be treated as if the child commit did not even have that parent, i.e.
the commit history needs to be clamped.
For all other scenarios, clamping the commit history is actually a bug, as it would hide repository corruption (for an analysis regarding shallow and partial clones, see the analysis further down).
Add a flag to optionally ask the function to ignore missing commits, as --update-shallow
needs it to, while detecting missing objects as a repository corruption error by default.
This flag is needed, and cannot be replaced by is_repository_shallow()
to indicate that situation, because that function would return 0 in the --update-shallow
scenario: There is not actually a shallow
file in that scenario, as demonstrated e.g. by t5537.10 ("add new shallow root with receive.updateshallow on") and t5538.4 ("add new shallow root with receive.updateshallow on").
Note: shallow commits' parents are set to NULL
internally already, therefore there is no need to special-case shallow repositories here, as the merge-base logic will not try to access parent commits of shallow commits.
Likewise, partial clones aren't an issue either: If a commit is missing during the revision walk in the merge-base logic, it is fetched via promisor_remote_get_direct()
.
And not only the single missing commit object: Due to the way the "promised" objects are fetched (in fetch_objects()
in promisor-remote.c
, using fetch --filter=blob:none
), there is no actual way to fetch a single commit object, as the remote side will pass that commit OID to pack-objects
--revs [...]
which in turn passes it to rev-list
which interprets this as a commit range instead of a single object.
Therefore, in partial clones (unless they are shallow in addition), all commits reachable from a commit that is in the local object database are also present in that local database.