diff options
author | Gordon GECOS <u@adam> | 2020-10-31 13:33:21 -0400 |
---|---|---|
committer | Gordon GECOS <u@adam> | 2020-10-31 13:33:21 -0400 |
commit | 3c23eac02d98fa8ccd27d2e8b19fc81060a0c52c (patch) | |
tree | 3f05b57e8f8ae5975ef1b28e5424fe12abed18be /src | |
parent | 111b011a6b0c514fb8912710fd132b3ff983c004 (diff) |
import newer git-ll-remote
Diffstat (limited to 'src')
-rwxr-xr-x | src/git-ll-remote | 202 |
1 files changed, 196 insertions, 6 deletions
diff --git a/src/git-ll-remote b/src/git-ll-remote index 4052a41..f4b058d 100755 --- a/src/git-ll-remote +++ b/src/git-ll-remote | |||
@@ -1,12 +1,202 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | while [ $# -gt 0 ] | ||
4 | do | ||
5 | case "$1" in | ||
6 | --) shift; break;; | ||
7 | -?) eval "OPT_${1#-}=y" | ||
8 | shift | ||
9 | ;; | ||
10 | --*=*) kv=${1#--} | ||
11 | k=${kv##=*} | ||
12 | v=${kv%*=} | ||
13 | eval "OPT_${k}=\$1" "$v" | ||
14 | shift | ||
15 | ;; | ||
16 | -*) exit 1;; | ||
17 | *) break;; | ||
18 | esac | ||
19 | done | ||
20 | |||
3 | remote=${1:-origin} | 21 | remote=${1:-origin} |
4 | 22 | ||
5 | git ls-remote $remote | | 23 | SHOW=ahead |
24 | [ "$OPT_a" ] && SHOW=all | ||
25 | [ "$OPT_r" ] && SHOW=behind | ||
26 | [ "$OPT_u" ] && SHOW=upto | ||
27 | QUIET= | ||
28 | [ "$OPT_q" ] && QUIET=y | ||
29 | [ "$OPT_n" ] && NS_ONLY=y | ||
30 | [ "$OPT_N" ] && NS_ONLY= | ||
31 | |||
32 | show_message() | ||
33 | { | ||
34 | show_${SHOW}_message | ||
35 | } | ||
36 | |||
37 | show_all_message() | ||
38 | { | ||
39 | cat >&2 <<EOF | ||
40 | Showing all remote branches: | ||
41 | |||
42 | EOF | ||
43 | } | ||
44 | |||
45 | show_all_none_message() | ||
46 | { | ||
47 | cat >&2 <<EOF | ||
48 | No remote branches. | ||
49 | EOF | ||
50 | } | ||
51 | |||
52 | show_ahead_message() | ||
53 | { | ||
54 | cat >&2 <<EOF | ||
55 | Showing remote branches that are ahead (they have pushed onto your HEAD): | ||
56 | |||
57 | EOF | ||
58 | } | ||
59 | |||
60 | show_ahead_none_message() | ||
61 | { | ||
62 | x=$(cat <<EOF) | ||
63 | No remote branches are ahead of your HEAD. %d other remote branches were not | ||
64 | listed. | ||
65 | EOF | ||
66 | printf "$x\n" "$1" >&2 | ||
67 | |||
68 | } | ||
69 | |||
70 | show_behind_message() | ||
71 | { | ||
72 | cat >&2 <<EOF | ||
73 | Showing remote branches that are behind (your HEAD has commits on top of | ||
74 | the remote branch): | ||
75 | |||
76 | EOF | ||
77 | } | ||
78 | |||
79 | show_behind_none_message() | ||
80 | { | ||
81 | x=$(cat <<EOF) | ||
82 | No remotes branches are behind your HEAD. %d other remote branches were not | ||
83 | listed. | ||
84 | EOF | ||
85 | printf "$x\n" "$1" >&2 | ||
86 | |||
87 | } | ||
88 | |||
89 | show_upto_message() | ||
90 | { | ||
91 | cat >&2 <<EOF | ||
92 | Showing remote branches that are even with your HEAD. | ||
6 | 93 | ||
7 | while read hash ref; do | 94 | EOF |
8 | case $ref in refs/namespaces/*) | 95 | } |
9 | git fetch $remote $ref; | 96 | |
10 | git show $hash | sed '/^$/q';; | 97 | show_upto_none_message() |
98 | { | ||
99 | x=$(cat <<EOF) | ||
100 | No remote branches are even with your HEAD. %d other remote branches were not | ||
101 | listed. | ||
102 | EOF | ||
103 | printf "$x\n" "$1" >&2 | ||
104 | } | ||
105 | |||
106 | have_ref() | ||
107 | { | ||
108 | git rev-list --quiet "$1" 2>/dev/null | ||
109 | } | ||
110 | |||
111 | git_fetch() | ||
112 | { | ||
113 | local hash="$1" ref="$2" | ||
114 | have_ref "$hash" || git fetch "$remote" "$ref" | ||
115 | } | ||
116 | |||
117 | is_same_ref() | ||
118 | { | ||
119 | [ "$1" = "$2 " ] || [ "$(git rev-parse "$1")" = "$(git rev-parse "$2")" ] | ||
120 | } | ||
121 | |||
122 | is_ancestor() | ||
123 | { | ||
124 | if is_same_ref "$1" "$2" | ||
125 | then false | ||
126 | else git merge-base --is-ancestor "$1" "$2" | ||
127 | fi | ||
128 | } | ||
129 | |||
130 | verdict() | ||
131 | { | ||
132 | if is_same_ref HEAD "$1" | ||
133 | then echo even | ||
134 | elif is_ancestor "$1" HEAD | ||
135 | then echo behind | ||
136 | elif is_ancestor HEAD "$1" | ||
137 | then echo ahead | ||
138 | else echo diverged | ||
139 | fi | ||
140 | } | ||
141 | |||
142 | show_this_remote_branch() | ||
143 | { | ||
144 | local hash="$1" | ||
145 | case "$SHOW" in | ||
146 | all) VERDICT=$(verdict "$hash") ;; | ||
147 | behind) is_ancestor "$hash" HEAD ;; | ||
148 | ahead) is_ancestor HEAD "$hash" ;; | ||
149 | upto) is_same_ref HEAD "$hash" ;; | ||
11 | esac | 150 | esac |
12 | done | 151 | } |
152 | |||
153 | handle_hash_ref() | ||
154 | { | ||
155 | local hash="$1" ref="$2" | ||
156 | git_fetch "$hash" "$ref" || exit | ||
157 | |||
158 | if show_this_remote_branch "$hash" | ||
159 | then | ||
160 | if [ ! "$QUIET" -a "$listed" -eq 0 ] | ||
161 | then | ||
162 | show_message | ||
163 | fi | ||
164 | |||
165 | if [ "$SHOW" = all ] | ||
166 | then | ||
167 | >&2 printf 'remote: %s (%s)\n' "$ref" "$VERDICT" | ||
168 | else | ||
169 | >&2 printf 'remote: %s\n' "$ref" | ||
170 | fi | ||
171 | |||
172 | git show "$hash" | sed '/^$/q' | ||
173 | listed=$((listed + 1)) | ||
174 | else | ||
175 | skipped=$((skipped + 1)) | ||
176 | fi | ||
177 | } | ||
178 | |||
179 | read_hashes() | ||
180 | { | ||
181 | while read hash ref; do | ||
182 | [ "$hash" != From ] || continue | ||
183 | case "$ref" in | ||
184 | refs/namespaces/*) ;; | ||
185 | *) [ ! "$NS_ONLY" ] || continue ;; | ||
186 | esac | ||
187 | handle_hash_ref "$hash" "$ref" | ||
188 | done | ||
189 | } | ||
190 | |||
191 | finalize() | ||
192 | { | ||
193 | if [ "$listed" -eq 0 ] | ||
194 | then | ||
195 | show_${SHOW}_none_message "$skipped" | ||
196 | fi | ||
197 | } | ||
198 | |||
199 | skipped=0 | ||
200 | listed=0 | ||
201 | git ls-remote $remote | (read_hashes && finalize) | ||
202 | |||