#!/bin/bash
SOURCE="$0"
source /usr/lib/elive-tools/functions
EL_REPORTS="1"
el_make_environment
#set -v
#set -T
# set -x
#set -e

# TODO: alternative to bkp that should be faster, try git stage
# TODO: create a list of commits already-imported, so when we run again a same git-watcher, they should be skipped (and removed from the counter list) -- or at least list all the commits that we cherry-picked, if they are matched when we enter on them, show a warning message saying that we already cherry-picked it to FOO (mark this too)

#===  FUNCTION  ================================================================
#          NAME:  exit_cleanups
#   DESCRIPTION:  delete temporal things when exit
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
exit_cleanups(){
    # pre {{{
    el_debug

    # }}}
    # do we need to recover our original position?
    travel_restore

    if ! [[ -e "$conf_repo_d/flags/persistent_watcher" ]] ; then
        rm -rf "$conf_repo_d"
    fi

    # tell us if we save
    if [[ -e "$conf_repo_d/flags/persistent_watcher" ]] ; then
        el_explain 0 "Session __saved__"
    else
        el_explain 0 "Session not saved"
    fi

    # share session always when exiting
    if ((is_shared)) && [[ -d "$shared_personal_d" ]] ; then
        # store actual position for future calls of this tool
        if [[ "$commit_id" != "$( tail -1 "$shared_personal_d/last_commit_tracked" 2>/dev/null )" ]] ; then
            # store our commit-id
            echo "$commit_id" > "$shared_personal_d/last_commit_tracked"
            # store our progress
            echo -e "$counter $counter_total" > "$shared_personal_d/last_commit_tracked_progress"

            #echo "$counter $counter_total" > "$shared_personal_d/last_commit_tracked_progress"
            el_explain 0 "Share __saved__"
        fi

    else
        el_explain 0 "Session is not shared"
    fi

    # do we had another branch outside git-watcher? restore it
    if [[ -n "$branch_working_prev" ]] ; then
        command git checkout --quiet "$branch_working_prev"
    fi

    rm -rf "$tmpdir" "$tmpdir_sources"
}

el_add_on_exit exit_cleanups

#===  FUNCTION  ================================================================
#          NAME:  shared_accounts_state_show
#   DESCRIPTION:  scan and show status of other accounts
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
shared_accounts_state_show(){
    # pre {{{
    el_debug

    local _user _dir _email
    # }}}

    # loop for each user found
    if ((is_shared)) ; then
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "  ${el_c_gr}${el_c_blink}Scanning paralel universes...${el_c_n}"

        for _dir in "$shared_d"/*
        do
            [[ ! -d "$_dir" ]] && continue

            _email="$( basename "$_dir" )"
            _user="$( cat "$_dir/username.txt" )"
            _commit_id="$( cat "$_dir/last_commit_tracked" )"
            _commits_step="$( cat "$_dir/last_commit_tracked_progress" | awk '{print $1}' )"
            _commits_total="$( cat "$_dir/last_commit_tracked_progress" | awk '{print $2}' )"

            # skip our own user
            # TODO: re-enable after to finish tests
            #if [[ "${git_email}" = "$_email" ]] ; then
                #continue
            #fi

            # header nice image
            if [[ -n "$TERMINOLOGY" ]] ; then
                if [[ -s "$_dir/gravatar.png" ]] ; then
                    tycat "$_dir"/gravatar.png
                fi
            fi

            echo -e "..:: $_user ::.."
            echo -e "email:   $_email"
            echo -e "step:    ${el_c_n}[${el_c_g}${_commits_step}${el_c_n}/${el_c_y}${_commits_total}${el_c_n}]${el_c_n}  (${_commit_id:0:12})"


            # only if we are not ourselves
            if [[ "${git_email}" != "$_email" ]] ; then
                # anything to work later?
                if [[ "$_commits_total" -gt "$_commits_total_biggest" ]] ; then
                    _commits_total_biggest="$_commits_total"
                    _commits_total_biggest_user="$_user"
                fi

                if [[ "$_commits_step" -gt "$_commits_step_biggest" ]] ; then
                    _commits_step_biggest="$_commits_step"
                    _commits_step_biggest_user="$_user"
                    _commit_id_biggest="$_commit_id"
                fi

                # show available time-traveling capsules
                if el_check_dir_has_files "${_dir}/ttc/to_${git_email}/review" 2>/dev/null ; then
                    _ttc_counter="$( ls -1 "${_dir}/ttc/to_${git_email}/review" | wc -l )"
                    el_explain 0 "__${_user}__ has __${_ttc_counter}__ XXTime-Traveling CapsulesXX for you!"
                fi

                if el_check_dir_has_files "${_dir}/ttc/to_${git_email}/questions" 2>/dev/null ; then
                    _ttc_counter="$( ls -1 "${_dir}/ttc/to_${git_email}/questions" | wc -l )"
                    el_explain 0 "__${_user}__ has __${_ttc_counter}__ XXQuestionsXX in Capsules for you!"
                fi

            fi

            # done
            echo -e ""
        done
    fi

    # compare and update if needed
    if [[ "$_commits_total_biggest" -gt "$counter_total" ]] ; then
        el_explain 0 "Seems like __${_commits_total_biggest_user}__ is using an updated repo than yours"
        if el_confirm "Update your git repo now? (git pull --rebase)" ; then

            # which remote to fetch from?
            if [[ -z "$remote_fetching_working" ]] ; then
                if [[ "$( command git remote -v | grep -F "(fetch)" | awk '{print $1}' | wc -l )" -gt 1 ]] ; then
                    echo -e "\nWhich remote ID you want to track the changes on '$branch_working' from? (empty cancels)\n"
                    command git remote -v | grep -F "(fetch)" | sed -e 's|(fetch).*$||g' | column -t | awk '{$1 = "(id: "$1") "; print $0}'

                    read -e remote_fetching_working
                else
                    remote_fetching_working="$(command git remote -v | grep -F "(fetch)" | awk '{print $1}' | head -1 )"
                fi

                echo "$remote_fetching_working" > "$conf_remote_fetch_working_from_f"
            fi

            # pull remote
            #command git pull --rebase "$remote_fetching_working" "$branch_working" # don't use this method, leads to diverged branches
            command git pull --quiet --rebase "$remote_fetching_working" "+${branch_working}:refs/remotes/${remote_fetching_working}/${branch_working}"

            check_if_has_diverged

            # update total of commits
            do_count_commits "force"
            is_recount_position_needed=1

            _is_shared_scanned=1
        fi
    fi

    # walk steps?
    if [[ "$_commits_step_biggest" -gt "$counter" ]] ; then
        el_explain 0 "Seems like __${_commits_step_biggest_user}__ is ahead of you"

        if el_confirm "Join its commit-id position?" ; then
            commit_id="$_commit_id_biggest"

            # update total of commits
            do_count_commits "force"
            unset commits_history
            unset counter
            is_recount_position_needed=1

            _is_shared_scanned=1
        fi
    fi


    #if ((_is_shared_scanned)) ; then
        #el_explain 0 "Finished to scan paralel worlds, press Enter to continue..."
        #read nothing
    #fi
}

#===  FUNCTION  ================================================================
#          NAME:  shared_messages_create
#   DESCRIPTION:  elaborate messages to send to other users
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
shared_messages_create(){
    # pre {{{
    el_debug
    local _message_option _mark_message _entity _entity_email

    # }}}

    # Select a user where to send message:
    el_explain 0 "Other carbon-based life forms:"
    echo -en "${el_c_g}"

    if [[ -z "$shared_d" ]] ; then
        # if we are not running on shared session, just insert an email
        echo -e "\n${el_c_g}Type a destination email:${el_c_n}"
        read -e _entity_email

    else
        if [[ "$( ls -1 "${shared_d}" | grep -Fv "$git_email" | wc -l )" -gt 1 ]] ; then
            ls -1 "${shared_d}" | grep -Fv "$git_email"
            echo -en "${el_c_n}"

            # FIXME: improve this: we are using email based now
            echo -e "\nType an email entity:"
            read -e _entity_email
        else
            _entity_email="$( ls -1 "${shared_d}" | grep -Fv "$git_email" | tail -1 )"
            el_explain 0 "Messaging to the XX${_entity_email}XX carbon-based life form"
        fi

        if ! [[ -d "${shared_d}/$_entity_email" ]] ; then
            el_error "Carbon-based life form doesn't exist, are you in the correct planet?"
            echo -e "\nType an entity:"
            read -e _entity_email

            if ! [[ -d "${shared_d}/$_entity_email" ]] ; then
                return 0
            fi
        fi

        # get email of entity
        # FIXME: get nickname instead
        _entity_email="$( cat "${shared_d}/${_entity_email}/email.txt" | grep -F "@" )"
    fi

    # FIXME: what?
    if ! echo "$_entity_email" | grep -Fqs "$_entity_email" ; then
        el_error "$_entity_email has not a valid email?: $_entity_email"
    fi


    # message type?
    option_show "i" "Import request for this commit"
    option_show "a" "Ask a question to ${_entity_email} (not importing required)"
    ###option_show "r" "Reply a question"
    option_show "q" "quit this menu"

    read -N 1 _message_option

    # message?
    echo -e "\nMessage to include?  (blank = no message)"
    read -e _mark_message

    # get the remote working repo url to include in the email {{{
    if [[ -z "$remote_working" ]] ; then
        if [[ "$( command git remote -v | grep -F "(push)" | awk '{print $1}' | wc -l )" -gt 1 ]] ; then
            echo -e "\nWhich one is the remote repo where you normally push your work that is shared with your collaborators?\n"
            command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | column -t | awk '{$1 = "(id: "$1") "; print $0}'

            echo -e "\nInsert remote repo:"
            read -e remote_working

            # translate remote-id to url, which is what we need
            if command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | awk '{print $1}' | grep -qs "^$remote_working" ; then
                remote_working="$( command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | grep "^$remote_working" | head -1 | awk '{$1 = ""; print $0}' )"
                # remove extra leading blank chars
                read -r remote_working <<< "$remote_working"
            fi


            # small check, just in case
            if ! echo "$remote_working" | grep -qsE "(@|:|/)" ; then
                el_error "Have you inserted the identifier instead of the remote URL? mmh... do it again:"
                read -e remote_working
            fi
        else
            remote_working="$( command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | head -1 | awk '{$1 = ""; print $0}' )"
        fi

        #echo "$remote_working" > "$conf_remote_work_from_f"
    fi

    read -r remote_working <<< "$remote_working"
    remote_working="$( echo "$remote_working" | sed -e 's|/|%|g' )"
    # }}}

    # send email and set specific values
    case "$_message_option" in
        a|A)
            _message_option="questions"

            el_explain 0 "Sending email..."

            email-sender -q -t "$_entity_email" -s "$git_username has a question for you" -S "<i style=\"color: #FC61B3;\">${git_email}</i> wants to ask you:" <<EOF
<p><strong> Message: ${_mark_message} </strong></p>

To know more you need to take a <i>Time-Traveling Capsule</i> to join its universe, for that:

<ul>
<li>cd into your git copy of: '${remote_working//%/\/}' <i>(${git_username} has it at: ${working_directory_d})</i></li>
<li>run the command:  <strong>$(basename $0) -w ${branch_working} ${tool_arguments} -g ${commit_id}</strong></li>
</ul>
EOF

            ;;
        i|I)
            _message_option="review"

            el_explain 0 "Sending email..."

            email-sender -q -t "$_entity_email" -s "$git_username wants to know if we should backport a commit" -S "<i style=\"color: #FC61B3;\">${git_email}</i> wants you to consider backporting this commit from '${branch_watch}' into '${branch_working}' " <<EOF
<p><strong>Message: ${_mark_message} </strong></p>

To take your <i>Time-Traveling Capsule</i> you should:

<ul>
<li>cd into your git copy of: '${remote_working//%/\/}' <i>(${git_username} has it on ${working_directory_d})</i></li>
<li>run the command:  <strong>$(basename $0) -w ${branch_working} $tool_arguments -g ${commit_id}</strong></li>
</ul>

Or, without the -g option you can just read your capsules in any moment, if you have it shared
EOF
            ;;
        q|Q)
            return 0
            ;;
        *)
            el_error "Unknown message type option, canceling"
            return 0
            ;;
    esac

    # create shared marks
    if ((is_shared)) ; then
        mkdir -p "${shared_personal_d}/ttc/to_$_entity_email/$_message_option/${commit_id}"

        if [[ -n "$_mark_message" ]] ; then
            echo "${git_email}: $_mark_message" >> "${shared_personal_d}/ttc/to_$_entity_email/$_message_option/${commit_id}/message.txt"
        fi

        # mark position too
        echo -e "[$counter/$counter_total] " >> "${shared_personal_d}/ttc/to_$_entity_email/$_message_option/${commit_id}/position.txt"
    fi

}

#===  FUNCTION  ================================================================
#          NAME:  check_if_has_diverged
#   DESCRIPTION:  simple checker about if the branch has diverged
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
check_if_has_diverged(){
    if command git status | grep -iqs "your branch.*have diverged" ; then
        echo -e "" 1>&2
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        el_explain 0 "XXWarning: your branch has divergedXX"
        el_explain 0 "This can happen if you rebased some commits, so you can push --force to your remote if nobody else got your previous commits"
        el_explain 0 "You should check your git history and status XXmanuallyXX, exit from this tool and do it by yourself"
        el_explain 0 "This can probably happen if only a __branch was updated__ without all of them, a good solution to try is to pull from the entire remote, like for example: __git pull --rebase origin__"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "" 1>&2
    fi

}

#===  FUNCTION  ================================================================
#          NAME:  scan_travels
#   DESCRIPTION:  Scans available travels and allow to pick them
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
scan_travels(){
    # pre {{{
    el_debug
    if ! ((is_shared)) ; then
        el_explain 0 "Skipping scan for capsules, this watcher is not shared"
        return 0
    fi


    local _user _dir _email
    # }}}

    # loop for each user found
    echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
    echo -e "  ${el_c_gr}${el_c_blink}Scanning Time-Traveling Capsules...${el_c_n}"

    for _dir in "$shared_d"/*
    do
        [[ ! -d "$_dir" ]] && continue

        _email="$( basename "$_dir" )"
        _user="$( cat "$_dir/username.txt" )"
        _commit_id="$( cat "$_dir/last_commit_tracked" )"
        _commits_step="$( cat "$_dir/last_commit_tracked_progress" | awk '{print $1}' )"
        _commits_total="$( cat "$_dir/last_commit_tracked_progress" | awk '{print $2}' )"

        # skip our own user
        if [[ "${git_email}" = "$_email" ]] ; then
            continue
        fi

        # show available time-traveling capsules
        if el_check_dir_has_files "${_dir}/ttc/to_${git_email}/review" 2>/dev/null ; then
            _ttc_review=1
        fi

        if el_check_dir_has_files "${_dir}/ttc/to_${git_email}/questions" 2>/dev/null ; then
            _ttc_question=1
        fi


        # show info of only needed ones
        if ((_ttc_review)) || ((_ttc_question)) ; then
            # header nice image
            if [[ -n "$TERMINOLOGY" ]] ; then
                if [[ -s "$_dir/gravatar.png" ]] ; then
                    tycat "$_dir"/gravatar.png
                fi
            fi

            echo -e "..:: $_user ::.."
            #echo -e ""
            echo -e "email:   $_email"
            echo -e "step:    ${el_c_n}[${el_c_g}${_commits_step}${el_c_n}/${el_c_y}${_commits_total}${el_c_n}]${el_c_n}  (${_commit_id:0:12})"
        fi

        if ((_ttc_review)) ; then
            _ttc_counter="$( ls -1 "${_dir}/ttc/to_${git_email}/review" | wc -l )"
            #el_explain 0 "XX${_user}XX wants you to consider backporting XX${_ttc_counter}XX __commits__:"
            el_explain 0 "XX${el_c_underline}${_ttc_counter} Backporting requestsXX:"

            while read -ru 3 dir
            do
                [[ -d "$dir" ]] || continue

                _has_capsules=1
                _ttc_id_last="$( basename "$dir" )"

                echo -e "${el_c_b}ID:       ${el_c_g}${_ttc_id_last}${el_c_n}"

                if [[ -s "$dir/position.txt" ]] ; then
                    echo -en "${el_c_b}Position: ${el_c_y}"
                    cat "$dir/position.txt" 2>/dev/null
                fi
                if [[ -s "$dir/message.txt" ]] ; then
                    echo -e "${el_c_b}Message:  ${el_c_m2}"
                    cat "$dir/message.txt" 2>/dev/null
                fi
                echo -e "${el_c_n}"

            done 3<<< "$( find "${_dir}/ttc/to_${git_email}/review" -mindepth 1 -maxdepth 1 -type d )"
        fi

        if ((_ttc_question)) ; then
            _ttc_counter="$( ls -1 "${_dir}/ttc/to_${git_email}/questions" | wc -l )"
            #el_explain 0 "XX${_user}XX wants you to ask you XX${_ttc_counter}XX things about specific commits:"
            el_explain 0 "XX${el_c_underline}${_ttc_counter} QuestionsXX:"

            while read -ru 3 dir
            do
                [[ -d "$dir" ]] || continue

                _has_capsules=1
                _ttc_id_last="$( basename "$dir" )"

                echo -e "${el_c_b}ID:       ${el_c_g}${_ttc_id_last}${el_c_n}"

                if [[ -s "$dir/position.txt" ]] ; then
                    echo -en "${el_c_b}Position: ${el_c_y}"
                    cat "$dir/position.txt" 2>/dev/null
                fi
                if [[ -s "$dir/message.txt" ]] ; then
                    echo -e "${el_c_b}Message:  ${el_c_m2}"
                    cat "$dir/message.txt" 2>/dev/null
                fi
                echo -e "${el_c_n}"

            done 3<<< "$( find "${_dir}/ttc/to_${git_email}/questions" -mindepth 1 -maxdepth 1 -type d )"
        fi


        # done
        echo -e ""
    done

    # finished
    if ((_has_capsules)) ; then
        # fast way to read messages if only one
        if [[ "${_ttc_counter}" = "1" ]] && [[ -n "$_ttc_id_last" ]] ; then
            # only one question? directly go to it
            el_explain 0 "Let's __travel__ to $_ttc_id_last"

            go_to_commit "$_ttc_id_last"
        else
            go_to_commit
        fi
    else
        el_explain 0 "No messages for you"
    fi

}

#===  FUNCTION  ================================================================
#          NAME:  scan_marked_states
#   DESCRIPTION:  Scans and show marked states like todo's
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
scan_marked_states(){
    # pre {{{
    el_debug

    # }}}
    if ! el_check_dir_has_files "${conf_repo_d}/ttc" 2>/dev/null ; then
        return 0
    fi

    echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
    el_explain 0 "You have XXNew MessagesXX"


    while read -ru 3 dir
    do
        [[ -d "$dir" ]] || continue

        echo -e "${el_c_b}ID:       ${el_c_g}$(basename "$dir" )${el_c_n}"

        if [[ -s "$dir/message.txt" ]] ; then
            echo -en "${el_c_b}Message:  ${el_c_m2}"
            cat "$dir/message.txt" 2>/dev/null
            echo -e "${el_c_n}"
        fi

        el_explain 0 "You can travel to its __ID__ on the __g__ option"
        el_explain 0 "If you need external help you can go to it and send a message to somebody"

        if el_confirm "Delete it?" ; then
            rm -rf "$dir"
        fi


    done 3<<< "$( find "${conf_repo_d}/ttc/" -mindepth 1 -maxdepth 1 -type d )"


    #echo -e "Press Enter to continue..."
    #LC_ALL=C sleep 0.8
    #read nothing

}

#===  FUNCTION  ================================================================
#          NAME:  conf_share_setup
#   DESCRIPTION:  configure shares if not configured yet
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
conf_share_setup(){
    # pre {{{
    local arg
    el_debug

    # }}}
    # TODO: implementation:
    # - run an inotify in BG that prints el_explain's everytime founds a modification of X files, + read nada
    # - send email summarized to collaborators when we finish & save a session
    # - mark "points" to ask collaborators to review them, a message must be included, and options should be shown as resolved/unnaccepted, etc... which reverse notification
    # -
    #
    # TODO: show marks / messages, reviews, etc...
    # TODO: marks:
    #       - later / todo
    #       - review (accept / approve)
    #       - ask/suggest a cherry-pick
    #       - message to @who
    #       - positions (marks of commits should move you [temporally] to the marked position)


    # TODO: INBOX: show by default message to "you"


    # setup new shared conf
    if ! [[ -L "$conf_repo_d/shared" ]] ; then
        if el_confirm "Enable sharing features?" ; then
            # let's cowork!
            run_dropbox

            # dropbox shared dir
            local _dropbox_dir
            if [[ -n "$shared_main_d" ]] ; then
                _dropbox_dir="$shared_main_d"
            else
                _dropbox_dir="$( find-approximate-matching-homedir dropbox )"
                if [[ -e "$_dropbox_dir" ]] ; then
                    _dropbox_dir="$_dropbox_dir/git-watcher-shared-work"
                else
                    _dropbox_dir="$HOME/Dropbox/git-watcher-shared-work"
                fi
            fi

            # insert shared dir on dropbox, default name exist to ask for a new shared one (you don't want to share your main one with everybody)
            if [[ -d "$_dropbox_dir" ]] ; then
                echo -e "\nInsert a directory from your Dropbox folder to use it for the sharing features (insert a new one if you are creating a new share, or type an existing directory if you want to join a share. Use Tab to autocomplete paths)\nFor example: $_dropbox_dir"
                read -e shared_main_d
                if [[ -z "$shared_main_d" ]] ; then
                    echo -e "\nYou must type the directory path previously said:"
                    read -e shared_main_d
                fi
                if [[ -z "$shared_main_d" ]] ; then
                    echo -e "\nYou must insert the path of your dropbox shared directory for git-watcher, similar to the previous example"
                    read -e shared_main_d
                fi

                # remove extra leading blank chars
                read -r shared_main_d <<< "${shared_main_d%/}"

            else
                shared_main_d="${_dropbox_dir%/}"
            fi

            # verify
            if [[ "$shared_main_d" != /* ]] ; then
                el_error "A directory to share must be specified like in the example, aborting..."
                sleep 2
                return 0
            fi

            # join an existing share
            #if [[ -d "$shared_main_d" ]] && [[ "$( find "$shared_main_d" -mindepth 2 -maxdepth 2 -type d | grep "::.*::" | wc -l )" -gt 0 ]] ; then
            if [[ -d "$shared_main_d/$remote_working/$repo_id_shared" ]] ; then
                #if [[ "$( find "$shared_main_d" -mindepth 2 -maxdepth 2 -type d | grep "::.*::" | wc -l )" -gt 1 ]] ; then
                    #find "$shared_main_d" -mindepth 2 -maxdepth 2 -type d
                    #echo -e "\nType the name ^ of the wanted shared to use"
                    #read -e _link
                #else
                    #_link="$( find "$shared_main_d" -mindepth 2 -maxdepth 2 -type d | grep "::.*::" | tail -1 )"
                #fi
                _link="$shared_main_d/$remote_working/$repo_id_shared"

                # if has files, its already shared:
                if el_check_dir_has_files "$_link" ; then
                    ln -s "$_link" "$conf_repo_d/shared"
                    el_explain 0 "Your __shared environment__ is ready!"
                    el_explain 0 "Run again the tool __to start using it__..."
                fi

            else

                # create new share
                if [[ ! -d "$shared_main_d" ]] ; then
                    mkdir -p "$shared_main_d"
                    # add a small readme file
                    echo -e "This directory is used for share git-watcher projects, do not delete it, so it is used automagically by the git-watcher tool, you don't need to do anything with it, but you can manually modify things on it! There's no manual pages so use your intuition superpowers!" > "$shared_main_d/README.txt"
                fi

                # remote working place, needed for use as an identifier in the shares
                if [[ -z "$remote_working" ]] ; then
                    if [[ "$( command git remote -v | grep -F "(push)" | awk '{print $1}' | wc -l )" -gt 1 ]] ; then
                        echo -e "\nWhich one is the remote repo where you normally push your work that is shared with your collaborators?\n"
                        command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | column -t | awk '{$1 = "(id: "$1") "; print $0}'

                        echo -e "\nInsert remote repo:"
                        read -e remote_working

                        # translate remote-id to url, which is what we need
                        if command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | awk '{print $1}' | grep -qs "^$remote_working" ; then
                            remote_working="$( command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | grep "^$remote_working" | head -1 | awk '{$1 = ""; print $0}' )"
                        fi


                        # small check, just in case
                        if ! echo "$remote_working" | grep -qsE "(@|:|/)" ; then
                            el_error "Have you inserted the identifier instead of the remote URL? mmh... do it again:"
                            read -e remote_working
                        fi
                    else
                        remote_working="$( command git remote -v | grep -F "(push)" | sed -e 's|(push).*$||g' | head -1 | awk '{$1 = ""; print $0}' )"
                    fi

                    echo "$remote_working" > "$conf_remote_work_from_f"
                fi

                read -r remote_working <<< "$remote_working"
                remote_working="$( echo "$remote_working" | sed -e 's|/|%|g' )"


                # send invitations (+ instructions) via email
                echo -e "\nInsert a list of emails to send invitations to this watcher with the needed instructions (can be empty):"
                read -e _emails_invitations
                _emails_invitations="$( echo "$_emails_invitations" | tr ',' ' ' | tr ';' ' ' | tr ' ' '\n' | sort -u )"
                while read -ru 3 _email
                do
                    [[ -z "$_email" ]] && continue

                    el_explain 0 "Sending email to __${_email}__"
                    email-sender -q -t "$_email" -s "$git_username wants to share a $(basename $0) with you" -S "Instructions to join the git-watcher of <i style=\"color: #FC61B3;\">${git_email}</i>:" <<EOF
    <i>This could be one of the most amazing tools that you may have never see!</i>
    <ol>
        <li>Open your email with the Dropbox Shared invitation, your friend needs to give you Edit access to this directory first</li>
        <li>After, go to your git repository clone that references to <code>${remote_working//%/\/}</code>, and run from it the command: <strong>$(basename $0) $tool_arguments</strong> </li>
        <li>Then exit from git-watcher, saving the Session with the Shared features, and follow the instructions</li>
        <li>Now just run again '<strong>$(basename $0) $tool_arguments</strong>' to start using it in shared mode!</li>
    </ol>
EOF
                done 3<<< "$( echo "$_emails_invitations" | grep -F "@" )"


                # create location for this repository identifier
                if ! [[ -d "$shared_main_d/$remote_working/$repo_id_shared" ]] ; then
                    mkdir -p "$shared_main_d/$remote_working/$repo_id_shared"
                    el_explain 2 "created watcher reference in __$shared_main_d/$remote_working/${repo_id_shared}__"

                    # invite friends! (on this step because we are the first ones to use this share, dir not existed before)
                    if el_confirm "If you don't have Shared yet the '${shared_main_d##*/}' directory from your Dropbox with your collaborators you need to do it now, allowing them to make changes on it. Open Dropbox Web settings now?" ; then
                        { /etc/alternatives/x-www-browser "https://www.dropbox.com/home" & disown ; } 1>/dev/null 2>&1
                        sleep 5
                    fi
                fi

                # add the shared link
                ln -s "$shared_main_d/$remote_working/$repo_id_shared" "$conf_repo_d/shared"

                # instructions
                el_explain 0 "You are now ready to work with others on this shared watcher!"
                el_explain 0 "The next time that you work on this watcher, your collaborators will be __notified__ when using it too, and in the same way you __can continue__ from their updated steps"

            fi


            # include your user structured directory
            shared_d="$conf_repo_d/shared"
            shared_personal_d="$shared_d/$git_email"
            mkdir -p "$shared_personal_d"

            echo "$git_email" > "$shared_personal_d/email.txt"
            echo "$git_username" > "$shared_personal_d/username.txt"

            # save gravatar too, w00t!
            curl -s "http://www.gravatar.com/avatar/$( echo -n "$git_email" | awk '{print tolower($0)}' | tr -d '\n ' | md5sum --text | tr -d '\- ' )?s=64&d=404" > "$shared_personal_d/gravatar.png"
            if ! file "$shared_personal_d/gravatar.png" | grep -qsi "image" ; then
                rm -f "$shared_personal_d/gravatar.png"
            fi


            # sync our changes
            run_dropbox

            # save this conf as default
            echo "$shared_main_d" > "$conf_d/shared_main_default_dir.txt"

            # save shared confs at exit
            is_shared=1
        fi
    fi
}
#===  FUNCTION  ================================================================
#          NAME:  run_dropbox
#   DESCRIPTION:  run the dropbox daemon
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
run_dropbox(){
    # pre {{{
    el_debug

    el_dependencies_check "dropbox"

    # }}}
    if ! ps ux | grep -Fv grep | grep -qs "$HOME/\.dropbox-dist/.*dropbox" ; then
        el_explain 0 "Starting dropbox..."
        dropbox start -i  2>/dev/null 1>&2
        sleep 5
    fi
}

#===  FUNCTION  ================================================================
#          NAME:  position_save
#   DESCRIPTION:  mark our position
#    PARAMETERS:  commit_id
#       RETURNS:  -
#===============================================================================
position_save(){
    # mark our new position
    if [[ -n "$commit_id" ]] ; then
        el_array_member_add "$commit_id" "${commits_history[@]}" ; commits_history=("${_out[@]}")
        echo "$commit_id" > "$conf_commit_last_f"
        el_debug "stored '$commit_id' to '$conf_commit_last_f'"
    fi
}

#===  FUNCTION  ================================================================
#          NAME:  notify_success
#   DESCRIPTION:  notify that a step went successfully
#===============================================================================
notify_success(){
    if ((NOSOUND)) || [[ ! -e "/usr/share/sounds/elive/1up.wav" ]] ; then
        el_notify soft logo-elive "$(basename $0)" "Success"
    else
        if [[ -x "$( which paplay )" ]] ; then
            paplay --volume=45000 /usr/share/sounds/elive/1up.wav &
        else
            if [[ -x "$( which aplay )" ]] ; then
                aplay /usr/share/sounds/elive/1up.wav 1>/dev/null 2>&1 &
            fi
        fi
    fi
}

#===  FUNCTION  ================================================================
#          NAME:  go_to_commit
#   DESCRIPTION:  go to a commit position, and returns back on the normal history when finished
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
go_to_commit(){
    # pre {{{
    el_debug
    # }}}
    # FIXME: if we have a capsule, print it

    # save our real position
    _commit_id="$commit_id"

    # ask for ID if we are not requesting it directly
    if [[ -n "$1" ]] ; then
        commit_id="$1"
    else
        echo -e "Insert the ID to travel"
        read -e commit_id
    fi

    # check if space-time position exists
    if ! command git rev-parse "$commit_id" 1>/dev/null 2>&1 ; then
        el_error "This ID don't exist?"

        echo -e "Insert the commit-ID to go on"
        read -e commit_id

        if ! command git rev-parse "$commit_id" 1>/dev/null 2>&1 ; then

            el_error "Commit-id not found. Perhaps you need to update your repo first?"
            LC_ALL=C sleep 0.4

            el_explain 0 "restoring original ID..."
            # something went wrong so make sure the user read this rare-case moment
            sleep 1
            commit_id="$_commit_id"
            unset is_traveling

            return 0
        fi
    fi

    # we got an ID, so we are in
    is_traveling=1

    tycat "/usr/share/git-watcher/images/ttc.gif"

    # mark our new position
    #position_save

    # count our new position
    do_count_commits

    # shared things here? {{{
    for dir in "${shared_d}/"*"/ttc/to_${git_email}/questions"/*
    do
        [[ -d "$dir" ]] || continue

        _ttc_id="$( basename "$dir" )"
        _ttc_id_user="$( echo "$dir" | sed -e "s|^.*$shared_d/||g" -e "s|/ttc/.*$||" )"
        _ttc_id_user_email="$( cat "$shared_d/$_ttc_id_user/email.txt" )"

        if [[ "$commit_id" = "$_ttc_id" ]] ; then
            echo ""
            el_explain 0 "You have a question here:"

            echo -en "${el_c_m2}"
            cat "$dir/message.txt"
            echo -en "${el_c_n}"

            echo -e "Reply to $_ttc_id_user ? (empty for cancel)"
            read -e _mark_message

            if [[ -n "$_mark_message" ]] ; then
                mkdir -p "${shared_personal_d}/ttc/to_$_ttc_id_user/questions/${commit_id}"

                el_explain 0 "Sending email..."

                email-sender -q -t "$_ttc_id_user_email" -s "$git_username has answered you" -S "<i style=\"color: #FC61B3;\">${git_email}</i> thinks that:" <<EOF
<p><strong>
$_mark_message
</strong></p>
From your question about:
<ul>
$(cat "$dir/message.txt")
</ul>

To know more you need to take a <i>Time-Traveling Capsule</i> to join its universe, for that:

<ul>
<li>cd into your git copy of: '${remote_working}' <i>(${git_username} has it at: ${working_directory_d})</i></li>
<li>copy and run the command:$  <strong>$(basename $0) -w ${branch_working} $tool_arguments -g ${commit_id}</strong></li>
</ul>
EOF


                cat "$dir/message.txt" >> "${shared_personal_d}/ttc/to_$_ttc_id_user/questions/${commit_id}/message.txt"
                echo "${git_email}: $_mark_message" >> "${shared_personal_d}/ttc/to_$_ttc_id_user/questions/${commit_id}/message.txt"

                rm -rf "$dir"
            else
                if el_confirm "Delete ${_ttc_id_user}'s question-type capsule?" ; then
                    rm -rf "$dir"
                fi
            fi
        fi
    done
    # requests to deal with?
    for dir in "${shared_d}/"*"/ttc/to_${git_email}/review"/*
    do
        [[ -d "$dir" ]] || continue

        _ttc_id="$( basename "$dir" )"
        _ttc_id_user="$( echo "$dir" | sed -e "s|^.*$shared_d/||g" -e "s|/ttc/.*$||" )"

        if [[ "$commit_id" = "$_ttc_id" ]] ; then
            if el_confirm "Delete ${_ttc_id_user}'s backport-type capsule?" ; then
                rm -rf "$dir"
            fi
        fi
    done


    # - shared things here? }}}

    # and so, what you want to do now?
    options_main_interact

    # restore our original position
    travel_restore

}

#===  FUNCTION  ================================================================
#          NAME:  travel_restore
#   DESCRIPTION:  restores a possible traveled position
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
travel_restore(){
    # pre {{{
    el_debug

    # we should not be here
    if ! ((is_traveling)) ; then
        return 0
    fi

    if ! [[ -n "$_commit_id" ]] ; then
        el_error "You have not a location of origin in your passport for traveling? (prev commit-id)"
    fi

    # }}}

    tycat "/usr/share/git-watcher/images/ttc.gif"
    el_explain 0 "Restoring time-traveling position!"
    LC_ALL=C sleep 0.3

    # marks: delete
    if [[ -d "${conf_repo_d}/ttc/${commit_id}" ]] ; then

        if el_confirm "Delete marked state?" ; then
            if el_check_variables "conf_repo_d|commit_id" ; then

                rm -rf "${conf_repo_d}/ttc/${commit_id}"
                el_debug "deleted mark: '${conf_repo_d}/ttc/${commit_id}'"
            else
                el_error "Very fatal error, report it, we were going to rm -rf something wrong but this super smart application avoided it!"
            fi
        fi
    fi

    # Questions to deal with?
    # should create a new question with the previous question pre-pended? sounds like the easiest way
    for dir in "${shared_d}/"*"/ttc/to_${git_email}/questions"/*
    do
        [[ -d "$dir" ]] || continue

        _ttc_id="$( basename "$dir" )"
        _ttc_id_user="$( echo "$dir" | sed -e "s|^.*$shared_d/||g" -e "s|/ttc/.*$||g" )"
        _ttc_id_user_email="$( cat "$shared_d/$_ttc_id_user/email.txt" )"

        if [[ "$commit_id" = "$_ttc_id" ]] ; then
            echo ""
            el_explain 0 "You have a pending message:"

            echo -en "${el_c_m2}"
            cat "$dir/message.txt"
            echo -en "${el_c_n}"

            echo -e "Reply to $_ttc_id_user ? (empty for cancel)"
            read -e _mark_message

            if [[ -n "$_mark_message" ]] ; then
                mkdir -p "${shared_personal_d}/ttc/to_$_ttc_id_user/questions/${commit_id}"

                el_explain 0 "Sending email..."

                email-sender -q -t "$_ttc_id_user_email" -s "$git_username has answered you" -S "<i style=\"color: #FC61B3;\">${git_email}</i> thinks that:" <<EOF
<p><strong>
$_mark_message
</strong></p>
From your question about:
<ul>
$(cat "$dir/message.txt")
</ul>

To know more you need to take a <i>Time-Traveling Capsule</i> to join its universe, for that:

<ul>
<li>cd into your git copy of: '${remote_working}' <i>(${git_username} has it at: ${working_directory_d})</i></li>
<li>copy and run the command: $  <strong>$(basename $0) -w ${branch_working} $tool_arguments -g ${commit_id}</strong></li>
</ul>
EOF


                cat "$dir/message.txt" >> "${shared_personal_d}/ttc/to_$_ttc_id_user/questions/${commit_id}/message.txt"
                echo "${git_email}: $_mark_message" >> "${shared_personal_d}/ttc/to_$_ttc_id_user/questions/${commit_id}/message.txt"

                rm -rf "$dir"
            else
                if el_confirm "Delete ${_ttc_id_user}'s question-type capsule?" ; then
                    rm -rf "$dir"
                fi
            fi
        fi
    done
    # requests to deal with?
    for dir in "${shared_d}/"*"/ttc/to_${git_email}/review"/*
    do
        [[ -d "$dir" ]] || continue

        _ttc_id="$( basename "$dir" )"
        _ttc_id_user="$( echo "$dir" | sed -e "s|^.*$shared_d/||g" -e "s|/ttc/.*$||" )"

        if [[ "$commit_id" = "$_ttc_id" ]] ; then
            if el_confirm "Delete ${_ttc_id_user}'s backport-type capsule?" ; then
                rm -rf "$dir"
            fi
        fi
    done


    # we are back! let's restore
    commit_id="$_commit_id"

    # count our new position
    do_count_commits
    is_recount_position_needed=1

    # mark our back position
    #position_save

    unset is_traveling
}
#===  FUNCTION  ================================================================
#          NAME:  show_history
#   DESCRIPTION:  show last history if any
#    PARAMETERS:  [$1 = lines]
#       RETURNS:  -
#===============================================================================
show_history(){
    # pre {{{
    el_debug
    local lines

    # }}}
    el_explain 0 "History:"

    if [[ -n "$1" ]] ; then
        lines="$1"
        shift
    else
        lines="$( LC_ALL=C command git status | grep "ahead.*by.*commits" | sed -e 's|^.* by ||g' -e 's| commits.*$||g' )"
    fi

    if [[ -n "$lines" ]] ; then
        #lines="$(( $lines + 1 ))"
        el_explain 0 "Your __not pushed__ changes:"


        command git log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' --abbrev-commit --date=relative -$lines
    else
        lines=16
        el_explain 0 "Recent __${lines}__ history in your working branch (newest to oldest):"
        command git --no-pager log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' --abbrev-commit --date=relative -${lines}
        # seems like we miss a newline:
        echo

    fi
}

#===  FUNCTION  ================================================================
#          NAME:  show_states
#   DESCRIPTION:  shows our actual snapshoted states list available
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
show_states(){
    # pre {{{
    local _branch_working _keyword_search _files_search is_header_show _progress _commits_total _commits_remaining _commits_done _author_search _dir_sources

    el_check_variables "conf_d"
    el_check_dirs "$conf_d"
    # - pre }}}

    while read -ru 3 line
    do
        if [[ -d "$conf_d/$line" ]] ; then
            if ! ((is_header_show)) ; then
                #echo -e "Watchers:"
                #echo '---------'

                echo -e "${el_c_b}Watchers Tracking:${el_c_n}"
                echo -e "Progress: | From Branch: | To branch: | Options: | | Working Directory:"
                echo -e "|"

                is_header_show=1
            fi

            el_debug "entry is $line"

            _dir_sources="$(    echo "$line" | awk -F "::" '{print $1}' | sed -e 's|%|/|g' )"
            _branch_watch="$(   echo "$line" | awk -F "::" '{print $2}' )"
            _branch_working="$( echo "$line" | awk -F "::" '{print $3}' )"
            _options_before="$( echo "$line" | awk -F "::" '{print $4}' )"
            _options_after="$(  echo "$line" | awk -F "::" '{print $5}' )"

            _commits_remaining="$( echo "$( cat "$conf_d/$line/last_commit_tracked_progress" 2>/dev/null | tr ' ' '/'  )" )"


            if [[ "$_branch_working" = "$branch_working" ]] \
                && [[ "$_branch_watch" = "$branch_watch" ]] \
                && [[ "$_options_before" = "${options_extra_git_before[*]//\//%}" ]] \
                && [[ "$_options_after" = "${options_extra_git_after[*]//\//%}" ]] \
                ; then
                echo -e "${el_c_g} $_commits_remaining | $_branch_watch | $_branch_working | $_options_before | $_options_after | $_dir_sources  ${el_c_y}${el_c_n}"
            else

                if [[ -n "$_branch_working" ]] ; then

                    echo -e "$_commits_remaining | $_branch_watch | $_branch_working | $_options_before | $_options_after | $_dir_sources"

                fi
            fi


            unset _branch_working _keyword_search _files_search _author_search _commits_remaining _commits_total _progress
        fi
    done 3<<< "$( ls -1 "$conf_d" )"  | column -s $'|' -t
    # append space
    echo '' 1>&2

    # end
    echo '' 1>&2
}

#===  FUNCTION  ================================================================
#          NAME:  show_commit_stat
#   DESCRIPTION:  show the actual commit stat, good to "remember" where you are
#    PARAMETERS:  $1 = pre-git options
#       RETURNS:  -
#===============================================================================
show_commit_stat(){
    # pre {{{
    el_debug
    local pre_git_options

    el_check_variables "commit_id"
    pre_git_options="$1"

    # }}}
    # show actual position
    #echo -e "${el_c_y} [$counter/$counter_total] ${el_c_g} Position in remaining commits  ${el_c_n}"
    #echo -e "${el_c_y}[$counter/$counter_total] ${el_c_n}"

    # show actual commit-id
    if [[ -n "$keyword_search" ]] ; then
        # hilight the keyword to search
        command git $pre_git_options show --stat "$commit_id" | grep --color -Ei "^|$keyword_search|"
    else
        command git $pre_git_options show --stat "$commit_id"
    fi
}

#===  FUNCTION  ================================================================
#          NAME:  clear_screen
#   DESCRIPTION:  clears the screen
#    PARAMETERS:  $1 = default | interactive
#       RETURNS:  -
#===============================================================================
clear_screen(){
    # pre {{{
    local mode
    el_debug

    mode="$1"
    el_check_variables "mode"

    #if [[ "$counter" -gt "$counter_total" ]] || [[ "$counter" -le 0 ]] ; then
        #el_debug "not clearing the screen"
        #echo -e "\n\n"
        #return 0
    #fi

    # }}}
    case "$mode" in
        default)
            true
            ;;
        interactive)
            echo -e "\nPress Enter to continue..." 1>&2
            read nothing
            ;;
    esac

    if [[ "${EL_DEBUG}" -lt "3" ]] ; then
        # clear is not enough, if you scroll back you can see old things, reset is too slow, so let's put some huge separator instead
        echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
        echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
        echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

        clear
    else
        echo -e "\n\n\n\n\n\n\n"
    fi
}

#===  FUNCTION  ================================================================
#          NAME:  do_count_commits
#   DESCRIPTION:  counter of total commits to track
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
do_count_commits(){
    # pre {{{
    el_debug

    local _counter _counter_total _is_commit_id_last_reached

    el_check_variables "branch_working|branch_watch"

    unset _is_commit_id_last_reached
    _counter_total="$counter_total"
    _counter="$counter"

    # 1 means no commit, so calculate it correctly
    if [[ "$_counter_total" = 1 ]] ; then
        _counter_total=0
    fi

    counter_total=0
    counter=1

    if [[ "$1" = "force" ]] ; then
        unset commits_list
    fi
    # }}}
    # sometimes is slow, so show debug
    if [[ -z "$commits_list" ]] ; then
        echo -en "\r\033[K${el_c_b}Computing space time coordinates... ${el_c_n}"

        # precache the full commits list in a variable
        commits_list="$( command git log --format=format:'%H' ${options_extra_git_before[*]} --reverse "$branch_working".."$branch_watch" ${options_extra_git_after[*]} )"

        # pre-statistics a bit: show the amount of commits between branches
        while read -ru 3 line
        do
            counter_total="$(( $counter_total + 1 ))"

            # skip until last commit
            if [[ -n "$commit_id" ]] && ! ((_is_commit_id_last_reached)) ; then
                if [[ "$line" = "$commit_id" ]] ; then
                    _is_commit_id_last_reached=1
                else
                    # loop until we reach the desired commit
                    counter="$(( $counter + 1 ))"
                fi
            fi

            echo -en "\r\033[K${el_c_b}Computing space time coordinates: \t${el_c_y}[$counter/$counter_total]   ${el_c_n}"

        done 3<<< "$( echo "$commits_list" )"


        if [[ "$counter" -le "$counter_total" ]] ; then
            echo -en "\r\033[K${el_c_b}Computing space time coordinates: \t${el_c_y}[$counter/$counter_total]   ${el_c_n}"
        else
            echo -en "\r\033[K${el_c_b}Computing space time coordinates: \t${el_c_y}[???/$counter_total]   ${el_c_n}"
        fi
        echo ""
    fi


    # do we have found new commits?
    if [[ -n "$_counter_total" ]] ; then
        if ! [[ "$(( $counter_total - $_counter_total ))" = 0 ]] ; then
            el_explain 0 "Nice! XX$(( $counter_total - $_counter_total ))XX New commits found on this watcher!"
            echo "Press Enter to continue"
            read nothing
        fi
    fi

    if [[ "${counter}" -gt "${counter_total}" ]] ; then
        # show this on the counter tab instead, because this commit is out of our tracking line,
        # we will go back later so nothing to worry about
        counter="0"
    fi


    el_explain 3 "Recounted commits: counter is $counter, total commits is $counter_total"
}

#===  FUNCTION  ================================================================
#          NAME:  do_cherry_pick_menu
#   DESCRIPTION:  menu of options in cherry-pick state, useful when it fails
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
do_cherry_pick_menu(){
    # pre {{{
    el_debug

    # }}}

    echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
    option_show "s" "Show status"
    option_show "d" "Show actual diff"
    option_show "m" "mergetool (auto / smart mode)"
    option_show "M" "mergetool (manual / human mode)"
    option_show "e" "Edit modified files"
    option_show "l" "Login Shell"
    option_show "f" "Finish - return to main menu in any state"
    option_show "a" "Abort cherry-pick"
    option_show "c" "Continue cherry-pick in progress / Next commit"
    echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

    read -N 1 option
    echo

    case "$option" in
        s)
            command git status

            $FUNCNAME
            ;;
        d)  # show patch
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            command git status
            GIT_PAGER=cat  command git diff --cached
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            # return back to main menu
            $FUNCNAME

            ;;
        m)
            # add the conf if doesn't exist yet
            if ! grep -qs "mergetool.*meld-merge" "$HOME/.gitconfig" ; then
                # Set the default merge tool and conflict style
                git config --global merge.tool merge
                git config --global merge.conflictstyle diff3
                # add the good meld configuration for this mode
                git config --global mergetool.meld-merge.cmd "meld \$REMOTE \$BASE \$LOCAL -o \$MERGED --auto-merge --diff \$REMOTE \$BASE --diff \$LOCAL \$BASE --diff \$REMOTE \$MERGED \$LOCAL"
                # comment the code
sed -i '/\[mergetool "meld-merge"\]/!b; /\[mergetool "meld-merge"\]/a \
    ; When Merge (not rebase):\
    ;   upstream updates | merged | my changes\
    ;   - 2 tab:  my changes | old state\
    ;   - 3 tab:  upstream updates | old state\
    ; When Rebase: similar but in the inverse way (upstream VS my changes)\
    ; INFO: is much better to use merge than rebase: because in rebase we need to resolve the conflicts in the same way, but we need to do it for each commit, so is much more work, "merge" instead shows the conflicts of the final result only and so to adapt it is much easier. Also, rebase rewrites the history and on merge I can always go back to see how it was the history before when it worked in previous versions of my modifications.\
    ;' ~/.gitconfig


            fi

            # run the mergetool
            command git mergetool -t meld-merge

            # show differences
            GIT_PAGER=cat  command git diff --cached --ignore-all-space

            # mergetool can success or not, so ask again what to do
            $FUNCNAME
            ;;

        M)
            if ! grep -qs "mergetool.*meld-manual" "$HOME/.gitconfig" ; then
                # Set the default merge tool and conflict style
                git config --global merge.tool merge
                git config --global merge.conflictstyle diff3
                # add the good meld configuration for this mode
                git config --global mergetool.meld-manual.cmd "meld \$LOCAL \$MERGED \$REMOTE --output \$MERGED --diff \$BASE \$MERGED \$REMOTE --diff \$LOCAL \$BASE \$REMOTE --diff \$REMOTE \$BASE --diff \$LOCAL \$BASE"
                # comment the code
                sed -i '/\[mergetool "meld-manual"\]/!b; /\[mergetool "meld-manual"\]/a \
    ; Note: This version ensures that no auto merges have been made, and it shows demos of the other differences in the merge attempt.\
    ; It is much more difficult than the auto merge, and the auto merge should show enough information to avoid confusion,\
    ; but this version ensures that **all** the differences are seen.\
    ;\
    ; Explanation:\
    ; 1. TAB: Left is the original file, right is the changes to import. You should place them in the middle file.\
    ; 2. TAB: Original content that tried to be merged into the middle.\
    ; 3. TAB: Demo history of changes that should happen; left is the original file, right is the commit from.\
    ; 4. TAB: Demo of what lacks from our commit to import into our half-merged contents.\
    ; 5. TAB: Demo of what was tried to change (half-merged) in our local file.\
    ;' ~/.gitconfig


            fi

            # run the mergetool
            command git mergetool -t meld-manual

            # show differences
            GIT_PAGER=cat  command git diff --cached --ignore-all-space

            # mergetool can success or not, so ask again what to do
            $FUNCNAME
            ;;

        e)  # edit files
            # TODO: enter in the specific lines if vim
            if [[ -z "$EDITOR" ]] ; then
                echo -e "Type the editor (command) that you want to use:"
                read -e EDITOR
            fi

            # edit files
            $EDITOR $( command git status --porcelain | awk '{print $2}' | paste -s -d " " - )

            # update contents
            command git add -u

            # show differences
            GIT_PAGER=cat  command git diff --cached --ignore-all-space

            # mergetool can success or not, so ask again what to do
            $FUNCNAME
            ;;
        l)
            shell_start

            $FUNCNAME
            ;;
        c)
            # TODO: improve this option, is not easy to find (far on the list, we need an option for "accepted merge" or similar, more intuitive)
            # TODO: check the options, we don't want to write a message probably, do we also want to use the option -x ?
            if command git cherry-pick --continue --no-edit ; then
                # fix possible whitespace issues
                command git rebase --whitespace=fix HEAD~1

                # store actual position for future calls of this tool
                position_save

                # make a list of the commits that we have already imported
                if ! grep -qs "^${commit_id}$" "${conf_imported_commits_list_f}" ; then
                    echo "$commit_id ${branch_working}" >> "$conf_imported_commits_list_f"
                    if ((is_shared)) ; then
                        echo "$commit_id ${branch_working}" >> "${conf_imported_commits_list_shared_f}"
                    fi
                fi

                # return to the main menu since we continued successfully
                true
            else
                $FUNCNAME
            fi

            # show differences
            GIT_PAGER=cat  command git show --pretty=format: --patch HEAD

            ;;

        f)
            true
            ;;

        a|z) # shortcut to "a" too if we want to call it as "abort"
            command git cherry-pick --abort

            el_explain 0 "Aborted cherry-pick..."
            LC_ALL=C sleep 1.2

            ;;

        *)
            # return back to main menu because you picked a wrong option accidentally
            echo -e "wrong option?"
            sleep 1
            $FUNCNAME
            return
            ;;

    esac

    # remove unwanted .orig files remaining
    if command git status -su | grep -e"\.orig$" ; then
        command git status -su | grep -e"\.orig$" | cut -f2 -d" " | xargs rm -f 2>/dev/null
    fi

}
#===  FUNCTION  ================================================================
#          NAME:  do_cherry_pick
#   DESCRIPTION:    run a cherry-pick to the commit_id variable, run helpers if something fails
#===============================================================================
do_cherry_pick(){
    # pre {{{
    el_debug

    # }}}

    if ! do_compare_before_after "$commit_id" ; then
        if ! el_confirm "Import anyways?" ; then
            return 0
        fi
    fi

    el_explain 0 "git cherry-pick --keep-redundant-commits -Xpatience -x -s '$commit_id'"
    if command git cherry-pick --keep-redundant-commits -Xpatience -x -s "$commit_id" ; then
        # fix possible whitespace issues
        command git rebase --whitespace=fix HEAD~1

        if [[ "$( command git diff --unified=0 HEAD~1 | wc -l )" = 0 ]] ; then
            # last import shows an empty diff, like it was already included in the history or is a useless commit for our branch
            el_explain 0 "\nXXWarning:XX seems like this commit didn't changed anything, probably because the code was already imported, you can keep it for historical purposes or you can remove it to have a more clean history."
            show_history 3
            if el_confirm "Remove it?" ; then
                command git reset --quiet --hard HEAD~1
            fi
        else
            # correctly imported

            command git --no-pager show

            notify_success
            el_explain 0 "__Successfully applied!__\n\n"
            #el_explain 0 "If you need to __add related__ commits in more cherry-picks, use the list-nearest feature and give the commits in a list to the multiple-cherry-pick feature"

            #echo -e "Press Enter to continue"
            #read nothing
            #sleep 1
        fi
        # store actual position for future calls of this tool
        position_save

        # make a list of the commits that we have already imported
        if ! grep -qs "^${commit_id}$" "${conf_imported_commits_list_f}" ; then
            echo "$commit_id ${branch_working}" >> "$conf_imported_commits_list_f"
            if ((is_shared)) ; then
                echo "$commit_id ${branch_working}" >> "${conf_imported_commits_list_shared_f}"
            fi
        fi

        el_debug "stored '$commit_id' to '$conf_commit_last_f'"

    else
        el_error "Oops, cherry-pick failed! select an option now:"

        do_cherry_pick_menu
    fi

    # ammend the commit with the previous one and use the previous commit message
    if [[ "$1" = "amend" ]] ; then
        # keeps your changes in the staging area (index), so you can easily amend the commit.
        command git reset --soft HEAD~1
        command git commit -q --amend --no-edit
    fi


    show_history
    LC_ALL=C sleep 0.4

}

#===  FUNCTION  ================================================================
#          NAME:  do_cherry_pick_multiple
#   DESCRIPTION:  do cherry-picking of multiple commits
#    PARAMETERS:  $1 = comma-separated list of commit-ids to cherry-pick
#       RETURNS:  -
#===============================================================================
do_cherry_pick_multiple(){
    # pre {{{
    local commits
    el_debug

    commits="$1"
    commits="${commits//,/ }"

    # }}}

    if [[ -n "$commits" ]] ; then
        el_explain 0 "command git cherry-pick --keep-redundant-commits -x -s $commits"

        if command git cherry-pick --keep-redundant-commits -x -s $commits  ; then
            # fix possible whitespace issues
            command git rebase --whitespace=fix HEAD~1

            notify_success
            el_explain 0 "__Successfully applied!__  Press Enter to continue"
            read nothing
        else
            el_error "Oops, cherry-pick failed! select an option now:"

            do_cherry_pick_menu
        fi

        show_history
    fi
}

#===  FUNCTION  ================================================================
#          NAME:  do_compare_before_after
#   DESCRIPTION:  create two directories with only the modified files
#                 after and before to import a commit, useful to see differences
#    PARAMETERS:  $1 = commit_id (or commits, with comma)  to import
#       RETURNS:  true if there's differences, false if not
#===============================================================================
do_compare_before_after(){
    # pre {{{
    local commits _commit_id commit_id commits_amount
    unset file files
    el_debug

    commits="$*"
    commits="${commits//,/ }"

    commits_amount="$( echo "$commits" | wc -w )"
    commit_first="${commits%% }"

    # }}}

    # remove the previously modified files
    rm -rf "$tmpdir/sources_BEFORE" "$tmpdir/sources_AFTER" "$tmpdir/sources_NEWCLEAN"
    mkdir -p "$tmpdir/sources_BEFORE" "$tmpdir/sources_AFTER" "$tmpdir/sources_NEWCLEAN"

    # update temporal code copy
    el_explain 0 "Updating temporal copy on '${tmpdir_sources}'..."
    if el_check_dir_has_files "${tmpdir_sources%/}/" ; then
        rsync -aq --delete "${working_directory_d%/}/" "${tmpdir_sources%/}/"
    else
        rm -rf "${tmpdir_sources%/}/" 1>/dev/null 2>&1 || true
        cp -a --reflink=auto "${working_directory_d%/}/" "${tmpdir_sources%/}/"
    fi

    # get the before state
    cd "$tmpdir_sources"
    if [[ "${#commits_history[@]}" = "1" ]] && [[ "$commits_amount" = "1" ]] ; then
        # fetch the previous commit to the actual (unique) one in order to know the previous state
        _commit_id="$( command git log --pretty=%P -n 1 "$( echo "${commits_history[@]}" | tail -n 1 )" | head -n 1 )"
    else
        if [[ "${#commits_history[@]}" -gt $commits_amount ]] ; then
            _commit_id="${commits_history[$(( ${#commits_history[@]} - 1 - $commits_amount ))]}"
        else
            _commit_id="$( echo "$commits_list" | grep -B 1 "${commit_first}" | head -1 )"

            command git log --oneline --abbrev=12 --graph --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' ${options_extra_git_before[*]} "$branch_working".."$branch_watch" ${options_extra_git_after[*]} | grep --color -C 8 "${commit_first:0:12}"
            if ! el_confirm "Warning: feature not fully tested: we are using the first commit "${commit_first}" of the list as ID to know the previous one in order to compare states SINCE this one: '${_commit_id}', '${#commits_history[*]} -gt $commits_amount' , is this correct?" ; then
                return 1
            fi
        fi
    fi

    el_explain 0 "Fetching previous state '${_commit_id}'"
    command git checkout --quiet "${_commit_id}" 1>/dev/null

    # save files before to apply the commit
    for commit_id in ${commits} ; do
        while read -ru 3 file
        do
            printf "%s\n" "$file" | cpio --quiet -padu -- "$tmpdir/sources_BEFORE"
        done 3<<< "$( git --no-pager show "$commit_id" | lsdiff | sed -e 's|^a/||g' -e 's|^b/||g' )"
    done

    # apply the commits
    if ! command git cherry-pick --keep-redundant-commits -Xpatience -x -s $commits 1>/dev/null ; then
        el_error "failed using: git cherry-pick --keep-redundant-commits -Xpatience -x -s $commits"
        shell_start
    fi

    # save files after to apply the commit
    for commit_id in ${commits} ; do
        while read -ru 3 file
        do
            printf "%s\n" "$file" | cpio --quiet -padu -- "$tmpdir/sources_AFTER"
            el_array_member_add "$file" "${files[@]}" ; files=("${_out[@]}")
        done 3<<< "$( git --no-pager show "$commit_id" | lsdiff | sed -e 's|^a/||g' -e 's|^b/||g' )"
    done

    # remove the temporally imported commit
    command git reset --quiet --hard HEAD~${commits_amount}

    # go back to original directory
    cd "$working_directory_d"

    # make a copy of the new sources to include in the diff to always visualize them if we make (auto) modifications
    while read -ru 3 file
    do
        printf "%s\n" "$file" | cpio --quiet -padu -- "$tmpdir/sources_NEWCLEAN"
    done 3<<< "$( echo "${files[@]}")"

    # return result
    if [[ "$( diff --color=never -Naur "$tmpdir/sources_BEFORE" "$tmpdir/sources_AFTER" | lsdiff | wc -l )" -ge 1 ]] ; then
        return 0
    else
        echo -e "${el_c_b}No differences found${el_c_n}"
        return 1
    fi

}

# starts a temporal shell to manual work
shell_start(){
    el_explain 0 "XXStarted login shellXX, use ^d or logout when you finish to return back here"

    $SHELL -l
}
#===  FUNCTION  ================================================================
#          NAME:  option_show
#   DESCRIPTION:  show an option to pick in a nice-colored way
#    PARAMETERS:  $1 = char, $2 = description
#       RETURNS:  -
#===============================================================================
option_show(){
    # pre {{{
    local char
    local description

    char="$1"
    description="$2"
    el_check_variables "char"

    # }}}

    echo -e "${el_c_c} ${char}  ${el_c_g}${description}${el_c_n}"

}

#===  FUNCTION  ================================================================
#          NAME:  options_main_interact
#   DESCRIPTION:
#    PARAMETERS:  -
#       RETURNS:  -
#===============================================================================
options_main_interact(){
    # pre {{{
    el_debug
    local _counter_show

    if ((is_recount_position_needed)) ; then
        return 0
    fi
    # }}}
    if [[ "${counter}" = "0" ]] ; then
        _counter_show="out of this universe"
    else
        _counter_show="$counter"
    fi

    echo -e ""
    #echo -e "${el_c_y} [$counter/$counter_total] ${el_c_g} Position in remaining commits  ${el_c_n}"
    if ((is_traveling)) ; then
        echo -e "${el_c_b}-----------------------${el_c_gr}(${el_c_m}parallel reality${el_c_gr})${el_c_b}--------${el_c_y}[${el_c_g}$_counter_show${el_c_y}/$counter_total]${el_c_b}-----${el_c_n}"
    else
        echo -e "${el_c_b}-----------------------------------------------------${el_c_y}[$_counter_show/$counter_total]${el_c_b}-----${el_c_n}"
    fi
    echo -e "${el_c_y}   OPTIONS: ${el_c_n}"
    option_show "n"         "Next commit"
    option_show "p"         "Prev commit" # history-based now
    option_show "s"         "Show commit summary"
    option_show "S"         "Show Status info"
    option_show "h"         "History show"
    option_show "d"         "Show diff"
    option_show "D"         "Show diff of your last working commit"
    option_show "a"         "list Around nearest commits (on our working progress)"
    option_show "A"         "list Around nearest commits (from the watching branch)"
    option_show "i"         "Import this commit (cherry-pick)"
    option_show "I"         "Import this commit merging with the previous one (cherry-pick)"
    option_show "o"         "Import other or multiple commits (cherry-pick)"
    if [[ -n "$user_input_backport_branches" ]] ; then
        option_show "b"         " > Backport to: $user_input_backport_branches"
    else
        option_show "b"         "Backport to other branches too (define them as comma-separated)"
    fi
    option_show "e"         "Edit the files affected by the last commit"
    option_show "E"         "Edit visually the compared changes"
    option_show "v"         "Visualize (and edit) how the contents would change if we import them"
    option_show "V"         "Visualize an Edit with auto merge"
    option_show "H"         "Helper AI: get help from AI to import this commit"
    option_show "f"         "Fix (edit) our last commit description (--amend)"
    option_show "F"         "Fix the history of last commits (rebase interactive)"
    option_show "m"         "Mark, adds a mark on this position, to review later"
    option_show "M"         "Message, questions and requests to others"
    option_show "r"         "Read Capsules"
    option_show "g"         "Go to commit id (space-time travel)"
    option_show "G"         "Go to a counter position"
    option_show "u"         "Update working branch (pull --rebase)"
    option_show "U"         "Update watching branch (pull --rebase)"
    option_show "P"         "Push changes"

    option_show "c"         "compile (make), useful for check if new code is compatible"
    if [[ -n "$user_input_command" ]] ; then
        #option_show "r"     " > Run:  $user_input_command"
        option_show "C"     " > Compile:  $user_input_command"
    else
        option_show "C"         "own Command to run (ex: make && sudo make install && enlightenment_remote -restart)"
    fi
    option_show "l"         "Login Shell (to do things manually)"
    option_show "B/R"       "Backup / Restore directory state (bkp tool)" # bkp is the best option for not mess up things, can be slow but it has also incrememental saving states too

    option_show "z"         "Undo last commit in your working branch"
    #if [[ -e "$conf_repo_d/flags/persistent_watcher" ]] ; then
        option_show "Z"         "Delete this watcher"
    #fi
    option_show "q"         "Quit"
    if [[ ! -e "$conf_repo_d/flags/persistent_watcher" ]] || [[ ! -L "$conf_repo_d/shared" ]] ; then
        option_show "Q"         "Quit & Save progress"
    fi
    echo -e "${el_c_b}================================================================${el_c_n}"

    if grep -qs "^${commit_id}" "$conf_imported_commits_list_f" "${conf_imported_commits_list_shared_f}"  2>/dev/null ; then
        echo -e ""
        el_explain 0 "XXNoteXX: this commit was __already imported__, to the branch __$(grep "^$commit_id" "${conf_imported_commits_list_f}" "${conf_imported_commits_list_shared_f}" 2>/dev/null | tail -1 | awk '{print $2}' )__"
        echo -e ""
    fi

    check_if_has_diverged

    # select an option {{{
    #read -N 1 option

    # alternative to previous "read", this option makes possible to skip multichars entries tripling the loop for when you use inputs like "up arrow", it basically cleans the input to a single entry and accepts only alpha/numeric values
    local _c _d
    while read -N 1 _c
    do
        while read -t 0
        do read -N1 _d
            _c+=$_d
        done
        option="$( printf "%q" "$_c" | grep --color=never -E "^[[:alnum:]]$" )"
        break
    done

    el_debug "option picked is: '$option'"
    echo

    # }}}

    case "$option" in
        r)  # read messages / capsules
            scan_travels

            # go back to main menu
            $FUNCNAME

            ;;

        n)  # Next commit
            #el_explain 0 "Saving last commit watched"
            position_save
            return 0

            ;;
        p)  # Prev commit
            # FIXME: we can go BACKWARDS 0 and -1 -2 -3... make a check in the main "while true" loop for not be able to go before the first commit
            # FIXME: (in E's git we have a bkp saved that includes only one commit about the XDG issue, not 2 ones, we need to "bkp g" to this state in order to reproduce this problem)
                # so there is, go to that state and use the option "U" to update the watching branch, it founds 1 new commit, but then it should show that we are in the commit 11/13 (if we was in 11/12 previously) but instead it tells us that we are in 14/13, wrong!!!!
                # FIXME 2: there's also another problem: when updating with the option "U" it doesn't include the force-update that we did, and it shows a "branch diversion" message, we need to HILIGHT it and warn the user, requesting him to investigate the issue, which should be probably fixed with a simple "git pull --rebase REMOTE" (not-including the branch seems like to accept the force-update)

            if ((is_traveling)) ; then
                # so we return from who called it, which is go_to_commit
                return 0
            fi

            # use history mode if available which is faster than recount log
            if [[ "${#commits_history[@]}" -gt 1 ]] ; then
                # delete our actual position in the history (so the last element in array is the previous position)
                el_array_member_unset "$commit_id" "${commits_history[@]}" ; commits_history=("${_out[@]}")
                # set the commit to go as the previous one:
                commit_id="${commits_history[$(( ${#commits_history[@]} - 1 ))]}"
                el_debug "history mode (${#commits_history[@]})"
            else
                if [[ "${#commits_history[@]}" -le 1 ]] ; then
                    unset commits_history
                fi
                # get the previous commit id
                commit_id="$( echo "$commits_list" | grep -B 1 "$commit_id" | head -1 )"
            fi

            position_save

            # set the counter to count another commit remaining
            counter="$(( $counter - 1 ))"

            # exit loop if no remaining commits
            if [[ "$counter" -le 0 ]] ; then
                el_explain 0 "You cannot go before the creation of the universe!"
                sleep 3
            fi

            # cleanup
            clear_screen default

            # go back to positioning loop
            is_recount_position_needed=1
            return 0


            ;;
        g)  # go to commit id
            go_to_commit

            # go back to main menu
            $FUNCNAME

            ;;
        G)  # go to a jumping mode commit

            echo -e "\n${el_c_g}Type a number of the counter to jump:${el_c_n}"
            read -e _n

            if echo "$_n" | grep -v "[[:alpha:]]" | grep -qs "[[:digit:]]" ; then

                commit_id="$( echo "$commits_list" | head -n "$_n" | tail -1 )"

                # mark our new position
                unset commits_history
                position_save

                # count to the actual jump
                counter="$_n"
                # exit loop if no remaining commits
                if [[ "$counter" -le 0 ]] ; then
                    el_explain 0 "You cannot go before the creation of the universe!"
                    sleep 3
                fi

                # always remove one, because we return 0
                counter="$(( $counter + -1 ))"

                # cleanup
                clear_screen default

                # go back to positioning loop
                is_recount_position_needed=1
                return 0
            else
                el_error "You need to insert a numeric value in the range of the watching commits"
                sleep 2
                $FUNCNAME
            fi


            ;;
        u)  # update working branch

            # which remote to fetch from?
            if [[ -z "$remote_fetching_working" ]] ; then
                if [[ "$( command git remote -v | grep "(fetch)" | awk '{print $1}' | wc -l )" -gt 1 ]] ; then
                    echo -e "\nWhich remote ID you want to track the changes on '$branch_working' from? (empty cancels)\n"
                    command git remote -v | grep "(fetch)" | sed -e 's|(fetch).*$||g' | column -t | awk '{$1 = "(id: "$1") "; print $0}'

                    read -e remote_fetching_working
                else
                    remote_fetching_working="$(command git remote -v | grep "(fetch)" | awk '{print $1}' | head -1 )"
                fi

                echo "$remote_fetching_working" > "$conf_remote_fetch_working_from_f"
            fi

            #el_explain 0 "git pull --rebase $remote_fetching_working $branch_working"
            el_explain 0 "git pull --rebase \"$remote_fetching_working\" \"+${branch_working}:refs/remotes/${remote_fetching_working}/${branch_working}\""
            #command git pull --rebase "$remote_fetching_working" "$branch_working"  # don't use this method, leads to diverged branches
            command git pull --quiet --rebase "$remote_fetching_working" "+${branch_working}:refs/remotes/${remote_fetching_working}/${branch_working}"
            sleep 2
            check_if_has_diverged

            # update total of commits
            do_count_commits "force"
            is_recount_position_needed=1

            # return back to main menu
            $FUNCNAME

            ;;
        U)  # update watching branch

            # which remote to fetch from?
            if [[ -z "$remote_fetching_watch" ]] ; then
                if [[ "$( command git remote -v | grep "(fetch)" | awk '{print $1}' | wc -l )" -gt 1 ]] ; then
                    echo -e "\nWhich remote ID you want to track the changes on '$branch_watch' from ?\n"
                    #command git remote -v | grep "(fetch)" | awk '{print $1}'
                    command git remote -v | grep "(fetch)" | sed -e 's|(fetch).*$||g' | column -t | awk '{$1 = "(id: "$1") "; print $0}'

                    read -e remote_fetching_watch
                else
                    remote_fetching_watch="$(command git remote -v | grep "(fetch)" | awk '{print $1}' | head -1 )"
                fi

                echo "$remote_fetching_watch" > "$conf_remote_fetch_watch_from_f"
            fi


            el_explain 0 "git checkout $branch_watch"
            command git checkout --quiet "$branch_watch"

            #el_explain 0 "git pull --rebase $remote_fetching_watch $branch_watch"
            el_explain 0 "git pull --rebase \"$remote_fetching_watch\" \"+${branch_watch}:refs/remotes/${remote_fetching_watch}/${branch_watch}\""
            #command git pull --rebase "$remote_fetching_watch" "$branch_watch"  # buggy method
            command git pull --rebase "$remote_fetching_watch" "+${branch_watch}:refs/remotes/${remote_fetching_watch}/${branch_watch}"
            sleep 2
            check_if_has_diverged

            # go back to our working one
            el_explain 0 "git checkout $branch_working"
            command git checkout --quiet "$branch_working"
            check_if_has_diverged


            # update total of commits
            do_count_commits "force"
            is_recount_position_needed=1

            # return back to main menu
            $FUNCNAME

            ;;
        s)  # show info
            # show actual commit-id
            show_commit_stat


            # return back to main menu
            $FUNCNAME
            ;;
        S)  # show detailed info
            echo -e "\n\n\n\n\n\n\n\n\n\n\n"
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            # show history
            show_history
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            # show status
            el_explain 0 "Status:"
            command git status

            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            # show actual commit-id
            show_commit_stat

            # return back to main menu
            $FUNCNAME
            ;;

        h)  #history
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            # show history
            show_history
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            # return back to main menu
            $FUNCNAME

            ;;
        d)  # show patch
            clear_screen default
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            command git --no-pager show "$commit_id" | lsdiff
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            command git show "$commit_id"
            # return back to main menu
            $FUNCNAME

            ;;

        D)  # show diff
            clear_screen default
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            command git --no-pager show HEAD | lsdiff
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            command git show --pretty=format: --patch HEAD

            # return back to main menu
            $FUNCNAME

            ;;
        e)  # edit files
            if [[ -z "$EDITOR" ]] ; then
                echo -e "Type the editor (command) that you want to use:"
                read -e EDITOR
            fi

            # edit files
            $EDITOR $(git --no-pager show "$commit_id" | lsdiff | sed -e 's|^a/||g' -e 's|^b/||g' | tr '\n' ' ' )

            if [[ "$( command git diff --unified=0 HEAD~1 | wc -l )" -gt 0 ]] ; then
                command git diff
                if el_confirm "Save your modifications into the previous commit?" ; then
                    command git add -u
                    command git commit --amend --no-edit
                fi
            fi

            # show back the diff, we always want to see it again
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"
            command git --no-pager show "$commit_id" | lsdiff
            echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

            command git --no-pager show "$commit_id"

            # return back to main menu
            $FUNCNAME

            ;;

        E)  # edit files
            el_info "Showing the diff between: sources_before, sources_after, sources_new"
            if do_compare_before_after "$commit_id" ; then
                meld --diff "$tmpdir/sources_BEFORE" "$tmpdir/sources_AFTER" "$( pwd )" \
                    --diff "$tmpdir/sources_AFTER" "$( pwd )" "$tmpdir/sources_NEWCLEAN"
            fi

            if el_confirm "Run a git commit to save your changes?" ; then
                command git add -u
                command git commit
            fi


            # return back to main menu
            $FUNCNAME

            ;;
        f)  # edit the last commit description
            command git commit -q --amend
            # return back to main menu
            $FUNCNAME

            ;;
        F)  # edit the last history
            command git rebase --interactive "${branch_parent}"
            # return back to main menu
            $FUNCNAME

            ;;
        v)  # edit (visualize) how the contents would change if we import it
            el_info "Showing the diff between the original sources and the modified ones (not actual new sources)"
            if do_compare_before_after "$commit_id" ; then
                # compare files
                diff -Naur "$tmpdir/sources_BEFORE" "$tmpdir/sources_AFTER" | colordiff
                meld "$tmpdir/sources_BEFORE" "$tmpdir/sources_AFTER"
            fi


            # return back to main menu
            $FUNCNAME

            ;;
        V)  # edit files with auto merge
            el_info "Showing a smart diff between the:  sources_Before, sources_After, and the sources_New with the automated merging\n  + includes tabs for: sources_Before vs sources_After\n  + sources_After vs sources_New\n  + sources_NewClean vs sources_New"
            if do_compare_before_after "$commit_id" ; then
                while read -ru 3 file
                do
                    [[ ! -s "$file" ]] && continue
                    [[ ! -e "$file" ]] && continue
                    file="$( echo "$file" | sed -e "s|^.*${tmpdir}/sources_BEFORE/||g" )"

                    meld \
                        "$tmpdir/sources_BEFORE/$file" "$( pwd )/$file"  "$tmpdir/sources_AFTER/$file"\
                        --output "$( pwd )/$file" --auto-merge \
                        --diff "$tmpdir/sources_BEFORE/$file" "$tmpdir/sources_AFTER/$file" \
                        --diff "$tmpdir/sources_AFTER/$file" "$( pwd )/$file" \
                        --diff "$tmpdir/sources_NEWCLEAN/$file" "$( pwd )/$file"


                done 3<<< "$( find "${tmpdir}/sources_BEFORE" -type f )"
            fi

            if [[ "$( command git diff --unified=0 HEAD~1 | wc -l )" -gt 0 ]] ; then
                if el_confirm "Run a git commit to save your changes?" ; then
                    command git add -u
                    command git commit
                fi
            fi


            # return back to main menu
            $FUNCNAME

            ;;
        H)  # edit files with auto merge
            pwd="$(pwd)"

            # dependencies
            if ! el_dependencies_check "aider" ; then
                el_error "Aider is not installed, install it first and configure it: pipx install aider-chat"
                return 1
            fi
            if [[ -z "$ai_model" ]] ; then
                el_info "Type the model you want to use:"
                echo -e "
  gemini-pro                | (best overall quality)
  gemini-flash              | (fast, large files)
  deepseek                  | (middle quality, cheap)
  sonnet                    | (from Claude, very good quality, more expensive)
  4o                        | (from OpenAI, good quality, average price)
  o1-mini / o1-preview      | (from OpenAI, very good quality, much more expensive)
  "
                read ai_model

            fi

            EL_REPORTS=0  el_warning "Temporal code with 3 different ways to generate the NEW patch, try all of them manually commenting the other blocks of code and running a meld to see which option generates the best results in order to keep it as selected option"


            # my original code
            if do_compare_before_after "$commit_id" ; then
                while read -ru 3 file
                do
                    [[ ! -s "$file" ]] && continue
                    [[ ! -e "$file" ]] && continue
                    file="$( echo "$file" | sed -e "s|^.*${tmpdir}/sources_AFTER/||g" )"
                    ext="${file##*.}"

                    # cleanup
                    rm -rf "${tmpdir}/helper_ai"
                    mkdir -p "${tmpdir}/helper_ai"

                    # copy files
                    cp -f "$tmpdir/sources_BEFORE/$file" "${tmpdir}/helper_ai/source_file_before.${ext}"
                    cp -f "$tmpdir/sources_AFTER/$file" "${tmpdir}/helper_ai/source_file_after.${ext}"
                    cp -f "$(pwd)/$file" "${tmpdir}/helper_ai/source_file_NEW_to_modify.${ext}"

                    # prepare environment
                    cd "$tmpdir/helper_ai"
                    diff -Nau "source_file_before.${ext}" "source_file_after.${ext}" > "source_file_patch.diff"
                    rm -f "source_file_before.${ext}" "source_file_after.${ext}"

                    rm -rf .git
                    git init .
                    git add *
                    git commit -m init

                    aider \
                        --code-theme monokai \
                        --git \
                        --lint-cmd 'c:cppcheck' \
                        --no-attribute-author \
                        --no-attribute-commit-message-author \
                        --no-attribute-commit-message-committer \
                        --no-auto-commits \
                        --no-auto-test \
                        --no-check-update \
                        --no-gitignore \
                        --yes \
                        --model ${ai_model} \
                        source_file*  \
                        --message "I have an old source code modification that I want to import again in the new upstream code that changed a bit. My patch is the file 'source_file_patch.diff' and I need to implement these changes into the file 'source_file_NEW_to_modify.${ext}'. Only modify 'source_file_NEW_to_modify.${ext}'. Don't tell me about any compile instructions, commands to run, or anything similar, just do the modifications for the source code file and only that."
                        # --message "I have an old source code modification that I want to import again in the new upstream clean code. The original file was 'source_file_before.${ext}', my patch is the file 'source_file_patch.diff', they needss to be imported now into the file 'source_file_NEW_to_modify.${ext}'. Only modify 'source_file_NEW_to_modify.${ext}'. Don't tell me any compile instructions or anything else, just do the modifications for the source code file."
                done 3<<< "$( find "${tmpdir}/sources_AFTER" -type f )"
            fi

            ## improved version 1
            # if do_compare_before_after "$commit_id" ; then
            #     while read -ru 3 file
            #     do
            #         [[ ! -s "$file" ]] && continue
            #         [[ ! -e "$file" ]] && continue
            #         file="$( echo "$file" | sed -e "s|^.*${tmpdir}/sources_AFTER/||g" )"
            #         ext="${file##*.}"
            #
            #         # Verificar que el archivo existe en el directorio actual
            #         if [[ ! -f "$(pwd)/$file" ]]; then
            #             el_warning "File '$file' not found in current directory, skipping"
            #             continue
            #         fi
            #
            #         # cleanup
            #         rm -rf "${tmpdir}/helper_ai"
            #         mkdir -p "${tmpdir}/helper_ai"
            #
            #         # copy files
            #         cp -f "$tmpdir/sources_BEFORE/$file" "${tmpdir}/helper_ai/source_file_before.${ext}"
            #         cp -f "$tmpdir/sources_AFTER/$file" "${tmpdir}/helper_ai/source_file_after.${ext}"
            #         cp -f "$(pwd)/$file" "${tmpdir}/helper_ai/source_file_NEW_to_modify.${ext}"
            #
            #         # prepare environment
            #         cd "$tmpdir/helper_ai"
            #
            #         # Generate patch with context
            #         diff -Nau "source_file_before.${ext}" "source_file_after.${ext}" > "source_file_patch.diff"
            #
            #         # Create a summary of key differences between old and new code
            #         {
            #             echo "KEY DIFFERENCES BETWEEN OLD AND NEW CODE:"
            #             echo "=========================================="
            #             echo "File: $file"
            #             echo ""
            #             echo "Structural changes detected:"
            #             # Extract function/class name changes
            #             diff -u "source_file_before.${ext}" "source_file_NEW_to_modify.${ext}" | \
            #                 grep -E '^[-+][^-+]' | head -10 | sed 's/^/  /'
            #                                 echo ""
            #                                 echo "Patch to apply (from old version):"
            #                                 cat "source_file_patch.diff"
            #                             } > "context_summary.txt"
            #
            #                             rm -f "source_file_before.${ext}" "source_file_after.${ext}"
            #
            #                             rm -rf .git
            #                             git init .
            #                             git add *
            #                             git commit -m init
            #
            #         # Improved AI prompt with better context
            #         aider \
            #             --code-theme monokai \
            #             --git \
            #             --lint-cmd 'c:cppcheck' \
            #             --no-attribute-author \
            #             --no-attribute-commit-message-author \
            #             --no-attribute-commit-message-committer \
            #             --no-auto-commits \
            #             --no-auto-test \
            #             --no-check-update \
            #             --no-gitignore \
            #             --yes \
            #             --model "${ai_model}" \
            #             source_file* context_summary.txt \
            #             --message "I need to adapt an old patch to new code. Here's the context:
            #
            #         1. OLD CODE: The original code that was modified (source_file_before.${ext} -> source_file_after.${ext})
            #         2. PATCH: The specific changes made (source_file_patch.diff)
            #         3. NEW CODE: The current code that needs updating (source_file_NEW_to_modify.${ext})
            #         4. CONTEXT: Key differences between old and new versions (context_summary.txt)
            #
            #         Please analyze the logical intent of the patch and apply equivalent changes to the NEW CODE. Focus on:
            #         - Understanding WHAT the patch does functionally, not just the literal changes
            #         - Adapting the changes to the new code structure
            #         - Maintaining the same behavior/logic in the new context
            #
            #         Only modify 'source_file_NEW_to_modify.${ext}'. Output only the modified code, no explanations."
            #
            #         # Copy back the modified file if it was changed
            #         if [[ -f "source_file_NEW_to_modify.${ext}" ]] && \
            #             ! cmp -s "source_file_NEW_to_modify.${ext}" "$pwd/$file"; then
            #                         cp -f "source_file_NEW_to_modify.${ext}" "$pwd/$file"
            #                         el_info "Updated: $file"
            #                     else
            #                         el_info "No changes needed for: $file"
            #         fi
            #
            #     done 3<<< "$( find "${tmpdir}/sources_AFTER" -type f )"
            # fi

            ## improved version 2
#             if do_compare_before_after "$commit_id" ; then
#                 # Get context from user about the patch purpose
#                 el_info "Please provide context about what this patch does:"
#                 echo -e "\nWhat problem does this patch solve or what functionality does it add?"
#                 read -p "Patch purpose: " patch_purpose
#                 echo -e "\nWhat behavior changes should be preserved?"
#                 read -p "Behavior description: " patch_behavior
#
#                 # Create a context file that will be used for all files
#                 mkdir -p "${tmpdir}/helper_ai"
#                 cat > "${tmpdir}/helper_ai/patch_context.md" << EOF
# # PATCH ADAPTATION CONTEXT
#
# ## PATCH PURPOSE
# $patch_purpose
#
# ## EXPECTED BEHAVIOR
# $patch_behavior
#
# ## ADAPTATION INSTRUCTIONS
# 1. Analyze the semantic intent of the original patch
# 2. Find equivalent components in the new code structure
# 3. Preserve the business logic, not necessarily the syntax
# 4. Maintain consistency with the new code's patterns and style
# 5. Only modify the target file, don't change other files
#
# ## IMPORTANT
# - Focus on semantic equivalence, not textual similarity
# - The new code may have different architecture/structure
# - Adapt the change to fit the new context appropriately
# EOF
#
#                 while read -ru 3 file
#                 do
#                     [[ ! -s "$file" ]] && continue
#                     [[ ! -e "$file" ]] && continue
#
#                     file_relative="$( echo "$file" | sed -e "s|^.*${tmpdir}/sources_AFTER/||g" )"
#                     ext="${file_relative##*.}"
#
#                     # Check if file exists in current directory
#                     if [[ ! -f "$(pwd)/$file_relative" ]]; then
#                         el_warning "File '$file_relative' doesn't exist in current directory, skipping..."
#                         continue
#                     fi
#
#                     # cleanup and setup per-file directory
#                     file_workspace="${tmpdir}/helper_ai/${file_relative//\//_}"
#                     rm -rf "$file_workspace"
#                     mkdir -p "$file_workspace"
#
#                     # copy files with better naming
#                     cp -f "$tmpdir/sources_BEFORE/$file_relative" "$file_workspace/OLD_before_patch.${ext}"
#                     cp -f "$tmpdir/sources_AFTER/$file_relative" "$file_workspace/OLD_after_patch.${ext}"
#                     cp -f "$(pwd)/$file_relative" "$file_workspace/NEW_target_to_modify.${ext}"
#                     cp -f "${tmpdir}/helper_ai/patch_context.md" "$file_workspace/"
#
#                     # prepare diff and analysis
#                     cd "$file_workspace"
#                     diff -Nau "OLD_before_patch.${ext}" "OLD_after_patch.${ext}" > "patch_changes.diff"
#
#                     # Create a summary of what changed in the original patch
#                     cat >> "patch_context.md" << EOF
# ## FILE-SPECIFIC CONTEXT
# File: $file_relative
# Original changes: $(wc -l < patch_changes.diff) lines modified
#
# ### ORIGINAL CHANGES SUMMARY:
# $(grep '^+' patch_changes.diff | head -10 | sed 's/^+/  Added: /' | head -5)
# $(grep '^-' patch_changes.diff | head -10 | sed 's/^-/  Removed: /' | head -5)
# EOF
#
#                     # Initialize git repo
#                     rm -rf .git
#                     git init -q
#                     git add -A
#                     git commit -q -m "initial"
#
#                     el_info "Processing: $file_relative"
#
#                     # Use improved prompt with semantic context
#                     aider \
#                         --code-theme monokai \
#                         --git \
#                         --lint-cmd 'c:cppcheck' \
#                         --no-attribute-author \
#                         --no-attribute-commit-message-author \
#                         --no-attribute-commit-message-committer \
#                         --no-auto-commits \
#                         --no-auto-test \
#                         --no-check-update \
#                         --no-gitignore \
#                         --yes \
#                         --model "${ai_model}" \
#                         . \
#                         --message "I need to adapt an old patch to new code with different structure.
#
#         CONTEXT: Read 'patch_context.md' first to understand the patch purpose.
#
#         FILES:
#         - 'OLD_before_patch.${ext}': Original code before patch
#         - 'OLD_after_patch.${ext}': Original code after patch
#         - 'patch_changes.diff': Exact changes made in original patch
#         - 'NEW_target_to_modify.${ext}': New code where changes need adaptation
#
#         TASK: Apply the semantic intent of the original patch to 'NEW_target_to_modify.${ext}'. The new code may have different structure, so focus on preserving behavior, not syntax.
#
#         RULES:
#         1. Only modify 'NEW_target_to_modify.${ext}'
#         2. Adapt to the new code's architecture and style
#         3. Preserve the business logic from the original patch
#         4. Don't explain, just output the modified code
#         "
#
#                     # Copy back the modified file if aider succeeded
#                     if [[ -f "NEW_target_to_modify.${ext}" ]] && [[ -s "NEW_target_to_modify.${ext}" ]]; then
#                         cp -f "NEW_target_to_modify.${ext}" "$(pwd)/$file_relative"
#                         el_success "Updated: $file_relative"
#                     else
#                         el_error "Failed to process: $file_relative"
#                     fi
#
#                 done 3<<< "$( find "${tmpdir}/sources_AFTER" -type f )"
#
#                 # Also check for files that were deleted in the patch
#                 el_info "Checking for files that might have been deleted in original patch..."
#                 while read -ru 3 file
#                 do
#                     file_relative="$( echo "$file" | sed -e "s|^.*${tmpdir}/sources_BEFORE/||g" )"
#                     if [[ ! -f "${tmpdir}/sources_AFTER/$file_relative" ]] && [[ -f "$(pwd)/$file_relative" ]]; then
#                         el_warning "File '$file_relative' was deleted in original patch but exists in current code. Consider manual review."
#                     fi
#                 done 3<<< "$( find "${tmpdir}/sources_BEFORE" -type f )"
#             fi
#



            cd "$pwd"
            if [[ "$( command git diff --unified=0 HEAD~1 | wc -l )" -gt 0 ]] ; then
                if el_confirm "Run a git commit to save your changes?" ; then
                    command git add -u
                    command git commit
                fi
            fi


            # return back to main menu
            $FUNCNAME

            ;;
        i)  # cherry-pick
            do_cherry_pick

            # separator
            echo -e "\n\n"

            # go to next commit
            return 0
            ;;

        I)  # cherry-pick
            do_cherry_pick amend

            # separator
            echo -e "\n\n"

            # go to next commit
            return 0
            ;;

        o)  # cherry-pick

            # first:  list around nearest
            el_explain 0 "(commits from oldest to newest)"
            command git log --oneline --abbrev=12 ${options_extra_git_before[*]} "$branch_working".."$branch_watch" ${options_extra_git_after[*]} | tac | grep --color -C 20 "${commit_id:0:12}"

            el_explain 0 "Give a list of spaces-separated commits to cherry-pick in earlier-order"
            el_explain 0 "Use the 'listing-nearest' feature to show more commits. Empty value will skip the action"

            read _commits

            do_cherry_pick_multiple "$_commits"

            # show the last commit, to make sure that we know where we are
            show_commit_stat --no-pager

            # return back to main menu
            $FUNCNAME

            ;;
        b)  # extra branches where to backport
            if [[ -z "$user_input_backport_branches" ]] ; then
                echo -e "Set the name of the branches which you want to backport too, ex. ${branch_working}-dev"
                read -e user_input_backport_branches
            fi

            if [[ -n "$user_input_backport_branches" ]] ; then
                while read -ru 3 branch
                do
                    if ! command git checkout --quiet "$branch" ; then
                        el_error "branch '$branch' doesn't exist, create it first"
                        break
                    fi
                    do_cherry_pick
                done 3<<< "$( echo "$user_input_backport_branches" | tr ',' '\n' )"

                command git checkout --quiet "$branch_working"
            else
                el_explain 0 "Skipping..."
                sleep 1
            fi

            # return back to main menu
            $FUNCNAME
            ;;
        m)
            el_explain 0 "TODO / mark added"

            echo -e "\nMessage to include?  (blank = ignore)"
            read -e _mark_message

            # create mark
            mkdir -p "${conf_repo_d}/ttc/${commit_id}"

            if [[ -n "$_mark_message" ]] ; then
                echo "$_mark_message" >> "${conf_repo_d}/ttc/${commit_id}/message.txt"
            fi

            # return back to main menu
            $FUNCNAME

            ;;
        M)

            # create messages for other users
            shared_messages_create

            # return back to main menu
            $FUNCNAME

            ;;
        z)  # undo

            # show our actual commit
            show_history
            echo ""

            if el_confirm "Do you want to permanently remove the last (first line) commit?" ; then
                el_explain 0 "$ git reset --hard HEAD~1"
                command git reset --quiet --hard HEAD~1
                # delete it from the list of the ones we have imported too
                sed -i "s|$commit_id ${branch_working}||g" "$conf_imported_commits_list_f" 2>/dev/null
                sed -i "/^$/d" "$conf_imported_commits_list_f" 2>/dev/null
                # shared confs too
                if [[ -s "$conf_imported_commits_list_shared_f" ]] ; then
                    sed -i "s|${commit_id}.*$||g" "$conf_imported_commits_list_shared_f" 2>/dev/null
                    sed -i "/^$/d" "$conf_imported_commits_list_shared_f" 2>/dev/null
                fi
            fi

            # return back to main menu
            $FUNCNAME
            ;;
        Z)  # delete this watcher
            el_explain 0 "removing directory \"${conf_repo_d}\""
            rm -rf "${conf_repo_d}"
            el_explain 0 "Watcher removed, you can create it again as: __$(basename $0) ${tool_arguments}__"
            exit 0
            ;;
        c)  # make
            if make ; then
                el_explain 0 "__Compiled Correctly__"
            else
                el_explain 0 "XXCompilation FailedXX"
            fi


            #el_speak_text "make complete"
            # return back to main menu
            $FUNCNAME
            ;;
        C)  # command specific
            if [[ -z "$user_input_command" ]] ; then
                echo -e "\nEnter the command that you want to use:"
                echo -e "Example:  make && sudo make install && enlightenment_remote -restart"
                read -e user_input_command
            fi

            if [[ -n "$user_input_command" ]] ; then
                if ! bash -c "$user_input_command" ; then
                    el_speak_text "error, compilation failed"
                else
                    el_speak_text "compilation finished successfully"
                fi
            fi

            # return back to main menu
            $FUNCNAME
            ;;
        a)  #  list around nearest
            el_explain 0 "nearest commits to your actual position in our working branch:"

            el_explain 2 "command git log --oneline --abbrev=12 --graph --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' ${options_extra_git_before[*]} \"$branch_working\"..\"$branch_watch\" ${options_extra_git_after[*]} | grep --color -C 25 \"${commit_id:0:12}\""
            command git log --oneline --abbrev=12 --graph --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' ${options_extra_git_before[*]} "$branch_working".."$branch_watch" ${options_extra_git_after[*]} | grep --color -C 25 "${commit_id:0:12}"

            el_explain 0 "list showed from newest to oldest"


            # return back to main menu
            $FUNCNAME
            ;;
        A)  # list Around nearest commits full
            el_explain 0 "nearest commits to your actual position in the watching branch history:"

            el_explain 2 "command git log --oneline --abbrev=12 --graph --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' ${options_extra_git_before[*]} \"$branch_watch\" | grep --color -C 25 \"${commit_id:0:12}\""

            command git log --oneline --abbrev=12 --graph --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(bold white)%an%C(reset) %C(white)— %s%C(reset)%C(bold yellow)%d%C(reset)' ${options_extra_git_before[*]} "$branch_watch" | grep --color -C 25 "${commit_id:0:12}"

            el_explain 0 "list showed from newest to oldest"

            # return back to main menu
            $FUNCNAME
            ;;
        l)  # shell
            shell_start

            # return back to main menu
            $FUNCNAME

            ;;
        B)  # bkp
            EL_DEBUG=1 bkp --quiet save

            # return back to main menu
            $FUNCNAME
            ;;
        R)  # bkp
            EL_DEBUG=1 bkp --quiet get

            # return back to main menu
            $FUNCNAME
            ;;
        P)  # push
            command git push

            # return back to main menu
            $FUNCNAME
            ;;
        Q)  # quit

            # ask if save
            if ! [[ -e "$conf_repo_d/flags/persistent_watcher" ]] ; then
                # add a mark to know that this is a persistent watcher to save
                touch "$conf_repo_d/flags/persistent_watcher"

                # save some needed info
                echo "$branch_working" > "$conf_branch_working_f"
            fi

            # ask if share, only if we are saving session
            if [[ -e "$conf_repo_d/flags/persistent_watcher" ]] ; then
                if ! [[ -L "$conf_repo_d/shared" ]] ; then
                    # ask and conf about sharing session
                    conf_share_setup
                fi
            fi

            exit

            ;;
        q) # quit
            exit
            ;;


        # LAST option
        *)
            # return back to main menu because you picked a wrong option accidentally
            echo -e "wrong option?"
            sleep 1
            $FUNCNAME
            ;;
    esac
}
#===  FUNCTION  ================================================================
#          NAME:  usage_show
#===============================================================================
usage_show(){
    echo ""
    echo -e "$(basename $0) is an amazing GIT tool that gives you multiple features, being especially useful to maintain forks, track changes in source codes, backport features between branches, and investigate things in the history of changes" 1>&2

    #echo -e "Important notes: " 1>&2
    #echo -e " - watching states will be saved and can be shareable among collaborators, check the '${conf_d}' dir" 1>&2
    #echo -e " - the last-commit ID is memorized, based on the directory-name/working-branch/keyword name" 1>&2

    echo -e ""
    echo -e "Options:"
    option_show "-b" "Branch from where you want to track changes"
    option_show "-w" "Branch on which you are working to"
    option_show "-c" "Commit descriptions, search for that keyword, for example 'fix'"
    option_show "-k" "Keyword search in code differences (note: may be slow)"
    option_show "-K" "Keyword search in code differences (case sensitive)"
    option_show "-a" "Author (committer) of commits to search, useful for track changes from somebody (name/email, one word)"
    option_show "-f" "Files/dirs which to track changes only, comma-separated, ex: 'src/bin/e_border.c,src/bin/e_win.c'"
    echo -e ""
    option_show "-g" "Go to commit-id (temporally)"
    echo -e ""
    option_show "Notes: use -s to not playing sound notifications"


    echo -e ""
    echo -e "Example of a new watcher: $(basename $0) -b master -k backports" 1>&2
    echo -e "To delete an existing watcher just remove the dir reference in .git-watcher" 1>&2

    echo -e ""

    show_states
}

main(){
    # version of this tool
    tool_version="1.4"
    tool_arguments="$@"
    # pre {{{

    # get the working branch name
    branch_working="$( command git symbolic-ref HEAD 2>/dev/null | sed 's|refs/heads/||' )"
    working_directory_d="$( pwd )"

    if [[ -z "$branch_working" ]] ; then
        el_error "You are not in a git repository, this tool is meant to be used from a git repo"
        exit 1
    fi

    tmpdir="/tmp/.$(basename $0)-$( basename $(pwd) )-${USER}"
    tmpdir_sources="/tmp/.$(basename $0)-${USER}/sources"
    rm -rf "$tmpdir" "$tmpdir_sources"
    mkdir -p "$tmpdir" "$tmpdir_sources"

    if ! el_dependencies_check "rsync|git|bkp|email-sender" ; then
        exit 1
    fi

    # }}}
    # input parameters {{{

    while getopts "b:w:c:k:K:a:f:g:s:" opt ; do
        case "$opt" in
            b)
                branch_watch="$OPTARG"
                ;;
            w)
                branch_working="$OPTARG"
                ;;
            c)
                keyword_search="$OPTARG"
                el_array_member_add "-i" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "-E" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "--grep" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "$keyword_search" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                ;;
            k)
                keyword_search="$OPTARG"
                el_array_member_add "-G" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "$keyword_search" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                ;;
            K)
                keyword_search="$OPTARG"
                el_array_member_add "-i" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "-G" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "$keyword_search" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                ;;
            a)
                # better to be case-insensitive
                author_search="$OPTARG"
                # more than one word don't works in our getargs, so just use one
                if echo "$author_search" | grep -qs "\ " ; then
                    el_explain 0 "XXWarningXX: there's a space included in your author's name, you can use its email instead which is a single word, continuing using: __${author_search%% *}__"
                fi
                author_search="${author_search%% *}"
                #options_extra_git_before="--committer='$author_search' $options_extra_git_before"
                el_array_member_add "-i" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "--committer" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                el_array_member_add "$author_search" "${options_extra_git_before[@]}" ; options_extra_git_before=("${_out[@]}")
                ;;
            f)
                files_search="$OPTARG"
                el_array_member_add "--" "${options_extra_git_after[@]}" ; options_extra_git_after=("${_out[@]}")

                while read -ru 3 file
                do
                    if [[ -d "$file" ]] ; then
                        # append a / at the end of the entry, force it to not have wrongly duplicated sessions
                        el_array_member_add "${file%/}/" "${options_extra_git_after[@]}" ; options_extra_git_after=("${_out[@]}")
                    else
                        el_array_member_add "${file}" "${options_extra_git_after[@]}" ; options_extra_git_after=("${_out[@]}")
                    fi

                done 3<<< "$( echo "${files_search//,/ }" | tr ' ' '\n' )"

                ;;
            g)
                travel_commit_id="$OPTARG"
                is_travel_wanted=1
                ;;
            s)
                export NOSOUND=1
                ;;
            \?|*)
                echo ""
                #echo "Invalid option" 1>&2
                usage_show
                exit
                ;;
            :)
                echo ""
                #echo "Option -$OPTARG requires an argument" 1>&2
                usage_show
                exit
                ;;
        esac
    done

    # check if we are at night, note: we need a better way to configure this (from desktop)
    hour="$(date +%k)"
    if [[ "${hour}" -ge "21" ]] || [[ "$hour" -lt "8" ]] ; then
        export NOSOUND=1
    fi

    branch_parent="$( command git show-branch | sed "s/].*//" | grep "\*" | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed "s/^.*\[//" )"
    # get the first commit from the working branch
    if [[ -z "$branch_parent" ]] ; then
        branch_parent="$( command git rev-list --first-parent ${branch_working} | tail -1 )"
    fi

    # - input parameters }}}
    # configurations saved {{{
    conf_d="$HOME/.config/$(basename $0)"

    # checks {{{

    if ! el_check_dirs "$conf_d" 2>/dev/null ; then
        mkdir -p "$conf_d"
    fi

    if el_check_variables "branch_working|branch_watch" 2>/dev/null ; then
        el_explain 0 "Branch tracking from: __${branch_watch}__"
        el_explain 0 "Branch to work on:    __${branch_working}__"
        if [[ "${branch_watch}" = "${branch_working}" ]] ; then
            el_explain 0 "XXWarning:XX Branch tracking is the same as where you are working on, you may not see any commit because you are comparing the same thing"
        fi
    else
        usage_show
        exit
    fi

    # check if we have checkoutable the watching branch too
    # update: we may not need to checkoutable, just access (like when a branch is just fetched)
    if ! command git branch -va | awk '{print $1}' | grep -v "remotes/" | grep -qsw "$branch_watch" ; then
        el_explain 0 "Pre-checking out: __${branch_working}__"
        #command git checkout --quiet "${branch_watch}"
        command git checkout --quiet "${branch_working}"
    fi
    # force checkout in the working branch
    if ! [[ "$( command git symbolic-ref HEAD 2>/dev/null | sed 's|refs/heads/||' )" = "$branch_working" ]] ; then
        branch_working_prev="$( command git symbolic-ref HEAD 2>/dev/null | sed 's|refs/heads/||' )"
        el_explain 0 "checking on: __${branch_working}__"
        command git checkout --quiet "${branch_working}"
    fi

    # }}}

    # append keyword in conf file if we have it
    working_directory_identifier="$( pwd | sed -e 's|/|%|g' )"
    # XXX update show_states too if you change this:
    repo_id="${working_directory_identifier}::${branch_watch}::${branch_working}::${options_extra_git_before[*]//\//%}::${options_extra_git_after[*]//\//%}"
    repo_id_shared="${branch_watch}::${branch_working}::${options_extra_git_before[*]//\//%}::${options_extra_git_after[*]//\//%}"
    conf_repo_d="${conf_d}/${repo_id}"

    mkdir -p "$conf_repo_d/flags"
    mkdir -p "$conf_repo_d/ttc"

    conf_commit_last_f="${conf_repo_d}/last_commit_tracked"
    conf_imported_commits_list_f="${conf_repo_d}/commits_imported_list"
    conf_commit_last_progress_f="${conf_repo_d}/last_commit_tracked_progress"
    conf_remote_fetch_working_from_f="${conf_repo_d}/remote_fetching_working_from"
    conf_remote_fetch_watch_from_f="${conf_repo_d}/remote_fetching_watch_from"
    conf_remote_work_from_f="${conf_repo_d}/remote_fetching_from"
    conf_branch_working_f="${conf_repo_d}/branch_working_for"
    tool_version_f="${conf_repo_d}/version_tool.txt"

    # - configurations saved }}}
    # version tool {{{
    el_check_variables "tool_version"
    if [[ -s "$tool_version_f" ]] ; then
        tool_version_watcher="$( tail -1 "$tool_version_f" 2>/dev/null )"
    else
        tool_version_watcher="$tool_version"
        echo "$tool_version" > "${tool_version_f}"
    fi

    # upgrade required
    if dpkg --compare-versions "$tool_version_watcher" gt "$tool_version" ; then
        el_package_update_last_version "elive-tools"
        el_error "Your $(basename $0) has been upgraded, run it again"

        exit
    fi

    # our tool is newer, manual upgrade required
    if dpkg --compare-versions "$tool_version_watcher" lt "$tool_version" ; then
        # prev conf dir:
        _conf_repo_d="${conf_repo_d}.old_v$tool_version_watcher"

        # do a backup for meld if wanted
        cp -a "${conf_repo_d}" "${_conf_repo_d}"
        el_explain 0 "XXWarning:XX your watcher confs needs to be upgraded, you can __manually__ merge later your old dir bits (first exit saving session) using meld as:  $  __meld \"${_conf_repo_d}\" \"${conf_repo_d}\"__"

        echo -e "\nPress Enter to continue..." 1>&2
        read nothing


        # migration upgrade cases (auto hooks): {{{
        while true
        do
            case "$tool_version_watcher" in
                1\.1)
                    # this version just needs to remove a file
                    el_explain 0 "Dummy / test upgrade state"
                    tool_version_watcher="1.2"
                    ;;
                1\.2)
                    # this version just needs to remove a file
                    set -x
                    rm -f "${conf_d}/version.txt"
                    rm -f "${conf_repo_d}/remote_fetching_from"
                    set +x

                    el_explain 0 "removed wrong files (you can safely continue)"
                    tool_version_watcher="1.3"
                    ;;
                1\.3)
                    # we moved to a different dir structure, pwd is needed on repo_id
                    el_explain 0 "entirely restructure was needed"

                    tool_version_watcher="1.3"
                    ;;
                *)
                    el_explain 0 "Nothing more to __automatically__ upgrade"
                    break
                    ;;
            esac
        done

        echo -e "\nPress Enter to continue..." 1>&2
        read nothing


        # }}}

        # update version number
        echo "$tool_version" > "$tool_version_f"
    fi


    # }}}
    # configurations get {{{


    # last commit
    if [[ -s "$conf_commit_last_f" ]] ; then
        commit_id="$( tail -1 "$conf_commit_last_f" )"

        # always know the parent commit of the actual one in order to avoid bugs like in the visualize feature run in the startup
        commit_id_prev="$( command git log "${commit_id}^1" -n 1 --format=%H )"
        #commit_id_prev="$( command git log --pretty=%P -n 1 "${commit}" | head -n 1 )"
        if [[ -n "$commit_id_prev" ]] ; then
            el_array_member_add "$commit_id_prev" "${commits_history[@]}" ; commits_history=("${_out[@]}")
        fi

        el_array_member_add "$commit_id" "${commits_history[@]}" ; commits_history=("${_out[@]}")
    fi


    # remote fetching
    if [[ -s "$conf_remote_fetch_working_from_f" ]] ; then
        remote_fetching_working="$( tail -1 "$conf_remote_fetch_working_from_f" )"
    fi
    if [[ -s "$conf_remote_fetch_watch_from_f" ]] ; then
        remote_fetching_watch="$( tail -1 "$conf_remote_fetch_watch_from_f" )"
    fi
    # remote working
    if [[ -s "$conf_remote_work_from_f" ]] ; then
        remote_working="$( tail -1 "$conf_remote_work_from_f" )"
    fi


    # branch working
    if [[ -s "$conf_branch_working_f" ]] ; then
        _branch_working="$( tail -1 "$conf_branch_working_f" )"
        if [[ "$branch_working" != "$_branch_working" ]] ; then
            el_explain 0 "XXWarningXX: you have already a watcher like this, but your actual working branch is __${branch_working}__ and not __${_branch_working}__"
            if el_confirm "Want to switch to $_branch_working ?" ; then
                branch_working="${_branch_working}"
                command git checkout --quiet "$branch_working"
                check_if_has_diverged
            fi
        fi
    fi

    # fetch the branch if was not locally fetch yet
    if ! command git branch | grep -qsE "\s*${branch_watch}$" ; then
        command git checkout --quiet "$branch_watch"
        command git checkout --quiet "$branch_working"
    fi

    # get username / email or assign them if they are not already added
    git_email="$( command git config user.email | tail -1 )"
    if [[ -z "$git_email" ]] ; then
        echo -e "Insert your email (to use with GIT)"
        read -e git_email
        read -r git_email <<< "$git_email"
        if [[ -n "$git_email" ]] ; then
            command git config --global user.email "$git_email"
        else
            el_error "You need to insert an email assigned with your GIT ID, aborting..."
            exit 1
        fi
    fi
    git_username="$( command git config user.name | tail -1 )"
    if [[ -z "$git_username" ]] ; then
        echo -e "Insert your GIT username / nickname"
        read -e git_username
        read -r git_username <<< "$git_username"
        if [[ -n "$git_username" ]] ; then
            command git config --global user.name "$git_username"
        else
            el_error "You need to insert an username assigned with your GIT ID, aborting..."
            exit 1
        fi
    fi

    # do we are in a saved session?
    if [[ -e "$conf_repo_d/flags/persistent_watcher" ]] ; then
        is_session_saved=1
    fi

    # - configurations get }}}

    # get share configurations
    if [[ -s "$conf_d/shared_main_default_dir.txt" ]] ; then
        shared_main_d="$( cat "$conf_d/shared_main_default_dir.txt" )"
    fi

    if [[ -L "$conf_repo_d/shared" ]] ; then
        is_shared=1

        shared_d="$conf_repo_d/shared"
        shared_personal_d="$shared_d/$git_email"
        conf_imported_commits_list_shared_f="${shared_d}/commits_imported_list"

        # start the share daemon
        run_dropbox
    fi

    # get the total of commits list
    do_count_commits

    # debug
    if [[ "${EL_DEBUG}" -ge "2" ]] ; then
        el_explain 2 "git log __${options_extra_git_before[*]} --reverse __${branch_working}__..__${branch_watch}__ __${options_extra_git_after[*]}"
    fi

    if ! ((is_travel_wanted)) ; then
        # scan your own to-do marks:
        scan_marked_states

        # scan if other users are ahead of you
        shared_accounts_state_show

        echo -e "${el_c_b}----------------------------------------------------------------${el_c_n}"

    fi

    # FIXME: the option showing "commits not pushed yet" not works well, the comparison is wrong? it doesnt point to the correct remote maybe?

    # loop
    while true
    do

        # loop!
        while read -ru 3 line
        do
            # update watching branch if needed {{{
            if [[ -z "$line" ]] ; then
                if el_confirm "Nothing found. Update your git watching branch now? (git pull --rebase)" ; then
                    # which remote to fetch from?
                    if [[ -z "$remote_fetching_watch" ]] ; then
                        if [[ "$( command git remote -v | grep "(fetch)" | awk '{print $1}' | wc -l )" -gt 1 ]] ; then
                            echo -e "\nWhich remote ID you want to track the changes on '$branch_watch' from ?\n"
                            #command git remote -v | grep "(fetch)" | awk '{print $1}'
                            command git remote -v | grep "(fetch)" | sed -e 's|(fetch).*$||g' | column -t | awk '{$1 = "(id: "$1") "; print $0}'

                            read -e remote_fetching_watch
                        else
                            remote_fetching_watch="$(command git remote -v | grep "(fetch)" | awk '{print $1}' | head -1 )"
                        fi

                        echo "$remote_fetching_watch" > "$conf_remote_fetch_watch_from_f"
                    fi

                    el_explain 0 "git checkout $branch_watch"
                    command git checkout --quiet "$branch_watch"

                    #el_explain 0 "git pull --rebase $remote_fetching_watch $branch_watch"
                    el_explain 0 "git pull --rebase \"$remote_fetching_watch\" \"+${branch_watch}:refs/remotes/${remote_fetching_watch}/${branch_watch}\""
                    #command git pull --rebase "$remote_fetching_watch" "$branch_watch"  # buggy method
                    command git pull --quiet --rebase "$remote_fetching_watch" "+${branch_watch}:refs/remotes/${remote_fetching_watch}/${branch_watch}"

                    # go back to our working one
                    el_explain 0 "git checkout $branch_working"
                    command git checkout --quiet "$branch_working"
                    check_if_has_diverged


                    # update total of commits
                    #is_recount_position_needed=1
                    counter=1
                    do_count_commits "force"
                    break 1
                else
                    exit
                fi
            fi

            # }}}
            # nothing found at all, exiting
            if [[ "$counter" -gt "$counter_total" ]] || [[ "$counter" -le 0 ]] ; then
                is_recount_position_needed=1
                counter=1
            fi

            # recount our position against our commit-id
            if ((is_recount_position_needed)) ; then
                #echo -en "\r${el_c_b}--- Traveling back in time: ${el_c_y}($counter/$counter_total)${el_c_b} ---${el_c_n}"
                #el_debug "recounting position needed"
                if [[ -n "$commit_id" ]] && [[ "$line" = "$commit_id" ]] ; then
                    is_commit_id_last_reached=1
                    unset is_recount_position_needed
                    #echo -e "" # append a newline because the counter entered on itself
                else
                    # loop until we reach the desired commit
                    #el_debug "skipping commit because is not $commit_id : $line"
                    counter="$(( $counter + 1 ))"

                    continue
                fi
            fi

            # skip until last commit, this only runs when starting back a watcher
            if ! ((is_commit_id_last_reached)) && ((is_session_saved)) ; then
                if [[ -n "$commit_id" ]] && [[ "$line" = "$commit_id" ]] ; then
                    is_commit_id_last_reached=1
                else
                    if [[ -n "$commit_id" ]] ; then
                        # loop until we reach the desired commit
                        el_debug "skipping commit because is not $commit_id : $line"
                        continue
                    fi
                fi
            else
                # we are in a new session, simulate that we have reached the last needed position
                is_commit_id_last_reached=1
            fi


            # get the commit id of this loop
            commit_id="${line}"
            el_array_member_add "$commit_id" "${commits_history[@]}" ; commits_history=("${_out[@]}")

            if ((is_travel_wanted)) && [[ -n "$travel_commit_id" ]] ; then
                go_to_commit "$travel_commit_id"
            fi

            # show actual commit
            show_commit_stat --no-pager

            # store actual position for future calls of this tool
            echo "$commit_id" > "$conf_commit_last_f"
            #el_debug "stored '$commit_id' to '$conf_commit_last_f'"

            echo -e "$counter $counter_total" > "$conf_commit_last_progress_f"
            #el_debug "stored counter at '$counter' with '$counter_total' total in '$conf_commit_last_progress_f'"


            #
            # show main options
            options_main_interact

            if ((is_recount_position_needed)) ; then
                break 1
            fi

            el_debug "going to next loop"
            #
            #

            # exit loop if no remaining commits
            if [[ "$counter" -ge "$counter_total" ]] || [[ "$counter" -le "0" ]] || [[ "$counter_total" -le "0" ]] ; then
                is_recount_position_needed=1
                break 1
            fi

            # count another commit because we go to next loop
            counter="$(( $counter + 1 ))"


            # clear screen, but after that we did everything before to start
            #clear_screen default

        done 3<<< "$( echo "$commits_list" )"
        # if you search with -k without matches, infinite loop happens, avoid it with this check
        if [[ "$counter" -ge "$counter_total" ]] || [[ "$counter" -le "0" ]] || [[ "$counter_total" -le "0" ]] ; then
            is_recount_position_needed=1
            break
        fi

        if ((is_recount_position_needed)) ; then
            counter=1
            unset is_commit_id_last_reached
            clear_screen default
            #el_explain 0 "recounting..."
        fi
    done


    if ((is_commit_id_last_reached)) ; then
        el_explain 0 "__No more commits found__"
    else
        if ((is_header_show)) ; then
            el_error "Something wrong happened? seems like we cannot found your last position, so where is this commit then? $commit_id"
        else
            # instead of just exit, give at least the options (if you need to update for example)
            unset is_recount_position_needed
            options_main_interact

            el_explain 0 "XXNo commitsXX found"
        fi
    fi

}

#
#  MAIN
#
main "$@"

exit $?

#
# vim: set foldmethod=marker :
#

