fork-g/bin/get

236 lines
5.9 KiB
Text
Raw Normal View History

2015-07-16 18:20:55 -04:00
#!/bin/bash
# I'm writing this in BASH because I hate myself, apparently.
2015-07-17 00:24:23 -04:00
list_branches() {
2015-07-16 18:20:55 -04:00
git for-each-ref refs/heads --format="%(refname:short)"
}
2015-07-17 00:24:23 -04:00
list_remote_branches() {
2015-07-16 18:20:55 -04:00
git for-each-ref refs/heads --format="%(refname:short)"
}
2015-07-17 01:25:50 -04:00
2015-07-16 18:20:55 -04:00
case "$1" in
2015-07-17 01:25:50 -04:00
"")
echo 'TODO: Display help, or git status if inside a repo'
;;
2015-07-16 18:20:55 -04:00
stage)
if [ -z "$2" ]; then
echo Staging all modified files
git add -u :/
else
echo Staging "${@:2}"
git add "${@:2}"
fi
;;
unstage)
echo Unstaging
if [ -z "$2" ]; then
echo The stage has been reset.
git reset HEAD
else
git reset HEAD "${@:2}"
fi
;;
reset)
echo Resetting
if [ -z "$2" ]; then
echo The working directory has been reset.
git checkout -f HEAD
else
git checkout "${@:2}"
fi
;;
commit)
echo "Parent commit: $(git log --abbrev-commit -1 --pretty=format:'%C(bold blue)%s%Creset %Cgreen(%cr)%Creset')"
2015-07-16 18:20:55 -04:00
if [ -z "$2" ]; then
read -p 'Message: ' msg
git commit -m "$msg"
else
git commit -m "$2"
fi
;;
undo)
case "$2" in
commit)
echo Undoing last commit
git reset --soft HEAD~1
;;
esac
;;
2015-07-16 18:20:55 -04:00
branch)
echo 'Switching to branch'
if [ -z "$2" ]; then
echo '! Specify branch name'
else
2015-08-04 16:42:34 -04:00
git stash save --include-untracked --quiet 'get-branch autostash' # Save branch index state
2015-07-16 18:20:55 -04:00
if git rev-parse --verify --quiet "$2" > /dev/null; then
git checkout "$2"
else
git checkout -b "$2"
fi
2015-08-04 16:42:34 -04:00
git stash pop --quiet # Restore branch index state
2015-07-16 18:20:55 -04:00
fi
;;
rmbranch)
echo 'Delete branch'
if [ -z "$2" ]; then
echo '! Specify branch name'
else
git branch -d "$2"
fi
;;
2015-07-17 01:25:50 -04:00
fetch)
2015-07-16 18:20:55 -04:00
echo Updating
if [ -z "$2" ]; then
git fetch --all
2015-07-17 01:35:25 -04:00
branches="$(list_branches)"
2015-07-16 18:20:55 -04:00
else
2015-07-17 01:35:25 -04:00
branches = "${@:2}"
git fetch "$branches"
2015-07-16 18:20:55 -04:00
fi
2015-07-17 01:35:25 -04:00
# Fast-forward local branches. I owe a lot to http://stackoverflow.com/a/24451300/2168416
current_branch=$(git rev-parse --abbrev-ref HEAD)
for local_branch in $branches; do
remote=$(git config --get branch.$local_branch.remote)
remote_branch=$(git config --get branch.$local_branch.merge | sed 's:refs/heads/::')
# Git throws an error if we try the fetch command on the current branch. Sheesh
if [ "$current_branch" = "$local_branch" ]; then
git merge --ff-only $remote/$remote_branch
else
git fetch $remote $remote_branch:$local_branch
fi
done
2015-07-16 18:20:55 -04:00
;;
ignore)
;;
status)
# TODO: figure out how to git config --global color.status always automatically.
git status \
2015-07-18 20:28:52 -04:00
| grep -v 'On branch' \
| grep -v '(use "git push" to publish your local commits)' \
| grep -v '(use "git reset HEAD <file>..." to unstage)' \
| grep -v '(use "git add <file>..." to update what will be committed)' \
| grep -v '(use "git checkout -- <file>..." to discard changes in working directory)' \
| grep -v '(use "git add <file>..." to include in what will be committed)' \
2015-07-16 18:20:55 -04:00
| grep -v 'nothing added to commit but untracked files present (use "git add" to track)'
;;
diff)
if [ -z "$2" ]; then
echo 'Compare working tree with HEAD'
git diff HEAD
else
if [ -z "$3" ]; then
if [ "$2" = 'STAGE' ]; then
echo 'Compare working tree with stage'
git diff
else
echo "Compare working tree with $2"
git diff "$2"
fi
else
if [ "$2" = 'STAGE' ]; then
echo "Compare stage with $3"
git diff --cached "$3"
else
echo "Compare $2 with $3"
git diff "$2" "$3"
fi
fi
fi
;;
review)
echo 'Compare stage with HEAD'
git diff --cached HEAD
;;
push)
echo 'Pushing'
# Check to see if upstream is set.
if git rev-parse --abbrev-ref @{upstream} >/dev/null ; then
git push
else
# Get local branch name
local_branch=$(git rev-parse --abbrev-ref HEAD)
# Check for multiple remotes
remote_count=$(git remote show | wc -l)
remotes=$(git remote show | tr '\n' ' ' | sed 's/\s*$//g')
if [ "$remote_count" = "1" ]; then
# If only one remote
remote="$remotes"
else
read -p "Which remote to push? (${remotes}): " remote
fi
read -p "Choose name for branch on '${remote}' [${local_branch}]: " remote_branch
if [ "$remote_branch" = "" ]; then
remote_branch="$local_branch"
fi
echo "I will run git push --set-upstream ${remote} ${remote_branch}"
git push --set-upstream ${remote} ${remote_branch}
fi
;;
2015-08-01 01:29:27 -04:00
clone)
# Github username, if available
github_user=$(git config github.user)
# Turn "username/repo" into full Github URL
if [[ "$2" =~ ^[^/]+/[^/]+$ ]]
then
url="https://github.com/$2"
# Turn "repo" into "username/repo" Github URL
elif [[ "$2" =~ ^[^/]+$ ]] && ! [ -z "$github_user" ]
then
url="https://github.com/${github_user}/$2"
else
url="$2"
fi
echo Cloning $url
git clone "$url"
;;
2015-08-04 16:42:52 -04:00
squash)
# I implement squash a little differently than most.
# 1) Rebase squashing aggregates commit messages, which is usually
# counter to the purpose of squashing, which is to hide the fact
# that a change took several real commits.
# 2) Rebasing also deletes commits by default, which is problematic
# if you have pushed those commits to the server already.
# This solution is more gentle in that it creates a new commit with
# a new commit message containing the same changes as the old
# series of commits, but doesn't delete the old commits, leaving them
# as a branch.
# TODO: check argument is numeric
if [[ "$2" =~ ^[0-9]+$ ]]
then
echo "Squash the following commits together:"
git log --abbrev-commit \
--color \
--graph \
--ancestry-path \
--pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' \
HEAD...HEAD~$2
read -p 'Message: ' msg
git stash save --include-untracked --quiet 'get-squash autostash'
git reset --soft HEAD~$(($2+1))
git commit -m "$msg"
git stash pop --quiet
else
echo "The second argument is expected to be an integer."
fi
;;
2015-07-16 18:20:55 -04:00
esac