#!/bin/bash # YummyYummySourceControl - Simple and convenient Git wrapper # # Copyright (C) 2007 Tim Janik # # 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/^ //;/^[ ]*$/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] - add branch (forcable)' echo -e '\tyybranchdel [-f] - 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 [revision] - add tag' echo -e '\tyytagdel - delete tag' echo -e '\tyyuncommit - undo the last commit (must be unpushed)' echo -e '\tyyview - browse & navigate the history' echo -e '\tyywarp - 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