#!/bin/bash ################################################################################################# # title :git-myshellconfig-checkout # # description :checkout git detached HEAD # # author :Jakobus Schürz # # changes by :Jakobus Schürz # # created :17.01.2019 # # updated :28.10.2020 # # version :2.0 # # usage :git myshellconfig-checkout [-h] # # notes : # ################################################################################################# [ -z "${MSC_GIT+x}" ] && MSC_GIT=git [ -z "${MSC_LOGDIR+x}" ] && export MSC_LOGDIR="${HOME}/logs" [ -z "${MSC_LOGFILE+x}" ] && export MSC_LOGFILE="${MSC_LOGDIR}/myshellconfig.log" #MSC_LOGDIR="./logs" #MSC_LOGFILE="${MSC_LOGDIR}/git.log" [ -d "${MSC_LOGDIR}" ] || mkdir -p "${MSC_LOGDIR}" [ -z "${MSC_GIT_REMOTE_NAME+x}" ] && export MSC_GIT_REMOTE_NAME=$($MSC_GIT rev-parse --abbrev-ref @{u} 2>/dev/null | cut -d'/' -f1) [ -z "${MSC_GIT_BRANCH:+x}" ] && export MSC_GIT_BRANCH=master gitupdateend() { cat << EOF >> "${MSC_LOGFILE}" +-----ENDE git update repo $(date) ---------------------------------+ EOF } ENTRY cat << EOF >> "${MSC_LOGFILE}" +-----BEGINN git update repo $(date) -------------------------------+ EOF set -- $(getopt -u -o hrs --long headless,force-repo-update,force-submodules-update -- "$@" ) loginfo "git checkout-options: $@" while [ $# -gt 0 ]; do case $1 in -h|--headless) # Headless repo local PRE="${MSC_GIT_REMOTE_NAME}" shift ;; -r|--force-repo-update) dorepomodupdate="true" shift ;; -s|--force-submodules-update) dosubmodupdate="true" shift ;; --) shift break ;; *) echo "1: $1" PRE="" echo bla shift ;; esac done # If MSC_GIT_TAG is set, checkout is always headless. [ -z "${MSC_GIT_TAG:+x}" ] || { export MSC_GIT_BRANCH=${MSC_GIT_TAG}; export PRE=""; echo "DEBUG"; } # Output #echo -n " remote: ${MSC_GIT_REMOTE_NAME}, branch: ${MSC_GIT_BRANCH}: " # Check for updates in submodules only if last check was INTERVALL hours in the past #if [ $(cat ${MSC_BASE%/}${MSC_BASE:+/}.last_update_submodules 2>/dev/null || echo 0 ) \ [ -z "${MSC_GIT_UPD_REPO_STATFILE+x}" ] && export MSC_GIT_UPD_REPO_STATFILE="${MSC_BASE%/}${MSC_BASE:+/}.last_update_repo" [ -z "${MSC_GIT_UPD_SUBMOD_STATFILE+x}" ] && export MSC_GIT_UPD_SUBMOD_STATFILE="${MSC_BASE%/}${MSC_BASE:+/}.last_update_submodules" if [ $(stat --printf %Y ${MSC_GIT_UPD_REPO_STATFILE} 2>/dev/null || echo 0 ) \ -lt $(date --date="${MSC_GIT_REPO_UPDATE_INTERVALL-${MSC_GIT_REPO_UPDATE_INTERVALL_DEFAULT}} hours ago" "+%s") \ -a ${MSC_GIT_REPO_UPDATE-${MSC_GIT_REPO_UPDATE_DEFAULT-true}} ]; then [ -z "${dorepoupdate+x}" ] && dorepoupdate="true" fi if [ $(stat --printf %Y ${MSC_GIT_UPD_SUBMOD_STATFILE} 2>/dev/null || echo 0 ) \ -lt $(date --date="${MSC_GIT_SUBMODULES_UPDATE_INTERVALL-${MSC_GIT_SUBMODULES_UPDATE_INTERVALL_DEFAULT}} hours ago" "+%s") \ -a ${MSC_GIT_SUBMODULES_UPDATE-${MSC_GIT_SUBMODULES_UPDATE_DEFAULT-true}} ]; then [ -z "${dosubmodupdate+x}" ] && dosubmodupdate="true" fi #echo $MSC_GIT fetch ${MSC_GIT_REMOTE_NAME} -p 1>&2 if $dorepoupdate; then loginfo "$MSC_GIT submodule sync" logdebug "$($MSC_GIT submodule sync 2>&1)" loginfo "fetch repo${dosubmodupdate:+ and submodules}" $MSC_GIT fetch ${dosubmodupdate:+--recurse-submodules} ${MSC_GIT_REMOTE_NAME} -p 2>>"${MSC_LOGFILE}"|| { logwarning fetch failed; gitupdateend; exit 1; } if ${dosubmodupdate:-false}; then lastupdatesubmodules fi echo "Check for local changes:" >> "${MSC_LOGFILE}" if $MSC_GIT diff-index --ignore-submodules --exit-code HEAD -- >> "${MSC_LOGFILE}" ; then cat << EOF >> "${MSC_LOGFILE}" no changes in local repo $MSC_GIT checkout ${PRE}${PRE:+/}${MSC_GIT_BRANCH} EOF $MSC_GIT checkout ${PRE}${PRE:+/}${MSC_GIT_BRANCH} 1>>"${MSC_LOGFILE}" 2>>"${MSC_LOGFILE}"|| { gitupdateend; exit 2; } $MSC_GIT merge FETCH_HEAD 1>>"${MSC_LOGFILE}" 2>>"${MSC_LOGFILE}"|| { gitupdateend; exit 3; } if ${dosubmodupdate:+false}; then $MSC_GIT submodule update --init --recursive fi touch $MSC_GIT_UPD_REPO_STATFILE else logwarning -n " Lokale Änderungen festgestellt:" echo " Siehe Logfile ${MSC_LOGFILE}" >&2 cat << EOF >> "${MSC_LOGFILE}" um die Änderung zurückzusetzen bitte $MSC_GIT checkout \$FILENAME oder um alle lokalen Änderungen auf einmal zurückzusetzen: $MSC_GIT checkout . ausführen Die Änderungen sind: $($MSC_GIT diff-index HEAD --|awk '{print $5, $6}') $($MSC_GIT diff-index -p HEAD --) EOF gitupdateend exit 4 fi loginfo "repo${dosubmodupdate:+ and submodules} synced" if ${dosubmodupdate:-false}; then loginfo "update and commit submodules" logdebug "$($MSC_GIT submodule update --remote)" logdebug "$($MSC_GIT commit -a -m 'update submodules')" touch $MSC_GIT_UPD_SUBMOD_STATFILE logwarning "submodules synced" fi fi EXIT exit $rc