@@ -224,6 +224,34 @@ function ghcommiturl() {
224224 sha=$( git rev-parse " ${1:- HEAD} " ) || return 1
225225 echo " $( gh repo view --json url -q .url) /commit/${sha} "
226226}
227+ # generate a github compare url for the current branch vs. upstream default branch;
228+ # handles forks by checking which remote the branch tracks vs. origin
229+ function ghbranchcompare() {
230+ local branch upstream_ref tracking_remote
231+ branch=$( git rev-parse --abbrev-ref HEAD) || return 1
232+
233+ # which remote does this branch track?
234+ upstream_ref=$( git rev-parse --abbrev-ref @{u} 2> /dev/null)
235+ tracking_remote=${upstream_ref%%/* } # e.g. "noahp" from "noahp/my-branch"
236+ [[ -z " $tracking_remote " ]] && tracking_remote=" origin"
237+
238+ # origin is the canonical upstream repo (gh resolves it from the origin remote)
239+ local origin_json origin_owner repo_name default_branch
240+ origin_json=$( gh repo view --json name,owner,defaultBranchRef) || return 1
241+ origin_owner=$( jq -r .owner.login <<< " $origin_json" )
242+ repo_name=$( jq -r .name <<< " $origin_json" )
243+ default_branch=$( jq -r .defaultBranchRef.name <<< " $origin_json" )
244+
245+ if [[ " $tracking_remote " != " origin" ]]; then
246+ # extract owner from the tracking remote's URL (works for both ssh and https)
247+ local remote_url fork_owner
248+ remote_url=$( git remote get-url " $tracking_remote " ) || return 1
249+ fork_owner=$( echo " $remote_url " | sed ' s|.*github\.com[:/]\([^/]*\)/.*|\1|' )
250+ echo " https://github.com/${origin_owner} /${repo_name} /compare/${default_branch} ...${fork_owner} :${repo_name} :${branch} "
251+ else
252+ echo " https://github.com/${origin_owner} /${repo_name} /compare/${default_branch} ...${branch} "
253+ fi
254+ }
227255
228256# Other aliases
229257
0 commit comments