chiark / gitweb /
Merge branch 'i/build' into refs/top-bases/i/basis-merge
[topgit.git] / tg.sh
diff --git a/tg.sh b/tg.sh
index c77898678cdd275783746b0567a6de7edb905192..838dc49185be1fa81b288830ca950725d469ae10 100644 (file)
--- a/tg.sh
+++ b/tg.sh
@@ -18,6 +18,20 @@ die()
        exit 1
 }
 
+# Make sure we are in the worktree, not under .git; die otherwise
+ensure_git_repo_or_die()
+{
+       local is_inside_repo is_inside_git_dir
+       is_inside_repo=1
+       is_inside_git_dir=$(git rev-parse --is-inside-git-dir 2>/dev/null) ||
+               is_inside_repo=0
+
+       case "$is_inside_repo/$is_inside_git_dir" in
+       0*) die "Cannot run outside of a Git repository.";;
+       1/true) die "Cannot run from inside \`.git\` hierarchy, please switch to work-tree.";;
+       esac
+}
+
 # cat_file TOPIC:PATH [FROM]
 # cat the file PATH from branch TOPIC when FROM is empty.
 # FROM can be -i or -w, than the file will be from the index or worktree,
@@ -284,15 +298,23 @@ needs_update()
        recurse_deps branch_needs_update "$@"
 }
 
-# branch_empty NAME
+# branch_empty NAME [-i | -w]
 branch_empty()
 {
-       [ -z "$(git diff-tree "refs/top-bases/$1" "$1" -- | fgrep -v "  .top")" ]
+       [ "$(pretty_tree "$1" -b)" = "$(pretty_tree "$1" ${2-})" ]
 }
 
-# list_deps
+# list_deps [-i | -w]
+# -i/-w apply only to HEAD
 list_deps()
 {
+       local head
+       local head_from
+       local from
+       head_from=${1-}
+       head="$(git symbolic-ref -q HEAD)" ||
+               head="..detached.."
+
        git for-each-ref refs/top-bases |
                while read rev type ref; do
                        name="${ref#refs/top-bases/}"
@@ -300,7 +322,10 @@ list_deps()
                                continue;
                        fi
 
-                       git cat-file blob "$name:.topdeps" | while read dep; do
+                       from=$head_from
+                       [ "refs/heads/$name" = "$head" ] ||
+                               from=
+                       cat_file "$name:.topdeps" $from | while read dep; do
                                dep_is_tgish=true
                                ref_exists "refs/top-bases/$dep"  ||
                                        dep_is_tgish=false
@@ -353,8 +378,8 @@ do_help()
                setup_pager
                @cmddir@/tg-$1 -h 2>&1 || :
                echo
-               if [ -r "@sharedir@/tg-$1.txt" ] ; then
-                       cat "@sharedir@/tg-$1.txt"
+               if [ -r "@docdir@/tg-$1.txt" ] ; then
+                       cat "@docdir@/tg-$1.txt"
                fi
        else
                echo "`basename $0`: no help for $1" 1>&2
@@ -363,6 +388,29 @@ do_help()
        fi
 }
 
+# Check whether we are supposed to output the help message
+should_do_help()
+{
+       # we are being sourced for utility functions, never run help
+       [ -z "$tg__include" ] || return 1
+
+       local prev
+       while [ -n "$1" ]; do
+               case "$1" in
+               help|--help|-h)
+                       shift
+                       echo "${1:-$prev}"
+                       return 0
+               esac
+               prev="$1"
+               shift
+       done
+
+       # run help when there was no previous topic, meaning that there where
+       # no arguments at all
+       test -z "$prev"
+}
+
 ## Pager stuff
 
 # isatty FD
@@ -416,6 +464,11 @@ get_temp()
 [ -d "@cmddir@" ] ||
        die "No command directory: '@cmddir@'"
 
+# check if we should run help and get the topic while we're at it
+help_topic="$(should_do_help "$@")" && { do_help "$help_topic"; exit 0; }
+
+ensure_git_repo_or_die
+
 ## Initial setup
 
 set -e
@@ -455,9 +508,6 @@ cmd="$1"
 shift
 
 case "$cmd" in
-help|--help|-h)
-       do_help "$1"
-       exit 0;;
 --hooks-path)
        # Internal command
        echo "@hooksdir@";;