diff options
author | Uwe Kleine-König <ukleinek@strlen.de> | 2010-09-08 17:55:00 +0200 |
---|---|---|
committer | Uwe Kleine-König <ukleinek@strlen.de> | 2010-09-08 17:55:00 +0200 |
commit | 451726236e8e7b7329117d839370d7b755dba99e (patch) | |
tree | 731aa86796b99f7c760ccad127181a80cbcb0070 /uglib.sh | |
download | ubergit-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.sh | 193 |
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 |