diff --git a/bin/homeshick b/bin/homeshick index 82f7322..6304d92 100755 --- a/bin/homeshick +++ b/bin/homeshick @@ -171,6 +171,7 @@ case $cmd in cd) help cd ;; # cd is implemented in the homeshick.{sh,csh} helper script. help) help $help_cmd ;; *) + pull_completed=() for param in "${params[@]}"; do case $cmd in clone) @@ -182,7 +183,15 @@ case $cmd in refresh) (refresh $threshhold "$param") ;; pull) - (pull "$param") && pull_completed+=("$param") ;; + prev_hash=$(cd "$repos/$param" && git rev-parse HEAD -- 2>/dev/null) + (pull "$param") + result=$? + if [[ $result -eq 0 ]]; then + curr_hash=$(cd "$repos/$param" && git rev-parse HEAD --) + [[ "$prev_hash" != "$curr_hash" ]] && pull_completed+=("$param") + fi + (exit $result) + ;; symlink|link) symlink "$param" ;; track) diff --git a/lib/commands/pull.sh b/lib/commands/pull.sh index cc3b138..5e7360b 100644 --- a/lib/commands/pull.sh +++ b/lib/commands/pull.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -BEFORE_PULL_TAG=__homeshick-before-pull__ pull() { [[ ! $1 ]] && help_err pull local castle=$1 @@ -14,15 +13,6 @@ pull() { return "$EX_SUCCESS" fi - # this tag is exceedingly unlikely to already exist, but if it does, error - # out and let the user resolve it - (cd "$repo" && git rev-parse --verify "refs/tags/$BEFORE_PULL_TAG" &>/dev/null) && \ - err "$EX_DATAERR" "Pull marker tag ($BEFORE_PULL_TAG) already exists in $repo. Please resolve this before pulling." - # make a tag at the current commit, so we can compare against it below - (cd "$repo" && git tag --no-sign "$BEFORE_PULL_TAG" 2>&1) - # remove the tag if one of the git operations fails - trap 'cd "$repo" && git tag -d "$BEFORE_PULL_TAG" &>/dev/null' EXIT - local git_out git_out=$(cd "$repo" && git pull 2>&1) || \ err "$EX_SOFTWARE" "Unable to pull $repo. Git says:" "$git_out" @@ -36,7 +26,6 @@ pull() { err "$EX_SOFTWARE" "Unable update submodules for $repo. Git says:" "$git_out" fi success - trap - EXIT return "$EX_SUCCESS" } @@ -46,17 +35,14 @@ symlink_new_files() { local castle=$1 shift local repo="$repos/$castle" - local git_out - git_out=$(cd "$repo" && git diff --name-only --diff-filter=AR "$BEFORE_PULL_TAG" HEAD -- home 2>/dev/null | wc -l 2>&1) - local result=$? - # Remove the tag before doing anything else - (cd "$repo" && git tag -d "$BEFORE_PULL_TAG" &>/dev/null) - if [[ $result -ne 0 ]]; then - continue # Ignore errors, this operation is not mission critical - fi if [[ ! -d $repo/home ]]; then continue; fi + # @{1} refers to the previous reflog entry on the current branch, which + # will be right before the pull + if ! git_out=$(cd "$repo" && git diff --name-only --diff-filter=AR '@{1}' HEAD -- home 2>/dev/null | wc -l 2>&1); then + continue # Ignore errors, this operation is not mission critical + fi if [[ $git_out -gt 0 ]]; then updated_castles+=("$castle") fi diff --git a/test/suites/pull.bats b/test/suites/pull.bats index be03d1a..71f8329 100755 --- a/test/suites/pull.bats +++ b/test/suites/pull.bats @@ -13,24 +13,6 @@ teardown() { } 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() { # takes castle name as first argument and expected commit hash as second ( @@ -111,7 +93,6 @@ expect_no_new_files() { (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" ] } @@ -124,7 +105,6 @@ expect_no_new_files() { [ ! -e "$HOME/.gitignore" ] run homeshick pull rc-files <<> .git/config + ) + + [ ! -e "$HOME/.bashrc" ] + [ ! -e "$HOME/.gitignore" ] + run homeshick pull --batch pull-test + assert_success + expect_no_new_files pull-test + [ ! -e "$HOME/.bashrc" ] + [ ! -e "$HOME/.gitignore" ] +}