summaryrefslogtreecommitdiffstats
path: root/uglib.sh
diff options
context:
space:
mode:
authorUwe Kleine-König <ukleinek@strlen.de>2010-09-08 17:55:00 +0200
committerUwe Kleine-König <ukleinek@strlen.de>2010-09-08 17:55:00 +0200
commit451726236e8e7b7329117d839370d7b755dba99e (patch)
tree731aa86796b99f7c760ccad127181a80cbcb0070 /uglib.sh
downloadubergit-451726236e8e7b7329117d839370d7b755dba99e.tar.gz
ubergit-451726236e8e7b7329117d839370d7b755dba99e.tar.xz
early draft of ubergit
Signed-off-by: Uwe Kleine-König <ukleinek@strlen.de>
Diffstat (limited to 'uglib.sh')
-rw-r--r--uglib.sh193
1 files changed, 193 insertions, 0 deletions
diff --git a/uglib.sh b/uglib.sh
new file mode 100644
index 0000000..3e92bd1
--- /dev/null
+++ b/uglib.sh
@@ -0,0 +1,193 @@
+## authorinfo ## {{{2
+authorinfo() {
+ # XXX: implement parsing .ubergit/author
+ # more XXX: get author from $1
+ echo "GIT_AUTHOR_NAME='Uwe Kleine-König'"
+ echo "GIT_AUTHER_EMAIL='ukl@pengutronix.de'"
+ echo "GIT_AUTHER_DATE='1283281597 +0200'"
+}
+
+## assert ## {{{2
+assert() {
+ "$@" || die "assertion failed: $*"
+}
+
+## base ## {{{2
+base() {
+ assert is_topic "$1"
+
+ git cat-file blob "$1:.ubergit/base" \
+ | sed -e 's/ *#.*//; /^$/d'
+}
+
+## commitenv ## {{{2
+commitenv() {
+ local commit
+ commit="$1"; shift
+
+ # XXX: apply the right dose of authorinfo(), committerinfo(), eval and sq()
+ env GIT_AUTHOR_NAME='Uwe Kleine-König' GIT_AUTHOR_EMAIL='ukl@pengutronix.de' GIT_AUTHOR_DATE='1283281597 +0200' GIT_COMMITTER_NAME='Uwe Kleine-König' GIT_COMMITTER_EMAIL='ukl@pengutronix.de' GIT_COMMITTER_DATE='1283281597 +0200' "$@"
+}
+
+## commiterinfo ## {{{2
+committerinfo() {
+ assert is_topic "$1"
+
+ # XXX: get commiter from $1
+ echo "GIT_COMMITTER_NAME='Uwe Kleine-König'"
+ echo "GIT_COMMITTER_EMAIL='ukl@pengutronix.de'"
+ echo "GIT_COMMITTER_DATE='1283281597 +0200'"
+}
+
+## debug ## {{{2
+debug() {
+ echo -- "$*" > /dev/tty
+}
+
+## deps ## {{{2
+deps() {
+ assert test "$#" = "1"
+ assert is_sha1 "$1"
+ if is_topic "$1"; then
+ local base deplines
+
+ base="$(base "$1")"
+
+ # this removes the final newline
+ git cat-file blob "$base:.ubergit/deps" | sed -e 's/ *#.*//; /^$/d'
+ fi
+}
+
+## die ## {{{2
+die() {
+ printf "fatal: %s\n" "$*" >&2
+ exit 1
+}
+
+## export_rev_chk ## {{{2
+export_rev_chk() {
+ assert is_sha1 "$1"
+ eval test -z "\$exported_$1"
+}
+
+## export_rev_cmd ## {{{2
+export_rev_cmd() {
+ local deps parent exported
+
+ assert is_sha1 "$1"
+
+ # XXX: is this portable?
+ deps="$(printf "%s" "$(deps "$1")" | tr '\012' ' ')"
+
+ case "$deps" in
+ "")
+ eval "exported_$1=$1"
+ return
+ ;;
+ *" "*)
+ # >1 dependency
+ parent="$(printf "exported base for $1\n" \
+ | commitenv "$1" git commit-tree "$(pretty_tree "$(base "$1")")" $(set -f; for p in $deps; do eval printf "%s" "\" -p \$exported_$p\""; done))"
+ ;;
+ *)
+ # single dependency
+ parent=$(eval printf "\$exported_$deps")
+ ;;
+ esac
+
+ exported="$(msg "$1" |
+ git stripspace |
+ commitenv "$1" git commit-tree "$(pretty_tree "$1")" -p "$parent"
+ )"
+ eval "exported_$1=$exported"
+}
+
+## export_rev ## {{{2
+export_rev() {
+ local ref
+ assert is_sha1 "$1"
+
+ ref="$1"
+
+ recurse_deps export_rev_cmd export_rev_chk "$ref"
+
+ eval echo "\$exported_$ref"
+}
+
+## is_sha1 ## {{{2
+is_sha1() {
+ assert test "$#" = 1
+ git rev-parse -q --verify "$1" >/dev/null &&
+ test "$(git rev-parse --verify "$1")" = "$1"
+}
+
+## is_ugbase ## {{{2
+is_base() {
+ rev_has_file "$1" ".ubergit/deps"
+}
+
+## is_topic ## {{{2
+is_topic() {
+ rev_has_file "$1" ".ubergit/base"
+}
+
+## is_ugish ## {{{2
+is_ugish() {
+ rev_has_file "$1" ".ubergit/"
+}
+
+## msg ## {{{2
+msg() {
+ assert test "$#" = 1
+ assert is_topic "$1"
+
+ git cat-file blob "$1:.ubergit/msg"
+}
+
+## pretty_tree ## {{{2
+pretty_tree() {
+ git ls-tree --full-tree "$1" \
+ | awk -F ' ' '$2 != ".ubergit"' \
+ | git mktree
+}
+
+## recurse_deps ## {{{2
+## recurse_deps <cmd> <recchk> <commitish>
+recurse_deps() {
+ local recdep_cmd recdep_recchk recdep
+ recdep_cmd="$1"; shift
+ recdep_recchk="$1"; shift
+
+ if is_topic "$1" && "$recdep_recchk" "$@"; then
+ for recdep in $(deps "$1"); do
+ debug "recurse: patch=$1, dep=$recdep"
+ recurse_deps "$recdep_cmd" "$recdep_recchk" "$recdep" "$@" || return "$?"
+ done
+ fi
+
+ "$recdep_cmd" "$@"
+}
+
+## rev_has_file ## {{{2
+rev_has_file() {
+ git ls-tree --full-tree --name-only "$1" "$2" | grep . > /dev/null
+}
+
+## rev_verify ## {{{2
+rev_verify() {
+ git rev-parse --verify -q "$1" >/dev/null
+}
+
+## sq ## {{{2
+sq() {
+ # depends on git >= v1.6.4-rc0~24^2~22
+ git rev-parse --sq-quote "$@"
+}
+
+## option parsing ## {{{1
+if test -n "$UG_OPTIONS_SPEC"; then
+ # depends on git >= v1.7.2-rc3~1^2~2, because before passing
+ # --keep-dashdash made git ignore --stop-at-non-option
+ #eval "$(printf "%s\n" "$UG_OPTIONS_SPEC" | git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- "$@" || exit "$?")"
+ eval "$(printf "%s\n" "$UG_OPTIONS_SPEC" | git rev-parse --parseopt --stop-at-non-option -- "$@" || exit "$?")"
+fi