Skip to content

Instantly share code, notes, and snippets.

@rae
Created April 4, 2013 15:59
Show Gist options
  • Save rae/5311672 to your computer and use it in GitHub Desktop.
Save rae/5311672 to your computer and use it in GitHub Desktop.
This is my Git-specific zshrc that gets sourced from my main ~/.zshrc
# git
## branch operations
####
#### screw it; I compiled my own version of git on Dreamhost, so I'm no longer checking for
#### git versions older than 1.7.4.4
####
## not the best but it's hard to compare version #s, so just see if we're running
## on Debian, which means we're on Dreamhost where git is old, old, old
#if [[ $(osversion) =~ Debian* ]]; then
# if [[ "`git --version`" < "git version 1.7.4.4" ]]; then
# git_pretty_format='%Cred%h%Creset < %p%C(magenta) %ad%Creset %Cgreen(%cd) %C(bold blue)<%an>%Creset%n%s%b%Creset'
#else
# git_pretty_format='%Cred%h%Creset < %p%C(magenta)%d%Creset (%Cgreen%ad%Creset) %C(bold blue) %an <%ae>%Creset%n%B'
#fi
git_pretty_format='%Cred%h%Creset < %p%C(magenta)%d%Creset (%Cgreen%ad%Creset) %C(bold blue) %an <%ae>%Creset%n%B'
git_log_pattern='\*[ |]*[0-9a-f][0-9a-f][0-9a-f]* < .*'
blame() {
for file; do
git blame -C -C -C -M -M --date=relative --abbrev HEAD "$file"
done
}
# print current branch
br() { git symbolic-ref --quiet HEAD | sed 's#^refs/heads/##' }
branch() { git branch $*; }
## not-necessarily-branch operations
checkout() {
git checkout $*
# this allows the prompt to catch up, if needed
cd .
}
# search through commit messages
cgrep() {
for i; do;
log "HEAD^{/$i}^".."HEAD^{/$i}"
done
}
clone() { git clone --recursive $*; }
commit() { git commit $*; }
config() {
if [ $# = 0 ]; then
# no args means spit out current config
git config -l
else
git config $*
fi
}
each() { git submodule foreach $*; }
fetch() { git fetch $*; }
# does a git diff of either HEAD or for each listed commit hash
gdesc() {
opts=()
[ $# = 0 ] && set HEAD
while getopts puU: flag; do
case "$flag" in
p|u) opts+=("-$flag") ;;
U) opts+=("-U"$OPTARG) ;;
esac
done
shift $OPTIND-1
for hash in $*; do
echo gdiff $opts "${hash}^1" "${hash}"
gdiff $opts "${hash}^1" "${hash}"
done
}
gdiff() {
# pipe through "less" with a pattern that marks file separators
git diff --color --no-prefix -b -w $* \
| less --pattern='^diff.*'
}
ggrep() { git grep $*; }
gitsetup() {
# ignore ^M at end of line
git config --global core.whitespace cr-at-eol
git config --global core.autocrlf true
}
# run gitk nicely on a Mac
gk() {
gitk --all --since="3 months ago" $* &;
sleep 4
osascript <<EOF
tell application "Wish"
activate
end tell
EOF
}
# print out HEAD's hash
HEAD() { git rev-list -n 1 HEAD }
# logging - with merge messages
logg() {
width=$(tput cols)
git log \
--color \
--graph \
--pretty=format:"${git_pretty_format}" \
--abbrev-commit \
--date=relative \
--stat=$(($width-10)),$(($width-50)) \
$* \
| less --pattern="${git_log_pattern}"
}
# logging - without merge messages
log() { logg --no-merges $*; }
# one-line log: hash < parentHash (date) <userRealName>
log1() {
git log \
--decorate=full \
--pretty=format:"%Cred%h%Creset < %p%C(magenta)%d%Creset %Cgreen(%cd) %C(bold blue)<%an>%Creset" \
--abbrev-commit \
--date=relative \
--no-merges \
$*;
}
# short log - shows commit message and count of changed files
slog() {
git log \
--graph \
--pretty=format:"${git_pretty_format}" \
--abbrev-commit \
--date=relative \
--no-merges \
--shortstat \
$* \
| less --pattern="${git_log_pattern}"
}
# another one-line short short log; like log1 but also shows color and author email address
sslog() {
local format='%Cred%h%Creset < %p%C(magenta)%d%Creset (%Cgreen%ad%Creset) %C(bold blue) %an <%ae>%Creset'
git log \
--graph \
--pretty=format:"${format}" \
--abbrev-commit \
--date=relative \
--no-merges \
$* \
| less --pattern="${git_log_pattern}"
}
# go to master branch
master() {
git checkout $* master
# gives prompt a chance to change
cd .
}
merge() { git merge --no-ff $*; }
# print out previous HEAD hash
prev() { git rev-list -n 1 ORIG_HEAD }
push() {
if [ $# = 0 ]; then
# put just the current branch
git push origin $(br)
else
git push $*;
fi
}
# pull changes and show a log of what's been updated
pull() {
old_head=$(HEAD)
# use --rebase to keep your local commits "above" remote commits
git pull --rebase $*;
# show changes since last pull - in chrono order (normally "git log" is reverse chrono)
echo ""
git log --pretty=format:"%h %d %cd <%an>%n%B" --reverse ${old_head}..HEAD | cat;
}
# pull + pull all submodules
ppull() {
d="$PWD"
root=$(git rev-parse --show-toplevel)
[[ $root != $d ]] && cd "$root"
echo "# pulling top level"
pull
echo "# pulling all submodules to latest; hope they're on a branch"
each git pull --rebase
[[ $root != $d ]] && cd "$d"
}
reflog() { git reflog $*; }
revert() { git checkout -- $*; }
show() {
width=$(tput cols)
git show \
--color \
--pretty=format:"${git_pretty_format}" \
--abbrev-commit \
--date=relative \
--no-merges \
--stat=$(($width-10)),$(($width-50)) \
-p $* | less --pattern='^diff.*'
}
# stash, pull and then un-stash
spull() {
git stash
pull $*
git stash pop
}
st() { git status $*; }
stash() { git stash $*; }
# look for a tag with "testflight" and do a log up to but not including that commit
tflog() {
div="-----------------------------------"
if [ $# = 0 ]; then
start=$(git tag | grep testflight | egrep -v `date +%Y%m%d` | sort | tail -1)
else
start="$1"
shift
fi
fmt="${div}%n%h [%ad] %an <%ae>%n%B"
(git log --no-merges --reverse --pretty=format:"${fmt}" --abbrev-commit --date=iso $* ${start}..HEAD;
echo "${div}") | less
}
update() { git submodule update $*; }
##
## TestFlight support
##
tftag() {
if [ $# = 0 ]; then
commit=HEAD
timestamp=$(date +%Y%m%d-%H%M)
else
# tag the named commit with the appropriate testflight tag
commit="$1"
commitTime=($(git log --date=raw --pretty=format:"%ad" "${commit}^..${commit}"))
timestamp=$(date -r ${commitTime[1]} +%Y%m%d-%H%M )
shift
fi
# do a simple git tag for TestFlight builds
build=$(git describe $* $commit | awk -F - '{ print $2; }')
tag="testflight-${build}-${timestamp}"
echo "# tagging $commit with $tag"
git tag $tag $commit
}
##
## prompt support
##
# figure out the git branch
gb() {
## Note: do *not* use the "cd" command in this function, even with "-q".
## It messes with "cd -" if you do. Also, you can get into an infinite loop
## really easily.
##
git_branch=$(git symbolic-ref --quiet HEAD | sed 's#^refs/heads/##')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment