990 lines
28 KiB
Bash
Executable File
990 lines
28 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Copyright 2023 The Kubernetes Authors.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
set -o errexit
|
|
set -o nounset
|
|
set -o pipefail
|
|
|
|
function fail() {
|
|
echo "FAIL:" "$@" >&3
|
|
return 42
|
|
}
|
|
|
|
function pass() {
|
|
echo "PASS"
|
|
}
|
|
|
|
function assert_file_exists() {
|
|
if ! [[ -f "$1" ]]; then
|
|
fail "$1 does not exist"
|
|
fi
|
|
}
|
|
|
|
function assert_file_absent() {
|
|
if [[ -f "$1" ]]; then
|
|
fail "$1 exists but should not"
|
|
fi
|
|
}
|
|
|
|
function assert_eq() {
|
|
if [[ "$1" == "$2" ]]; then
|
|
return
|
|
fi
|
|
fail "'$1' does not equal '$2'"
|
|
}
|
|
|
|
function assert_substr() {
|
|
if [[ "$1" == *"$2"* ]]; then
|
|
return
|
|
fi
|
|
fail "'$1' does not contain '$2'"
|
|
}
|
|
|
|
# DIR is the directory in which all this test's state lives.
|
|
RUNID="${RANDOM}${RANDOM}"
|
|
DIR="/tmp/git-sync-git.$RUNID"
|
|
mkdir "$DIR"
|
|
|
|
# WORKDIR is where test cases run
|
|
WORKDIR="$DIR/work"
|
|
function clean_workdir() {
|
|
rm -rf "$WORKDIR"
|
|
mkdir -p "$WORKDIR"
|
|
}
|
|
|
|
#
|
|
# After all the test functions are defined, we can iterate over them and run
|
|
# them all automatically. See the end of this file.
|
|
#
|
|
|
|
##############################################
|
|
# Test `git init` on an existing repo
|
|
##############################################
|
|
function git::reinit_existing_repo() {
|
|
git init -b main
|
|
date > file
|
|
git add file
|
|
git commit -qam 'commit_1'
|
|
TREE1="$(git ls-tree HEAD | cut -d' ' -f3 | cut -f1)"
|
|
git init
|
|
TREE2="$(git ls-tree HEAD | cut -d' ' -f3 | cut -f1)"
|
|
assert_eq "$TREE1" "$TREE2"
|
|
}
|
|
|
|
##############################################
|
|
# Test `git fetch` of a branch
|
|
##############################################
|
|
function git::fetch_upstream_branch() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b main
|
|
|
|
# A commit on branch 1
|
|
git checkout -b upstream_branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
|
|
# A commit on branch 2
|
|
git checkout -b upstream_branch_2
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
cd clone
|
|
git init -b clone_branch
|
|
|
|
assert_substr "$(git cat-file -t "$SHA1" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_branch_1
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA1"
|
|
assert_file_exists file_1
|
|
assert_file_absent file_2
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_branch_2
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
git checkout "$SHA2"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
}
|
|
|
|
##############################################
|
|
# Test `git fetch` of a tag
|
|
##############################################
|
|
function git::fetch_upstream_tag() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b main
|
|
|
|
# A tag on branch 1 (not at HEAD)
|
|
git checkout -b upstream_branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
git tag upstream_tag_1
|
|
|
|
# Another tag on branch 1 (at HEAD)
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
git tag upstream_tag_2
|
|
|
|
# A tag on branch 2 (not at HEAD)
|
|
git checkout -b upstream_branch_2
|
|
date > file_3
|
|
git add file_3
|
|
git commit -qam 'commit_3'
|
|
SHA3="$(git rev-parse HEAD)"
|
|
git tag upstream_tag_3
|
|
|
|
# Another tag on branch 2 (at HEAD)
|
|
date > file_4
|
|
git add file_4
|
|
git commit -qam 'commit_4'
|
|
SHA4="$(git rev-parse HEAD)"
|
|
git tag upstream_tag_4
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
pushd clone >/dev/null
|
|
git init -b clone_branch
|
|
|
|
assert_substr "$(git cat-file -t "$SHA1" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag_1
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA1"
|
|
assert_file_exists file_1
|
|
assert_file_absent file_2
|
|
assert_file_absent file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag_2
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA2"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_absent file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag_3
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA3")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA3"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_exists file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag_4
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA3")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA4")" "commit"
|
|
git checkout "$SHA4"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_exists file_3
|
|
assert_file_exists file_4
|
|
}
|
|
|
|
##############################################
|
|
# Test `git fetch` of an annotated tag
|
|
##############################################
|
|
function git::fetch_upstream_tag_annotated() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b main
|
|
|
|
# A tag on branch 1 (not at HEAD)
|
|
git checkout -b upstream_branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_1" upstream_anntag_1
|
|
|
|
# Another tag on branch 1 (at HEAD)
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_2" upstream_anntag_2
|
|
|
|
# A tag on branch 2 (not at HEAD)
|
|
git checkout -b upstream_branch_2
|
|
date > file_3
|
|
git add file_3
|
|
git commit -qam 'commit_3'
|
|
SHA3="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_3" upstream_anntag_3
|
|
|
|
# Another tag on branch 2 (at HEAD)
|
|
date > file_4
|
|
git add file_4
|
|
git commit -qam 'commit_4'
|
|
SHA4="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_4" upstream_anntag_4
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
pushd clone >/dev/null
|
|
git init -b clone_branch
|
|
|
|
assert_substr "$(git cat-file -t "$SHA1" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag_1
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA1"
|
|
assert_file_exists file_1
|
|
assert_file_absent file_2
|
|
assert_file_absent file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag_2
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA2"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_absent file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag_3
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA3")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA3"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_exists file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag_4
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA3")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA4")" "commit"
|
|
git checkout "$SHA4"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_exists file_3
|
|
assert_file_exists file_4
|
|
}
|
|
|
|
##############################################
|
|
# Test `git fetch` of a SHA
|
|
##############################################
|
|
function git::fetch_upstream_sha() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b main
|
|
|
|
# A commit on branch 1 (not at HEAD)
|
|
git checkout -b upstream_branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
|
|
# Another commit on branch 1 (at HEAD)
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
|
|
# A commit on branch 2 (not at HEAD)
|
|
git checkout -b upstream_branch_2
|
|
date > file_3
|
|
git add file_3
|
|
git commit -qam 'commit_3'
|
|
SHA3="$(git rev-parse HEAD)"
|
|
|
|
# Another commit on branch 2 (at HEAD)
|
|
date > file_4
|
|
git add file_4
|
|
git commit -qam 'commit_4'
|
|
SHA4="$(git rev-parse HEAD)"
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
pushd clone >/dev/null
|
|
git init -b clone_branch
|
|
|
|
assert_substr "$(git cat-file -t "$SHA1" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA1"
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA2" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA1"
|
|
assert_file_exists file_1
|
|
assert_file_absent file_2
|
|
assert_file_absent file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA2"
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA3" 2>&1 || true)" "could not get object info"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA2"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_absent file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA3"
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA3")" "commit"
|
|
assert_substr "$(git cat-file -t "$SHA4" 2>&1 || true)" "could not get object info"
|
|
git checkout "$SHA3"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_exists file_3
|
|
assert_file_absent file_4
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA4"
|
|
assert_eq "$(git cat-file -t "$SHA1")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA2")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA3")" "commit"
|
|
assert_eq "$(git cat-file -t "$SHA4")" "commit"
|
|
git checkout "$SHA4"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_file_exists file_3
|
|
assert_file_exists file_4
|
|
}
|
|
|
|
##############################################
|
|
# Test git shallow fetch from a branch
|
|
##############################################
|
|
function git::shallow_fetch_branch() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b upstream_branch
|
|
|
|
# Some commits
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA="$(git rev-parse HEAD)"
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
cd clone
|
|
git init -b clone_branch
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_branch
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_branch --depth 1
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "true"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_branch --unshallow
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
}
|
|
|
|
##############################################
|
|
# Test git shallow fetch from a tag
|
|
##############################################
|
|
function git::shallow_fetch_tag() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b upstream_branch
|
|
|
|
# Some commits
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA="$(git rev-parse HEAD)"
|
|
git tag upstream_tag
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
cd clone
|
|
git init -b clone_branch
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag --depth 1
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "true"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_tag --unshallow
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
}
|
|
|
|
##############################################
|
|
# Test git shallow fetch from an annotated tag
|
|
##############################################
|
|
function git::shallow_fetch_tag_annotated() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b upstream_branch
|
|
|
|
# Some commits
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA="$(git rev-parse HEAD)"
|
|
git tag -am "upstream_anntag" upstream_anntag
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
cd clone
|
|
git init -b clone_branch
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag --depth 1
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "true"
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_anntag --unshallow
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
}
|
|
|
|
##############################################
|
|
# Test git shallow fetch from a SHA
|
|
##############################################
|
|
function git::shallow_fetch_sha() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b upstream_branch
|
|
|
|
# Some commits
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA="$(git rev-parse HEAD)"
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
cd clone
|
|
git init -b clone_branch
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA"
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA" --depth 1
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "true"
|
|
|
|
git fetch "file://$WORKDIR/upstream" "$SHA" --unshallow
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
}
|
|
|
|
##############################################
|
|
# Test git fetch with depth too large
|
|
##############################################
|
|
function git::fetch_too_large_depth() {
|
|
mkdir upstream
|
|
pushd upstream >/dev/null
|
|
git init -b upstream_branch
|
|
|
|
# Some commits
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA="$(git rev-parse HEAD)"
|
|
|
|
popd >/dev/null
|
|
|
|
mkdir clone
|
|
cd clone
|
|
git init -b clone_branch
|
|
|
|
git fetch "file://$WORKDIR/upstream" upstream_branch --depth 1000
|
|
git checkout "$SHA"
|
|
assert_file_exists file_1
|
|
assert_file_exists file_2
|
|
assert_eq "$(git rev-parse --is-shallow-repository)" "false"
|
|
}
|
|
|
|
##############################################
|
|
# Test git rev-parse with a branch
|
|
##############################################
|
|
function git::rev_parse_branch() {
|
|
mkdir repo
|
|
pushd repo >/dev/null
|
|
git init -b main
|
|
|
|
# A commit on branch 1
|
|
git checkout -b branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
|
|
# A commit on branch 2
|
|
git checkout -b branch_2
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
|
|
assert_eq "$(git rev-parse branch_1)" "$SHA1"
|
|
assert_eq "$(git rev-parse 'branch_1^{commit}')" "$SHA1"
|
|
assert_eq "$(git rev-parse branch_2)" "$SHA2"
|
|
assert_eq "$(git rev-parse 'branch_2^{commit}')" "$SHA2"
|
|
}
|
|
|
|
##############################################
|
|
# Test git rev-parse with a tag
|
|
##############################################
|
|
function git::rev_parse_tag() {
|
|
mkdir repo
|
|
pushd repo >/dev/null
|
|
git init -b main
|
|
|
|
# A tag on branch 1 (not at HEAD)
|
|
git checkout -b branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
git tag tag_1
|
|
|
|
# Another tag on branch 1 (at HEAD)
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
git tag tag_2
|
|
|
|
# A tag on branch 2 (not at HEAD)
|
|
git checkout -b branch_2
|
|
date > file_3
|
|
git add file_3
|
|
git commit -qam 'commit_3'
|
|
SHA3="$(git rev-parse HEAD)"
|
|
git tag tag_3
|
|
|
|
# Another tag on branch 2 (at HEAD)
|
|
date > file_4
|
|
git add file_4
|
|
git commit -qam 'commit_4'
|
|
SHA4="$(git rev-parse HEAD)"
|
|
git tag tag_4
|
|
|
|
assert_eq "$(git rev-parse tag_1)" "$SHA1"
|
|
assert_eq "$(git rev-parse 'tag_1^{commit}')" "$SHA1"
|
|
assert_eq "$(git rev-parse tag_2)" "$SHA2"
|
|
assert_eq "$(git rev-parse 'tag_2^{commit}')" "$SHA2"
|
|
assert_eq "$(git rev-parse tag_3)" "$SHA3"
|
|
assert_eq "$(git rev-parse 'tag_3^{commit}')" "$SHA3"
|
|
assert_eq "$(git rev-parse tag_4)" "$SHA4"
|
|
assert_eq "$(git rev-parse 'tag_4^{commit}')" "$SHA4"
|
|
}
|
|
|
|
##############################################
|
|
# Test git rev-parse with an annotated tag
|
|
##############################################
|
|
function git::rev_parse_tag_annotated() {
|
|
mkdir repo
|
|
pushd repo >/dev/null
|
|
git init -b main
|
|
|
|
# A tag on branch 1 (not at HEAD)
|
|
git checkout -b branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_1" anntag_1
|
|
|
|
# Another tag on branch 1 (at HEAD)
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_2" anntag_2
|
|
|
|
# A tag on branch 2 (not at HEAD)
|
|
git checkout -b branch_2
|
|
date > file_3
|
|
git add file_3
|
|
git commit -qam 'commit_3'
|
|
SHA3="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_3" anntag_3
|
|
|
|
# Another tag on branch 2 (at HEAD)
|
|
date > file_4
|
|
git add file_4
|
|
git commit -qam 'commit_4'
|
|
SHA4="$(git rev-parse HEAD)"
|
|
git tag -am "anntag_4" anntag_4
|
|
|
|
# Annotated tags have their own SHA, which can be found with rev-parse, but
|
|
# it doesn't make sense to test rev-parse against itself.
|
|
assert_eq "$(git rev-parse 'anntag_1^{commit}')" "$SHA1"
|
|
assert_eq "$(git rev-parse 'anntag_2^{commit}')" "$SHA2"
|
|
assert_eq "$(git rev-parse 'anntag_3^{commit}')" "$SHA3"
|
|
assert_eq "$(git rev-parse 'anntag_4^{commit}')" "$SHA4"
|
|
}
|
|
|
|
##############################################
|
|
# Test git rev-parse with a SHA
|
|
##############################################
|
|
function git::rev_parse_sha() {
|
|
mkdir repo
|
|
pushd repo >/dev/null
|
|
git init -b main
|
|
|
|
# A commit on branch 1 (not at HEAD)
|
|
git checkout -b branch_1
|
|
date > file_1
|
|
git add file_1
|
|
git commit -qam 'commit_1'
|
|
SHA1="$(git rev-parse HEAD)"
|
|
SHORT1="${SHA1%????????}"
|
|
|
|
# Another commit on branch 1 (at HEAD)
|
|
date > file_2
|
|
git add file_2
|
|
git commit -qam 'commit_2'
|
|
SHA2="$(git rev-parse HEAD)"
|
|
SHORT2="${SHA2%????????}"
|
|
|
|
# A commit on branch 2 (not at HEAD)
|
|
git checkout -b branch_2
|
|
date > file_3
|
|
git add file_3
|
|
git commit -qam 'commit_3'
|
|
SHA3="$(git rev-parse HEAD)"
|
|
SHORT3="${SHA3%????????}"
|
|
|
|
# Another commit on branch 2 (at HEAD)
|
|
date > file_4
|
|
git add file_4
|
|
git commit -qam 'commit_4'
|
|
SHA4="$(git rev-parse HEAD)"
|
|
SHORT4="${SHA4%????????}"
|
|
|
|
assert_eq "$(git rev-parse "$SHA1")" "$SHA1"
|
|
assert_eq "$(git rev-parse "$SHA1^{commit}")" "$SHA1"
|
|
assert_eq "$(git rev-parse "$SHORT1")" "$SHA1"
|
|
assert_eq "$(git rev-parse "$SHA2")" "$SHA2"
|
|
assert_eq "$(git rev-parse "$SHA2^{commit}")" "$SHA2"
|
|
assert_eq "$(git rev-parse "$SHORT2")" "$SHA2"
|
|
assert_eq "$(git rev-parse "$SHA3")" "$SHA3"
|
|
assert_eq "$(git rev-parse "$SHA3^{commit}")" "$SHA3"
|
|
assert_eq "$(git rev-parse "$SHORT3")" "$SHA3"
|
|
assert_eq "$(git rev-parse "$SHA4")" "$SHA4"
|
|
assert_eq "$(git rev-parse "$SHA4^{commit}")" "$SHA4"
|
|
assert_eq "$(git rev-parse "$SHORT4")" "$SHA4"
|
|
}
|
|
|
|
##############################################
|
|
# Test git rev-parse with a non-existent ref
|
|
##############################################
|
|
function git::rev_parse_non_existent_name() {
|
|
mkdir repo
|
|
pushd repo >/dev/null
|
|
git init -b main
|
|
|
|
assert_substr "$(git rev-parse does-not-exist 2>&1 || true)" "unknown revision"
|
|
}
|
|
|
|
##############################################
|
|
# Test git rev-parse with a non-existent sha
|
|
##############################################
|
|
function git::rev_parse_non_existent_sha() {
|
|
mkdir repo
|
|
pushd repo >/dev/null
|
|
git init -b main
|
|
|
|
# As long as it tastes like a SHA, rev-parse is happy, but there is no
|
|
# commit for it.
|
|
assert_eq "$(git rev-parse 0123456789abcdef0123456789abcdef01234567)" "0123456789abcdef0123456789abcdef01234567"
|
|
assert_substr "$(git rev-parse '0123456789abcdef0123456789abcdef01234567^{commit}' 2>&1 || true)" "unknown revision"
|
|
# Less-than-full SHAs do not work.
|
|
assert_substr "$(git rev-parse 0123456789abcdef 2>&1 || true)" "unknown revision"
|
|
assert_substr "$(git rev-parse '0123456789abcdef^{commit}' 2>&1 || true)" "unknown revision"
|
|
}
|
|
|
|
#
|
|
# main
|
|
#
|
|
|
|
function list_tests() {
|
|
(
|
|
shopt -s extdebug
|
|
declare -F \
|
|
| cut -f3 -d' ' \
|
|
| grep "^git::" \
|
|
| while read -r X; do declare -F "$X"; done \
|
|
| sort -n -k2 \
|
|
| cut -f1 -d' ' \
|
|
| sed 's/^git:://'
|
|
)
|
|
}
|
|
|
|
# Figure out which, if any, tests to run.
|
|
mapfile -t all_tests < <(list_tests)
|
|
tests_to_run=()
|
|
|
|
function print_tests() {
|
|
echo "available tests:"
|
|
for t in "${all_tests[@]}"; do
|
|
echo " $t"
|
|
done
|
|
}
|
|
|
|
# Validate and accumulate tests to run if args are specified.
|
|
for arg; do
|
|
# Use -? to list known tests.
|
|
if [[ "${arg}" == "-?" ]]; then
|
|
print_tests
|
|
exit 0
|
|
fi
|
|
if [[ "${arg}" =~ ^- ]]; then
|
|
echo "ERROR: unknown flag '${arg}'"
|
|
exit 1
|
|
fi
|
|
# Make sure each non-flag arg matches at least one test.
|
|
nmatches=0
|
|
for t in "${all_tests[@]}"; do
|
|
if [[ "${t}" =~ ${arg} ]]; then
|
|
nmatches=$((nmatches+1))
|
|
# Don't run tests twice, just keep the first match.
|
|
if [[ " ${tests_to_run[*]} " == *" ${t} "* ]]; then
|
|
continue
|
|
fi
|
|
tests_to_run+=("${t}")
|
|
continue
|
|
fi
|
|
done
|
|
if [[ ${nmatches} == 0 ]]; then
|
|
echo "ERROR: no tests match pattern '${arg}'"
|
|
echo
|
|
print_tests
|
|
exit 1
|
|
fi
|
|
tests_to_run+=("${matches[@]}")
|
|
done
|
|
set -- "${tests_to_run[@]}"
|
|
|
|
# If no tests were specified, run them all.
|
|
if [[ "$#" == 0 ]]; then
|
|
set -- "${all_tests[@]}"
|
|
fi
|
|
|
|
function finish() {
|
|
r=$?
|
|
trap "" INT EXIT ERR
|
|
if [[ $r != 0 ]]; then
|
|
echo
|
|
echo "the directory $DIR was not removed as it contains"\
|
|
"log files useful for debugging"
|
|
fi
|
|
exit $r
|
|
}
|
|
trap finish INT EXIT ERR
|
|
|
|
echo
|
|
echo "test root is $DIR"
|
|
echo
|
|
|
|
# Run a test function and return its error code. This is needed because POSIX
|
|
# dictates that `errexit` does not apply inside a function called in an `if`
|
|
# context. But if we don't call it with `if`, then it terminates the whole
|
|
# test run as soon as one test fails. So this jumps through hoops to let the
|
|
# individual test functions run outside of `if` and return a code in a
|
|
# variable.
|
|
#
|
|
# Args:
|
|
# $1: the name of a variable to populate with the return code
|
|
# $2+: the test function to run and optional args
|
|
function run_test() {
|
|
retvar=$1
|
|
shift
|
|
|
|
declare -g "$retvar"
|
|
local restore_opts
|
|
restore_opts=$(set +o)
|
|
set +o errexit
|
|
set +o nounset
|
|
set +o pipefail
|
|
(
|
|
set -o errexit
|
|
set -o nounset
|
|
set -o pipefail
|
|
"$@"
|
|
)
|
|
eval "$retvar=$?"
|
|
eval "$restore_opts"
|
|
}
|
|
|
|
# Override local configs for predictability in this test.
|
|
export GIT_CONFIG_GLOBAL=/dev/null
|
|
export GIT_CONFIG_SYSTEM=/dev/null
|
|
|
|
# TODO: add a flag to run all the tests inside the git-sync container image
|
|
# Iterate over the chosen tests and run them.
|
|
FAILS=()
|
|
FINAL_RET=0
|
|
RUNS="${RUNS:-1}"
|
|
for t; do
|
|
TEST_RET=0
|
|
RUN=0
|
|
while (( "${RUN}" < "${RUNS}" )); do
|
|
clean_workdir
|
|
|
|
pushd "$WORKDIR" >/dev/null
|
|
|
|
sfx=""
|
|
if (( "${RUNS}" > 1 )); then
|
|
sfx=" ($((RUN+1))/${RUNS})"
|
|
fi
|
|
echo -n "testcase ${t}${sfx}: "
|
|
|
|
# Set &3 for our own output, let testcases use &2 and &1.
|
|
exec 3>&1
|
|
|
|
# See comments on run_test for details.
|
|
RUN_RET=0
|
|
LOG="${DIR}/log.$t"
|
|
run_test RUN_RET "git::${t}" >"${LOG}.${RUN}" 2>&1
|
|
if [[ "$RUN_RET" == 0 ]]; then
|
|
pass
|
|
else
|
|
TEST_RET=1
|
|
if [[ "$RUN_RET" != 42 ]]; then
|
|
echo "FAIL: unknown error"
|
|
fi
|
|
fi
|
|
RUN=$((RUN+1))
|
|
|
|
popd >/dev/null
|
|
done
|
|
if [[ "$TEST_RET" != 0 ]]; then
|
|
FINAL_RET=1
|
|
FAILS+=("$t (log: ${LOG}.*)")
|
|
fi
|
|
done
|
|
if [[ "$FINAL_RET" != 0 ]]; then
|
|
echo
|
|
echo "the following tests failed:"
|
|
for f in "${FAILS[@]}"; do
|
|
echo " $f"
|
|
done
|
|
exit 1
|
|
fi
|
|
|
|
# Finally...
|
|
echo
|
|
if [[ "${CLEANUP:-}" == 0 ]]; then
|
|
echo "leaving logs in $DIR"
|
|
else
|
|
rm -rf "$DIR"
|
|
fi
|
|
|