tg: accomodate multiple git worktrees
[topgit/pro.git] / tg-info.sh
blob1e66d84f6316b3a6373f069d5543cb1c448d36b1
1 #!/bin/sh
2 # TopGit - A different patch queue manager
3 # Copyright (C) Petr Baudis <pasky@suse.cz> 2008
4 # Copyright (C) Kyle J. McKay <mackyle@gmail.com> 2015
5 # GPLv2
7 USAGE="Usage: ${tgname:-tg} [...] info [--heads] [<name>]"
9 usage()
11 if [ "${1:-0}" != 0 ]; then
12 printf '%s\n' "$USAGE" >&2
13 else
14 printf '%s\n' "$USAGE"
16 exit ${1:-0}
19 ## Parse options
21 heads=
23 while [ $# -gt 0 ]; do case "$1" in
24 -h|--help)
25 usage
27 --heads)
28 heads=1
30 -?*)
31 echo "Unknown option: $1" >&2
32 usage 1
35 break
37 esac; shift; done
38 [ $# -gt 0 ] || set -- HEAD
39 [ $# -eq 1 ] || die "name already specified ($1)"
40 name="$1"
42 # true if $1 is an ancestor of (or the same as) $2
43 is_ancestor()
45 [ "$(git rev-list --count --max-count=1 "$1" --not "$2" --)" = "0" ]
48 if [ -n "$heads" ]; then
49 verify="$name"
50 ! test="$(verify_topgit_branch "${name:-HEAD}" -f)" || verify="refs/heads/$test"
51 hash="$(git rev-parse --verify --quiet "$verify" --)" || die "no such ref: $name"
52 $tg summary --tgish-only --heads |
53 while read -r head; do
54 if is_ancestor "$hash" "refs/heads/$head"; then
55 printf '%s\n' "$head"
57 done
58 exit 0
61 name="$(verify_topgit_branch "${name:-HEAD}")"
62 base_rev="$(git rev-parse --short --verify "refs/$topbases/$name" -- 2>/dev/null)" ||
63 die "not a TopGit-controlled branch"
65 measure="$(measure_branch "refs/heads/$name" "$base_rev")"
67 echo "Topic Branch: $name ($measure)"
68 if [ "$(git rev-parse --verify --short "refs/heads/$name" --)" = "$base_rev" ]; then
69 echo "* No commits."
70 exit 0
73 git cat-file blob "$name:.topmsg" | grep ^Subject: || :
75 echo "Base: $base_rev"
76 branch_contains "refs/heads/$name" "refs/$topbases/$name" ||
77 echo "* Base is newer than head! Please run \`$tgdisplay update\`."
79 if has_remote "$name"; then
80 echo "Remote Mate: $base_remote/$name"
81 branch_contains "refs/$topbases/$name" "refs/remotes/$base_remote/$topbases/$name" ||
82 echo "* Local base is out of date wrt. the remote base."
83 branch_contains "refs/heads/$name" "refs/remotes/$base_remote/$name" ||
84 echo "* Local head is out of date wrt. the remote head."
85 branch_contains "refs/remotes/$base_remote/$name" "refs/heads/$name" ||
86 echo "* Local head is ahead of the remote head."
89 git cat-file blob "$name:.topdeps" 2>/dev/null |
90 sed '1{ s/^/Depends: /; n; }; s/^/ /;'
92 depcheck="$(get_temp tg-depcheck)"
93 missing_deps=
94 needs_update "$name" >"$depcheck" || :
95 if [ -n "$missing_deps" ]; then
96 echo "MISSING: $missing_deps"
98 depcheck2="$(get_temp tg-depcheck2)"
99 sed '/^!/d' <"$depcheck" >"$depcheck2"
100 if [ -s "$depcheck2" ]; then
101 echo "Needs update from:"
102 # 's/ [^ ]* *$//' -- last is $name
103 # 's/^[:] /:/' -- don't distinguish base updates
104 <"$depcheck2" sed -e 's/ [^ ]* *$//' -e 's/^[:] /:/' |
105 while read dep chain; do
106 case "$dep" in
108 dep="${dep#:}"
109 fulldep="refs/heads/$dep"
110 extradep="refs/$topbases/$dep"
113 extradep=
114 case "$dep" in
115 refs/*)
116 fulldep="$dep";;
118 fulldep="refs/heads/$dep";;
119 esac
121 esac
122 printf '%s' "$dep "
123 [ -n "$chain" ] && printf '%s' "(<= $(echol "$chain" | sed 's/ / <= /')) "
124 printf '%s' "($(eval measure_branch '"$fulldep"' '"refs/heads/$name"' ${extradep:+\"\$extradep\"}))"
125 echo
126 done | sed 's/^/ /'
127 else
128 echo "Up-to-date${missing_deps:+ (except for missing dependencies)}."
131 # vim:noet