Initial Commit - moved out of ubuntu_config.
This commit is contained in:
154
lib/git/fallback/status_shortcuts_shell.sh
Normal file
154
lib/git/fallback/status_shortcuts_shell.sh
Normal file
@@ -0,0 +1,154 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Git Breeze - Streamline your git workflow.
|
||||
# Copyright 2011 Nathan Broadbent (http://madebynathan.com). All Rights Reserved.
|
||||
# Released under the LGPL (GNU Lesser General Public License)
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
# bash/zsh 'git_status_shortcuts' implementation, in case Ruby is not installed.
|
||||
# Of course, I wrote this function first, and then rewrote it in Ruby.
|
||||
#
|
||||
# Processes 'git status --porcelain', and exports numbered
|
||||
# env variables that contain the path of each affected file.
|
||||
# Output is also more concise than standard 'git status'.
|
||||
#
|
||||
# Call with optional <group> parameter to just show one modification state
|
||||
# # groups => 1: staged, 2: unmerged, 3: unstaged, 4: untracked
|
||||
# --------------------------------------------------------------------
|
||||
git_status_shortcuts() {
|
||||
zsh_compat # Ensure shwordsplit is on for zsh
|
||||
local IFS=$'\n'
|
||||
local git_status="$(git status --porcelain 2> /dev/null)"
|
||||
|
||||
if [ -n "$git_status" ] && [[ $(echo "$git_status" | wc -l) -le $gs_max_changes ]]; then
|
||||
unset stat_file; unset stat_col; unset stat_msg; unset stat_grp; unset stat_x; unset stat_y
|
||||
# Clear numbered env variables.
|
||||
for (( i=1; i<=$gs_max_changes; i++ )); do unset $git_env_char$i; done
|
||||
|
||||
# Get branch
|
||||
local branch=`git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
|
||||
# Get project root
|
||||
if [ -d .git ]; then
|
||||
local project_root="$PWD"
|
||||
else
|
||||
local project_root=$(git rev-parse --git-dir 2> /dev/null | sed "s%/\.git$%%g")
|
||||
fi
|
||||
|
||||
# Colors
|
||||
local c_rst="\e[0m"
|
||||
local c_branch="\e[1m"
|
||||
local c_header="\e[0m"
|
||||
local c_dark="\e[2;37m"
|
||||
local c_del="\e[0;31m"
|
||||
local c_mod="\e[0;32m"
|
||||
local c_new="\e[0;33m"
|
||||
local c_ren="\e[0;34m"
|
||||
local c_cpy="\e[0;33m"
|
||||
local c_ign="\e[0;36m"
|
||||
# Following colors must be prepended with modifiers e.g. '\e[1;', '\e[0;'
|
||||
local c_grp_1="33m"; local c_grp_2="31m"; local c_grp_3="32m"; local c_grp_4="36m"
|
||||
|
||||
local f=1; local e=1 # Counters for number of files, and ENV variables
|
||||
|
||||
echo -e "$c_dark#$c_rst On branch: $c_branch$branch$c_rst $c_dark| [$c_rst*$c_dark]$c_rst => \$$git_env_char*\n$c_dark#$c_rst"
|
||||
|
||||
for line in $git_status; do
|
||||
if [[ $shell == *bash ]]; then
|
||||
x=${line:0:1}; y=${line:1:1}; file=${line:3}
|
||||
else
|
||||
x=$line[1]; y=$line[2]; file=$line[4,-1]
|
||||
fi
|
||||
|
||||
# Index modification states
|
||||
msg=""
|
||||
case "$x$y" in
|
||||
"DD") msg=" both deleted"; col="$c_del"; grp="2";;
|
||||
"AU") msg=" added by us"; col="$c_new"; grp="2";;
|
||||
"UD") msg="deleted by them"; col="$c_del"; grp="2";;
|
||||
"UA") msg=" added by them"; col="$c_new"; grp="2";;
|
||||
"DU") msg=" deleted by us"; col="$c_del"; grp="2";;
|
||||
"AA") msg=" both added"; col="$c_new"; grp="2";;
|
||||
"UU") msg=" both modified"; col="$c_mod"; grp="2";;
|
||||
"M"?) msg=" modified"; col="$c_mod"; grp="1";;
|
||||
"A"?) msg=" new file"; col="$c_new"; grp="1";;
|
||||
"D"?) msg=" deleted"; col="$c_del"; grp="1";;
|
||||
"R"?) msg=" renamed"; col="$c_ren"; grp="1";;
|
||||
"C"?) msg=" copied"; col="$c_cpy"; grp="1";;
|
||||
"??") msg="untracked"; col="$c_ign"; grp="4";;
|
||||
esac
|
||||
if [ -n "$msg" ]; then
|
||||
# Store data at array index and add to group
|
||||
stat_file[$f]=$file; stat_msg[$f]=$msg; stat_col[$f]=$col
|
||||
stat_grp[$grp]="${stat_grp[$grp]} $f"
|
||||
let f++
|
||||
fi
|
||||
|
||||
# Work tree modification states
|
||||
msg=""
|
||||
if [[ "$y" == "M" ]]; then msg=" modified"; col="$c_mod"; grp="3"; fi
|
||||
# Don't show {Y} as deleted during a merge conflict.
|
||||
if [[ "$y" == "D" && "$x" != "D" && "$x" != "U" ]]; then msg=" deleted"; col="$c_del"; grp="3"; fi
|
||||
if [ -n "$msg" ]; then
|
||||
stat_file[$f]=$file; stat_msg[$f]=$msg; stat_col[$f]=$col
|
||||
stat_grp[$grp]="${stat_grp[$grp]} $f"
|
||||
let f++
|
||||
fi
|
||||
done
|
||||
|
||||
IFS=" "
|
||||
grp_num=1
|
||||
for heading in 'Changes to be committed' 'Unmerged paths' 'Changes not staged for commit' 'Untracked files'; do
|
||||
# If no group specified as param, or specified group is current group
|
||||
if [ -z "$1" ] || [[ "$1" == "$grp_num" ]]; then
|
||||
local c_arrow="\e[1;$(eval echo \$c_grp_$grp_num)"
|
||||
local c_hash="\e[0;$(eval echo \$c_grp_$grp_num)"
|
||||
if [ -n "${stat_grp[$grp_num]}" ]; then
|
||||
echo -e "$c_arrow➤$c_header $heading\n$c_hash#$c_rst"
|
||||
_gs_output_file_group $grp_num
|
||||
fi
|
||||
fi
|
||||
let grp_num++
|
||||
done
|
||||
else
|
||||
# This function will slow down if there are too many changed files,
|
||||
# so just use plain 'git status'
|
||||
git status
|
||||
fi
|
||||
zsh_reset # Reset zsh environment to default
|
||||
}
|
||||
# Template function for 'git_status_shortcuts'.
|
||||
_gs_output_file_group() {
|
||||
for i in ${stat_grp[$1]}; do
|
||||
# Print colored hashes & files based on modification groups
|
||||
local c_group="\e[0;$(eval echo -e \$c_grp_$1)"
|
||||
|
||||
# Deduce relative path based on current working directory
|
||||
if [ -z "$project_root" ]; then
|
||||
relative="${stat_file[$i]}"
|
||||
else
|
||||
dest="$project_root/${stat_file[$i]}"
|
||||
relative="$(_gs_relative_path "$PWD" "$dest" )"
|
||||
fi
|
||||
|
||||
if [[ $f -gt 10 && $e -lt 10 ]]; then local pad=" "; else local pad=""; fi # (padding)
|
||||
echo -e "$c_hash#$c_rst ${stat_col[$i]}${stat_msg[$i]}:\
|
||||
$pad$c_dark [$c_rst$e$c_dark] $c_group$relative$c_rst"
|
||||
# Export numbered variables in the order they are displayed.
|
||||
# (Exports full path, but displays relative path)
|
||||
export $git_env_char$e="$project_root/${stat_file[$i]}"
|
||||
let e++
|
||||
done
|
||||
echo -e "$c_hash#$c_rst"
|
||||
}
|
||||
|
||||
# Show relative path if current directory is not project root
|
||||
_gs_relative_path(){
|
||||
# Credit to 'pini' for the following script.
|
||||
# (http://stackoverflow.com/questions/2564634/bash-convert-absolute-path-into-relative-path-given-a-current-directory)
|
||||
target=$2; common_part=$1; back=""
|
||||
while [[ "${target#$common_part}" == "${target}" ]]; do
|
||||
common_part="${common_part%/*}"
|
||||
back="../${back}"
|
||||
done
|
||||
echo "${back}${target#$common_part/}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user