summaryrefslogblamecommitdiffstats
path: root/git-base.sh
blob: 18d3dec920e4d2406a1d90d95972b2205db8de69 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

          
         











                              
               

                  





                                  
                                                




                                              
      









                                                    




                      
                 
      
                                                       



                    


                                     


             


                                                   






                    



                                                               
                                               

              
                                                    

              
      




               
                  








                                       
                  


                                     




















































                                                                                                 

























                                                                                     




                                              
                        
                  




                                                                                   

    
















                                                                 

















                                                                 
dot_git=""
cwd=""
remote=""

in_current_dir() {
  local wd="$(pwd)"
  if [[ "$wd" == $cwd ]]; then
    cwd="$wd"
    return 0
  else
    cwd="$wd"
    return 1
  fi
}

debug_print() {
  local debug=$1
  local message=$2
  if [[ $debug == "debug" ]]; then
    echo $message
  fi
}

dot_git() {
  if in_current_dir && [[ -n "$dot_git" ]]; then
    # cache dot_git to save calls to rev-parse
    echo $dot_git
  elif [ -d .git ]; then
    dot_git=".git"
    echo $dot_git
  else
    dot_git="$(git rev-parse --git-dir 2>/dev/null)"
    echo $dot_git
  fi
}

is_repo() {
  if [[ -n "$(dot_git)" ]]; then
    return 0
  else
    return 1
  fi
}

git_root() {
  if [ -d .git ]; then
    echo "$(pwd)"
  else
    echo "$(git rev-parse --show-toplevel 2>/dev/null)"
  fi
}

record_timestamp() {
  if is_repo; then
    touch "$(dot_git)/lastupdatetime"
  fi
}

timestamp() {
  if is_repo; then
    echo "$(stat -f%m "$(dot_git)/lastupdatetime")"
  fi
}

time_now() {
  echo "$(date +%s)"
}

time_to_update() {
  if is_repo; then
    local timesincelastupdate="$(($(time_now) - $(timestamp)))"
    local fiveminutes="$((5 * 60))"
    if (( "$timesincelastupdate" > "$5minutes" )); then
      # time to update return 0 (which is true)
      return 0
    else
      # not time to update return 1 (which is false)
      return 1
    fi
  else
    return 1
  fi
}

fetch_async() {
  local debug="$1"
  if time_to_update; then
    debug_print $debug "Starting fetch"
    fetch $debug &
  else
    debug_print $debug "Didn't fetch"
  fi
}

fetch() {
  local debug="$1"
  git fetch
  debug_print $debug "Finished fetch"
}

branch_name() {
  if is_repo; then
    local localBranch="$(git symbolic-ref --short HEAD)"
    echo $localBranch
  fi
}

is_tracking_remote() {
  if [[ -n "$(remote_branch_name)" ]]; then
    return 0
  else
    return 1
  fi
}

remote_branch_name() {
  if is_repo; then
    local remoteBranch="$(git for-each-ref --format='%(upstream:short)' | grep "$(branch_name)")"
    if [[ -n $remoteBranch ]]; then
      echo $remoteBranch
      return 0
    else
      return 1
    fi
  fi
}

commits_behind_of_remote() {
  if is_tracking_remote; then
    set --
    set -- $(git rev-list --left-right --count $(remote_branch_name)...HEAD)
    behind=$1
    ahead=$2
    set --
    echo $behind
  else
    echo "0"
  fi
}

commits_ahead_of_remote() {
  if is_tracking_remote; then
    set --
    set -- $(git rev-list --left-right --count $(remote_branch_name)...HEAD)
    behind=$1
    ahead=$2
    set --
    echo $ahead
  else
    echo "0"
  fi
}

remote_behind_of_master() {
  if is_tracking_remote; then
    set --
    set -- $(git rev-list --left-right --count origin/master...$(remote_branch_name))
    behind=$1
    ahead=$2
    set --
    echo $behind
  else
    echo "0"
  fi
}

remote_ahead_of_master() {
  if is_tracking_remote; then
    set --
    set -- $(git rev-list --left-right --count origin/master...$(remote_branch_name))
    behind=$1
    ahead=$2
    set --
    echo $ahead
  else
    echo "0"
  fi
}

porcelain_status() {
  echo "$(git status --porcelain 2>/dev/null)"
}

count_from_porcelain() {
  if is_repo; then
    status="$(porcelain_status)"
    pattern="$2"
    echo "$(echo "$status" | grep -p "$pattern" | wc -l | grep -oEi '[0-9][0-9]*')"
  else
    echo "0"
  fi
}

untracked_files() {
  echo "$(count_from_porcelain "$git_status" "?? ")"
}

staged_added_changes() {
  echo "$(count_from_porcelain "$git_status" "A[A|M|C|D|U|R ] ")"
}
staged_modified_changes() {
  echo "$(count_from_porcelain "$git_status" "M[A|M|C|D|U|R ] ")"
}
staged_deleted_changes() {
  echo "$(count_from_porcelain "$git_status" "D[A|M|C|D|U|R ] ")"
}
staged_renamed_changes() {
  echo "$(count_from_porcelain "$git_status" "R[A|M|C|D|U|R ] ")"
}

unstaged_modified_changes() {
  echo "$(count_from_porcelain "$git_status" "[A|M|C|D|U|R ]M ")"
}
unstaged_deleted_changes() {
  echo "$(count_from_porcelain "$git_status" "[A|M|C|D|U|R ]D ")"
}

conflicted_by_us_changes() {
  echo "$(count_from_porcelain "$git_status" "[A|M|C|D|R ]U ")"
}
conflicted_by_them_changes() {
  echo "$(count_from_porcelain "$git_status" "U[A|M|C|D|R ] ")"
}
conflicted_both_changes() {
  echo "$(count_from_porcelain "$git_status" "UU ")"
}