tg.sh: include bad ref in ref_exists_rev failure message
[topgit/pro.git] / tg-info.sh
blob3de77970ede628db49dec6aa0f9b1e2804d8252d
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, 2016, 2017
5 # GPLv2
7 USAGE="Usage: ${tgname:-tg} [...] info [--heads | --leaves] [<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=
22 leaves=
23 verbose=
25 while [ $# -gt 0 ]; do case "$1" in
26 -h|--help)
27 usage
29 --heads)
30 heads=1
32 --leaves)
33 leaves=1
35 -v|--verbose)
36 verbose=$(( ${verbose:-0} + 1 ))
38 -vv|-vvv|-vvvv|-vvvvv)
39 verbose=$(( ${verbose:-0} + ${#1} - 1 ))
41 -?*)
42 echo "Unknown option: $1" >&2
43 usage 1
46 break
48 esac; shift; done
49 [ "$heads$leaves" != "11" ] || die "mutually exclusive options --heads and --leaves"
50 [ $# -gt 0 ] || set -- HEAD
51 [ $# -eq 1 ] || die "name already specified ($1)"
52 name="$1"
54 process_dep()
56 if [ -n "$_dep_is_tgish" ] && [ -z "$_dep_missing$_dep_annihilated" ]; then
57 printf '%s\n' "$_dep ${_depchain##* }"
61 if [ -n "$heads" ]; then
62 no_remotes=1
63 base_remote=
64 verify="$name"
65 ! test="$(verify_topgit_branch "${name:-HEAD}" -f)" || verify="refs/heads/$test"
66 hash="$(git rev-parse --verify --quiet "$verify" --)" || die "no such ref: $name"
67 depslist="$(get_temp depslist)"
68 tg summary --topgit-heads |
69 while read -r onetghead; do
70 printf '%s %s\n' "$onetghead" "$onetghead"
71 recurse_deps process_dep "$onetghead"
72 done | sort -u >"$depslist"
73 git branch --no-color --contains "$hash" | cut -c 3- |
74 join -o 2.2 - "$depslist" |
75 sort -u
76 exit 0
79 name="$(verify_topgit_branch "${name:-HEAD}")"
80 if [ -n "$leaves" ]; then
81 find_leaves "$name"
82 exit 0
84 base_rev="$(git rev-parse --short --verify "refs/$topbases/$name" -- 2>/dev/null)" ||
85 die "not a TopGit-controlled branch"
87 measure="$(measure_branch "refs/heads/$name" "$base_rev")"
89 echo "Topic Branch: $name ($measure)"
91 nocommits=
92 [ "$(git rev-parse --verify --short "refs/heads/$name" --)" != "$base_rev" ] || nocommits=1
94 [ -n "$nocommits" ] || git cat-file blob "$name:.topmsg" 2>/dev/null | grep ^Subject: || :
96 if [ "${verbose:-0}" -ge 1 ]; then
97 scratch="$(get_temp scratch)"
98 printf '%s\n' "$name" >"$scratch"
99 dependents="$(get_temp dependents_list)"
100 tg summary --deps | sort -k2,2 | join -1 2 - "$scratch" | cut -d ' ' -f 2 | sort -u >"$dependents"
101 if ! [ -s "$dependents" ]; then
102 echo "Dependents: [none]"
103 else
104 if [ "${verbose:-0}" -le 1 ]; then
105 sed '1{ s/^/Dependents: /; n; }; s/^/ /;' <"$dependents"
106 else
107 minwidth=0
108 while read -r endent; do
109 [ ${#endent} -le $minwidth ] || minwidth=${#endent}
110 done <"$dependents"
111 prefix="Dependents:"
112 while read -r endent; do
113 ood=
114 contained_by "refs/heads/$name" "refs/$topbases/$endent" || ood=1
115 if [ -n "$ood" ]; then
116 printf '%s %-*s [needs merge]\n' "$prefix" $minwidth "$endent"
117 else
118 printf '%s %s\n' "$prefix" "$endent"
120 prefix=" "
121 done <"$dependents"
126 if [ -n "$nocommits" ]; then
127 echo "* No commits."
128 exit 0
131 echo "Base: $base_rev"
132 branch_contains "refs/heads/$name" "refs/$topbases/$name" ||
133 echo "* Base is newer than head! Please run \`$tgdisplay update\`."
135 if has_remote "$name"; then
136 echo "Remote Mate: $base_remote/$name"
137 branch_contains "refs/$topbases/$name" "refs/remotes/$base_remote/${topbases#heads/}/$name" ||
138 echo "* Local base is out of date wrt. the remote base."
139 branch_contains "refs/heads/$name" "refs/remotes/$base_remote/$name" ||
140 echo "* Local head is out of date wrt. the remote head."
141 branch_contains "refs/remotes/$base_remote/$name" "refs/heads/$name" ||
142 echo "* Local head is ahead of the remote head."
145 git cat-file blob "$name:.topdeps" 2>/dev/null |
146 sed '1{ s/^/Depends: /; n; }; s/^/ /;'
148 depcheck="$(get_temp tg-depcheck)"
149 missing_deps=
150 needs_update "$name" >"$depcheck" || :
151 if [ -n "$missing_deps" ]; then
152 echo "MISSING: $missing_deps"
154 depcheck2="$(get_temp tg-depcheck2)"
155 sed '/^!/d' <"$depcheck" >"$depcheck2"
156 if [ -s "$depcheck2" ]; then
157 echo "Needs update from:"
158 # 's/ [^ ]* *$//' -- last is $name
159 # 's/^[:] /:/' -- don't distinguish base updates
160 <"$depcheck2" sed -e 's/ [^ ]* *$//' -e 's/^[:] /:/' |
161 while read dep chain; do
162 case "$dep" in
164 dep="${dep#:}"
165 fulldep="refs/heads/$dep"
166 extradep="refs/$topbases/$dep"
169 extradep=
170 case "$dep" in
171 refs/*)
172 fulldep="$dep";;
174 fulldep="refs/heads/$dep";;
175 esac
177 esac
178 printf '%s' "$dep "
179 [ -n "$chain" ] && printf '%s' "(<= $(echol "$chain" | sed 's/ / <= /')) "
180 printf '%s' "($(eval measure_branch '"$fulldep"' '"refs/heads/$name"' ${extradep:+\"\$extradep\"}))"
181 echo
182 done | sed 's/^/ /'
183 else
184 echo "Up-to-date${missing_deps:+ (except for missing dependencies)}."