topgit: fully qualify more refs
[topgit/pro.git] / tg-checkout.sh
blob325268f0ed20f1545a098b4c5faa33995ef4053b
1 #!/bin/sh
2 # TopGit - A different patch queue manager
3 # Copyright (C) 2013 Per Cederqvist <ceder@lysator.liu.se>
4 # Copyright (C) 2015,2017 Kyle J. McKay <mackyle@gmail.com>
5 # All rights reserved.
6 # GPLv2
8 ## Parse options
10 USAGE="\
11 Usage: ${tgname:-tg} [...] checkout [--iow] [-f] [-b <branch>] (next | prev) [<steps>]
12 Or: ${tgname:-tg} [...] checkout [--iow] [-f] (next | prev) -a
13 Or: ${tgname:-tg} [...] checkout [--iow] [-f] [goto] [--] <pattern> | --series[=<head>]"
15 usage()
17 [ -z "$2" ] || printf '%s\n' "$2" >&2
18 if [ "${1:-0}" != 0 ]; then
19 printf '%s\n' "$USAGE" >&2
20 else
21 printf '%s\n' "$USAGE"
23 exit ${1:-0}
26 # Parse options
28 branch= # -b value
29 iowoptval= # "" or "$iowopt"
30 forceval= # "" or "-f"
31 dashdash= # "" or "1" if [goto] "--" [--series[=<head>]] seen
33 while [ $# -gt 0 ]; do case "$1" in
34 -h|--help)
35 usage
37 -f|--force)
38 forceval="-f"
40 --ignore-other-worktrees|--iow)
41 iowoptval="$iowopt"
43 --branch=*)
44 branch="${1#--branch=}"
45 [ -n "$branch" ] || usage 1 "--branch= requires a branch name"
47 --branch|-b)
48 [ $# -ge 2 ] || usage 1 "$1 requires an argument"
49 branch="$2"
50 [ -n "$branch" ] || usage 1 "$1 requires a branch name"
51 shift
53 --series|--series=*)
54 dashdash=1
55 break
57 --|goto)
58 [ "$1" != "goto" ] || [ "$2" != "--" ] || shift
59 shift
60 dashdash=1
61 break
63 -?*)
64 usage 1 "Unknown option: $1"
67 break
69 esac; shift; done
70 [ $# -ne 0 ] || [ -n "$dashdash" ] || set -- "next" # deprecated "next" alias
71 [ $# -gt 0 ] || usage 1
72 [ -n "$dashdash" ] ||
73 case "$1" in
74 n|next|push|child) shift;;
75 p|prev|previous|pop|parent|..) reverse=1; shift;;
76 -*) usage 1;;
77 *) dashdash=1;;
78 esac
80 choices="$(get_temp choices)"
81 desc=
83 if [ -n "$dashdash" ]; then
84 [ $# -eq 1 ] || usage 1 "goto mode requires exactly one pattern"
85 pattern="$1"
86 [ -n "$pattern" ] || usage 1 "goto mode requires a non-empty pattern"
87 case "$pattern" in
88 --series|--series=*)
89 tg --no-pager info "$pattern" "${branch:-HEAD}" >"$choices" || exit
90 desc=1
93 [ -z "$branch" ] || usage 1 "--branch not allowed in goto <pattern> mode"
94 tg --no-pager summary --list | grep -e "$pattern" >"$choices" || :
95 no_branch_found="No topic branch matches grep pattern '$pattern'"
97 esac
98 else
99 [ $# -gt 0 ] || set -- "1"
100 [ $# -eq 1 ] || usage 1 "next/previos permits no more than one argument"
101 case "$1" in
102 -a|--all)
103 [ -z "$branch" ] || usage 1 "--branch not allowed in --all mode"
104 navigate_deps -t -s=-1 ${reverse:+-r} >"$choices"
105 no_branch_found="No TopGit branches found at all!"
107 [1-9]*)
108 [ "$1" = "${1%%[!0-9]*}" ] || usage 1 "invalid next/previous step count"
109 v_verify_topgit_branch branch "${branch:-HEAD}"
110 navigate_deps -t -s="$1" ${reverse:+-r} "$branch" >"$choices" || exit
111 pl="s" dir="next"
112 [ "$steps" != 1 ] || pl=
113 [ -z "$reverse" ] || dir="previous"
114 no_branch_found="No $dir TopGit branch(es) found $steps$pl away"
117 usage 1 "invalid next/previous movement; must be --all or positive number"
119 esac
122 cnt=$(( $(wc -l <"$choices") ))
123 [ $cnt -gt 0 ] || die "$no_branch_found"
125 if [ $cnt -eq 1 ]; then
126 read -r choice <"$choices" || :
127 choice="${choice%%[ $tab]*}"
128 [ -n "$choice" ] || die "$no_branch_found"
129 else
130 echo "Please select one of the following topic branches:"
131 awk -v "desc=$desc" <"$choices" '
132 BEGIN { colcount = 0 }
133 function cols() {
134 if (colcount) return colcount
135 sizer = "exec stty size 0>&2 2>/dev/null"
136 info = ""
137 sizer | getline info
138 close sizer
139 colcount = 0
140 if (split(info, nums, " ") >= 2 && nums[2] ~ /^[1-9][0-9]*$/)
141 colcount = 0 + nums[2]
142 if (!colcount) colcount = 80
143 return colcount
146 if ($0 ~ /^[* ] /) {
147 mark = substr($0, 1, 2)
148 names = substr($0, 3)
149 } else {
150 mark = ""
151 names = $0
153 cnt = split(names, name, " ")
154 if (!cnt) next
155 annotation = ""
156 if (cnt > 1) {
157 if (desc) {
158 annotation = names
159 sub(/^[ \t]+/, "", annotation)
160 sub(/^[^ \t]+[ \t]+/, "", annotation)
161 sub(/[ \t]+$/, "", annotation)
162 if (annotation != "") annotation = " " annotation
163 } else {
164 for (i = 2; i <= cnt; ++i) {
165 annotation = annotation ", " name[i]
167 annotation = " [" substr(annotation, 3) "]"
170 if (desc)
171 line = sprintf("%-39s%s", sprintf("%6d %s%s", NR, mark, name[1]), annotation)
172 else
173 line = sprintf("%6d %s%s%s", NR, mark, name[1], annotation)
174 printf "%.*s\n", cols() - 1, line
176 printf '%s' "Input the number: "
177 read -r n
178 [ -n "$n" ] && [ "$n" = "${n%%[!0-9]*}" ] || die "Bad input"
179 [ $n -ge 1 ] && [ $n -le $cnt ] || die "Input out of range"
180 choice="$(sed -n ${n}p <"$choices")" || :
181 case "$choice" in "* "*|" "*) choice="${choice#??}"; esac
182 choice="${choice%%[ $tab]*}"
183 [ -n "$choice" ] || die "Bad input"
185 git checkout $iowoptval $forceval "$choice" --