X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=tg.sh;h=f1b323b7cbe543994f373523ab2b84b814fd0adc;hb=49b02b3a83f5f17c973b11111a48f8fde1df50b5;hp=1f259e3a03d60dad30bac2a34253cd9a78a1d7ca;hpb=f59e4f9e87e5f485fdaee0af002edd2105fa298a;p=topgit.git diff --git a/tg.sh b/tg.sh index 1f259e3..f1b323b 100644 --- a/tg.sh +++ b/tg.sh @@ -14,7 +14,7 @@ info() die() { - info "fatal: $*" + info "fatal: $*" >&2 exit 1 } @@ -25,20 +25,67 @@ cat_file() arg="$1" case "$arg" in '(w):'*) - arg=$(echo "$arg" | tail --bytes=+5) - cat "$arg" - return + cat "${arg#(w):}" ;; '(i):'*) # ':file' means cat from index - arg=$(echo "$arg" | tail --bytes=+5) - git cat-file blob ":$arg" + git cat-file blob "${arg#(i)}" ;; *) git cat-file blob "$arg" + ;; esac } +# get tree for the committed topic +get_tree_() +{ + echo "$1" +} + +# get tree for the base +get_tree_b() +{ + echo "refs/top-bases/$1" +} + +# get tree for the index +get_tree_i() +{ + git write-tree +} + +# get tree for the worktree +get_tree_w() +{ + i_tree=$(git write-tree) + ( + # the file for --index-output needs to sit next to the + # current index file + : ${GIT_INDEX_FILE:="$git_dir/index"} + TMP_INDEX="$(mktemp "${GIT_INDEX_FILE}-tg.XXXXXX")" + git read-tree -m $i_tree --index-output="$TMP_INDEX" && + GIT_INDEX_FILE="$TMP_INDEX" && + export GIT_INDEX_FILE && + git diff --name-only -z HEAD | + git update-index -z --add --remove --stdin && + git write-tree && + rm -f "$TMP_INDEX" + ) +} + +# pretty_tree NAME [-b | -i | -w] +# Output tree ID of a cleaned-up tree without tg's artifacts. +# NAME will be ignored for -i and -w, but needs to be present +pretty_tree() +{ + name=$1 + source=${2#?} + git ls-tree --full-tree "$(get_tree_$source "$name")" | + awk -F ' ' '$2 !~ /^.top/' | + git mktree +} + # setup_hook NAME setup_hook() { @@ -54,6 +101,8 @@ setup_hook() else hook_call="exec $hook_call" fi + # Don't call hook if tg is not installed + hook_call="if which \"$tg\" > /dev/null; then $hook_call; fi" # Insert call into the hook { echo "#!/bin/sh" @@ -126,6 +175,13 @@ branch_annihilated() test "$(git rev-parse "$mb^{tree}")" = "$(git rev-parse "$_name^{tree}")"; } +# is_sha1 REF +# Whether REF is a SHA1 (compared to a symbolic name). +is_sha1() +{ + [ "$(git rev-parse "$1")" = "$1" ] +} + # recurse_deps CMD NAME [BRANCHPATH...] # Recursively eval CMD on all dependencies of NAME. # CMD can refer to $_name for queried branch name, @@ -230,6 +286,27 @@ branch_empty() [ -z "$(git diff-tree "refs/top-bases/$1" "$1" -- | fgrep -v " .top")" ] } +# list_deps +list_deps() +{ + git for-each-ref refs/top-bases | + while read rev type ref; do + name="${ref#refs/top-bases/}" + if branch_annihilated "$name"; then + continue; + fi + + git cat-file blob "$name:.topdeps" | while read dep; do + dep_is_tgish=true + ref_exists "refs/top-bases/$dep" || + dep_is_tgish=false + if ! "$dep_is_tgish" || ! branch_annihilated $dep; then + echo "$name $dep" + fi + done + done +} + # switch_to_base NAME [SEED] switch_to_base() { @@ -304,7 +381,7 @@ setup_pager() # now spawn pager - export LESS=${LESS:-FRSX} # as in pager.c:pager_preexec() + export LESS="${LESS:-FRSX}" # as in pager.c:pager_preexec() _pager_fifo_dir="$(mktemp -t -d tg-pager-fifo.XXXXXX)" _pager_fifo="$_pager_fifo_dir/0"