-#!/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_must_fail 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 &&
- test_must_fail 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