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 case "$branch" in ""|
*[" $tab"]*) continue; esac
124 if v_verify_topgit_branch
"" "$branch" -f; then
125 [ -n "$annok" ] ||
! branch_annihilated
"$branch" ||
continue
126 if contained_by
"$findrev" "refs/$topbases/$branch"; then
127 [ -z "$strict" ] ||
continue
128 depth
="$(git rev-list --count --ancestry-path "refs
/$topbases/$branch" --not "$findrev")"
129 depth
=$
(( ${depth:-0} + 1 ))
133 localcnt
=$
(( ${localcnt:-0} + 1 ))
134 [ ${#branch} -le $localwide ] || localwide
=${#branch}
135 printf '%s %s\n' "$depth" "$branch" >>"$localb"
138 [ -n "$remotes" ] && [ -z "$localcnt" ] && [ "${branch#remotes/}" != "$branch" ] ||
continue
139 rbranch
="${branch#remotes/}"
140 rremote
="${rbranch%%/*}"
141 rbranch
="${rbranch#*/}"
142 [ "remotes/$rremote/$rbranch" = "$branch" ] ||
continue
143 v_is_remote_tgbranch rtopbases
"$rremote" "$rbranch" ||
continue
144 if contained_by
"$findrev" "refs/remotes/$rremote/${rtopbases#heads/}/$rbranch"; then
145 [ -z "$strict" ] ||
continue
146 depth
="$(git rev-list --count --ancestry-path "refs
/remotes
/$rremote/${rtopbases#heads/}/$rbranch" --not "$findrev")"
147 depth
=$
(( ${depth:-0} + 1 ))
151 remotecnt
=$
(( ${remotecnt:-0} + 1 ))
152 [ ${#branch} -le $remotewide ] || remotewide
=${#branch}
153 [ -n "$remoteb" ] || remoteb
="$(get_temp remoteb)"
154 printf '%s %s\n' "$depth" "remotes/$rremote/$rbranch" >>"$remoteb"
157 $(git branch --no-color ${remotes:+-a} --contains "$findrev")
159 [ -n "$localcnt$remotecnt" ] ||
exit 1
160 [ -z "$localcnt" ] ||
[ ${verbose:-0} -le 0 ] || make_deps_list
161 if [ -n "$localcnt" ]; then
169 sort -k1,1n
"$process" |
170 while read -r depth ref
; do
171 [ -n "$mindepth" ] || mindepth
="$depth"
172 [ $depth -le $mindepth ] ||
continue
175 while read -r oneresult
; do
178 [ -z "$annok" ] ||
[ -z "$depslist" ] ||
! branch_annihilated
"$oneresult" || isann
=1
179 [ -z "$depslist" ] ||
[ -n "$isann" ] ||
180 headinfo
="$(printf '%s\n' "$oneresult" | join -o 2.2 - "$depslist" |
181 sort -u | paste -d , -s - | sed -e 's/,/, /g')"
182 [ -z "$annok" ] ||
[ -z "$depslist" ] ||
[ -z "$isann" ] || headinfo
=":annihilated:"
183 if [ -z "$headinfo" ]; then
184 printf '%s\n' "$oneresult"
186 printf '%-*s [%s]\n' $minwide "$oneresult" "$headinfo"