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
185 # if $1 is non-empty, show the dep only (including self), not the edge (no self)
188 if [ -n "$branches" ]; then
190 [ -z "$1" ] || edgenum
=1
192 recurse_deps_exclude
="$exclude"
193 recurse_deps_internal
-n ${tgish:+-t} -m ${1:+-s} -e=$edgenum -- $branches |
sort -u
196 [ -z "$1" ] || cutcmd
='| cut -d " " -f 2 | sort -u'
198 [ -z "$tg_read_only" ] ||
[ -z "$tg_ref_cache" ] ||
! [ -s "$tg_ref_cache" ] ||
199 refslist
="-r=\"$tg_ref_cache\""
201 v_get_tdopt tdopt
"$head_from"
202 eval run_awk_topgit_deps
"$refslist" "$tdopt" "${tgish:+-t}" \
203 "${1:+-s}" '-n -x="$exclude" "refs/$topbases"' "$cutcmd"
207 if [ -n "$deps$depsonly$sort" ]; then
208 eval show_deps
$depsonly "${sort:+|tsort}"
212 if [ -n "$rdeps" ]; then
215 recurse_deps_exclude
="$exclude"
218 if [ -n "$heads" ]; then
223 } |
while read -r b
; do
224 case "$exclude" in *" $b "*) continue; esac
225 ref_exists
"refs/heads/$b" ||
continue
226 [ -z "$showbreak" ] ||
echo
228 recurse_deps_internal
${tgish:+-t} -n -s ${rdepsonce:+-o=-1} "$b" |
229 awk -v elided
="$rdepsonce" '{
230 if ($1 == "1" || NF < 5) next
233 sub(/^[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+/, "")
236 if (elided && xvisits > 0) xtra="^"
243 if [ -n "$headsonly" ]; then
245 branches
="$(show_heads)"
248 [ -n "$withdeps" ] || withdeps
="$defwithdeps"
249 if [ -z "$doingall$terse$graphviz$sort$withdeps$branches" ]; then
250 branches
="$(tg info --heads 2>/dev/null | paste -d " " -s -)" ||
:
251 [ -z "$branches" ] || withdeps
=1
253 [ "$withdeps" != "0" ] || withdeps
=
254 if [ -n "$withdeps" ]; then
255 [ "$withdeps" != "2" ] || branches
="$(show_heads_topgit | paste -d " " -s -)"
258 origbranches
="$branches"
259 branches
="$(show_deps 1 | paste -d " " -s -)"
263 if [ -n "$terse" ]; then
265 [ -z "$tg_read_only" ] ||
[ -z "$tg_ref_cache" ] ||
! [ -s "$tg_ref_cache" ] ||
266 refslist
="-r=\"$tg_ref_cache\""
267 cmd
="run_awk_topgit_msg --list"
268 [ $verbose -lt 2 ] || cmd
="run_awk_topgit_msg -c -nokind"
269 [ $verbose -gt 0 ] || cmd
="run_awk_topgit_branches -n"
270 eval "$cmd" "$refslist" '-i="$branches" -x="$exclude" "refs/$topbases"'
274 curname
="$(strip_ref "$
(git symbolic-ref
-q HEAD
)")" ||
:
276 if [ -n "$graphviz" ]; then
278 '# GraphViz output; pipe to:
279 # | dot -Tpng -o <output>
287 label="TopGit Layout\n\n\n"
292 show_deps |
while read -r name dep
; do
293 printf '"%s" -> "%s";\n' "$name" "$dep"
294 if [ "$name" = "$curname" ] ||
[ "$dep" = "$curname" ]; then
295 printf '"%s" [%s];\n' "$curname" "style=filled,fillcolor=yellow"
306 [ -z "$tg_read_only" ] ||
[ -z "$tg_ref_cache" ] ||
! [ -s "$tg_ref_cache" ] ||
307 refslist
="-r=\"$tg_ref_cache\""
308 msgsfile
="$(get_temp msgslist)"
309 eval run_awk_topgit_msg
-nokind "$refslist" '"refs/$topbases"' >"$msgsfile"
310 needs_update_check_clear
311 needs_update_check_no_same
=1
312 [ -z "$branches" ] ||
[ -n "$withdeps" ] ||
return 0
313 [ -n "$withdeps" ] || origbranches
="$(navigate_deps -s=-1 | paste -d ' ' -s -)"
314 for onehead
in $origbranches; do
315 case "$exclude" in *" $onehead "*) continue; esac
316 needs_update_check
$onehead
318 aheadlist
=" $needs_update_ahead "
326 [ "$name" != "$curname" ] || current
='>'
328 [ "$name" = "$curname" ] ||
331 ! branch_empty
"$name" $from || nonempty
='0'
333 [ -z "$base_remote" ] || remote
='l'
334 ! has_remote
"$name" || remote
='r'
336 [ "$remote" != 'r' ] ||
! ref_exists
"refs/remotes/$base_remote/${topbases#heads/}/$name" ||
{
337 branch_contains
"refs/$topbases/$name" "refs/remotes/$base_remote/${topbases#heads/}/$name" &&
338 branch_contains
"refs/heads/$name" "refs/remotes/$base_remote/$name"
340 [ "$remote" != 'r' -o "$rem_update" = 'R' ] ||
{
341 branch_contains
"refs/remotes/$base_remote/$name" "refs/heads/$name" 2>/dev
/null
343 needs_update_check
"$name"
345 ! vcontains needs_update_behind
"$name" || deps_update
='D'
347 ! vcontains needs_update_partial
"$name" || deps_missing
='!'
349 branch_contains
"refs/heads/$name" "refs/$topbases/$name" || base_update
='B'
351 case "$aheadlist" in *" $name "*) ahead
='*'; esac
353 printf '%-8s %s\n' "$current$nonempty$remote$rem_update$deps_update$deps_missing$base_update$ahead" \
359 if (msgsfile != "") {
360 while ((e = (getline msg <msgsfile)) > 0) {
361 gsub(/[ \t]+/, " ", msg)
363 if (split(msg, scratch, " ") < 2 ||
364 scratch[1] == "" || scratch[2] == "") continue
365 msg = substr(msg, length(scratch[1]) + 2)
366 msgs[scratch[1]] = msg
372 name = substr($0, 10)
373 if (name != "" && name in msgs)
374 printf "%-39s\t%s\n", $0, msgs[name]
381 cmd
='get_branch_list | while read name; do process_branch; done'
382 [ -z "$msgsfile" ] || cmd
="$cmd"' | awk -v msgsfile="$msgsfile" "$awkpgm"'