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

bash
# 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)

bash
# 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:

bash
# 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:

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

Quick Commit Helper Script

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

bash
# 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

bash
# 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

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

Essential GitHub CLI Aliases

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

bash
# 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

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

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

yaml
# 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:

bash
cd your-repo
pre-commit install

5. Repository Templates

Create Issue Templates

Create .github/ISSUE_TEMPLATE/bug_report.md:

markdown
---
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:

markdown
---
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:

markdown
## 🎯 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:

bash
#!/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:

bash
#!/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:

bash
# 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)

bash
# 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)

bash
# 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:

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

9. Branch Management Workflow

Feature Branch Workflow Script

Create ~/bin/git-feature.sh:

bash
#!/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:

bash
#!/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:

bash
# 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:

bash
#!/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.