254 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# set -x 
 | 
						|
 | 
						|
source ./log_helpers
 | 
						|
source ./general_utils
 | 
						|
 | 
						|
 | 
						|
# if [ ${git_helpers_sourced:-1} = "1" ]; then
 | 
						|
#    readonly git_helpers_sourced=${BASH_SOURCE[0]}
 | 
						|
 | 
						|
readonly repository_already_up_to_date=2
 | 
						|
 | 
						|
#
 | 
						|
exec_git_command () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    log_debug "$func:${LINENO} exec-ing [$*]"
 | 
						|
    
 | 
						|
    local __git_result=$(exec_process_substitution $*)
 | 
						|
    log_debug "$func:${LINENO} result=$__git_result"
 | 
						|
 | 
						|
    printf '%s' "$__git_result"
 | 
						|
}
 | 
						|
 | 
						|
# 
 | 
						|
latest_commit () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    # git reflog -> 46c5896 HEAD@{0}: commit: Made update_helpers 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:${LINENO} commit -> $c"
 | 
						|
            printf "%s\n" "$c"
 | 
						|
        else
 | 
						|
            log_crit "$func:${LINENO} wrong format for commit c=$c"
 | 
						|
        fi
 | 
						|
    else 
 | 
						|
        log_crit "$func:${LINENO} 'git reflog' result empty"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
# 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
 | 
						|
 | 
						|
git_branch () {
 | 
						|
    # always relative to a git repository
 | 
						|
    echo $(git branch -a | grep '*' | awk '{ print $2 }')
 | 
						|
}
 | 
						|
 | 
						|
git_customer_branch () {
 | 
						|
    if cd_customer_repository; then
 | 
						|
        customer_branch=$(git_branch)
 | 
						|
        cd_home;
 | 
						|
        echo $customer_branch
 | 
						|
    fi
 | 
						|
}
 | 
						|
# clone the customer repository in ./workspace.
 | 
						|
# this is done only once.
 | 
						|
# 
 | 
						|
# Cloning into 'customer_281'...
 | 
						|
# remote: Enumerating objects: 1087, done.
 | 
						|
# remote: Counting objects: 100% (1087/1087), done.
 | 
						|
# remote: Compressing objects: 100% (946/946), done.
 | 
						|
# remote: Total 1087 (delta 404), reused 0 (delta 0), pack-reused 0
 | 
						|
# Receiving objects: 100% (1087/1087), 103.27 KiB | 873.00 KiB/s, done.
 | 
						|
# Resoving deltas: 100% (410/410), done.
 | 
						|
#
 | 
						|
clone_customer_repository () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    if [ "$PWD" != "$WORKING_DIRECTORY" ]; then
 | 
						|
        log_fatal "$func:${LINENO} PD != WD ($PWD != $WORKING_DIRECTORY)"
 | 
						|
    fi
 | 
						|
   
 | 
						|
    mkdir -p "./$WORKSPACE_DIR"
 | 
						|
    # check if the directory is empty. If so, clone the
 | 
						|
    # customer repository
 | 
						|
    if ! find ./$WORKSPACE_DIR -mindepth 1 -maxdepth 1 | read; then
 | 
						|
        log_info "$func:${LINENO} cloning ${1} into ${PWD}/${WORKSPACE_DIR}..."
 | 
						|
        if ! cd "./$WORKSPACE_DIR"; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not change to $WORKSPACE_DIR"
 | 
						|
        fi
 | 
						|
        if ! exec_git_command git clone "$1"; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not clone $1"
 | 
						|
        fi
 | 
						|
        ##########################  CLONING DONE   ############################
 | 
						|
        log_debug "$func:${LINENO} cloning ${1} done"
 | 
						|
        # after cloning, cd into repository, and re-initialize,
 | 
						|
        # setting the work-tree as "/". This has the effect that
 | 
						|
        # a "git pull" will automatically fetched files in the
 | 
						|
        # corresponding sytem-folders.
 | 
						|
        #######################  CD INTO REPOSITORY  ##########################
 | 
						|
        if ! cd ${CUSTOMER_ID_BASE_DIR}; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not change to $CUSTOMER_ID_BASE_DIR"
 | 
						|
        fi
 | 
						|
        log_debug "$func:${LINENO} cd into $CUSTOMER_ID_BASE_DIR"
 | 
						|
        ##################### CONFIGURE HOOKS DIRECTORY  ######################
 | 
						|
        if ! exec_git_command git config core.hooksPath .githooks; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not configure hooks directory"
 | 
						|
        fi
 | 
						|
        ###################### CHECKOUT LOCAL BRANCH  #########################
 | 
						|
        if ! exec_git_command git checkout "$LOCAL_BRANCH"; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not checkout $LOCAL_BRANCH"
 | 
						|
        fi
 | 
						|
        log_debug "$func:${LINENO} checked out local branch $LOCAL_BRANCH"
 | 
						|
        ######################## CONFIGURE WORKTREE  ##########################
 | 
						|
        if ! exec_git_command git config core.worktree "/"; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not configure worktree '/'"
 | 
						|
        fi
 | 
						|
        log_debug "$func:${LINENO} configured worktree '/'"
 | 
						|
        ########################### FETCH ALL #################################
 | 
						|
        if ! exec_git_command git fetch --all; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} can not fetch --all for $LOCAL_BRANCH"
 | 
						|
        fi
 | 
						|
        log_debug "$func:${LINENO} fetch repository"
 | 
						|
        ########################## RE-INIT REPOSITORY  ########################
 | 
						|
        if ! exec_git_command git reset --hard "$LOCAL_BRANCH"; then
 | 
						|
            update_psa_clone_error  # message to ISMAS
 | 
						|
            log_fatal "$func:${LINENO} re-init of $LOCAL_BRANCH failed"
 | 
						|
        fi
 | 
						|
        log_debug "$func:${LINENO} reset --hard $LOCAL_BRANCH"
 | 
						|
        INITIAL_CLONE=true
 | 
						|
        log_debug "$func:${LINENO} re-init of ${1} done"
 | 
						|
        update_psa_clone_customer_repository
 | 
						|
    else
 | 
						|
        # the directory is not empty, so we assume the
 | 
						|
        # customer-repository has been cloned already
 | 
						|
        if ! [[ -d "./${WORKSPACE_DIR}/$CUSTOMER_ID" ]]; then
 | 
						|
            log_fatal "$func:${LINENO} $PWD $WORKSPACE_DIR/$CUSTOMER_ID"\
 | 
						|
                "wrong repository: $(ls -d './${WORKSPACE_DIR}/*')"
 | 
						|
        fi
 | 
						|
        local __m="./${WORKSPACE_DIR}/$CUSTOMER_ID exists"
 | 
						|
        log_info "$func:${LINENO} $__m, no clone necessary"
 | 
						|
    fi
 | 
						|
 | 
						|
    cd_home
 | 
						|
}
 | 
						|
# clone_customer_repository ->
 | 
						|
# https://git.mimbach49.de/GerhardHoffmann/customer_281.git
 | 
						|
 | 
						|
cd_customer_repository () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
 | 
						|
    if [ "$PWD" != "$WORKING_DIRECTORY" ]; then
 | 
						|
        log_fatal "$func:${LINENO} PD != WD ($PWD != $WORKING_DIRECTORY)"
 | 
						|
    fi
 | 
						|
 | 
						|
    if ! [[ -d "$CUSTOMER_ID_BASE_DIR" ]]; then
 | 
						|
        log_fatal "$func:${LINENO}: $CUSTOMER_ID_BASE_DIR does not exist!"
 | 
						|
    fi
 | 
						|
    
 | 
						|
    if ! cd "$CUSTOMER_ID_BASE_DIR"; then
 | 
						|
        log_fatal "$func:${LINENO}: cannot cd to $CUSTOMER_ID_BASE_DIR !!!"
 | 
						|
    fi
 | 
						|
 | 
						|
    log_debug "$func:${LINENO}: cd to $CUSTOMER_ID_BASE_DIR"
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
cd_home () {
 | 
						|
    if cd "$WORKING_DIRECTORY" &>/dev/null ; then
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
}
 | 
						|
 | 
						|
pull_customer_repository () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
 | 
						|
    if ! cd_customer_repository; then
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    log_crit "$func:${LINENO}: executing 'git pull'..."
 | 
						|
    exec_git_command 'git pull'
 | 
						|
 | 
						|
    # GIT_UPDATE_LOG updated by hook post-merge. it contains the names of the
 | 
						|
    # changed files or opkg-commands to execute.
 | 
						|
    # If 'git pull' has fetched new data, then there are lines starting with
 | 
						|
    # DOWNLOAD or EXECUTE.
 | 
						|
    if grep -qE "^[[:space:]]*(DOWNLOAD|EXECUTE)" "$GIT_UPDATE_LOG"; then
 | 
						|
        log_info "$func:${LINENO}: new data fetched from repository"
 | 
						|
        cd_home; return 0
 | 
						|
    fi
 | 
						|
     
 | 
						|
    log_warn "$func:${LINENO}: no data fetched from repository"
 | 
						|
    cd_home; return 1
 | 
						|
}
 | 
						|
# pull_customer_repository customer_281
 | 
						|
 | 
						|
changed_file_names () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    if  cd_customer_repository ; then
 | 
						|
        local git_res=$(exec_git_command 'git diff --stat master@{1} master')
 | 
						|
        git_res=${git_res//[$'\r\n\t']/ }
 | 
						|
        log_debug "$func:${LINENO}: git_res=$git_res"
 | 
						|
        local file_names=""
 | 
						|
        for f in ${KNOWN_FILES[@]} ; do 
 | 
						|
            if grep -qE "${f}" <<< "$git_res"; then
 | 
						|
                if ! [ -z $file_names ]; then
 | 
						|
                    file_names="$f $file_names"
 | 
						|
                else
 | 
						|
                    file_names="$f"
 | 
						|
                fi
 | 
						|
                log_debug "$func:${LINENO}: $f found in $git_res"
 | 
						|
            fi
 | 
						|
        done    
 | 
						|
 | 
						|
        cd_home; log_debug "$func:${LINENO}: file_names=$file_names" ;
 | 
						|
        printf '%s' "$file_names" 
 | 
						|
    else
 | 
						|
        log_crit "$func:${LINENO}: cannot cd to $customer_repository "\
 | 
						|
            "while in $PWD"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
get_blob () {   # get the blob of the file(name) passed as $1
 | 
						|
                # note: this can be used for any file in the filesystem
 | 
						|
    echo $(git hash-object $1)
 | 
						|
}
 | 
						|
 | 
						|
get_commit_for_blob () {
 | 
						|
    blob=$(get_blob $1)
 | 
						|
    if [ ! -z $blob ]; then
 | 
						|
        # search for the blob in all commits for the file(name) $1
 | 
						|
        echo $(echo $(git log --all --pretty=format:%H -- $1) |
 | 
						|
               xargs -I{} sh -c "git ls-tree {} -- $1         |
 | 
						|
               grep -q $blob && echo {}")
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
 |