tg-contains.sh: new command to show containing TopGit branch(es)
[topgit/pro.git] / tg-info.sh
blobac846e9b98817beec3cd31dc492a0be925b4f9d4
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=
24 while [ $# -gt 0 ]; do case "$1" in
25 -h|--help)
26 usage
28 --heads)
29 heads=1
31 --leaves)
32 leaves=1
34 -?*)
35 echo "Unknown option: $1" >&2
36 usage 1
39 break
41 esac; shift; done
42 [ "$heads$leaves" != "11" ] || die "mutually exclusive options --heads and --leaves"
43 [ $# -gt 0 ] || set -- HEAD
44 [ $# -eq 1 ] || die "name already specified ($1)"
45 name="$1"
47 process_dep()
49 if [ -n "$_dep_is_tgish" ] && [ -z "$_dep_missing$_dep_annihilated" ]; then
50 printf '%s\n' "$_dep ${_depchain##* }"
54 if [ -n "$heads" ]; then
55 no_remotes=1
56 base_remote=
57 verify="$name"
58 ! test="$(verify_topgit_branch "${name:-HEAD}" -f)" || verify="refs/heads/$test"
59 hash="$(git rev-parse --verify --quiet "$verify" --)" || die "no such ref: $name"
60 depslist="$(get_temp depslist)"
61 $tg summary --topgit-heads |
62 while read -r onetghead; do
63 printf '%s %s\n' "$onetghead" "$onetghead"
64 recurse_deps process_dep "$onetghead"
65 done | LC_ALL=C sort -u >"$depslist"
66 git branch --no-color --contains "$hash" | LC_ALL=C cut -c 3- |
67 LC_ALL=C join -o 2.2 - "$depslist" |
68 LC_ALL=C sort -u
69 exit 0
72 name="$(verify_topgit_branch "${name:-HEAD}")"
73 if [ -n "$leaves" ]; then
74 find_leaves "$name"
75 exit 0
77 base_rev="$(git rev-parse --short --verify "refs/$topbases/$name" -- 2>/dev/null)" ||
78 die "not a TopGit-controlled branch"
80 measure="$(measure_branch "refs/heads/$name" "$base_rev")"
82 echo "Topic Branch: $name ($measure)"
83 if [ "$(git rev-parse --verify --short "refs/heads/$name" --)" = "$base_rev" ]; then
84 echo "* No commits."
85 exit 0
88 git cat-file blob "$name:.topmsg" | grep ^Subject: || :
90 echo "Base: $base_rev"
91 branch_contains "refs/heads/$name" "refs/$topbases/$name" ||
92 echo "* Base is newer than head! Please run \`$tgdisplay update\`."
94 if has_remote "$name"; then
95 echo "Remote Mate: $base_remote/$name"
96 branch_contains "refs/$topbases/$name" "refs/remotes/$base_remote/${topbases#heads/}/$name" ||
97 echo "* Local base is out of date wrt. the remote base."
98 branch_contains "refs/heads/$name" "refs/remotes/$base_remote/$name" ||
99 echo "* Local head is out of date wrt. the remote head."
100 branch_contains "refs/remotes/$base_remote/$name" "refs/heads/$name" ||
101 echo "* Local head is ahead of the remote head."
104 git cat-file blob "$name:.topdeps" 2>/dev/null |
105 sed '1{ s/^/Depends: /; n; }; s/^/ /;'
107 depcheck="$(get_temp tg-depcheck)"
108 missing_deps=
109 needs_update "$name" >"$depcheck" || :
110 if [ -n "$missing_deps" ]; then
111 echo "MISSING: $missing_deps"
113 depcheck2="$(get_temp tg-depcheck2)"
114 sed '/^!/d' <"$depcheck" >"$depcheck2"
115 if [ -s "$depcheck2" ]; then
116 echo "Needs update from:"
117 # 's/ [^ ]* *$//' -- last is $name
118 # 's/^[:] /:/' -- don't distinguish base updates
119 <"$depcheck2" sed -e 's/ [^ ]* *$//' -e 's/^[:] /:/' |
120 while read dep chain; do
121 case "$dep" in
123 dep="${dep#:}"
124 fulldep="refs/heads/$dep"
125 extradep="refs/$topbases/$dep"
128 extradep=
129 case "$dep" in
130 refs/*)
131 fulldep="$dep";;
133 fulldep="refs/heads/$dep";;
134 esac
136 esac
137 printf '%s' "$dep "
138 [ -n "$chain" ] && printf '%s' "(<= $(echol "$chain" | sed 's/ / <= /')) "
139 printf '%s' "($(eval measure_branch '"$fulldep"' '"refs/heads/$name"' ${extradep:+\"\$extradep\"}))"
140 echo
141 done | sed 's/^/ /'
142 else
143 echo "Up-to-date${missing_deps:+ (except for missing dependencies)}."
146 # vim:noet