#!/bin/bash
# YummyYummySourceControl - Simple and convenient Git wrapper
#
# Copyright (C) 2007 Tim Janik <
[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# If you have not received a copy of the GNU General Public License
# along with this program, see:
http://www.gnu.org/licenses/
#set -e # exit on errors
#set -x # show commands
VERSION=YummyYummySourceControl-0.5
# setup
SETBOLD=true ; SETNORM=true ; COLOR= ; OUT=cat ; YYHELP=
# perform wildcard string matches
function match() {
pattern="$1"
searchtext="$2"
case "$searchtext" in
$pattern) return 0 ;; # $pattern must be unquoted to allow *?[]
esac
return 1
}
# configure for terminals with ANSI color escapes
TAB=$'\t' # joe(1) syntax highlighting is broken for $''
test -t 1 && match $'*\e[31m*' "`tput setaf 1 2>/dev/null`" && {
SETBOLD=echo\ -ne\ '\e[1m' ; SETNORM=echo\ -ne\ '\e[0m'
BOLD=$'\e[1m'; GREEN=$'\e[32m'; TURK=$'\e[36m'; NORM=$'\e[0m';
COLOR=--color ; OUT=less\ -R
#' # work around syntax highlighting in old joe(1) versions wrg $''
# we hardcode ANSI escapes directly because less -R can only deal with \e[*m
}
# find repository
match '*/yyhelp*' "/$0" && YYHELP=1 # no repo required
gitdir="$(git-rev-parse --git-dir 2>/dev/null)"
if test -f "$gitdir/HEAD" ; then
githead="$gitdir/`git-symbolic-ref -q HEAD || echo HEAD`"; test -e "$githead" || githead=
gitprefix="$(git-rev-parse --show-prefix)" ; test -z "$gitprefix" && gitprefix=. # no subdir support if GIT_DIR is set
elif ! test "$YYHELP" ; then
echo "`basename \"$0\"`: No repository" >&2 ; exit 9
fi
# GIT commands
case "/$0" in
*/yyadd) exec git-update-index --add -- "$@" ;;
*/yyblame) test -z "$*" && exec yyhelp
git-blame -- "$@" | {
test -n "$COLOR" &&
sed "/^[^()]\+(Not Committed Yet\b/{ s/^\([^()]\+\)(\([^()]\+\))\(.*\)/$GREEN\1$TURK(\2)$GREEN\3$NORM/; p; d };
s/^\([^()]\+\)(\([^()]\+\))/$BOLD\1$NORM$TURK(\2)$NORM/" \
|| cat ; } | $OUT ;;
*/yybranch) test -z "$*" && exec yyhelp
test "x$1" = "x-f" && exec git-branch -f "$2"
test -n "$1" && exec git-branch "$1" ;;
*/yybranchdel) test -z "$*" && exec yyhelp
test "x$1" = "x-f" && exec git-branch -D "$2"
test "x$1" = "x-D" && exec git-branch -D "$2"
test -n "$1" && exec git-branch -d "$1" ;;
*/yyChangeLog) test -n "$*" && exec yyhelp
git-log --pretty='format:%ad %an # %H (%cn)%n%n%s%n%n%b' |
sed 's/^/ /;s/^ //;/^[ ]*<unknown>$/d' | $OUT ;;
*/yycommit) cg-commit -- "$@" && test "true" = "`git-config --bool yyhelp.auto-push-commits`" && yypushpull ;;
*/yydiff) git-update-index --refresh > /dev/null
git-diff-index -r -m -C -p $COLOR HEAD -- "$@" | $OUT ;;
*/yygc) test -n "$*" && exec yyhelp
exec git-gc --prune ;;
*/yyinfo) test -n "$*" && exec yyhelp
REPO="`cd \"$gitdir/..\" && basename \"$(pwd)\" `"
REPODIR="`git-rev-parse --show-cdup`" ; test -z "$REPODIR" && REPODIR=.
URL="`git-config --get remote.origin.url`"; test -z "$URL" && URL="`cat $gitdir/remotes/origin 2>/dev/null | sed -n '/^URL: /{s/^URL: //;p;q}'`"
SVNURL="`git-config --get svn-remote.svn.url`";
test -z "$URL" -a -r "$gitdir/branches/origin" && URL="`cat $gitdir/branches/origin`" # cogito location
test -z "$URL" && URL="`cd \"$gitdir\" && pwd`" # no url, must be local
OC="`git-rev-parse --verify origin 2>/dev/null`"; test -n "$OC" && OC="`date -d \"$(git-log -n1 --pretty=format:%cD $OC)\" '+%F %T %z'` # $OC"
HC="`git-rev-parse --verify HEAD 2>/dev/null`"; test -n "$HC" && HC="`date -d \"$(git-log -n1 --pretty=format:%cD $HC)\" '+%F %T %z'` # $HC"
true && echo "GIT-Repo: $REPO"
true && echo "URL: $URL"
test -n "$SVNURL" && echo "SVN: $SVNURL"
true && echo "Path: $REPODIR"
test -n "$HC" && echo "HEAD: $HC"
test -n "$OC" && echo "Origin: $OC"
;;
*/yylsbranches) test -n "$*" && exec yyhelp
exec git-branch $COLOR ;;
*/yylstags) test -n "$*" && exec yyhelp
exec git-tag -l '.*' ;;
*/yypull) exec git-pull ;;
*/yypushpull) test -n "$*" && exec yyhelp
git-push && git-pull || exit $? ;;
*/yyremove) exec git-update-index --force-remove -- "$@" ;;
*/yyreset) test -n "$*" && exec yyhelp
exec git-checkout -f HEAD ;;
*/yyrestore) git-ls-tree -r HEAD -- "$@" | git-update-index --index-info # resurrect deleted
exec git-checkout-index -f -u -- "$@" ;;
*/yystatus) test -z "$*" || match '-[tuc]' "$*" || exec yyhelp
git-update-index --refresh > /dev/null # update stat info
! match '*-[tc]*' "$*" && # list unknown files
git-ls-files --others --directory --exclude-from=$gitdir/info/exclude --exclude-per-directory=.gitignore |
{ test " $*" != " -u" && sed 's,^,? ,' || sed 's,/$,,' ; }
test " $*" != " -u" && { # list non-unknown files
if test -z "$githead" ; then # empty history, list new files
git-ls-files | sed 's/^/A /'
else # list known files, path-relative
test -s "$gitdir/commit-ignore" && commitignore="$gitdir/commit-ignore" || commitignore=
git-diff-index --name-status --no-renames HEAD . | while IFS="$TAB" read -r mode file ; do
case "$mode" in
D) test -n "$(git-diff-files -- "$file")" && mode=! ;;
M) test -n "$commitignore" && fgrep -qx "$file" "$commitignore" && mode=n ;;
esac
echo "$mode ${file#$gitprefix}"
done
fi
} | { test " $*" != " -c" && cat || sed 's/^[^ ] \([^ ].*\)/* \1:/' ; } ;;
*/yytag) (set -e && test -n "$*" && test -z "$3" && ! match "* -*" " $*" ) || exec yyhelp
test -n "$2" && exec git-tag "$1" "$2"
exec git-tag "$1" ;;
*/yytagdel) test -z "$*" && exec yyhelp
match "* -*" " $*" && exec yyhelp
exec git-tag -d "$1" ;;
*/yyuncommit) test -n "$*" && exec yyhelp
exec git-reset --soft HEAD~1 ;;
*/yyview) test -n "$*" && exec yyhelp
exec gitk --all -d ;;
*/yywarp) test -z "$*" && exec yyhelp
exec git-checkout "$1" ;;
*) test "$YYHELP" || { echo "`basename \"$0\"`: No such command" >&2 ; exit 9 ; } ;;
esac
test "$YYHELP" || exit 0 # successful command execution
YYHELP_ALIASES="yyadd yyblame yybranch yybranchdel yyChangeLog yycommit yydiff yygc yyinfo
yylsbranches yylstags yypull yypushpull yyremove yyreset yyrestore yystatus
yytag yytagdel yyuncommit yyview yywarp"
test "x$1" = "x--install-aliases" && {
git --version | egrep '^git version (1\.[5-9]\.|[2-9]\.)' -q ||
{ echo "$0: failed to install: missing git >= 1.5.0" >&2 ; exit 2 ; }
test -x ./yyhelp || { echo "$0: failed to install: missing ./yyhelp" >&2 ; exit 2 ; }
test -x /bin/bash || { echo "$0: failed to install: missing /bin/bash" >&2 ; exit 2 ; }
cg --help >/dev/null 2>&1 || { echo "$0: failed to install: missing cogito" >&2 ; exit 2 ; }
set -e
for i in $YYHELP_ALIASES ; do
test -L $i || ln -vs yyhelp $i
done
exit 0
}
test "x$1" = "x--uninstall-aliases" && {
set -e
for i in $YYHELP_ALIASES ; do
test -L $i && rm -vf $i
done
exit 0
}
# BACKGROUND
# The prefix 'yy' was choosen to allow conflict free shell completion.
# YummyYummySourceControl was started only after cogito was announced to be
# halted. It is meant to not depend on cogito one day, albeit that's not yet
# possible.
{ # yyhelp
echo -e 'YummyYummySourceControl YummyYummySourceControl'
echo
# 0\t911234567892123456789312345678941234567895123456789612345678971234567898
$SETBOLD
echo -e 'NAME'
$SETNORM
echo -e '\tYummyYummySourceControl - Simple and convenient Git wrapper'
echo
$SETBOLD
echo -e 'SYNOPSIS'
$SETNORM
echo -e '\tyyadd [FILES...] - add files to git repository'
echo -e '\tyyblame [FILES...] - annotate file source code'
echo -e '\tyybranch [-f] <branch> - add branch (forcable)'
echo -e '\tyybranchdel [-f] <branch> - delete branch (forcable)'
echo -e '\tyyChangeLog - show git log in ChangeLog style'
echo -e '\tyycommit [FILES...] - commit current working tree'
echo -e '\tyydiff [FILES...] - show committable differences in'
echo -e '\t working tree'
echo -e '\tyygc - repack and prune repository'
echo -e '\tyyhelp - display yy* help information'
echo -e '\tyyinfo - display repository information'
echo -e '\tyylsbranches - list branches'
echo -e '\tyylstags - list tags'
echo -e '\tyypull - pull upstream sources'
echo -e '\tyypushpull - push & pull upstream sources'
echo -e '\tyyremove [FILES...] - remove files from git repository'
echo -e '\tyyreset - reset (revert to HEAD) all files in the tree'
echo -e '\tyyrestore [FILES...] - forcefully recheckout specific files'
echo -e '\tyystatus [-t|-u|-c] - display working tree status'
echo -e '\t -t: trim unknown; -u: show unknown;'
echo -e '\t -c: trim and use commit message style'
echo -e '\tyytag <tag> [revision] - add tag'
echo -e '\tyytagdel <tag> - delete tag'
echo -e '\tyyuncommit - undo the last commit (must be unpushed)'
echo -e '\tyyview - browse & navigate the history'
echo -e '\tyywarp <branch> - checkout new branch'
echo
$SETBOLD
echo -e 'DESCRIPTION'
$SETNORM
echo -e '\tYummyYummySourceControl is a shallow wrapper around the myriads of'
echo -e '\tcommands and options offered by the Git(7) revision control system.'
echo -e '\tThe scope of this wrapper is confined to a farily basic set of actions'
echo -e '\taround source control management, such as adding/removing/modifying'
echo -e '\tfiles and the simplest forms of tag and branch handling.'
echo
$SETBOLD
echo -e 'CONFIGURATION'
$SETNORM
echo -e "\tThe yycommit command can be configured to automatically issue"
echo -e "\tyypushpull after successful commits with the following option:"
echo -e "\t\tgit-config yyhelp.auto-push-commits true"
echo
$SETBOLD
echo -e 'INSTALLATION'
$SETNORM
echo -e '\tTo install YummyYummySourceControl, copy yyhelp into a bin/ directory'
echo -e '\tfrom $PATH and invoke: ./yyhelp --install-aliases'
echo
$SETBOLD
echo -e 'HISTORY'
$SETNORM
echo -e "\tYummyYummySourceControl was created as a very shallow wrapper around"
echo -e "\tgit-* tool option variants, to simplify the common use cases."
echo -e "\tDepending on programming habits, YummyYummySourceControl may or may"
echo -e "\tnot suit a developers daily needs. It is in any case not meant as a"
echo -e "\tfull replacement for the git interface (there is e.g. no yyclone) and"
echo -e "\tsubject to change."
echo
VERSIONSTRING___________FIXED=`printf '%-30s' "$VERSION"`
echo -e "$VERSIONSTRING___________FIXED YummyYummySourceControl"
} | $OUT
exit 0