2 # TopGit contains command
3 # (C) 2017 Kyle J. McKay <mackyle@gmail.com>
8 Usage: ${tgname:-tg} [...] contains [-v] [-r] [--ann] [--no-strict] [--] <committish>"
12 if [ "${1:-0}" != 0 ]; then
13 printf '%s\n' "$USAGE" >&2
15 printf '%s\n' "$USAGE"
25 while [ $# -gt 0 ]; do case "$1" in
32 --ann|
--annihilated|
--annihilated-ok|
--annihilated-okay)
36 echo "Did you mean --verbose (-v) instead of --heads?" >&2
40 verbose
=$
(( ${verbose:-0} + 1 ))
42 -vv|
-vvv|
-vvvv|
-vvvvv)
43 verbose
=$
(( ${verbose:-0} + ${#1} - 1 ))
56 echo "Unknown option: $1" >&2
64 [ "$1" != "@" ] ||
set -- HEAD
67 findrev
="$(git rev-parse --verify "$1"^0 --)" ||
exit 1
69 # $1 => return correct $topbases value in here on success
71 # $3 => remote branch name
72 # succeeds if both refs/remotes/$2/$3 and refs/remotes/$2/${$1#heads/}/$3 exist
73 v_is_remote_tgbranch
()
75 git rev-parse
--quiet --verify "refs/remotes/$2/$3^0" -- >/dev
/null ||
return 1
76 if git rev-parse
--quiet --verify "refs/remotes/$2/${topbases#heads/}/$3^0" -- >/dev
/null
; then
77 [ -z "$1" ] ||
eval "$1="'"$topbases"'
80 git rev-parse
--quiet --verify "refs/remotes/$2/${oldbases#heads/}/$3^0" -- >/dev
/null ||
return 1
81 if [ -z "$annok" ]; then
82 rmb
="$(git merge-base "refs
/remotes
/$2/${oldbases#heads/}/$3^
0" "refs
/remotes
/$2/$3^
0" 2>/dev/null)" ||
:
83 if [ -n "$rmb" ]; then
84 rmbtree
="$(git rev-parse --quiet --verify "$rmb^
{tree
}" --)" ||
:
87 rbrtree
="$(git rev-parse --quiet --verify "refs
/remotes
/$2/$3^
{tree
}" --)" ||
:
88 [ -z "$rmbtree" ] ||
[ -z "$rbrtree" ] ||
[ "$rmbtree" != "$rbrtree" ] ||
return 1
91 [ -z "$1" ] ||
eval "$1="'"$oldbases"'
96 if [ -n "$_dep_is_tgish" ] && [ -z "$_dep_missing$_dep_annihilated" ]; then
97 printf '%s\n' "$_dep ${_depchain##* }"
106 depslist
="$(get_temp depslist)"
107 tg summary
--topgit-heads |
108 while read -r onetghead
; do
109 printf '%s %s\n' "$onetghead" "$onetghead"
110 recurse_deps process_dep
"$onetghead"
111 done |
sort -u >"$depslist"
116 localb
="$(get_temp localb)"
120 [ -z "$remotes" ] || remoteb
="$(get_temp remoteb)"
121 while IFS
= read -r branch
&& [ -n "$branch" ]; do
122 branch
="${branch#??}"
123 if v_verify_topgit_branch
"" "$branch" -f; then
124 [ -n "$annok" ] ||
! branch_annihilated
"$branch" ||
continue
125 if contained_by
"$findrev" "refs/$topbases/$branch"; then
126 [ -z "$strict" ] ||
continue
127 depth
="$(git rev-list --count --ancestry-path "refs
/$topbases/$branch" --not "$findrev")"
128 depth
=$
(( ${depth:-0} + 1 ))
132 localcnt
=$
(( ${localcnt:-0} + 1 ))
133 [ ${#branch} -le $localwide ] || localwide
=${#branch}
134 printf '%s %s\n' "$depth" "$branch" >>"$localb"
137 [ -n "$remotes" ] && [ -z "$localcnt" ] && [ "${branch#remotes/}" != "$branch" ] ||
continue
138 rbranch
="${branch#remotes/}"
139 rremote
="${rbranch%%/*}"
140 rbranch
="${rbranch#*/}"
141 [ "remotes/$rremote/$rbranch" = "$branch" ] ||
continue
142 v_is_remote_tgbranch rtopbases
"$rremote" "$rbranch" ||
continue
143 if contained_by
"$findrev" "refs/remotes/$rremote/${rtopbases#heads/}/$rbranch"; then
144 [ -z "$strict" ] ||
continue
145 depth
="$(git rev-list --count --ancestry-path "refs
/remotes
/$rremote/${rtopbases#heads/}/$rbranch" --not "$findrev")"
146 depth
=$
(( ${depth:-0} + 1 ))
150 remotecnt
=$
(( ${remotecnt:-0} + 1 ))
151 [ ${#branch} -le $remotewide ] || remotewide
=${#branch}
152 [ -n "$remoteb" ] || remoteb
="$(get_temp remoteb)"
153 printf '%s %s\n' "$depth" "remotes/$rremote/$rbranch" >>"$remoteb"
156 $(git branch ${remotes:+-a} --contains "$findrev")
158 [ -n "$localcnt$remotecnt" ] ||
exit 1
159 [ -z "$localcnt" ] ||
[ ${verbose:-0} -le 0 ] || make_deps_list
160 if [ -n "$localcnt" ]; then
168 sort -k1,1n
"$process" |
169 while read -r depth ref
; do
170 [ -n "$mindepth" ] || mindepth
="$depth"
171 [ $depth -le $mindepth ] ||
continue
174 while read -r oneresult
; do
177 [ -z "$annok" ] ||
[ -z "$depslist" ] ||
! branch_annihilated
"$oneresult" || isann
=1
178 [ -z "$depslist" ] ||
[ -n "$isann" ] ||
179 headinfo
="$(printf '%s\n' "$oneresult" | join -o 2.2 - "$depslist" |
180 sort -u | paste -d , -s - | sed -e 's/,/, /g')"
181 [ -z "$annok" ] ||
[ -z "$depslist" ] ||
[ -z "$isann" ] || headinfo
=":annihilated:"
182 if [ -z "$headinfo" ]; then
183 printf '%s\n' "$oneresult"
185 printf '%-*s [%s]\n' $minwide "$oneresult" "$headinfo"