GitHub
Status - ttps://www.githubstatus.com
Command palette (Command+K) - https://docs.github.com/en/get-started/using-github/github-command-palette
Code search:
Locking down your GitHub-hosted Domains - https://news.ycombinator.com/item?id=32435134
Desktop app: https://desktop.github.com - https://github.com/desktop/desktop
View raw commit/patch: add .patch to the commit URL, eg https://github.com/AlbertVilaCalvo/Android-Udacity-Popular-Movies/commit/5c1218db157fc6ce5dfd9c9e98f0522c67241963.patch
List of cool features of Git and GitHub - https://github.com/tiimgreen/github-cheat-sheet
Hub CLI - https://github.com/mislav/hub
SSH
https://docs.github.com/en/authentication/connecting-to-github-with-ssh
To test if SSH is set up correctly run ssh -T git@github.com. It should say:
Hi AlbertVilaCalvo! You've successfully authenticated, but GitHub does not provide shell access.
If it says "git@github.com: Permission denied (publickey).", it's not.
Doing cat ~/.ssh/config should show:
Host *.github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/github_personal
or
Host github.com bitbucket.org
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Misc
If you haven't used your SSH key for a year, then GitHub will automatically delete your inactive SSH key as a security precaution. For more information, see Deleted or missing SSH keys.
Add new SSH key
Do this when you set up a new Mac.
If you already have an SSH key, you can use it - see Checking for existing SSH keys. If you don't have a key or you don't want to use it, you need to generate a new key, add the private key (eg id_rsa) to the SSH agent, and add the public key (eg id_rsa.pub) to the account on GitHub.
You can optionally require a passphrase:
With SSH keys, if someone gains access to your computer, the attacker can gain access to every system that uses that key. To add an extra layer of security, you can add a passphrase to your SSH key.
When you generate an SSH key, you can add a passphrase to further secure the key. Whenever you use the key, you must enter the passphrase. If your key has a passphrase and you don't want to enter the passphrase every time you use the key, you can add your key to the SSH agent. The SSH agent manages your SSH keys and remembers your passphrase.
See Working with SSH key passphrases.
See detailed instructions for adding a new key at https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key
Create a new SSH key, using the email as a comment (a label):
ssh-keygen -t ed25519 -C "your_email@example.com" # default name is id_ed25519
ssh-keygen -t ed25519 -C "your_email@example.com" -f github_personal
# If Ed25519 is not supported use
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f github_personal
Start the ssh-agent in the background:
eval "$(ssh-agent -s)" # Agent pid 38878
Add the following to ~/.ssh/config (omitting UseKeychain if there's no passphrase):
Host github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Add the private key to the ssh-agent and, if there's a passphrase, store the passphrase in the keychain with --apple-use-keychain (you are prompted to enter the passphrase then):
# No passphrase
ssh-add ~/.ssh/id_ed25519
# With passphrase
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
It will say "Identity added: /Users/albert/.ssh/id_ed25519 (your_email@example.com)". For more info, see How can I permanently add my SSH private key to Keychain so it is automatically available to ssh?.
Finally, add the public key to GitHub.com. See instructions at https://docs.gzithub.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account. Go to https://github.com/settings/keys and click 'New SSH key'. Give it a name, choose 'Authentication Key' (we are not signing commits) and paste the public key:
pbcopy < ~/.ssh/id_ed25519.pub
Multiple SSH keys (for different GitHub accounts) on the same computer
Eg if we have a work GitHub account and want to commit on a personal repository on the work computer.
Resources followed:
- https://www.freecodecamp.org/news/manage-multiple-github-accounts-the-ssh-way-2dadc30ccaca
- https://stackoverflow.com/questions/3225862/multiple-github-accounts-ssh-config
- https://stackoverflow.com/questions/29023532/how-do-i-use-multiple-ssh-keys-on-github
Here I assume that I already have the SSH setup for the work GitHub account.
Note that this approach does not use add multiple entries to the ~/.ssh/config file. It's for specific repositories. It has the advantage that you don't need to change how you git clone a repository.
Create the new SSH key for the personal account: ssh-keygen -t ed25519 -C "mypersonal@email.com" -f github_personal. (If Ed25519 is not supported, use ssh-keygen -t rsa -b 4096 -C "mypersonal@email.com" -f github_personal.)
Copy github_personal.pub with pbcopy < github_personal.pub and add it at the GitHub website at https://github.com/settings/keys.
Add the SSH to keychain permanently with ssh-add --apple-use-keychain github_personal if there's a passphrase, otherwise use ssh-add github_personal. You'll need to type the passphrase if there's one. It will say "Identity added: github_personal (mypersonalemail@gmail.com)"
Update: to avoid the error "ERROR: Permission to AlbertVilaCalvo/XYZ.git denied to AlbertWork. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists." I've had to add this line to the ~/.zshrc: ssh-add --apple-use-keychain ~/.ssh/github_personal.
Update 2: instead of adding ssh-add ... to ~/.zshrc, this error may be fixed by having a ~/.ssh/config file with:
Host github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/github_personal
Clone the personal repository you want to contribute to. If you get the error "Please make sure you have the correct access rights and the repository exists", clone the repo with a specific SSH key with GIT_SSH_COMMAND="ssh -i ~/.ssh/github_personal" git clone git@github.com:AlbertVilaCalvo/zshrc.git. source
Once the repo is cloned, configure it to use the personal SSH key: git config core.sshCommand 'ssh -i ~/.ssh/github_personal'. I took this from https://stackoverflow.com/a/50746763/4034572
Important: don't forget to set the personal email on that repository, otherwise the work account will appear as a contributor on the personal repository: git config --local user.email mypersonal@email.com
Hide personal email address
Change the author of the last commit with git commit --amend --reset-author.
Check "Block command line pushes that expose my email" in https://github.com/settings/emails.
To change the email for a particular repository (not globally), go to https://github.com/settings/emails, copy the GitHub-provided noreply email address and then do:
git config user.email "{ID}+{username}@users.noreply.github.com "
You can check the current email with git config [--global] user.email.
Docs:
- https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/blocking-command-line-pushes-that-expose-your-personal-email-address
- https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/setting-your-commit-email-address
Trending
Trending repositories this week: https://github.com/trending?since=weekly&spoken_language_code=en
Alternatives (from https://news.ycombinator.com/item?id=32681319):
- https://github.com/explore
- https://ossinsight.io/
- https://trends.vercel.app/
- https://github.com/vitalets/github-trending-repos (they use https://github.com/trending/ according to https://news.ycombinator.com/item?id=32687015)
Shortcuts
https://docs.github.com/en/get-started/accessibility/keyboard-shortcuts
Press ? to view the shortcuts.
Browse code in web editor
- Click '.' - Announcement: https://twitter.com/github/status/1425505817827151872
- Add '1s' - For example: https://github1s.com/Microsoft/TypeScript/
Docs: https://docs.github.com/en/codespaces/the-githubdev-web-based-editor
gh CLI
Commands: https://cli.github.com/manual/gh
Usage examples: https://cli.github.com/manual/examples
https://docs.github.com/en/github-cli
Install: brew install gh
Help: use gh <command> <subcommand> --help (e.g. gh pr --help or gh pr view --help).
Tips
- Add
--webto almost any command to open it in the browser instead. - Target another repo with
-R owner/repo. --json <fields> --jq '<filter>'gives machine-readable output (great for scripting).- In Claude, prefix any in-session command with
!(e.g.! gh pr view 960 --web) to run it yourself.
Authenticate: gh auth login. Choose:
- Where do you use GitHub? GitHub.com
- What is your preferred protocol for Git operations on this host? SSH
- Upload your SSH public key to your GitHub account? Select the public key file, for example
/Users/albert/.ssh/id_ed25519.pub - Title for your SSH key: GitHub CLI
- How would you like to authenticate GitHub CLI? Login with a web browser
Auth
gh auth status # who am I, which scopes
gh auth refresh -s repo # add a scope later if something 404s
Pull requests
gh pr list # open PRs in this repo
gh pr status # PRs relevant to you (yours, review-requested)
gh pr view 960 # PR title, body, state, checks
gh pr view 960 --web # open PR #960 in the browser
gh pr view # PR for the CURRENT branch (no number needed)
gh pr diff 960 # the diff
gh pr checks 960 # CI status
gh pr checkout 960 # check out a PR's branch locally
Reading review comments
There are two kinds of comments, from two places:
- Conversation comments (general PR discussion) →
gh pr view 960 --comments - Inline review comments (anchored to a file + line — the
#discussion_r3556229001ones) → these live on a different endpoint, so use the API for precise path/line/body:
# all inline review comments on the PR
gh api repos/user-org/repo/pulls/960/comments \
--jq '.[] | {id, path, line, body}'
# just specific ones (by the r… id in the URL)
gh api repos/user-org/repo/pulls/960/comments \
--jq '.[] | select(.id==3556229001 or .id==3552213941)'
# filter fields
gh api repos/user-org/repo/pulls/960/comments \
--jq '.[] | select(.id==3556229001 or .id==3552213941) | {path, line, body}'
gh api --paginate repos/user-org/repo/pulls/960/comments \
--jq '.[] | select(.id==3556229001 or .id==3552213941) | "\n────────────────────────────────────────\nfile: \(.path):\(.line // .original_line)\nid: \(.id)\nby: \(.user.login)\n\n\(.body)"'
Replying / submitting a review
gh pr comment 960 --body "Fixed in <commit>." # PR-level comment
gh pr review 960 --comment --body "Addressed all comments." # review summary
gh pr review 960 --approve # approve
# reply to a specific inline thread (advanced, via API):
gh api repos/user-org/repo/pulls/960/comments/3552392095/replies \
-f body="Done 👍"
gh api
The power tool. When a command doesn't exist for what you need, hit the REST API directly:
gh api <path> # GET by default
gh api <path> --paginate # follow all pages
gh api <path> --jq '<filter>' # filter/format with jq syntax
gh api <path> -X POST -f key=value # POST with fields
Handy
gh browse # open the repo in the browser
gh browse src/.../index.tsx # open a specific file
gh run list # recent CI runs; gh run watch to follow one
gh search prs --author @me --state open
Markdown
It does not accept inline styles (style="margin-right: 10px;"), see https://github.com/github/markup
The HTML is sanitized, aggressively removing things that could harm you and your kin—such as
scripttags, inline-styles, andclassoridattributes.
Alerts:
- https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
- https://github.com/orgs/community/discussions/16925
Repository settings
General
Pull requests
[ ] Allow merge commits
[✓] Allow squash merging
Default commit message: Pull request title and commit details → With this setting you need to copy-paste the PR description to the commit message, which is a bit annoying, but you get all the commit history.
[✓] Allow rebase merging
[✓] Always suggest updating pull request branches
[✓] Allow auto-merge → This is only enabled for public repositories or if you have GitHub Pro/Team/etc.
[✓] Automatically delete head branches
Advanced Security
TODO
Rulesets
Prebuilt rulesets ready to import - https://github.com/github/ruleset-recipes
Define whether collaborators can delete or force push to the branch and set requirements for any pushes to the branch, such as passing status checks or a linear commit history.
There are two ways to make a branch protected:
- Classic branch protection rules. See About protected branches.
- Rulesets (new). See About rulesets.
The advantages of rulesets over branch protection rules are listed at About rulesets and protected branches.
There are two types of rulesets: branch and tag.
Protect main branch ruleset
GitHub Branch Protection Setup: Securing Your Main Branch with the New UI - https://tech-bridge-log.com/blog/github-branch-protection-setup
When you create a new repository, you'll see an alert with a button:
Your main branch isn't protected Protect this branch from force pushing or deletion, or require status checks before merging. View documentation.
To fix the issue, go to Settings → Rules → Rulesets and click "New ruleset". Select "New branch ruleset". Set this:
- Ruleset name: Protect main branch
- Enforcement status: Active
- Target branches: Include default branch
- Branch rules. Check the following:
- Restrict deletions (checked by default)
- Require linear history
- Require a pull request before merging
- Require conversation resolution before merging
- Allowed merge methods: Squash and Rebase
- Block force pushes (checked by default)
This creates the following JSON:
{
"id": 15207640,
"name": "Protect main branch",
"target": "branch",
"source_type": "Repository",
"source": "AlbertVilaCalvo/RecipeManager",
"enforcement": "active",
"conditions": {
"ref_name": {
"exclude": [],
"include": ["~DEFAULT_BRANCH"]
}
},
"rules": [
{
"type": "deletion"
},
{
"type": "non_fast_forward"
},
{
"type": "required_linear_history"
},
{
"type": "pull_request",
"parameters": {
"required_approving_review_count": 0,
"dismiss_stale_reviews_on_push": false,
"required_reviewers": [],
"require_code_owner_review": false,
"require_last_push_approval": false,
"required_review_thread_resolution": true,
"allowed_merge_methods": ["squash", "rebase"]
}
}
],
"bypass_actors": []
}
Status checks and path filters
From https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks and https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#example-including-paths
If a workflow is skipped due to path filtering, branch filtering or a commit message, then checks associated with that workflow will remain in a "Pending" state. A pull request that requires those checks to be successful will be blocked from merging.
Due to path filtering, a pull request that only changes a file in the root of the repository will not trigger this workflow and is blocked from merging. On the pull request, you would see "Waiting for status to be reported."
Allow required checks to pass/skip, not fail, when using path filtering - https://github.com/orgs/community/discussions/44490
Path filtering on required pull request checks - https://github.com/orgs/community/discussions/26857
How can I handle a required check that isn't always triggered? - https://stackoverflow.com/questions/77996177/how-can-i-handle-a-required-check-that-isnt-always-triggered
Branch protection: status checks for workflows with path conditions - https://stackoverflow.com/questions/79348923/branch-protection-status-checks-for-workflows-with-path-conditions
Merge queue
https://humanwhocodes.com/blog/2026/04/improving-developer-velocity-github-merge-queue/