Skip to content

Commit

Permalink
fix: consider $depth when deepening shallow clones
Browse files Browse the repository at this point in the history
fixes #315 by ensuring we always unshallow to the desired depth below
version.ref

Signed-off-by: Johannes Rudolph <[email protected]>
  • Loading branch information
JohannesRudolph committed Apr 15, 2020
1 parent ea7ee52 commit 87b6f9d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ correct key is provided set in `git_crypt_key`.
not pass a `paths` filter test from skewing the cloned history away from
`version.ref`, this resource will automatically deepen the clone until
`version.ref` is found again. It will deepen with exponentially increasing steps
until a maximum of 127 commits and after that resort to unshallow the repository.
until a maximum of 127 + `depth` commits or else resort to unshallow the repository.

* `submodules`: *Optional.* If `none`, submodules will not be
fetched. If specified as a list of paths, only the given paths will be
Expand Down
5 changes: 3 additions & 2 deletions assets/deepen_shallow_clone_until_ref_is_found_then_check_out
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ readonly ref="$2"
readonly tagflag="$3"

declare total_depth="$depth"
declare depth_from_ref=$((depth - 1))

# A shallow clone may not contain the Git commit $ref:
# 1. The depth of the shallow clone is measured backwards from the latest
Expand All @@ -26,15 +27,15 @@ declare total_depth="$depth"
git_dir="$(git rev-parse --git-dir)"
readonly git_dir

while ! git checkout -q "$ref" &>/dev/null; do
while ! git checkout -q "$ref~$depth_from_ref" &>/dev/null; do
# once the depth of a shallow clone reaches the max depth of the origin
# repo, Git silenty turns it into a deep clone
if [ ! -e "$git_dir"/shallow ]; then
echo "Reached max depth of the origin repo while deepening the shallow clone, it's a deep clone now"
break
fi

echo "Could not find ref ${ref} in a shallow clone of depth ${total_depth}"
echo "Could not find ref ${ref}~${depth_from_ref} in a shallow clone of depth ${total_depth}"

(( depth *= 2 ))

Expand Down
45 changes: 43 additions & 2 deletions test/get.sh
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ it_falls_back_to_deep_clone_if_ref_not_found() {

echo "testing for msg 1" >&2
for d in 1 3 7 15 31 63 127; do
grep "Could not find ref ${ref1} in a shallow clone of depth ${d}" <$TMPDIR/stderr
grep "Could not find ref ${ref1}~0 in a shallow clone of depth ${d}" <$TMPDIR/stderr
done
echo "test for msg 1 done" >&2

Expand All @@ -226,6 +226,46 @@ it_falls_back_to_deep_clone_if_ref_not_found() {
grep "Reached depth threshold 127, falling back to deep clone..." <$TMPDIR/stderr
}

it_considers_depth_if_ref_not_found() {
local repo=$(init_repo)
local depth=3

# make commits we're interested
local ref0=$(make_commit $repo)
local ref1=$(make_commit $repo)
local ref2=$(make_commit $repo)
local ref3=$(make_commit $repo)

# make a total of 22 commits, so that ref0 is never fetched
for (( i = 0; i < 18; i++ )); do
make_commit $repo >/dev/null
done

local dest=$TMPDIR/destination

( get_uri_at_depth_at_ref "file://$repo" $depth $ref3 $dest 3>&2- 2>&1- 1>&3- 3>&- | tee $TMPDIR/stderr ) 3>&1- 1>&2- 2>&3- 3>&- | jq -e "
.version == {ref: $(echo $ref3 | jq -R .)}
"

test -e $dest/some-file
test "$(git -C $dest rev-parse HEAD)" = $ref3
test "$(git -C $dest rev-parse HEAD~1)" = $ref2
test "$(git -C $dest rev-parse HEAD~2)" = $ref1
test -e "$dest/.git/shallow" # it's still shallow

echo "testing for 'could not find' messages'" >&2
for d in 3 9; do
grep "Could not find ref ${ref3}~2 in a shallow clone of depth ${d}" <$TMPDIR/stderr
done
echo "testing for 'could not find' messages done" >&2

echo "testing for 'deepening' messages'" >&2
for d in 6 12; do
grep "Deepening the shallow clone by an additional ${d}..." <$TMPDIR/stderr
done
echo "testing for 'deepening' messages' done" >&2
}

it_does_not_enter_an_infinite_loop_if_the_ref_cannot_be_found_and_depth_is_set() {
local repo=$(init_repo)
local ref1=$(make_commit $repo)
Expand Down Expand Up @@ -362,7 +402,7 @@ it_falls_back_to_deep_clone_of_submodule_if_ref_not_found() {

echo "testing for 'could not find' messages'" >&2
for d in 1 3 7 15 31 63 127; do
grep "Could not find ref ${submodule_repo_last_commit_id} in a shallow clone of depth ${d}" <$TMPDIR/stderr
grep "Could not find ref ${submodule_repo_last_commit_id}~0 in a shallow clone of depth ${d}" <$TMPDIR/stderr
done
echo "testing for 'could not find' messages done" >&2

Expand Down Expand Up @@ -739,6 +779,7 @@ run it_returns_list_of_tags_in_metadata
run it_honors_the_depth_flag
run it_can_get_from_url_at_depth_at_ref
run it_falls_back_to_deep_clone_if_ref_not_found
run it_considers_depth_if_ref_not_found
run it_does_not_enter_an_infinite_loop_if_the_ref_cannot_be_found_and_depth_is_set
run it_can_get_and_set_git_config
run it_returns_same_ref
Expand Down

0 comments on commit 87b6f9d

Please sign in to comment.