f4609b896f
This also bumps the stable nixpkgs to 20.09 as of 2020-11-21, because there is some breakage in the git build related to the netrc credentials helper which someone has taken care of in nixpkgs. The stable channel is not used for anything other than git, so this should be fine. Change-Id: I3575a19dab09e1e9556cf8231d717de9890484fb
216 lines
6.2 KiB
Bash
Executable file
216 lines
6.2 KiB
Bash
Executable file
#!/bin/sh
|
|
#
|
|
# Copyright (c) 2012 Robert Luberda
|
|
#
|
|
|
|
test_description='concurrent git svn dcommit'
|
|
. ./lib-git-svn.sh
|
|
|
|
|
|
|
|
test_expect_success 'setup svn repository' '
|
|
svn_cmd checkout "$svnrepo" work.svn &&
|
|
(
|
|
cd work.svn &&
|
|
echo >file && echo > auto_updated_file &&
|
|
svn_cmd add file auto_updated_file &&
|
|
svn_cmd commit -m "initial commit"
|
|
) &&
|
|
svn_cmd checkout "$svnrepo" work-auto-commits.svn
|
|
'
|
|
N=0
|
|
next_N()
|
|
{
|
|
N=$(( $N + 1 ))
|
|
}
|
|
|
|
# Setup SVN repository hooks to emulate SVN failures or concurrent commits
|
|
# The function adds
|
|
# either pre-commit hook, which causes SVN commit given in second argument
|
|
# to fail
|
|
# or post-commit hook, which creates a new commit (a new line added to
|
|
# auto_updated_file) after given SVN commit
|
|
# The first argument contains a type of the hook
|
|
# The second argument contains a number (not SVN revision) of commit
|
|
# the hook should be applied for (each time the hook is run, the given
|
|
# number is decreased by one until it gets 0, in which case the hook
|
|
# will execute its real action)
|
|
setup_hook()
|
|
{
|
|
hook_type="$1" # "pre-commit" or "post-commit"
|
|
skip_revs="$2"
|
|
[ "$hook_type" = "pre-commit" ] ||
|
|
[ "$hook_type" = "post-commit" ] ||
|
|
{ echo "ERROR: invalid argument ($hook_type)" \
|
|
"passed to setup_hook" >&2 ; return 1; }
|
|
echo "cnt=$skip_revs" > "$hook_type-counter"
|
|
rm -f "$rawsvnrepo/hooks/"*-commit # drop previous hooks
|
|
hook="$rawsvnrepo/hooks/$hook_type"
|
|
cat > "$hook" <<- 'EOF1'
|
|
#!/bin/sh
|
|
set -e
|
|
cd "$1/.." # "$1" is repository location
|
|
exec >> svn-hook.log 2>&1
|
|
hook="$(basename "$0")"
|
|
echo "*** Executing $hook $@"
|
|
set -x
|
|
. ./$hook-counter
|
|
cnt="$(($cnt - 1))"
|
|
echo "cnt=$cnt" > ./$hook-counter
|
|
[ "$cnt" = "0" ] || exit 0
|
|
EOF1
|
|
if [ "$hook_type" = "pre-commit" ]; then
|
|
echo "echo 'commit disallowed' >&2; exit 1" >>"$hook"
|
|
else
|
|
echo "PATH=\"$PATH\"; export PATH" >>"$hook"
|
|
echo "svnconf=\"$svnconf\"" >>"$hook"
|
|
cat >>"$hook" <<- 'EOF2'
|
|
cd work-auto-commits.svn
|
|
svn up --config-dir "$svnconf"
|
|
echo "$$" >> auto_updated_file
|
|
svn commit --config-dir "$svnconf" \
|
|
-m "auto-committing concurrent change"
|
|
exit 0
|
|
EOF2
|
|
fi
|
|
chmod 755 "$hook"
|
|
}
|
|
|
|
check_contents()
|
|
{
|
|
gitdir="$1"
|
|
(cd ../work.svn && svn_cmd up) &&
|
|
test_cmp file ../work.svn/file &&
|
|
test_cmp auto_updated_file ../work.svn/auto_updated_file
|
|
}
|
|
|
|
test_expect_success 'check if post-commit hook creates a concurrent commit' '
|
|
setup_hook post-commit 1 &&
|
|
(
|
|
cd work.svn &&
|
|
cp auto_updated_file au_file_saved &&
|
|
echo 1 >> file &&
|
|
svn_cmd commit -m "changing file" &&
|
|
svn_cmd up &&
|
|
! test_cmp auto_updated_file au_file_saved
|
|
)
|
|
'
|
|
|
|
test_expect_success 'check if pre-commit hook fails' '
|
|
setup_hook pre-commit 2 &&
|
|
(
|
|
cd work.svn &&
|
|
echo 2 >> file &&
|
|
svn_cmd commit -m "changing file once again" &&
|
|
echo 3 >> file &&
|
|
! svn_cmd commit -m "this commit should fail" &&
|
|
svn_cmd revert file
|
|
)
|
|
'
|
|
|
|
test_expect_success 'dcommit error handling' '
|
|
setup_hook pre-commit 2 &&
|
|
next_N && git svn clone "$svnrepo" work$N.git &&
|
|
(
|
|
cd work$N.git &&
|
|
echo 1 >> file && git commit -am "commit change $N.1" &&
|
|
echo 2 >> file && git commit -am "commit change $N.2" &&
|
|
echo 3 >> file && git commit -am "commit change $N.3" &&
|
|
# should fail to dcommit 2nd and 3rd change
|
|
# but still should leave the repository in reasonable state
|
|
test_must_fail git svn dcommit &&
|
|
git update-index --refresh &&
|
|
git show HEAD~2 | grep -q git-svn-id &&
|
|
! git show HEAD~1 | grep -q git-svn-id &&
|
|
! git show HEAD | grep -q git-svn-id
|
|
)
|
|
'
|
|
|
|
test_expect_success 'dcommit concurrent change in non-changed file' '
|
|
setup_hook post-commit 2 &&
|
|
next_N && git svn clone "$svnrepo" work$N.git &&
|
|
(
|
|
cd work$N.git &&
|
|
echo 1 >> file && git commit -am "commit change $N.1" &&
|
|
echo 2 >> file && git commit -am "commit change $N.2" &&
|
|
echo 3 >> file && git commit -am "commit change $N.3" &&
|
|
# should rebase and leave the repository in reasonable state
|
|
git svn dcommit &&
|
|
git update-index --refresh &&
|
|
check_contents &&
|
|
git show HEAD~3 | grep -q git-svn-id &&
|
|
git show HEAD~2 | grep -q git-svn-id &&
|
|
git show HEAD~1 | grep -q auto-committing &&
|
|
git show HEAD | grep -q git-svn-id
|
|
)
|
|
'
|
|
|
|
# An utility function used in the following test
|
|
delete_first_line()
|
|
{
|
|
file="$1" &&
|
|
sed 1d < "$file" > "${file}.tmp" &&
|
|
rm "$file" &&
|
|
mv "${file}.tmp" "$file"
|
|
}
|
|
|
|
test_expect_success 'dcommit concurrent non-conflicting change' '
|
|
setup_hook post-commit 2 &&
|
|
next_N && git svn clone "$svnrepo" work$N.git &&
|
|
(
|
|
cd work$N.git &&
|
|
cat file >> auto_updated_file &&
|
|
git commit -am "commit change $N.1" &&
|
|
delete_first_line auto_updated_file &&
|
|
git commit -am "commit change $N.2" &&
|
|
delete_first_line auto_updated_file &&
|
|
git commit -am "commit change $N.3" &&
|
|
# should rebase and leave the repository in reasonable state
|
|
git svn dcommit &&
|
|
git update-index --refresh &&
|
|
check_contents &&
|
|
git show HEAD~3 | grep -q git-svn-id &&
|
|
git show HEAD~2 | grep -q git-svn-id &&
|
|
git show HEAD~1 | grep -q auto-committing &&
|
|
git show HEAD | grep -q git-svn-id
|
|
)
|
|
'
|
|
|
|
test_expect_success 'dcommit --no-rebase concurrent non-conflicting change' '
|
|
setup_hook post-commit 2 &&
|
|
next_N && git svn clone "$svnrepo" work$N.git &&
|
|
(
|
|
cd work$N.git &&
|
|
cat file >> auto_updated_file &&
|
|
git commit -am "commit change $N.1" &&
|
|
delete_first_line auto_updated_file &&
|
|
git commit -am "commit change $N.2" &&
|
|
delete_first_line auto_updated_file &&
|
|
git commit -am "commit change $N.3" &&
|
|
# should fail as rebase is needed
|
|
test_must_fail git svn dcommit --no-rebase &&
|
|
# but should leave HEAD unchanged
|
|
git update-index --refresh &&
|
|
! git show HEAD~2 | grep -q git-svn-id &&
|
|
! git show HEAD~1 | grep -q git-svn-id &&
|
|
! git show HEAD | grep -q git-svn-id
|
|
)
|
|
'
|
|
|
|
test_expect_success 'dcommit fails on concurrent conflicting change' '
|
|
setup_hook post-commit 1 &&
|
|
next_N && git svn clone "$svnrepo" work$N.git &&
|
|
(
|
|
cd work$N.git &&
|
|
echo a >> file &&
|
|
git commit -am "commit change $N.1" &&
|
|
echo b >> auto_updated_file &&
|
|
git commit -am "commit change $N.2" &&
|
|
echo c >> auto_updated_file &&
|
|
git commit -am "commit change $N.3" &&
|
|
test_must_fail git svn dcommit && # rebase should fail
|
|
test_must_fail git update-index --refresh
|
|
)
|
|
'
|
|
|
|
test_done
|