2 # TopGit contains command
3 # (C) 2017 Kyle J. McKay <mackyle@gmail.com>
8 Usage: ${tgname:-tg} [...] contains [-v] [-r] [--no-strict] [--] <committish>"
12 if [ "${1:-0}" != 0 ]; then
13 printf '%s\n' "$USAGE" >&2
15 printf '%s\n' "$USAGE"
24 while [ $# -gt 0 ]; do case "$1" in
32 echo "Did you mean --verbose (-v) instead of --heads?" >&2
36 verbose
=$
(( ${verbose:-0} + 1 ))
38 -vv|
-vvv|
-vvvv|
-vvvvv)
39 verbose
=$
(( ${verbose:-0} + ${#1} - 1 ))
52 echo "Unknown option: $1" >&2
60 [ "$1" != "@" ] ||
set -- HEAD
63 findrev
="$(git rev-parse --verify "$1"^0 --)" ||
exit 1
65 # true if $1 is contained by (or the same as) $2
68 [ "$(git rev-list --count --max-count=1 "$1" --not "$2" --)" = "0" ]
71 # $1 => return correct $topbases value in here on success
73 # $3 => remote branch name
74 # succeeds if both refs/remotes/$2/$3 and refs/remotes/$2/${$1#heads/}/$3 exist
75 v_is_remote_tgbranch
()
77 git rev-parse
--quiet --verify "refs/remotes/$2/$3^0" -- >/dev
/null ||
return 1
78 if git rev-parse
--quiet --verify "refs/remotes/$2/${topbases#heads/}/$3^0" -- >/dev
/null
; then
79 [ -z "$1" ] ||
eval "$1="'"$topbases"'
82 git rev-parse
--quiet --verify "refs/remotes/$2/${oldbases#heads/}/$3^0" -- >/dev
/null ||
return 1
83 [ -z "$1" ] ||
eval "$1="'"$oldbases"'
88 if [ -n "$_dep_is_tgish" ] && [ -z "$_dep_missing$_dep_annihilated" ]; then
89 printf '%s\n' "$_dep ${_depchain##* }"
98 depslist
="$(get_temp depslist)"
99 $tg summary
--topgit-heads |
100 while read -r onetghead
; do
101 printf '%s %s\n' "$onetghead" "$onetghead"
102 recurse_deps process_dep
"$onetghead"
103 done | LC_ALL
=C
sort -u >"$depslist"
108 localb
="$(get_temp localb)"
112 [ -z "$remotes" ] || remoteb
="$(get_temp remoteb)"
113 while IFS
= read -r branch
&& [ -n "$branch" ]; do
114 branch
="${branch#??}"
115 if v_verify_topgit_branch
"" "$branch" -f; then
116 if contained_by
"$findrev" "refs/$topbases/$branch"; then
117 [ -z "$strict" ] ||
continue
118 depth
="$(git rev-list --count --ancestry-path "refs
/$topbases/$branch" --not "$findrev")"
119 depth
=$
(( ${depth:-0} + 1 ))
123 localcnt
=$
(( ${localcnt:-0} + 1 ))
124 [ ${#branch} -le $localwide ] || localwide
=${#branch}
125 printf '%s %s\n' "$depth" "$branch" >>"$localb"
128 [ -n "$remotes" ] && [ -z "$localcnt" ] && [ "${branch#remotes/}" != "$branch" ] ||
continue
129 rbranch
="${branch#remotes/}"
130 rremote
="${rbranch%%/*}"
131 rbranch
="${rbranch#*/}"
132 [ "remotes/$rremote/$rbranch" = "$branch" ] ||
continue
133 v_is_remote_tgbranch rtopbases
"$rremote" "$rbranch" ||
continue
134 if contained_by
"$findrev" "refs/remotes/$rremote/${rtopbases#heads/}/$rbranch"; then
135 [ -z "$strict" ] ||
continue
136 depth
="$(git rev-list --count --ancestry-path "refs
/remotes
/$rremote/${rtopbases#heads/}/$rbranch" --not "$findrev")"
137 depth
=$
(( ${depth:-0} + 1 ))
141 remotecnt
=$
(( ${remotecnt:-0} + 1 ))
142 [ ${#branch} -le $remotewide ] || remotewide
=${#branch}
143 [ -n "$remoteb" ] || remoteb
="$(get_temp remoteb)"
144 printf '%s %s\n' "$depth" "remotes/$rremote/$rbranch" >>"$remoteb"
147 $(git branch ${remotes:+-a} --contains "$findrev")
149 [ -n "$localcnt$remotecnt" ] ||
exit 1
150 [ -z "$localcnt" ] ||
[ ${verbose:-0} -le 0 ] || make_deps_list
151 if [ -n "$localcnt" ]; then
159 LC_ALL
=C
sort -k1,1n
"$process" |
160 while read -r depth ref
; do
161 [ -n "$mindepth" ] || mindepth
="$depth"
162 [ $depth -le $mindepth ] ||
continue
164 done | LC_ALL
=C
sort -u |
165 while read -r oneresult
; do
167 [ -z "$depslist" ] ||
168 headinfo
="$(printf '%s\n' "$oneresult" | join -o 2.2 - "$depslist" |
169 LC_ALL=C sort -u | paste -d , -s - | sed -e 's/,/, /g')"
170 if [ -z "$headinfo" ]; then
171 printf '%s\n' "$oneresult"
173 printf '%-*s [%s]\n' $minwide "$oneresult" "$headinfo"