From 26672cb9450af1fd61e4b55958f2ced3c0aa83a5 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Sat, 30 May 2020 14:18:41 -0400 Subject: improve git-ll-remote 0) If we already have the ref to be fetched, "git fetch" will no longer even be called, making this command much faster overall most of the time. 1) By default, only print remote branches that have pushed onto the local HEAD. If you don't do any rebasing, these correspond roughly to "pull requests". 2) With "-r", only print remote branches that are ANCESTORS of HEAD. These may be people you need to nag more because you are requesting the pull from them. As likely, they are old stale branches that you should delete. 3) With "-a", print everything. --- dot/local/bin/git-ll-remote | 111 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 7 deletions(-) (limited to 'dot') diff --git a/dot/local/bin/git-ll-remote b/dot/local/bin/git-ll-remote index 4052a41..a0e689b 100755 --- a/dot/local/bin/git-ll-remote +++ b/dot/local/bin/git-ll-remote @@ -1,12 +1,109 @@ #!/bin/sh +while [ $# -gt 0 ] +do + case "$1" in + --) shift; break;; + -?) eval "OPT_${1#-}=y" + shift + ;; + --*=*) kv=${1#--} + k=${kv##=*} + v=${kv%*=} + eval "OPT_${k}=\$1" "$v" + shift + ;; + -*) exit 1;; + *) break;; + esac +done + remote=${1:-origin} -git ls-remote $remote | +have_ref() +{ + git rev-list --quiet "$1" 2>/dev/null +} + +show_all_message() +{ + >&2 printf '%s\n' \ + 'Showing all remote branches:' \ + '' + +} + +show_normal_message() +{ + >&2 printf '%s\n' \ + 'Showing remote branches that have pushed onto your HEAD:' \ + '' +} + +show_reverse_message() +{ + >&2 printf '%s\n' \ + 'Showing branches unmerged on the REMOTE side (THEY need YOUR changes)' \ + 'because "-r" (reverse) was specified:' \ + '' +} + +handle_hash_ref() +{ + local hash="$1" ref="$2" + if ! have_ref $hash + then + git fetch $remote $ref; + fi + if [ -z "$OPT_r" ] + then + cmd="git merge-base --is-ancestor HEAD $hash" + else + cmd="git merge-base --is-ancestor $hash HEAD" + fi + if [ "$OPT_a" ] || $cmd + then + if ! [ "$OPT_q" ] + then + if [ "$OPT_a" ] + then show_all_message + elif [ "$OPT_r" -a "$listed" -eq 0 ] + then show_reverse_message + else show_normal_message + fi + fi + + >&2 printf 'remote: %s\n' "$ref" + git show $hash | sed '/^$/q' + listed=$((listed + 1)) + else + skipped=$((skipped + 1)) + fi +} + +read_hashes() +{ + while read hash ref; do + case $ref in + refs/namespaces/*) handle_hash_ref "$hash" "$ref" ;; + esac + done +} + +finalize() +{ + if [ "$listed" -eq 0 ] + then + if [ "$OPT_r" ] + then + >&2 printf 'Already up-to-date. (No remotes are ancestors of your HEAD; %d remotes up-to-date.)\n' "$skipped" + else + >&2 printf 'Already up-to-date. (No remotes have pushed onto your HEAD; %d remotes up-to-date.)\n' "$skipped" + fi + fi +} + +skipped=0 +listed=0 +git ls-remote $remote | (read_hashes && finalize) - while read hash ref; do - case $ref in refs/namespaces/*) - git fetch $remote $ref; - git show $hash | sed '/^$/q';; - esac - done -- cgit v1.2.3