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
30 echo "Usage: ${tgname:-tg} [...] summary [-t | --list | --heads[-only] | --sort | --deps[-only] | --rdeps | --graphviz] [-i | -w] [--tgish-only] [--with[out]-(deps|related)] [--exclude branch]... [--all | branch...]" >&2
38 [ -z "$head_from" ] || die
"-i and -w are mutually exclusive"
43 verbose
=$
(( $verbose + 1 ));;
45 terse
=1 verbose
=$
(( $verbose + 1 ));;
47 verbose
=$
(( $verbose + 2 ));;
49 terse
=1 verbose
=$
(( $verbose + 2 ));;
50 --heads|
--topgit-heads)
64 --without-deps|
--no-with-deps|
--without-related|
--no-with-related)
90 [ -n "${1#--exclude=}" ] || die
"--exclude= requires a branch name"
91 exclude
="$exclude ${1#--exclude=}";;
94 [ -n "$1" -a "$1" != "--all" ] || die
"--exclude requires a branch name"
95 exclude
="$exclude $1";;
103 [ $# -eq 0 ] || defwithdeps
=1
104 [ -z "$exclude" ] || exclude
="$exclude "
106 [ $# -ne 0 ] ||
[ z
"$head" != z
"" ] || doingall
=1
107 if [ "$1" = "--all" ]; then
108 [ -z "$withdeps" ] || die
"mutually exclusive options given"
109 [ $# -eq 1 ] || usage
115 [ "$heads$rdeps" != "11" ] ||
head=
116 [ $# -ne 0 -o -z "$head" ] ||
set -- "$head"
117 [ -z "$defwithdeps" ] ||
[ $# -ne 1 ] ||
[ z
"$1" != z
"HEAD" -a z
"$1" != z
"@" ] || defwithdeps
=2
119 [ "$terse$heads$headsonly$graphviz$sort$deps$depsonly" = "" ] ||
120 [ "$terse$heads$headsonly$graphviz$sort$deps$depsonly$rdeps" = "1" ] ||
121 [ "$terse$heads$headsonly$graphviz$sort$deps$depsonly$rdeps" = "11" -a "$heads$rdeps" = "11" ] ||
122 die
"mutually exclusive options given"
123 [ -z "$withdeps" -o -z "$rdeps$depsonly$heads$headsonly" ] ||
124 die
"mutually exclusive options given"
127 [ "$b" != "--all" ] || usage
128 branches
="$branches $(verify_topgit_branch "$b")"
133 if [ -n "$branches" ]; then
135 printf '%s\n' $branches |
sort -u
137 printf '%s\n' $branches
140 non_annihilated_branches
144 show_heads_independent
()
146 topics
="$(get_temp topics)"
147 get_branch_list |
sed -e 's,^\(.*\)$,refs/heads/\1 \1,' |
148 git cat-file
--batch-check='%(objectname) %(rest)' |
149 sort -u -b -k1,1 >"$topics"
150 git merge-base
--independent $
(cut
-d ' ' -f 1 <"$topics") |
151 sort -u -b -k1,1 |
join - "$topics" |
sort -u -b -k2,2 |
152 while read rev name
; do
153 case "$exclude" in *" $name "*) continue; esac
154 printf '%s\n' "$name"
160 if [ -n "$branches" ]; then
161 navigate_deps
-s=-1 -1 -- "$branches" |
sort
165 while read -r name
; do
166 case "$exclude" in *" $name "*) continue; esac
167 printf '%s\n' "$name"
173 if [ -n "$headsindep" ]; then
174 show_heads_independent
"$@"
176 show_heads_topgit
"$@"
180 if [ -n "$heads" -a -z "$rdeps" ]; then
187 case "$exclude" in *" $_dep "*) return; esac
188 case " $seen_deps " in *" $_dep "*) return 0; esac
189 seen_deps
="${seen_deps:+$seen_deps }$_dep"
190 [ -z "$tgish" -o -n "$_dep_is_tgish" ] ||
return 0
191 [ -z "$skip_ann" ] ||
[ -z "$_dep_annihilated" ] && printf '%s\n' "$_dep"
198 recurse_deps_exclude
=
199 get_branch_list |
while read _b
; do
200 case "$exclude" in *" $_b "*) continue; esac
201 case " $recurse_deps_exclude " in *" $_b "*) continue; esac
203 save_skip
="$skip_ann"
204 _dep
="$_b"; _dep_is_tgish
=1; skip_ann
=; show_dep
; skip_ann
="$save_skip"
205 recurse_deps show_dep
"$_b"
206 recurse_deps_exclude
="$recurse_deps_exclude $seen_deps"
210 if [ -n "$depsonly" ]; then
211 show_deps |
sort -u -b -k1,1
217 case "$exclude" in *" $_dep "*) return; esac
218 [ -z "$tgish" -o -n "$_dep_is_tgish" ] ||
return 0
220 [ -z "$rdepsonce" ] ||
[ "$_dep_xvisits" = 0 ] || elided
="^"
221 printf '%s %s\n' "$_depchain" "$_dep$elided"
224 if [ -n "$rdeps" ]; then
228 if [ -n "$heads" ]; then
234 case "$exclude" in *" $b "*) continue; esac
235 [ -z "$showbreak" ] ||
echo
237 ref_exists
"refs/heads/$b" ||
continue
241 recurse_deps
${rdepsonce:+-o=-o=-1} show_rdeps
"$b"
242 } |
sed -e 's/[^ ][^ ]*[ ]/ /g'
247 if [ -n "$deps" ]; then
248 if [ -n "$branches" ]; then
250 recurse_deps_exclude
="$exclude"
251 recurse_deps_internal
-n -t -m -e=2 -- $branches |
sort -u
254 [ -z "$tg_read_only" ] ||
[ -z "$tg_ref_cache" ] ||
! [ -s "$tg_ref_cache" ] ||
255 refslist
="-r=\"$tg_ref_cache\""
257 v_get_tdopt tdopt
"$head_from"
258 eval run_awk_topgit_deps
"$refslist" "$tdopt" '-n -t -x="$exclude" "refs/$topbases"'
263 if [ -n "$headsonly" ]; then
265 branches
="$(show_heads)"
268 [ -n "$withdeps" ] || withdeps
="$defwithdeps"
269 if [ -z "$doingall$terse$graphviz$sort$withdeps$branches" ]; then
270 branches
="$(tg info --heads 2>/dev/null | paste -d " " -s -)" ||
:
271 [ -z "$branches" ] || withdeps
=1
273 [ "$withdeps" != "0" ] || withdeps
=
274 if [ -n "$withdeps" ]; then
275 [ "$withdeps" != "2" ] || branches
="$(show_heads_topgit | paste -d " " -s -)"
278 origbranches
="$branches"
279 branches
="$(skip_ann=1; show_deps | sort -u -b -k1,1 | paste -d " " -s -)"
283 curname
="$(strip_ref "$
(git symbolic-ref
-q HEAD
)")" ||
:
285 if [ -n "$graphviz" ]; then
287 # GraphViz output; pipe to:
288 # | dot -Tpng -o <output>
296 label="TopGit Layout\n\n\n"
305 if [ -n "$sort" ]; then
306 tsort_input
="$(get_temp tg-summary-sort)"
319 [ -z "$tg_read_only" ] ||
[ -z "$tg_ref_cache" ] ||
! [ -s "$tg_ref_cache" ] ||
320 refslist
="-r=\"$tg_ref_cache\""
321 msgsfile
="$(get_temp msgslist)"
322 eval run_awk_topgit_msg
-nokind "$refslist" '"refs/$topbases"' >"$msgsfile"
323 needs_update_check_clear
324 needs_update_check_no_same
=1
325 [ -z "$branches" ] ||
[ -n "$withdeps" ] ||
return 0
326 [ -n "$withdeps" ] || origbranches
="$(navigate_deps -s=-1 | paste -d ' ' -s -)"
327 for onehead
in $origbranches; do
328 case "$exclude" in *" $onehead "*) continue; esac
329 needs_update_check
$onehead
331 aheadlist
=" $needs_update_ahead "
339 [ "$name" != "$curname" ] || current
='>'
341 [ "$name" = "$curname" ] ||
344 ! branch_empty
"$name" $from || nonempty
='0'
346 [ -z "$base_remote" ] || remote
='l'
347 ! has_remote
"$name" || remote
='r'
349 [ "$remote" != 'r' ] ||
! ref_exists
"refs/remotes/$base_remote/${topbases#heads/}/$name" ||
{
350 branch_contains
"refs/$topbases/$name" "refs/remotes/$base_remote/${topbases#heads/}/$name" &&
351 branch_contains
"refs/heads/$name" "refs/remotes/$base_remote/$name"
353 [ "$remote" != 'r' -o "$rem_update" = 'R' ] ||
{
354 branch_contains
"refs/remotes/$base_remote/$name" "refs/heads/$name" 2>/dev
/null
356 needs_update_check
"$name"
358 ! vcontains needs_update_behind
"$name" || deps_update
='D'
360 ! vcontains needs_update_partial
"$name" || deps_missing
='!'
362 branch_contains
"refs/heads/$name" "refs/$topbases/$name" || base_update
='B'
364 case "$aheadlist" in *" $name "*) ahead
='*'; esac
366 printf '%-8s %s\n' "$current$nonempty$remote$rem_update$deps_update$deps_missing$base_update$ahead" \
370 if [ -n "$terse" ]; then
372 [ -z "$tg_read_only" ] ||
[ -z "$tg_ref_cache" ] ||
! [ -s "$tg_ref_cache" ] ||
373 refslist
="-r=\"$tg_ref_cache\""
374 cmd
="run_awk_topgit_msg --list"
375 [ $verbose -lt 2 ] || cmd
="run_awk_topgit_msg -c -nokind"
376 [ $verbose -gt 0 ] || cmd
="run_awk_topgit_branches -n"
377 eval "$cmd" "$refslist" '-i="$branches" -x="$exclude" "refs/$topbases"'
382 [ -n "$graphviz$sort" ] || compute_ahead_list
386 case "$exclude" in *" $name "*) continue; esac
387 if [ -n "$graphviz$sort" ]; then
389 [ "$name" = "$curname" ] ||
391 cat_file
"refs/heads/$name:.topdeps" $from |
while read -r dep ||
[ -n "$dep" ]; do
393 ref_exists
"refs/$topbases/$dep" ||
395 [ -z "$tgish" ] ||
[ "$dep_is_tgish" = "true" ] ||
continue
396 if ! "$dep_is_tgish" ||
! branch_annihilated
$dep; then
397 if [ -n "$graphviz" ]; then
398 echo "\"$name\" -> \"$dep\";"
399 if [ "$name" = "$curname" ] ||
[ "$dep" = "$curname" ]; then
400 echo "\"$curname\" [style=filled,fillcolor=yellow];"
403 echo "$name $dep" >&4
414 if (msgsfile != "") {
415 while ((e = (getline msg <msgsfile)) > 0) {
416 gsub(/[ \t]+/, " ", msg)
418 if (split(msg, scratch, " ") < 2 ||
419 scratch[1] == "" || scratch[2] == "") continue
420 msg = substr(msg, length(scratch[1]) + 2)
421 msgs[scratch[1]] = msg
427 name = substr($0, 10)
428 if (name != "" && name in msgs)
429 printf "%-39s\t%s\n", $0, msgs[name]
434 cmd
='get_branch_list | process_branches'
435 [ -z "$msgsfile" ] || cmd
="$cmd"' | awk -v msgsfile="$msgsfile" "$awkpgm"'
438 if [ -n "$graphviz" ]; then
442 if [ -n "$sort" ]; then