Skip to content

GitHub Setup

Published: February 14, 2026 ยท Last edited: February 24, 2026

A balanced approach to GitHub configuration that reduces cognitive load, prevents mistakes, and maintains security.

Core Philosophy

  • Visual feedback at every step
  • Safety nets for common mistakes
  • Templates to reduce decision paralysis
  • Automation for repetitive tasks
  • Clear workflows that prevent "what was I doing?" moments

1. Git Global Configuration

Essential Settings

# Your identity
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Default branch name
git config --global init.defaultBranch main

# Better diff and merge tools
git config --global merge.conflictstyle diff3
git config --global diff.colorMoved zebra

# Auto-correct typos (waits 1.5 seconds before executing)
git config --global help.autocorrect 15

# Reuse recorded conflict resolutions
git config --global rerere.enabled true

# Default pull strategy (prevents unwanted merges)
git config --global pull.rebase true

# Push current branch by default
git config --global push.default current

# Show original branch name in git log
git config --global log.decorate auto

# Better whitespace handling
git config --global core.whitespace trailing-space,space-before-tab
git config --global apply.whitespace fix

Color Configuration (Visual Clarity)

# Enable colors everywhere
git config --global color.ui auto
git config --global color.status auto
git config --global color.branch auto
git config --global color.interactive auto
git config --global color.diff auto

# Custom colors for better visibility
git config --global color.status.added "green bold"
git config --global color.status.changed "yellow bold"
git config --global color.status.untracked "red bold"
git config --global color.branch.current "yellow reverse"
git config --global color.branch.local "yellow"
git config --global color.branch.remote "green"

Aliases

Add these to ~/.gitconfig or use the commands below:

# Status and Overview
git config --global alias.s "status -sb"
git config --global alias.ss "status"
git config --global alias.summary "log --oneline --graph --all --decorate -10"
git config --global alias.today "log --since='6am' --oneline --author='YOUR_EMAIL'"

# Visual History
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
git config --global alias.tree "log --oneline --graph --decorate --all"
git config --global alias.history "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"

# Branch Management
git config --global alias.br "branch -v"
git config --global alias.bra "branch -av"
git config --global alias.branches "branch -a"
git config --global alias.recent "branch --sort=-committerdate --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'"

# Common Operations
git config --global alias.co "checkout"
git config --global alias.cob "checkout -b"
git config --global alias.cm "commit -m"
git config --global alias.ca "commit --amend"
git config --global alias.can "commit --amend --no-edit"

# Undo Helpers (Safety Nets)
git config --global alias.unstage "reset HEAD --"
git config --global alias.uncommit "reset --soft HEAD^"
git config --global alias.undo "reset --hard HEAD^"
git config --global alias.discard "checkout --"

# Diff Helpers
git config --global alias.d "diff"
git config --global alias.ds "diff --staged"
git config --global alias.dc "diff --cached"
git config --global alias.changed "diff --name-only"

# Stash Helpers
git config --global alias.stashes "stash list"
git config --global alias.sp "stash pop"
git config --global alias.ss "stash save -u"

# Remote Operations
git config --global alias.sync "!git fetch --all --prune && git pull"
git config --global alias.publish "!git push -u origin $(git branch --show-current)"
git config --global alias.unpublish "!git push origin :$(git branch --show-current)"

# Information Gathering
git config --global alias.contributors "shortlog --summary --numbered"
git config --global alias.who "shortlog -sn --"
git config --global alias.tags "tag -l"
git config --global alias.remotes "remote -v"

# Workflow Helpers
git config --global alias.wip "commit -am 'WIP: work in progress'"
git config --global alias.save "!git add -A && git commit -m 'SAVEPOINT'"
git config --global alias.checkpoint "!git add -A && git commit -m 'CHECKPOINT: $(date)'"

2. Commit Message Templates

Create Template File

Create ~/.gitmessage.txt:

# <type>: <subject> (max 50 chars)
# |<----  Using a Maximum Of 50 Characters  ---->|

# Explain why this change is being made
# |<----   Try To Limit Each Line to a Maximum Of 72 Characters   ---->|

# Provide links or keys to any relevant tickets, articles or resources
# Example: Fixes #23

# --- COMMIT END ---
# Type can be:
#    feat     (new feature)
#    fix      (bug fix)
#    refactor (code change that neither fixes a bug nor adds a feature)
#    style    (formatting, missing semi colons, etc; no code change)
#    docs     (changes to documentation)
#    test     (adding or refactoring tests; no production code change)
#    chore    (updating grunt tasks etc; no production code change)
# --------------------
# Remember to:
#   - Use the imperative mood in the subject line
#   - Do not end the subject line with a period
#   - Separate subject from body with a blank line
#   - Use the body to explain what and why vs. how
#   - Can use multiple lines with "-" for bullet points in body
# --------------------

Enable the template:

git config --global commit.template ~/.gitmessage.txt

Quick Commit Helper Script

Create ~/bin/git-quick-commit.sh:

# Quick commit with type selection

echo "๐ŸŽฏ Quick Commit Helper"
echo ""
echo "What type of change is this?"
echo "1) feat     - New feature"
echo "2) fix      - Bug fix"
echo "3) docs     - Documentation"
echo "4) style    - Formatting"
echo "5) refactor - Code restructuring"
echo "6) test     - Tests"
echo "7) chore    - Maintenance"
echo ""
read -p "Choose (1-7): " choice

case $choice in
    1) type="feat" ;;
    2) type="fix" ;;
    3) type="docs" ;;
    4) type="style" ;;
    5) type="refactor" ;;
    6) type="test" ;;
    7) type="chore" ;;
    *) echo "Invalid choice"; exit 1 ;;
esac

read -p "Short description: " message

git add -A
git commit -m "$type: $message"
echo "โœ… Committed: $type: $message"

Make executable: chmod +x ~/bin/git-quick-commit.sh

Add alias: git config --global alias.qc "!~/bin/git-quick-commit.sh"

3. GitHub CLI Setup

Install GitHub CLI

# macOS
brew install gh

# Ubuntu/Debian
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh

Authenticate

gh auth login
# Follow the prompts - use browser authentication for easiest flow

Essential GitHub CLI Aliases

Add to ~/.bashrc or ~/.zshrc:

# Repository Operations
alias ghv='gh repo view --web'           # Open current repo in browser
alias ghc='gh repo clone'                # Clone a repo
alias ghr='gh repo create'               # Create new repo

# Pull Requests
alias ghpr='gh pr view --web'            # View current PR in browser
alias ghprs='gh pr list'                 # List all PRs
alias ghprc='gh pr create --web'         # Create PR in browser
alias ghprco='gh pr checkout'            # Checkout a PR locally

# Issues
alias ghi='gh issue view --web'          # View issue in browser
alias ghis='gh issue list'               # List issues
alias ghic='gh issue create --web'       # Create issue in browser

# Workflow status
alias ghw='gh run list --limit 5'        # Recent workflow runs
alias ghww='gh run watch'                # Watch current workflow

4. Pre-commit Hooks (Safety Nets)

Install Pre-commit Framework

pip install pre-commit --break-system-packages

Create .pre-commit-config.yaml in your repos:

# Pre-commit Configuration
# Catches common mistakes before they become commits

repos:
  # Basic checks
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      # File checks
      - id: check-added-large-files
        args: ['--maxkb=1000']
      - id: check-case-conflict
      - id: check-merge-conflict
      - id: check-symlinks
      - id: destroyed-symlinks

      # Content checks
      - id: detect-private-key
      - id: check-json
      - id: check-yaml
      - id: check-toml
      - id: check-xml

      # Git checks
      - id: check-vcs-permalinks
      - id: mixed-line-ending
      - id: trailing-whitespace
      - id: end-of-file-fixer

      # Prevent commits to main
      - id: no-commit-to-branch
        args: ['--branch', 'main', '--branch', 'master']

  # Secrets detection
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.1
    hooks:
      - id: gitleaks

  # Code formatting (optional - add per language)
  # - repo: https://github.com/psf/black
  #   rev: 23.12.1
  #   hooks:
  #     - id: black

Install hooks in a repo:

cd your-repo
pre-commit install

5. Repository Templates

Create Issue Templates

Create .github/ISSUE_TEMPLATE/bug_report.md:

---
name: Bug Report
about: Report a bug to help us improve
title: '[BUG] '
labels: bug
assignees: ''
---

## ๐Ÿ› Bug Description
<!-- A clear description of what the bug is -->

## ๐Ÿ” Steps to Reproduce
1. 
2. 
3. 

## โœ… Expected Behavior
<!-- What you expected to happen -->

## โŒ Actual Behavior
<!-- What actually happened -->

## ๐Ÿ“ธ Screenshots
<!-- If applicable, add screenshots -->

## ๐ŸŒ Environment
- OS: 
- Browser: 
- Version: 

## ๐Ÿ“ Additional Context
<!-- Any other context about the problem -->

Create .github/ISSUE_TEMPLATE/feature_request.md:

---
name: Feature Request
about: Suggest a new feature
title: '[FEATURE] '
labels: enhancement
assignees: ''
---

## ๐Ÿš€ Feature Description
<!-- Clear description of the feature -->

## ๐ŸŽฏ Problem This Solves
<!-- What problem does this solve? -->

## ๐Ÿ’ก Proposed Solution
<!-- How should this work? -->

## ๐Ÿ”„ Alternatives Considered
<!-- What other solutions did you consider? -->

## ๐Ÿ“ Additional Context
<!-- Any other context, mockups, or examples -->

Create Pull Request Template

Create .github/PULL_REQUEST_TEMPLATE.md:

## ๐ŸŽฏ What does this PR do?
<!-- Brief description of the changes -->

## ๐Ÿ“‹ Type of Change
- [ ] ๐Ÿ› Bug fix (non-breaking change which fixes an issue)
- [ ] โœจ New feature (non-breaking change which adds functionality)
- [ ] ๐Ÿ’ฅ Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] ๐Ÿ“ Documentation update
- [ ] ๐ŸŽจ Style/UI update
- [ ] โ™ป๏ธ Refactoring
- [ ] โœ… Test update

## ๐Ÿ”— Related Issues
<!-- Link related issues: Fixes #123, Relates to #456 -->

## ๐Ÿงช How Has This Been Tested?
<!-- Describe the tests you ran -->
- [ ] Test A
- [ ] Test B

## ๐Ÿ“ธ Screenshots (if applicable)
<!-- Add screenshots for UI changes -->

## โœ… Checklist
- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes

## ๐Ÿค” Questions or Notes
<!-- Anything reviewers should know? -->

6. Daily Workflow Scripts

Morning Git Status Check

Create ~/bin/git-morning-check.sh:

#!/bin/bash
# Check all your repos for uncommitted work

echo "๐ŸŒ… Good Morning! Checking your repos..."
echo ""

REPOS_DIR="${1:-$HOME/projects}"

if [ ! -d "$REPOS_DIR" ]; then
    echo "โŒ Directory $REPOS_DIR not found"
    exit 1
fi

found_issues=false

for repo in "$REPOS_DIR"/*; do
    if [ -d "$repo/.git" ]; then
        cd "$repo"

        repo_name=$(basename "$repo")

        # Check for uncommitted changes
        if [[ -n $(git status -s) ]]; then
            echo "๐Ÿ“ $repo_name: Has uncommitted changes"
            git status -s | sed 's/^/   /'
            echo ""
            found_issues=true
        fi

        # Check for unpushed commits
        unpushed=$(git log @{u}.. --oneline 2>/dev/null | wc -l)
        if [ "$unpushed" -gt 0 ]; then
            echo "โฌ†๏ธ  $repo_name: Has $unpushed unpushed commit(s)"
            git log @{u}.. --oneline | sed 's/^/   /'
            echo ""
            found_issues=true
        fi

        # Check for incoming commits
        git fetch --quiet 2>/dev/null
        incoming=$(git log ..@{u} --oneline 2>/dev/null | wc -l)
        if [ "$incoming" -gt 0 ]; then
            echo "โฌ‡๏ธ  $repo_name: Has $incoming incoming commit(s)"
            git log ..@{u} --oneline | sed 's/^/   /'
            echo ""
            found_issues=true
        fi

        # Check current branch
        branch=$(git branch --show-current)
        if [ "$branch" != "main" ] && [ "$branch" != "master" ]; then
            echo "๐ŸŒฟ $repo_name: On branch '$branch'"
            echo ""
            found_issues=true
        fi
    fi
done

if [ "$found_issues" = false ]; then
    echo "โœจ All repos are clean and synced!"
fi

echo ""
echo "๐Ÿ’ก Tip: Run 'git sync' in any repo to fetch and pull latest changes"

Make executable: chmod +x ~/bin/git-morning-check.sh

Quick Sync Script

Create ~/bin/git-sync-all.sh:

#!/bin/bash
# Sync all repos with remote

echo "๐Ÿ”„ Syncing all repositories..."
echo ""

REPOS_DIR="${1:-$HOME/projects}"

for repo in "$REPOS_DIR"/*; do
    if [ -d "$repo/.git" ]; then
        cd "$repo"
        repo_name=$(basename "$repo")

        echo "๐Ÿ“ฆ $repo_name"

        # Stash if there are changes
        if [[ -n $(git status -s) ]]; then
            git stash save "Auto-stash before sync $(date)" > /dev/null 2>&1
            echo "   ๐Ÿ’พ Stashed local changes"
        fi

        # Fetch and pull
        git fetch --all --prune > /dev/null 2>&1
        git pull --rebase > /dev/null 2>&1

        # Pop stash if we stashed
        if git stash list | grep -q "Auto-stash before sync"; then
            git stash pop > /dev/null 2>&1
            echo "   โ™ป๏ธ  Restored local changes"
        fi

        echo "   โœ… Synced"
        echo ""
    fi
done

echo "๐ŸŽ‰ All repositories synced!"

Make executable: chmod +x ~/bin/git-sync-all.sh

7. Visual Git Status in Prompt

Already included if you used the Starship prompt from the CLI guide, but here's a standalone version:

Add to ~/.bashrc:

# Git branch in prompt
parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

# Git status indicators
parse_git_dirty() {
    [[ $(git status --porcelain 2> /dev/null) ]] && echo "*"
}

# Update PS1 to include git info
export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)$(parse_git_dirty)\[\033[00m\]\$ '

8. GitHub Security Best Practices

SSH Key Setup (More Secure than HTTPS)

# Generate new SSH key
ssh-keygen -t ed25519 -C "your.email@example.com"

# Start ssh-agent
eval "$(ssh-agent -s)"

# Add key to agent
ssh-add ~/.ssh/id_ed25519

# Copy public key to clipboard
cat ~/.ssh/id_ed25519.pub
# Then add this to GitHub: Settings โ†’ SSH and GPG keys โ†’ New SSH key

Git Credential Helper (For HTTPS)

# Store credentials securely
git config --global credential.helper store

# Or use system keychain (macOS)
git config --global credential.helper osxkeychain

# Or use libsecret (Linux)
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

Protect Sensitive Data

Create ~/.gitignore_global:

# Secrets and credentials
.env
.env.*
*.pem
*.key
*.cert
secrets.yml
credentials.json
config/secrets.yml

# IDE files
.vscode/
.idea/
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

# Node
node_modules/
npm-debug.log

# Python
__pycache__/
*.pyc
.pytest_cache/
venv/
.venv/

# Logs
*.log
logs/

Apply globally:

git config --global core.excludesfile ~/.gitignore_global

9. Branch Management Workflow

Feature Branch Workflow Script

Create ~/bin/git-feature.sh:

#!/bin/bash
# Start a new feature branch with proper naming

echo "๐ŸŒฟ Starting a new feature branch"
echo ""

# Make sure we're starting from main/master
main_branch=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')

echo "๐Ÿ“ Current branch: $(git branch --show-current)"
echo "๐Ÿ”„ Switching to $main_branch..."

git checkout "$main_branch"
git pull origin "$main_branch"

echo ""
read -p "Feature name (use-kebab-case): " feature_name

if [ -z "$feature_name" ]; then
    echo "โŒ Feature name cannot be empty"
    exit 1
fi

branch_name="feature/$feature_name"

echo "๐ŸŒฑ Creating branch: $branch_name"
git checkout -b "$branch_name"

echo ""
echo "โœ… Ready to work on: $branch_name"
echo "๐Ÿ’ก When done, run: git publish"

Make executable: chmod +x ~/bin/git-feature.sh

Add alias: git config --global alias.feature "!~/bin/git-feature.sh"

Cleanup Old Branches

Create ~/bin/git-cleanup.sh:

#!/bin/bash
# Clean up merged branches

echo "๐Ÿงน Cleaning up merged branches..."
echo ""

# Get main branch name
main_branch=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')

# Make sure we're on main
git checkout "$main_branch"

# Update from remote
git fetch --all --prune

echo "๐Ÿ—‘๏ธ  Branches that will be deleted:"
git branch --merged | grep -v "^\*" | grep -v "$main_branch" | grep -v "develop"

echo ""
read -p "Delete these branches? [y/N] " confirm

if [[ $confirm == [yY] ]]; then
    git branch --merged | grep -v "^\*" | grep -v "$main_branch" | grep -v "develop" | xargs -n 1 git branch -d
    echo "โœ… Cleanup complete!"
else
    echo "โŒ Cleanup cancelled"
fi

Make executable: chmod +x ~/bin/git-cleanup.sh

10. Emergency Recovery Commands

Add to ~/.gitconfig or use these commands:

# Undo last commit but keep changes
git config --global alias.uncommit "reset --soft HEAD^"

# Undo last commit and discard changes (DANGEROUS)
git config --global alias.abort "reset --hard HEAD^"

# Undo all local changes
git config --global alias.nuke "!git reset --hard && git clean -fd"

# Go back to how remote looks
git config --global alias.remote-reset "!git fetch origin && git reset --hard origin/$(git branch --show-current)"

# Show what you're about to push
git config --global alias.preview "log @{u}.. --oneline"

# Safe force push (won't overwrite others' work)
git config --global alias.force-push "push --force-with-lease"

11. Quick Reference Cheatsheet

Create ~/bin/git-help.sh:

#!/bin/bash

cat << 'EOF'
๐ŸŽฏ GIT CHEATSHEET

๐Ÿ“Š STATUS & INFO
  git s               Quick status
  git ss              Full status
  git summary         Last 10 commits (visual)
  git tree            All branches (visual)
  git recent          Recent branches

๐ŸŒฟ BRANCHES
  git feature         Start new feature branch
  git br              List branches
  git co NAME         Switch to branch
  git cob NAME        Create and switch to branch

๐Ÿ’พ COMMITTING
  git qc              Quick commit wizard
  git wip             Save work-in-progress
  git save            Checkpoint everything
  git ca              Amend last commit
  git can             Amend without editing message

๐Ÿ”„ SYNC
  git sync            Fetch and pull
  git publish         Push current branch
  git preview         See what will be pushed

โ†ฉ๏ธ  UNDO (SAFE)
  git unstage FILE    Remove from staging
  git uncommit        Undo commit, keep changes
  git discard FILE    Discard file changes

๐Ÿ†˜ EMERGENCY
  git nuke            Reset everything (DANGEROUS!)
  git remote-reset    Reset to match remote

๐Ÿ“ฆ GITHUB CLI
  ghv                 Open repo in browser
  ghpr                Open PR in browser
  ghprc               Create PR
  ghi                 View issue

๐Ÿ” SEARCH & INFO
  git who             Contributors
  git today           What I did today
  git changed         Files changed

๐Ÿ’ก WORKFLOWS
  git-morning-check   Check all repos
  git-sync-all        Sync all repos
  git feature         Start feature branch
  git-cleanup         Delete merged branches
EOF

Make executable: chmod +x ~/bin/git-help.sh

Add alias: alias git-help='~/bin/git-help.sh'

Usage Tips

Daily Routine

  1. Morning: Run git-morning-check to see what you were working on
  2. Before starting work: Run git sync in the repo
  3. New feature: Use git feature to start a new branch
  4. Committing: Use git qc for guided commits
  5. Before ending day: Run git save or git checkpoint
  6. Weekly: Run git-cleanup to remove merged branches

Visual Cues to Trust

  • ๐ŸŒฟ Green = safe/clean
  • ๐Ÿ“ Yellow = changes present
  • โฌ†๏ธ Blue = need to push
  • โฌ‡๏ธ Purple = need to pull
  • โŒ Red = conflicts/problems

When You Forget What You Were Doing

  1. git s - See current status
  2. git summary - See recent commits
  3. git stashes - Check if you stashed something
  4. git today - What you committed today

Preventing Mistakes

The setup includes: - Pre-commit hooks that catch secrets and large files - Confirmation for destructive operations - Auto-stash before syncing - Can't commit directly to main/master - Preview what you're pushing before you push

Customization

Adjust based on your needs: - Change branch naming conventions - Add language-specific pre-commit hooks - Customize commit message templates - Add more safety aliases - Adjust colors for better visibility

Remember: The goal is reducing anxiety and preventing "oh no" moments.