Skip to content

Instantly share code, notes, and snippets.

@dakkar
Created May 4, 2019 14:19
Show Gist options
  • Save dakkar/11af7c32c4a4ec3f4d0167c6381ab367 to your computer and use it in GitHub Desktop.
Save dakkar/11af7c32c4a4ec3f4d0167c6381ab367 to your computer and use it in GitHub Desktop.
getting remote name and ref from local ref
#!/bin/bash
# git find-ref $committish
#
# figure out which remote a committish comes from, and open its
# corresponding web view in a browser
#
# NOTE: doesn't work with tag names, I'm not sure if it's possible to
# know where a tag comes from
# default to HEAD
rev="${1:-HEAD}"
# resolve the committisg to a branch name, plus possibly some parent
# information (e.g. `master`, `origin/master`, `origin/master~3`
ref="$(git name-rev --exclude='refs/tags/*' --name-only --no-undefined "$rev" 2>/dev/null )"
# default to master if we can't identify
: ${ref:=master}
# did we get a remote ref?
if [[ "$ref" == remotes/* ]]; then
ref="refs/$ref"
# scan all remotes (the `IFS` is to make sure we support remotes
# with spaces in their names, the `while ... done < <(foo)` is
# because `foo|while ... done` runs the `while` in a sub-shell and
# wouldn't update our variables)
while IFS=$'\n' read o; do
# this will produce something like
# `+refs/heads/*:refs/remotes/origin/*`
fetch="$(git config "remote.$o.fetch")"
fetch="${fetch#*:}"
# == does pattern matching
if [[ $ref == $fetch ]]; then
remote="$o"
# remove matching prefix, the `*` at the end will not eat
# anything because `#` removes the *shortest* matching
# prefix
ref="${ref#$fetch}"
break
fi
done < <(git remote)
else
# not an explicitly remote ref, let's get its remote from its
# tracking information
remote="$(git config --get "branch.${ref}.remote")"
: ${remote:=origin}
# and the remote branch name as well
merge_branch="$(git config --get "branch.${ref}.merge")"
merge_branch=${merge_branch#refs/heads/}
# if there's no merge branch, assume it's the same as the name we
# already got
ref="${merge_branch:-$ref}"
fi
remote_url="$(git remote get-url "$remote")"
: ${remote_url:="$(git remote get-url --push "$remote")"}
echo "ref=[${ref}]"
echo "remote=[${remote}]"
echo "remote_url=[${remote_url}]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment