-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
pull creates a temporary tag in each castle before running git pull, and uses it to determine which files have been added (and renamed) in symlink_new_files, which also deletes it.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#!/usr/bin/env bash | ||
|
||
# shellcheck disable=2164 | ||
fixture_pull_renamed() { | ||
local git_username="Homeshick user" | ||
local git_useremail="[email protected]" | ||
local repo="$REPO_FIXTURES/pull-renamed" | ||
git init "$repo" | ||
cd "$repo" | ||
git config user.name "$git_username" | ||
git config user.email "$git_useremail" | ||
mkdir home | ||
cd home | ||
|
||
cat > .bashrc-wrong-name <<EOF | ||
#!/usr/bin/env bash | ||
PS1='\[33[01;32m\]\u@\h\[33[00m\]:\[33[01;34m\]\w\' | ||
EOF | ||
git add .bashrc-wrong-name | ||
git commit -m '.bashrc file for my new repo' | ||
|
||
git mv .bashrc-wrong-name .bashrc | ||
git commit -m 'fixed .bashrc file name' | ||
|
||
cat >> .bashrc <<EOF | ||
export IMPORTANT_VARIABLE=1 | ||
EOF | ||
git add .bashrc | ||
git commit -m 'Modified .bashrc to set IMPORTANT_VARIABLE' | ||
} | ||
|
||
fixture_pull_renamed > /dev/null |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/usr/bin/env bash | ||
|
||
# shellcheck disable=2164 | ||
fixture_pull_test() { | ||
local git_username="Homeshick user" | ||
local git_useremail="[email protected]" | ||
local repo="$REPO_FIXTURES/pull-test" | ||
git init "$repo" | ||
cd "$repo" | ||
git config user.name "$git_username" | ||
git config user.email "$git_useremail" | ||
mkdir home | ||
cd home | ||
|
||
cat > .bashrc <<EOF | ||
#!/usr/bin/env bash | ||
PS1='\[33[01;32m\]\u@\h\[33[00m\]:\[33[01;34m\]\w\' | ||
EOF | ||
git add .bashrc | ||
git commit -m '.bashrc file for my new pull-test repo' | ||
|
||
cat > .gitignore <<EOF | ||
.DS_Store | ||
*.swp | ||
EOF | ||
git add .gitignore | ||
git commit -m 'Added .gitignore file' | ||
|
||
cat >> .bashrc <<EOF | ||
export IMPORTANT_VARIABLE=1 | ||
EOF | ||
git add .bashrc | ||
git commit -m 'Modified .bashrc to set IMPORTANT_VARIABLE' | ||
} | ||
|
||
fixture_pull_test > /dev/null |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,92 @@ teardown() { | |
delete_test_dir | ||
} | ||
|
||
BEFORE_PULL_TAG=__homeshick-before-pull__ | ||
assert_tag_is_removed() { | ||
local castle | ||
for castle in "$@"; do | ||
( | ||
cd "$HOME/.homesick/repos/$castle" || return $? | ||
# show all the tags if the test fails | ||
{ | ||
echo "all tags in $castle:" | ||
git show-ref --tags || true | ||
echo | ||
} >&2 | ||
# this tag should not exist | ||
run git rev-parse --verify "refs/tags/$BEFORE_PULL_TAG" >&2 2>&- | ||
assert_failure | ||
) | ||
done | ||
} | ||
|
||
assert_tag_points_to() { | ||
( | ||
castle="$1" | ||
tag_before="$2" | ||
cd "$HOME/.homesick/repos/$castle" || return $? | ||
# show all the tags if the test fails | ||
{ | ||
echo "all tags in $castle:" | ||
git show-ref --tags || true | ||
echo | ||
} >&2 | ||
tag_after=$(git rev-parse "refs/tags/$BEFORE_PULL_TAG") | ||
[ "$tag_before" == "$tag_after" ] | ||
) | ||
} | ||
|
||
reset_and_add_new_file() { | ||
# takes castle name as first argument and commit to reset to as second | ||
cd "$HOME/.homesick/repos/$1" || return $? | ||
git reset --hard "$2" >/dev/null | ||
|
||
git config user.name "Homeshick user" | ||
git config user.email "[email protected]" | ||
|
||
cat > home/.ignore <<EOF | ||
.DS_Store | ||
*.swp | ||
EOF | ||
git add home/.ignore >/dev/null | ||
git commit -m 'Added .ignore file' >/dev/null | ||
} | ||
|
||
expect_new_files() { | ||
# takes castle name as first argument, and new files as remaining arguments | ||
local castle="$1" | ||
shift | ||
local green='\e[1;32m' | ||
local cyan='\e[1;36m' | ||
local white='\e[1;37m' | ||
local reset='\e[0m' | ||
# these variables are intended to be parsed by printf | ||
# shellcheck disable=SC2059 | ||
{ | ||
printf "$cyan pull$reset %s\r" "$castle" | ||
printf "$green pull$reset %s\n" "$castle" | ||
printf "$white updates$reset The castle %s has new files.\n" "$castle" | ||
printf "$cyan symlink?$reset [yN] y\r" | ||
printf "$green symlink?$reset [yN] \n" | ||
for file in "$@"; do | ||
printf "$cyan symlink$reset %s\r" "$file" | ||
printf "$green symlink$reset %s\n" "$file" | ||
done | ||
} | assert_output - | ||
} | ||
|
||
expect_no_new_files() { | ||
# takes castle name as first argument | ||
local castle="$1" | ||
local green='\e[1;32m' | ||
local cyan='\e[1;36m' | ||
local reset='\e[0m' | ||
{ | ||
printf "$cyan pull$reset %s\r" "$castle" | ||
printf "$green pull$reset %s\n" "$castle" | ||
} | assert_output - | ||
} | ||
|
||
@test 'pull skips castles with no upstream remote' { | ||
castle 'rc-files' | ||
castle 'dotfiles' | ||
|
@@ -20,6 +106,153 @@ teardown() { | |
(cd "$HOME/.homesick/repos/rc-files" && git remote rm origin) | ||
run homeshick pull rc-files dotfiles | ||
[ $status -eq 0 ] # EX_SUCCESS | ||
assert_tag_is_removed rc-files dotfiles | ||
# dotfiles FETCH_HEAD should exist if the castle was pulled | ||
[ -e "$HOME/.homesick/repos/dotfiles/.git/FETCH_HEAD" ] | ||
} | ||
|
||
@test 'pull prompts for symlinking if new files are present' { | ||
castle 'rc-files' | ||
(cd "$HOME/.homesick/repos/rc-files" && git reset --hard HEAD~1 >/dev/null) | ||
homeshick link --batch --quiet rc-files | ||
|
||
[ ! -e "$HOME/.gitignore" ] | ||
run homeshick pull rc-files <<<y | ||
assert_success | ||
assert_tag_is_removed rc-files | ||
expect_new_files rc-files .gitignore | ||
[ -f "$HOME/.gitignore" ] | ||
} | ||
|
||
@test 'pull prompts for symlinking with renamed files' { | ||
castle 'pull-renamed' | ||
# reset to before .bashrc-wrong-name was renamed to .bashrc | ||
(cd "$HOME/.homesick/repos/pull-renamed" && git reset --hard HEAD~2 >/dev/null) | ||
|
||
[ ! -e "$HOME/.bashrc" ] | ||
run homeshick pull pull-renamed <<<y | ||
assert_success | ||
assert_tag_is_removed pull-renamed | ||
expect_new_files pull-renamed .bashrc | ||
[ -f "$HOME/.bashrc" ] | ||
} | ||
|
||
@test 'pull with no new files present' { | ||
castle 'pull-test' | ||
(cd "$HOME/.homesick/repos/pull-test" && git reset --hard HEAD~1 >/dev/null) | ||
|
||
run homeshick pull --batch pull-test | ||
assert_success | ||
assert_tag_is_removed pull-test | ||
expect_no_new_files pull-test | ||
} | ||
|
||
@test 'pull a recently-pulled castle again' { | ||
# this checks that we don't try to link files again if the last operation was | ||
# a pull | ||
castle 'rc-files' | ||
(cd "$HOME/.homesick/repos/rc-files" && git reset --hard HEAD~1 >/dev/null) | ||
homeshick pull --batch --force rc-files | ||
|
||
run homeshick pull --batch rc-files | ||
assert_success | ||
assert_tag_is_removed rc-files | ||
expect_no_new_files rc-files | ||
} | ||
|
||
@test 'pull a castle with a git conflict' { | ||
local castle=pull-test | ||
castle 'pull-test' | ||
(reset_and_add_new_file pull-test HEAD~2) | ||
(cd "$HOME/.homesick/repos/pull-test" && git config pull.rebase false && git config pull.ff only) | ||
|
||
[ ! -e "$HOME/.gitignore" ] | ||
run homeshick pull --batch pull-test | ||
assert_failure 70 # EX_SOFTWARE | ||
assert_tag_is_removed pull-test | ||
[ ! -e "$HOME/.gitignore" ] | ||
local red='\e[1;31m' | ||
local cyan='\e[1;36m' | ||
local reset='\e[0m' | ||
{ | ||
echo -ne "$cyan pull$reset pull-test\r" | ||
echo -ne "$red pull$reset pull-test\n" | ||
echo -ne "$red error$reset Unable to pull $HOME/.homesick/repos/pull-test. Git says:\n" | ||
echo "fatal: Not possible to fast-forward, aborting." | ||
} | assert_output - | ||
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (4.0)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (4.2)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (4.3)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (4.3.30)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (4.4)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (5.1.12)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (5.1.16)
Check failure on line 182 in test/suites/pull.bats GitHub Actions / test (5.2)
|
||
} | ||
|
||
@test 'pull cleans up any marker tags after a git error' { | ||
castle 'dotfiles' | ||
castle 'pull-test' | ||
castle 'nodirs' | ||
(reset_and_add_new_file pull-test HEAD~2) | ||
(cd "$HOME/.homesick/repos/pull-test" && git config pull.rebase false && git config pull.ff only) | ||
|
||
run homeshick pull --batch dotfiles pull-test nodirs | ||
assert_failure 70 # EX_SOFTWARE | ||
# tags in all castles should be cleaned up | ||
assert_tag_is_removed dotfiles pull-test nodirs | ||
local green='\e[1;32m' | ||
local red='\e[1;31m' | ||
local cyan='\e[1;36m' | ||
local reset='\e[0m' | ||
{ | ||
echo -ne "$cyan pull$reset dotfiles\r" | ||
echo -ne "$green pull$reset dotfiles\n" | ||
echo -ne "$cyan pull$reset pull-test\r" | ||
echo -ne "$red pull$reset pull-test\n" | ||
echo -ne "$red error$reset Unable to pull $HOME/.homesick/repos/pull-test. Git says:\n" | ||
echo "fatal: Not possible to fast-forward, aborting." | ||
echo -ne "$cyan pull$reset nodirs\r" | ||
echo -ne "$green pull$reset nodirs\n" | ||
} | assert_output - | ||
Check failure on line 209 in test/suites/pull.bats GitHub Actions / test (4.0)
Check failure on line 209 in test/suites/pull.bats GitHub Actions / test (4.2)
Check failure on line 209 in test/suites/pull.bats GitHub Actions / test (4.3)
Check failure on line 209 in test/suites/pull.bats GitHub Actions / test (4.4)
Check failure on line 209 in test/suites/pull.bats GitHub Actions / test (5.1.12)
Check failure on line 209 in test/suites/pull.bats GitHub Actions / test (5.1.16)
|
||
} | ||
|
||
@test 'pull a castle where the marker tag already exists' { | ||
castle 'rc-files' | ||
local tag_before | ||
tag_before=$( | ||
cd "$HOME/.homesick/repos/rc-files" && | ||
git reset --hard HEAD~1 >/dev/null && | ||
git tag "$BEFORE_PULL_TAG" HEAD^ && | ||
git rev-parse "$BEFORE_PULL_TAG" | ||
) | ||
|
||
[ ! -e "$HOME/.gitignore" ] | ||
run homeshick pull --batch rc-files | ||
assert_failure 65 # EX_DATAERR | ||
# tag should not be touched | ||
assert_tag_points_to rc-files "$tag_before" | ||
[ ! -e "$HOME/.gitignore" ] | ||
|
||
local red='\e[1;31m' | ||
local cyan='\e[1;36m' | ||
local reset='\e[0m' | ||
{ | ||
echo -ne "$cyan pull$reset rc-files\r" | ||
echo -ne "$red pull$reset rc-files\n" | ||
echo -ne "$red error$reset Pull marker tag ($BEFORE_PULL_TAG) already exists in $HOME/.homesick/repos/rc-files. Please resolve this before pulling." | ||
} | assert_output - | ||
} | ||
|
||
@test 'pull only cleans up the marker tag if we created it' { | ||
castle 'dotfiles' | ||
castle 'rc-files' | ||
local tag_before | ||
tag_before=$( | ||
cd "$HOME/.homesick/repos/rc-files" && | ||
git reset --hard HEAD~1 >/dev/null && | ||
git tag "$BEFORE_PULL_TAG" HEAD^ && | ||
git rev-parse "refs/tags/$BEFORE_PULL_TAG" | ||
) | ||
|
||
[ ! -e "$HOME/.gitignore" ] | ||
run homeshick pull --batch dotfiles rc-files | ||
assert_failure 65 # EX_DATAERR | ||
# tag in dotfiles should be cleaned up | ||
assert_tag_is_removed dotfiles | ||
# tag in rc-files should not be touched | ||
assert_tag_points_to rc-files "$tag_before" | ||
[ ! -e "$HOME/.gitignore" ] | ||
} |