Gitgo or: How I learned to live with VCS
UPDATE: Only keeping thins post around as a reminder of how far I've come.
UPDATE: This is a bit outdated now, as I have added some features and polished up the code a bit. I will post the update after the migration to Ghost is done.
UPDATE: Changed order of main to try to avoid push conflicts
UPDATE: Multi-directory bug squashed! (I think)
UPDATE: Found a bug that breaks the script if you are deep in a multi-directory Git repo and call this script. (All of my repos are currently only one directory deep, so it might be a bit before I squash this bug...)
Personally, I've never been one to use a version control system. Even during university, when it was a 'requirement' to use such a system, I opted out and used either no version control at all or Google Docs.
I didn't know what I was missing.
I have started using Git in my professional career, and I have to say I'm hooked. I'm just not overly fond of one aspect of Git. The commands.
Sure, after using it day in and day out it became less of a chore and more of a required familiarity, but I still wanted a better way so I decided to write a script in bash to help streamline my interactions with git.
#!/bin/bash -
#===============================================================================
#
# FILE: gitgo.rewrite.sh
#
# USAGE: ./gitgo.rewrite.sh
#
# DESCRIPTION:
#
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: ---
# ORGANIZATION:
# CREATED: 01/25/2013 01:46:29 PM CST
# REVISION: ---
#===============================================================================
#-------------------------------------------------------------------------------
# Set Colors for pretty output
#-------------------------------------------------------------------------------
txtred=$(tput setaf 1) # Red
txtgrn=$(tput setaf 2) # Green
txtylw=$(tput setaf 3) # Yellow
txtwht=$(tput setaf 7) # White
txtrst=$(tput sgr0) # Text reset.
#-------------------------------------------------------------------------------
# Trap Control-C and react by resetting HEAD for git
#-------------------------------------------------------------------------------
trap control_c SIGINT
control_c(){
echo -en "\n*** Ctrl^c caught. Exiting ***\n"
git reset HEAD;
exit 1
}
#-------------------------------------------------------------------------------
# Main Case Statement for setting flags
#-------------------------------------------------------------------------------
flags=$1
case "$flag" in
-y)
answer=$flag;;
-h)
echo "Help Documentation HERE";;
"")
echo "No Flags" > /dev/null ;;
*)
echo "Invalid Flag";;
esac
#-------------------------------------------------------------------------------
# Check if you are in a Git Reop, and fail/exit if not
#-------------------------------------------------------------------------------
isGit(){
check_repo=`git rev-parse --is-inside-work-tree`
if [ "$check_repo" == "true" ]
then
git_base_dir=`git rev-parse --show-toplevel`
cd $git_base_dir
main
else
echo "Not a git repository!"
exit
fi
}
gitLists(){
#-------------------------------------------------------------------------------
# Set Internal Field Seperator to NewLine
#-------------------------------------------------------------------------------
IFS=$'\n'
#-------------------------------------------------------------------------------
# Get list of untracked files
#-------------------------------------------------------------------------------
N=0
for i in $(git ls-files -o) ; do
#j="${git_base_dir}/$i"
untracked[$N]="$i"
let "N= $N + 1"
done
#-------------------------------------------------------------------------------
# Get list of modified files
#-------------------------------------------------------------------------------
N=0
for i in $(git diff --name-only --diff-filter=M) ; do
#j=`basename $i`
#modified[$N]="$j"
j="${git_base_dir}/$i"
modified[$N]="$j"
let "N= $N + 1"
done
#-------------------------------------------------------------------------------
# Get list of renamed files
#-------------------------------------------------------------------------------
N=0
for i in $(git diff --name-only --diff-filter=R) ; do
#j=`basename $i`
#modified[$N]="$j"
j="${git_base_dir}/$i"
renamed[$N]="$j"
let "N= $N + 1"
done
#-------------------------------------------------------------------------------
# Get list of delted files
#-------------------------------------------------------------------------------
N=0
for i in $(git ls-files --deleted) ; do
deleted[$N]="$i"
let "N= $N + 1"
done
}
gitStage(){
#-------------------------------------------------------------------------------
# Check for array lengths of 0
#-------------------------------------------------------------------------------
length_untracked=${#untracked[@]}
length_modified=${#modified[@]}
length_renamed=${#renamed[@]}
length_deleted=${#deleted[@]}
echo "$txtwht************** Changes **************$txtrst"
if [ $length_untracked -eq 0 ]
then
echo "$txtylw No new or untracked files found $txtrst"
else
for i in "${untracked[@]}"
do
echo -e "$txtgrn Adding new file: $i $txtrst"
git add $i
done
fi
if [ $length_modified -eq 0 ]
then
echo "$txtylw No modified files found $txtrst"
else
for i in "${modified[@]}"
do
echo -e "$txtgrn Updating modified file: $i $txtrst"
git add $i
done
fi
if [ $length_renamed -eq 0 ]
then
echo "$txtylw No renamed files found $txtrst"
else
for i in "${renamed[@]}"
do
echo -e "$txtgrn Adding renamed file: $i $txtrst"
git add $i
done
fi
if [ $length_deleted -eq 0 ]
then
echo "$txtylw No deleted files found $txtrst"
else
for i in "${deleted[@]}"
do
echo "$txtred Removing deleted file: $i $txtrst"
git rm $i
done
fi
echo "$txtwht*************************************$txtrst"
}
gitGo(){
#-------------------------------------------------------------------------------
# Ask to commit changes
#-------------------------------------------------------------------------------
if [ $length_untracked -eq 0 ] && [ $length_modified -eq 0 ] && [ $length_renamed -eq 0 ] && [ $length_deleted -eq 0 ]
then
echo "No Changes at all. No Need to Commit"
exit
fi
if [[ $flags == "-y" ]]
then
answer="yes"
else
echo -e "\nCommit Changes? (Yes/No)"
read -e answer
fi
case "$answer" in
[yY] | [yY][Ee][Ss])
echo "Comments? ENTER THEM NOW!!!";
read -e comments;
if [ "$comments" == "" ]
then
echo "Cannot commit without comments, ya turkey!!!"
git reset HEAD
exit 0
fi
git commit -m "$comments";
git push;
exit 0;;
[nN] | [nN][oO])
git reset HEAD;
exit 0;;
*)
echo Invalid option selected;
git reset HEAD;;
esac
}
#-------------------------------------------------------------------------------
# Main Function (calls err-body else)
#-------------------------------------------------------------------------------
main(){
gitLists
gitStage
git pull
gitGo
}
#-------------------------------------------------------------------------------
# Kick this pig
#-------------------------------------------------------------------------------
isGit
I'll be the first to admit that this has (in one way or another) already been done, and probably better too, but I wanted to create my own. I'm sure I'll keep adding to it, polishing it, and making sure I've accounted for most (if not all) edge cases or errors, and of course all the while using Git to keep track of the changes and GitLab to have a more visually pleasing view into it all.