local _gitdir local last_fetch local diff # exec 3>&1 4>&2 # trap 'exec 2>&4 1>&3' 0 1 2 3 # exec 1>>~/tmp/gitfetch.log 2>&1 cd $1 gitdir=$(git rev-parse --git-dir 2> /dev/null) || return 0 last_fetch=$(zstat +mtime $gitdir/FETCH_HEAD 2> /dev/null || echo 0) let "diff = $(strftime %s) - $last_fetch" if [ $diff -gt ${GIT_FETCH_INTERVAL:-30} ]; then setopt localoptions noshwordsplit # Sets `GIT_TERMINAL_PROMPT=0` to disable authentication prompt for Git fetch (Git 2.3+). export GIT_TERMINAL_PROMPT=0 # Set SSH `BachMode` to disable all interactive SSH password prompting. export GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-"ssh"} -o BatchMode=yes" local ref ref=$(command git symbolic-ref -q HEAD) local -a remote remote=($(command git for-each-ref --format='%(upstream:remotename) %(refname)' $ref)) if [[ -z $remote[1] ]]; then # No remote specified for this branch, skip fetch. return 97 fi # Default return code, which indicates Git fetch failure. local fail_code=99 # Guard against all forms of password prompts. By setting the shell into # MONITOR mode we can notice when a child process prompts for user input # because it will be suspended. Since we are inside an async worker, we # have no way of transmitting the password and the only option is to # kill it. If we don't do it this way, the process will corrupt with the # async worker. setopt localtraps monitor # Make sure local HUP trap is unset to allow for signal propagation when # the async worker is flushed. trap - HUP trap ' # Unset trap to prevent infinite loop trap - CHLD if [[ $jobstates = suspended* ]]; then # Set fail code to password prompt and kill the fetch. fail_code=98 kill %% fi ' CHLD # Only fetch information for the current branch and avoid # fetching tags or submodules to speed up the process. command git -c gc.auto=0 fetch \ --quiet \ --no-tags \ --recurse-submodules=yes \ $remote &>/dev/null & wait $! || return $fail_code unsetopt monitor fi return 0 # vim: set ts=2 sw=2 tw=0 ft=sh :