Files
dolt/integration-tests/bats/shallow-clone.bats
T
Tim Sehn 13390f62c3 Fix bats tests for repo requirement changes
- init.bats: Use status != 0 instead of status == 1 for flexibility
- shallow-clone.bats: Add cd into cloned directory after dolt_clone
- sql-local-remote.bats: Run commands from within the dolt database directory

These tests now properly cd into the dolt database directory before
running commands that require a repository context.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 17:41:00 -08:00

764 lines
21 KiB
Bash

#!/usr/bin/env bats
#
# Tests for shallow clone behavior. These tests use a remotesrv
# instance which hold databases with different commit history
# structures, then tests clone with different depths and validate
# behavior of other commands and stored procedures.
load $BATS_TEST_DIRNAME/helper/common.bash
remotesrv_pid=""
setup() {
skiponwindows "tests are flaky on Windows"
setup_no_dolt_init
}
teardown() {
stop_remotesrv
teardown_common
}
stop_remotesrv() {
if [ -n "$remotesrv_pid" ]; then
kill "$remotesrv_pid"
wait "$remotesrv_pid" || :
remotesrv_pid=""
fi
}
# serial repository is 7 commits:
# (init) <- (table create) <- (val 1) <- (val 2) <- (val 3) <- (val 4) <- (val 5) [main]
seed_local_remote() {
mkdir remote
cd remote
dolt init
dolt sql -q 'create table vals (i int primary key, s varchar(64));'
dolt add vals
dolt commit -m 'create table'
for SEQ in $(seq 5); do
dolt sql -q "insert into vals (i,s) values ($SEQ, \"val $SEQ\")"
dolt commit -a -m "Added Val: $SEQ"
done
dolt tag nonheadtag HEAD~2
cd ..
}
seed_and_start_serial_remote() {
seed_local_remote
cd remote
remotesrv --http-port 1234 --repo-mode &
remotesrv_pid=$!
cd ..
}
@test "shallow-clone: dolt_clone depth 1" {
seed_and_start_serial_remote
mkdir clones
cd clones
dolt sql -q "call dolt_clone('--depth', '1','http://localhost:50051/test-org/test-repo')"
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 1 ]
run dolt sql -q "select count(*) = 1 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "15" ]] || false # 1+2+3+4+5 = 15.
}
@test "shallow-clone: dolt_clone depth 2" {
seed_and_start_serial_remote
mkdir clones
cd clones
run dolt sql -q "call dolt_clone('--depth', '2','http://localhost:50051/test-org/test-repo')"
[ "$status" -eq 0 ]
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 2 ]
run dolt sql -q "select count(*) = 2 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "15" ]] || false # 1+2+3+4+5 = 15.
}
@test "shallow-clone: shallow clone with a file path" {
seed_local_remote
cd remote
dolt remote add origin file://../file-remote
dolt push origin main
cd ..
mkdir clones
cd clones
run dolt sql -q "call dolt_clone('--depth', '1','file://../file-remote')"
[ "$status" -eq 0 ]
cd file-remote
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 1 ]
run dolt sql -q "select count(*) = 1 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "15" ]] || false # 1+2+3+4+5 = 15.
}
@test "shallow-clone: dolt gc works" {
seed_and_start_serial_remote
mkdir clones
cd clones
dolt sql -q "call dolt_clone('--depth', '1','http://localhost:50051/test-org/test-repo')"
cd test-repo
dolt gc
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "15" ]] || false # 1+2+3+4+5 = 15.
}
@test "shallow-clone: fast forward merge" {
seed_local_remote
cd remote
dolt remote add origin file://../file-remote
dolt push origin main
cd ..
mkdir clones
cd clones
run dolt sql -q "call dolt_clone('--depth', '1','file://../file-remote')"
[ "$status" -eq 0 ]
cd file-remote
dolt checkout -b branch
dolt sql -q "insert into vals values (6, 'six')"
dolt commit -a -m "Added Val: 6 -> six"
dolt checkout main
dolt merge branch
}
@test "shallow-clone: simple merge" {
seed_local_remote
cd remote
dolt remote add origin file://../file-remote
dolt push origin main
cd ..
mkdir clones
cd clones
run dolt sql -q "call dolt_clone('--depth', '1','file://../file-remote')"
[ "$status" -eq 0 ]
cd file-remote
dolt checkout -b branch
dolt sql -q "insert into vals values (6, 'six')"
dolt commit -a -m "Added Val: 6 -> six"
dolt checkout main
dolt sql -q "insert into vals values (7, 'seven')"
dolt commit -a -m "Added Val: 7 -> seven"
dolt merge branch
}
@test "shallow-clone: no-op merge" {
seed_local_remote
cd remote
dolt remote add origin file://../file-remote
dolt push origin main
cd ..
mkdir clones
cd clones
run dolt sql -q "call dolt_clone('--depth', '1','file://../file-remote')"
[ "$status" -eq 0 ]
cd file-remote
dolt branch other HEAD
dolt checkout main
run dolt merge other
[ "$status" -eq 0 ]
[[ "$output" =~ "Everything up-to-date" ]] || false
}
@test "shallow-clone: push to a new remote should error" {
seed_and_start_serial_remote
mkdir clones
cd clones
dolt clone --depth 1 http://localhost:50051/test-org/test-repo
cd test-repo
dolt remote add altremote file://../file-remote-alt
run dolt push altremote main
[ "$status" -eq 1 ]
[[ "$output" =~ "shallow repository missing chunks to complete push" ]] || false
}
@test "shallow-clone: depth 3 clone of serial history" {
seed_and_start_serial_remote
mkdir clones
cd clones
run dolt clone --depth 3 http://localhost:50051/test-org/test-repo
[ "$status" -eq 0 ]
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[[ "${#lines[@]}" -eq 3 ]] || false
run dolt sql -q "select count(*) = 3 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
# NM4 - system table bug.
# run dolt sql -q "select count(*) = 3 from dolt_log"
# [ "$status" -eq 0 ]
# [[ "$output" =~ "true" ]] || false
#
# dolt_diff table will show two rows, because each row is a delta.
run dolt sql -q "select * from dolt_diff"
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 4 " ]] || false
! [[ "$output" =~ "Added Val: 3 " ]] || false
run dolt sql -q "select * from dolt_commits"
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 5 " ]] || false
[[ "$output" =~ "Added Val: 4 " ]] || false
[[ "$output" =~ "Added Val: 3 " ]] || false
! [[ "$output" =~ "Added Val: 2 " ]] || false
# A full clone would have 5 commits with i=1, so if we have 3, we are looking good.
run dolt sql -q "select count(*) = 3 from dolt_history_vals where i = 1"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
# A full clone would have 2 commits with i=4, and our shallow clone has all the commits for that row.
run dolt sql -q "select count(*) = 2 from dolt_history_vals where i = 4"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
run dolt sql -q "select count(distinct commit_hash) = 3 from dolt_history_vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "15" ]] # 1+2+3+4+5 = 15.
run dolt show HEAD
[ "$status" -eq 0 ]
[[ "$output" =~ "+ | 5 | val 5" ]] || false
! [[ "$output" =~ "val 4" ]] || false
run dolt show HEAD~1
[ "$status" -eq 0 ]
[[ "$output" =~ "+ | 4 | val 4" ]] || false
! [[ "$output" =~ "val 3" ]] || false
! [[ "$output" =~ "val 5" ]] || false
run dolt diff HEAD~2..HEAD
[ "$status" -eq 0 ]
[[ "$output" =~ "diff --dolt a/vals b/vals" ]] || false
[[ "$output" =~ "+ | 5 | val 5" ]] || false
[[ "$output" =~ "+ | 4 | val 4" ]] || false
! [[ "$output" =~ "val 3" ]] || false
# reverse diff check.
run dolt diff HEAD..HEAD~1
[ "$status" -eq 0 ]
[[ "$output" =~ "- | 5 | val 5" ]] || false
# Verify that the table is complete, with an as of query.
run dolt sql -q "select sum(i) from vals as of 'HEAD~1'"
[ "$status" -eq 0 ]
[[ "$output" =~ "10" ]] # 1+2+3+4 = 10.
}
@test "shallow-clone: depth which exceeds history" {
seed_and_start_serial_remote
mkdir clones
cd clones
# Depth is far greater than actual history length.
run dolt clone --depth 42 http://localhost:50051/test-org/test-repo
[ "$status" -eq 0 ]
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[[ "${#lines[@]}" -eq 7 ]] || false
run dolt sql -q "select count(*) = 7 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
run dolt show HEAD~6
[ "$status" -eq 0 ]
[[ "$output" =~ "Initialize data repository" ]] || false
}
@test "shallow-clone: as of gives decent error message" {
seed_and_start_serial_remote
mkdir clones
cd clones
run dolt clone --depth 3 http://localhost:50051/test-org/test-repo
[ "$status" -eq 0 ]
cd test-repo
run dolt sql -q "select sum(i) from vals as of 'HEAD~4'"
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
}
@test "shallow-clone: hashof sql function gives an error message" {
seed_and_start_serial_remote
mkdir clones
cd clones
run dolt clone --depth 2 http://localhost:50051/test-org/test-repo
[ "$status" -eq 0 ]
cd test-repo
run dolt sql -q "select hashof('HEAD~4')"
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
}
@test "shallow-clone: single depth clone of serial history" {
seed_and_start_serial_remote
mkdir clones
cd clones
dolt clone --depth 1 http://localhost:50051/test-org/test-repo
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 1 ]
run dolt sql -q "select count(*) = 1 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
## not working at the moment.... NM4.
## run dolt sql -q "select count(*) = 1 from dolt_log"
## [ "$status" -eq 0 ]
## [[ "$output" =~ "true" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "15" ]] || false # 1+2+3+4+5 = 15.
run dolt diff HEAD~1..HEAD
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
# Dolt show can't show the diff because we only have one half of the delta.
run dolt show
[ "$status" -eq 1 ]
[[ "$output" =~ "Added Val: 5" ]] || false # We do print the message of the commit, even though we can't show the diff.
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
run dolt tag tagfoo HEAD~1
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
run dolt revert HEAD~1
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
run dolt cherry-pick HEAD~1
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
}
@test "shallow-clone: shallow clone can push" {
seed_and_start_serial_remote
mkdir clones
cd clones
dolt clone --depth 1 http://localhost:50051/test-org/test-repo
cd test-repo
dolt sql -q "insert into vals (i,s) values (42, \"val 42\")"
run dolt status
[ "$status" -eq 0 ]
[[ "$output" =~ "Your branch is up to date with 'origin/main'." ]] || false
[[ "$output" =~ "Changes not staged for commit:" ]] || false
[[ "$output" =~ "modified: vals" ]] || false
dolt commit -a -m "Added Val: 42"
run dolt push origin main
[ "$status" -eq 0 ]
# Do a full clone and verify that the commit is there.
cd ..
dolt clone http://localhost:50051/test-org/test-repo full-clone
cd full-clone
run dolt show HEAD
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 42" ]] || false
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "57" ]] || false # 1+2+3+4+5+42 = 57.
}
@test "shallow-clone: fetch new changes after shallow clone" {
seed_and_start_serial_remote
mkdir clones
cd clones
# initial clone
dolt clone --depth 2 http://localhost:50051/test-org/test-repo
# clone another copy, and push to remote srv.
dolt clone http://localhost:50051/test-org/test-repo full-clone
cd full-clone
dolt sql -q "insert into vals (i,s) values (23, \"val 23\")"
dolt commit -a -m "Added Val: 23"
run dolt push origin main
[ "$status" -eq 0 ]
# Go to out of date clone, and fetch.
cd ../test-repo
run dolt pull
[ "$status" -eq 0 ]
[[ "$output" =~ "Fast-forward" ]] || false
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 3 ]
dolt show
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 23" ]] || false
}
@test "shallow-clone: fetch connected new branch works after shallow clone" {
seed_and_start_serial_remote
mkdir clones
cd clones
# initial clone
dolt clone --depth 2 http://localhost:50051/test-org/test-repo
# clone another copy, and push new branch to remote srv.
dolt clone http://localhost:50051/test-org/test-repo full-clone
cd full-clone
# Create two new commits on top of commit which exists in shallow clone.
dolt sql -q "insert into vals (i,s) values (23, \"val 23\")"
dolt commit -a -m "Added Val: 23"
dolt sql -q "insert into vals (i,s) values (42, \"val 42\")"
dolt commit -a -m "Added Val: 42"
dolt push origin HEAD:refs/heads/brch
cd ../test-repo
dolt fetch # Should pull new branch, and it's history should be length 4.
run dolt branch -a
[ "$status" -eq 0 ]
[[ "$output" =~ "remotes/origin/brch" ]] || false
run dolt log --oneline --decorate=no origin/brch
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 4 ]
run dolt show origin/brch
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 42" ]] || false
run dolt show origin/brch~1
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 23" ]] || falses
}
@test "shallow-clone: fetch disconnected new branch works after shallow clone" {
seed_and_start_serial_remote
mkdir clones
cd clones
# initial clone
dolt clone --depth 2 http://localhost:50051/test-org/test-repo
# clone another copy, and push new branch to remote srv.
dolt clone http://localhost:50051/test-org/test-repo full-clone
cd full-clone
# Create two new commits rooted from a commit which doesn't exist in the
dolt reset --hard HEAD~3 # HEAD~3 == (val 2)
dolt sql -q "insert into vals (i,s) values (13, \"val 13\")"
dolt commit -a -m "Added Val: 13"
dolt sql -q "insert into vals (i,s) values (11, \"val 11\")"
dolt commit -a -m "Added Val: 11"
dolt push origin HEAD:refs/heads/brch
cd ../test-repo
dolt fetch # Should pull new branch, and it's history should be length 2.
run dolt branch -a
[ "$status" -eq 0 ]
[[ "$output" =~ "remotes/origin/brch" ]] || false
run dolt log --oneline --decorate=no origin/brch
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 2 ]
run dolt show origin/brch
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 11" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals as of 'origin/brch'"
[ "$status" -eq 0 ]
[[ "$output" =~ "27" ]] # 1+2+11+13 = 27.
}
# complex repository is 14 commits with the following dag:
#
# (init) <- (table create) <- (val 1) <- (val 2) <- (val 3) <- (val 4) <- (val 5) <- (merge 2) [main]
# \ \ /
# \- (val 6) <- (val 7) <- (merge 1) <- (val 8) <-----/ <- (val 9) <- (val 10) [brch]
seed_and_start_complex_remote() {
mkdir remote
cd remote
dolt init
dolt sql -q 'create table vals (i int primary key, s varchar(64));'
dolt add vals
dolt commit -m 'create table'
for SEQ in $(seq 5); do
dolt sql -q "insert into vals (i,s) values ($SEQ, \"val $SEQ\")"
dolt commit -a -m "Added Val: $SEQ"
done
dolt checkout -b brch HEAD~5
for SEQ in $(seq 6 7); do
dolt sql -q "insert into vals (i,s) values ($SEQ, \"val $SEQ\")"
dolt commit -a -m "Added Val: $SEQ"
done
dolt merge main~2
for SEQ in $(seq 8 10); do
dolt sql -q "insert into vals (i,s) values ($SEQ, \"val $SEQ\")"
dolt commit -a -m "Added Val: $SEQ"
done
dolt checkout main
dolt merge brch~2
remotesrv --http-port 1234 --repo-mode &
remotesrv_pid=$!
cd ..
}
@test "shallow-clone: single depth clone of a complex history" {
seed_and_start_complex_remote
mkdir clones
cd clones
dolt clone --depth 1 http://localhost:50051/test-org/test-repo
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 1 ]
run dolt sql -q "select count(*) = 1 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
## not working at the moment.... NM4.
## run dolt sql -q "select count(*) = 1 from dolt_log"
## [ "$status" -eq 0 ]
## [[ "$output" =~ "true" ]] || false
# Verify that the table is complete.
run dolt sql -q "select sum(i) from vals"
[ "$status" -eq 0 ]
[[ "$output" =~ "36" ]] || false # 1+2+3+4+5+6+7+8 = 36.
}
@test "shallow-clone: depth 2 clone of a complex history" {
seed_and_start_complex_remote
mkdir clones
cd clones
# GHOST <- (val 5) <-\
# (merge 2) [main]
# GHOST <- (val 8) <-/
dolt clone --depth 2 http://localhost:50051/test-org/test-repo
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 3 ]
run dolt sql -q "select count(*) = 3 from dolt_log()"
[ "$status" -eq 0 ]
[[ "$output" =~ "true" ]] || false
## not working at the moment.... NM4.
## run dolt sql -q "select count(*) = 1 from dolt_log"
## [ "$status" -eq 0 ]
## [[ "$output" =~ "true" ]] || false
# compare the diff between the two parents of the merge commit.
run dolt diff HEAD^..HEAD^2
[ "$status" -eq 0 ]
[[ "$output" =~ "- | 4 | val 4" ]] || false
[[ "$output" =~ "- | 5 | val 5" ]] || false
[[ "$output" =~ "+ | 6 | val 6" ]] || false
[[ "$output" =~ "+ | 7 | val 7" ]] || false
[[ "$output" =~ "+ | 8 | val 8" ]] || false
}
@test "shallow-clone: clone alternate branch" {
seed_and_start_complex_remote
mkdir clones
cd clones
# Cloning depth 5 from brch should result in the following 6 commits:
# GHOST <- (val 3) <-\
# \
# GHOST <- (val 7) <- (merge 1) <- (val 8) <- (val 9) <- (val 10) [brch]
dolt clone --depth 5 --branch brch http://localhost:50051/test-org/test-repo
cd test-repo
run dolt status
[ "$status" -eq 0 ]
[[ "$output" =~ "On branch brch" ]] || false
[[ "$output" =~ "Your branch is up to date with 'origin/brch'" ]] || false
[[ "$output" =~ "nothing to commit, working tree clean" ]] || false
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 6 ]
run dolt diff HEAD~3^..HEAD~3^2 # compare (val 7) --> (val 3) [parents of the first merge]
[ "$status" -eq 0 ]
[[ "$output" =~ "+ | 1 | val 1" ]] || false
[[ "$output" =~ "+ | 2 | val 2" ]] || false
[[ "$output" =~ "+ | 3 | val 3" ]] || false
[[ "$output" =~ "- | 6 | val 6" ]] || false
[[ "$output" =~ "- | 7 | val 7" ]] || false
run dolt merge-base HEAD~3^ HEAD~3^2 # (val 3) and (val 3) have a common ancestor in a full clone, should error.
[ "$status" -eq 1 ]
[[ "$output" =~ "Commit not found. You are using a shallow clone" ]] || false
}
@test "shallow-clone: clone depth 5 on complex main" {
seed_and_start_complex_remote
mkdir clones
cd clones
# GHOST <- (val 2) <- (val 3) <- (val 4) <- (val 5) <- (merge 2) [main]
# \ /
# GHOST <- (val 6) <-(val 7) <- (merge 1) <- (val 8)
dolt clone --depth 5 http://localhost:50051/test-org/test-repo
cd test-repo
run dolt log --oneline --decorate=no
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 9 ]
run dolt merge-base HEAD^ HEAD^2 # (val 5) and (val 8) are the parents of the merge commit. Should return (val 3)
[ "$status" -eq 0 ]
commitid="$output"
run dolt show "$commitid"
[ "$status" -eq 0 ]
[[ "$output" =~ "Added Val: 3" ]] || false
}
# Tests to write:
# - Fetch after initial clone
# - Fetch when no changes have happened.
# - Fetch when there are remote changes on main
# - Fetch when there are remote changes on a branch
# - Pull after initial clone
# - Pull when no changes have happened.
# - Pull when there are remote changes on main
# - Sensible error when branching/checking out a commit which they don't have.
# - merge base errors
# - reset work to a commit we have, and errors when we don't have the commit.
# - Sensible error when we attempt to use HEAD~51 or something.
# - Don't serve from a shallow repository
# - remotesrv
# - sql-server
# - file (stretch?)
# - Dump?
# - Rebase?
# - Stash?
# - Fetch tags which refer to commits we don't have. Punt on tags entirely?