1# Clone a GitHub repo given its URL.
3# $1 = URL of the GitHub page
5# Because switching to the repo homepage, clicking, copying the clone URL,
6# typing 'git clone', pasting, are all more effort than I care to do manually.
7function github-clone --description "Clone a GitHub repository into my ~/repos directory"
8 set url (string replace '?tab=readme-ov-file' '' "$argv[1]")
10 # Get the identifiers for the repository
11 set components (string split "/" "$url")
13 if [ "$components[3]" != "github.com" ]
14 echo "$url is not a GitHub repo"
18 set owner $components[4]
19 set repo $components[5]
21 if [ (count $components) -gt 5 ]
22 # Detect if this is a pull request, and divert
23 if [ $components[6] = pull ]
24 github-add-pr-branch "$url"
29 set repo_url "git@github.com:$owner/$repo.git"
35 # If the repo already exists, check we have the selected fork
38 git remote -v | grep "$owner" >/dev/null 2>&1
40 print_info "-> git remote add $owner $repo_url"
41 git remote add $owner $repo_url
43 set remote (git remote -v | grep "$owner" | awk '{print $1}')
46 # Otherwise, clone a fresh copy of the repo
47 print_info "-> git clone $repo_url"
51 # If this looks like a Python repository, create a virtualenv
52 # in the root of the repo.
53 if [ -f "requirements.txt" ]
57 # I auto-populate .git/info/exclude with a few common entries to
58 # save having to do it later. (I could use a global .gitignore,
59 # but this way it's managed programatically and all local to the
60 # repo, which I slightly prefer to a homefolder full of manually
62 echo .DS_Store >>.git/info/exclude
66# Given a GitHub pull request, create the repo and make sure the remote
67# of the PR owner is added as a remote.
69# $1 = URL of the pull request
71# Sometimes when I'm looking at a pull request, it's useful to get the
72# branch locally and test/review/squash it as appropriate. This makes
75# Typically not called directly, but detected by 'github-open' and
76# switched to if looking at a pull request URL.
77function github-add-pr-branch
78 # First ensure we have a local clone of the repo
80 github-clone (string split "pull/" "$url" | head -n 1)
85 # Get the identifiers for the repository. A pull request URL is
88 # https://github.com/:owner/:repo/pull/:number#discussion_:comment
90 set components (string split "/" "$url")
92 if [ "$components[6]" != pull ]
93 echo "$url is not a GitHub pull request"
97 set owner $components[4]
98 set repo $components[5]
99 set number (echo $components[7] | tr '#' ' ' | awk '{print $1}')
101 set api_url "https://api.github.com/repos/$owner/$repo/pulls/$number"
102 set api_resp (curl -s -H "Accept: application/vnd.github.v3+json" "$api_url")
103 set pr_branch (echo $api_resp | jq '.head.repo.full_name' | tr '"' ' ' | awk '{print $1}')
105 git checkout (echo $api_resp | jq '.head.ref' | tr '"' ' ' | awk '{print $1}')