diff --git a/git_helpers.sh b/git_helpers.sh index 0608796..1343269 100755 --- a/git_helpers.sh +++ b/git_helpers.sh @@ -5,32 +5,63 @@ source ./log_helpers.sh GIT_SSL_NO_VERIFY=true -commit_before_pull="" +# +exec_git_command () { + local func="${FUNCNAME[0]}" + + log_debug "$func:${LINENO} exec-ing $1" -# save the last commit before executing 'git pull' -save_commit_before_pull () { - # git reflog -> 46c5896 HEAD@{0}: commit: Made update_helpers.sh executable - commit_before_pull=$(git reflog | grep "HEAD@{0}" | cut -d" " -f1) - if ! [ -z "$commit_before_pull" ]; then - if grep -qE "^[[:xdigit:]]{6,}$" <<< $commit_before_pull; then - return 0 + exec {fd}< <($1) + local ps_pid=$! # remember pid of process substitution + + local git_result="" + while read t <&$fd; do + if ! [ -z "$t" ]; then + git_result="${git_result}$t" fi - fi - commit_before_pull="" - return 1 + done + + exec {fd}>&- # close fd (i.e. process substitution) + wait $ps_pid # wait for the subshell to finish + + git_result=$(printf "$git_result" | tr '\n' ' ') + printf "%s\n" $git_result +} + +# +latest_commit () { + local func="${FUNCNAME[0]}" + # git reflog -> 46c5896 HEAD@{0}: commit: Made update_helpers.sh executable + local c=$(git reflog | grep "HEAD@{0}" | cut -d" " -f1) + if ! [ -z "$c" ]; then + if grep -qE "^[[:xdigit:]]{6,}$" <<< $c; then + log_debug "$func: commit -> $c" + printf "%s\n" $c + else + log_crit "$func: wrong format for commit c=$c" + printf "" + fi + else + log_crit "$func: 'git reflog' result empty" + printf "" + fi } -# save_commit_before_pull # fallback if something went wrong: revert to last valid commit revert_to_commit_before_pull () { + local func="${FUNCNAME[0]}" if ! [ -z "$commit_before_pull" ]; then if grep -qE "^[[:xdigit:]]{6,}$" <<< $commit_before_pull; then `git reset --hard "$commit_before_pull"` if [ $? -eq 0 ]; then + log_info "$func: git reset --hard $commit_before_pull" return 0 fi + log_crit "$func: 'git reset --hard $commit_before_pull' failed!" fi + log_crit "$func: wrong format for commit_before_pull" fi + log_crit "$func: empty commit_before_pull" return 1 } # revert_to_commit_before_pull @@ -58,39 +89,153 @@ clone_customer_repository () { fi return 1 } -# clone_customer_repository https://git.mimbach49.de/GerhardHoffmann/customer_281.git +# clone_customer_repository -> +# https://git.mimbach49.de/GerhardHoffmann/customer_281.git -pull_customer_repository () { +cd_customer_repository () { # has to be called in ./UpdateController local func="${FUNCNAME[0]}" current_dir=${PWD##*/} current_dir="./${current_dir:-/}" if [ "$current_dir" = "./UpdateController" ]; then - repository_dir="./workspace/$1" + repository_dir="./workspace/${customer_id}" if ! [[ -d "$repository_dir" ]]; then - log_crit "$func: $repository_dir does not exist!" + log_crit "$func:${LINENO}: $repository_dir does not exist!" return 1 fi - message=$(cd $repository_dir && git pull) - if [ "$message" = "Already up to date." ]; then - log_warn "$func: $repository_dir already up to date." + + if ! cd $repository_dir; then + log_crit "$func:${LINENO}: cannot change to $repository_dir!" return 1 fi - log_info "$func: $message" + log_debug "$func:${LINENO}: cd to $repository_dir!" + return 0 + fi + return 1 +} - # Updating a6dd5d7..46d6b37 +cd_home () { + if cd - &>/dev/null ; then + return 0 + fi + return 1 +} - while IFS= read -r $line; do - echo "$line" -# sed -E 's/(Updating\s+)([[:xdigit:]]+)(..)([[:xdigit:]]+).*?/\2 \4/' +pull_customer_repository () { + # has to be called in ./UpdateController + local func="${FUNCNAME[0]}" - done < <(printf "%s\n" "$message") - else - log_crit "$func not called in ./UpdateController" + if ! cd_customer_repository ; then return 1 fi + local commit_before_pull=$(latest_commit) + if [ -z $commit_before_pull ]; then + cd_home ; return 1 + fi + + log_debug "$func:${LINENO}: commit_before_pull=$commit_before_pull" + + exec {fd}< <(git pull) + local ps_pid=$! # remember pid of process substitution + + local git_result="" + while read t <&$fd; do + if ! [ -z "$t" ]; then + git_result="${git_result}$t" + fi + done + + exec {fd}>&- # close fd (i.e. process substitution) + wait $ps_pid # wait for the subshell to finish + + if [ -z "$git_result" ]; then + log_warn "$func:${LINENO}: git result empty" ; cd_home; + return 1 + fi + + log_debug "$func:${LINENO} git-pull-result=${git_result}" + + if [ "$git_result" = "Already up to date." ]; then + log_warn "$func:${LINENO}: $PWD already up to date." + cd_home ; return 1 + fi + + local commit_after_pull=$(latest_commit) + if [ -z $commit_after_pull ]; then + cd_home ; return 1 + fi + + log_debug "$func:${LINENO}: commit_after_pull=$commit_after_pull" + + # Note: # 'git pull' is a 'git fetch' followed by a 'git merge'. + # Here's the fetch portion: + # + # remote: Counting objects: 11, done. + # remote: Compressing objects: 100% (5/5), done. + # remote: Total 7 (delta 2), reused 0 (delta 0) + # + # At this point, you've told the remote what you want. + # It finds all the objects it needs to give you, + # compresses them for faster transfer over the network, + # and then reports what it's sending you. + # + # Unpacking objects: 100% (7/7), done. + # + # You receive the pack (set of compressed objects) and unpack it. + # + # From ssh://my.remote.host.com/~/git/myproject + # * branch master -> FETCH_HEAD + + # You've fetched the branch 'master' from the given remote; + # the ref FETCH_HEAD now points to it. + # Now we move on to the merge - precisely, git will merge + # FETCH_HEAD (the remote's master branch) into your current branch + # (presumably master). + # + ####################################################################### + # here starts "message" + # + # Updating 9d447d2..f74fb21 + # Fast forward + # + # It turns out that you haven't diverged from the remote's master branch, + # so the merge is a fast-forward (a trivial merge where it simply moves + # you forward in the history). + # + # Git notes the original position of your master branch (9d447d2) + # and the new position (f74fb21) it's been fast-forwarded to. + # If you had diverged from the remote's master branch, + # you'd see the output of a recursive merge here - Merge made + # by recursive, possibly along with some Auto-merged + # and (oh no!) merge conflicts! + # + # szeged/1/1/etc/psa_config/device.conf | 13 +++++++------ + # szeged/update.conf | 2 +- + # 2 files changed, 8 insertions(+), 7 deletions(-) + # + # Finally, it shows you the diffstat between the original and post-merge + # position of your master branch; + # this is basically what you'd get from + # + # git diff --stat master@{1} master. + # + + update_commit="${commit_before_pull}..${commit_after_pull}" + if ! grep -qE ".*Updating\s+${update_commit}.*?" <<< $git_result; then + log_crit "$func:${LINENO}: no $update_commit in [ $git_result ]" + cd_home ; return 1 + fi + return 0 } # pull_customer_repository customer_281 + +changed_files () { + local func="${FUNCNAME[0]}" + if cd_customer_repository ; then + printf "%s\n" $(exec_git_command 'git diff --stat master@{1} master') + cd_home + fi +}