Extra: Getting Started with GitHub

What is Git and GitHub?

Git is a distributed version control system that tracks changes in your code over time. Think of it as a sophisticated "undo" system that remembers every change you've ever made to your files.

GitHub is a cloud-based hosting service for Git repositories. It adds collaboration features like pull requests, issues, and project management tools on top of Git. Think of it as Google Drive for code, but with powerful version control and collaboration features.

Why use Version Control?

  • History Tracking: See who changed what and when

  • Backup: Your code is stored in multiple places

  • Collaboration: Multiple people can work on the same project

  • Branching: Experiment without breaking the main code

  • Rollback: Undo mistakes easily

Part 1: Setting up your GitHub account

If you Create a GitHub account go to github.com click the "Sign up" button and complete registration

Part 2: Installing and Configuring Git

2.1 Install Git on your computer

Windows Installation:

  1. Download Git

    • Click "Download for Windows"

    • The download should start automatically

  2. Run the Installer

    • Double-click the downloaded .exe file

    • Important settings during installation:

      • Default editor: Choose your preferred text editor (VS Code recommended for beginners)

      • PATH environment: Select "Git from the command line and also from 3rd-party software"

      • Line ending conversions: Choose "Checkout Windows-style, commit Unix-style"

      • Terminal emulator: "Use MinTTY"

      • Default branch name: "main" (GitHub's new standard)

      • Keep other settings as default

  3. Verify installation

    • Open Command Prompt or Git Bash

    • Type: git --version

    • You should see something like: git version 2.40.0

Mac Installation:

  1. Check if Git is Pre-installed

    git --version
    • If you see a version number, Git is already installed

    • If not, continue with installation

  2. Install via Homebrew (Recommended)

    # Install Homebrew if not already installed
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
    # Install Git
    brew install git
    
    # Verify installation
    git --version
  3. Alternative: Install via Xcode

    • Install Xcode Command Line Tools

    xcode-select --install

Linux Installation:

Ubuntu/Debian:

# Update package index
sudo apt update

# Install Git
sudo apt-get install git

# Verify installation
git --version

2.2 Configure Git

After installation, you must configure Git with your identity. This information is attached to every commit you make.

# Set your name (use your real name or GitHub username)
git config --global user.name "Your Name"

# Set your email (use the same email as your GitHub account)
git config --global user.email "your.email@example.com"

# Set default branch name to 'main' (modern standard)
git config --global init.defaultBranch main

# Set default editor (optional but helpful)
git config --global core.editor "code --wait"  # For VS Code
# Or for other editors:
# git config --global core.editor "nano"        # For Nano
# git config --global core.editor "vim"         # For Vim

# Enable colored output (makes reading git output easier)
git config --global color.ui auto

# View all your configurations
git config --list

Part 3: Authentication Methods

3.1 Understanding authentication options

GitHub offers several authentication methods. As of 2021, password authentication for Git operations was deprecated for security reasons. You now have two main options:

  1. Personal Access Tokens (PAT) - Easier for beginners

  2. SSH Keys - More secure and convenient long-term

3.2 Method 1: Personal Access Token (PAT) authentication

Creating a Personal Access Token:

  1. Navigate to token settings

    • Log into GitHub

    • Click your profile picture → Settings

    • Scroll down to "Developer settings" in the left sidebar

    • Click "Personal access tokens" → "Tokens (classic)"

    • Click "Generate new token" → "Generate new token (classic)"

  2. Configure your token

    • Note: Give it a descriptive name (e.g., "Personal Laptop Token")

    • Expiration: Select duration (90 days recommended for security)

    • Select scopes: For basic operations, check:

      • ✅ repo (Full control of private repositories)

      • ✅ workflow (Update GitHub Action workflows)

      • ✅ write:packages (Upload packages to GitHub Package Registry)

      • ✅ delete:packages (Delete packages from GitHub Package Registry)

    • Click "Generate token"

  3. Save your token

    • IMPORTANT: Copy the token immediately!

    • You won't be able to see it again

    • Store it securely (password manager recommended)

  4. Using your token

    When cloning a private repository or pushing changes:

    # Clone using token
    git clone https://github.com/username/repository.git
    # When prompted for password, paste your token (not your GitHub password)
    
    # Or include token in URL (less secure, not recommended)
    git clone https://<token>@github.com/username/repository.git
  5. Storing token credentials (Optional)

    To avoid entering your token repeatedly:

    Windows:

    # Git Credential Manager comes with Git for Windows
    git config --global credential.helper manager-core

    Mac:

    # Use macOS keychain
    git config --global credential.helper osxkeychain

    Linux:

    # Store credentials in memory for 15 minutes
    git config --global credential.helper cache
    
    # Or store for a specific duration (e.g., 1 hour = 3600 seconds)
    git config --global credential.helper 'cache --timeout=3600'

SSH keys provide a more secure and convenient way to authenticate. Once set up, you won't need to enter credentials for each operation.

Step 1: Check for existing SSH keys

# List files in your SSH directory
ls -al ~/.ssh

# Look for files like:
# id_rsa.pub
# id_ecdsa.pub
# id_ed25519.pub

If you see these files, you may already have SSH keys. You can use existing ones or create new ones.

Step 2: Generate a new SSH key pair

# Generate a new SSH key (recommended algorithm: ed25519)
ssh-keygen -t ed25519 -C "your_email@example.com"

# If your system doesn't support ed25519, use RSA
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

During key generation:

  1. Press Enter to accept default file location

  2. Enter a passphrase (recommended for security)

  3. Confirm the passphrase

  4. Your key pair is generated!

Understanding what was created:

  • Private key: ~/.ssh/id_ed25519 (NEVER share this!)

  • Public key: ~/.ssh/id_ed25519.pub (This goes to GitHub)

Step 3: Add SSH key to SSH agent

The SSH agent manages your keys and passphrases.

Mac/Linux:

# Start the ssh-agent in background
eval "$(ssh-agent -s)"

# Mac only: Configure SSH to use keychain
echo "Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519" >> ~/.ssh/config

# Add your SSH private key to the ssh-agent
ssh-add ~/.ssh/id_ed25519

Windows (Git Bash):

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

# Add your SSH key
ssh-add ~/.ssh/id_ed25519

Step 4: Copy your public key

Mac:

# Copy to clipboard
pbcopy < ~/.ssh/id_ed25519.pub

Linux:

# Display the key (then manually copy)
cat ~/.ssh/id_ed25519.pub

# Or use xclip if installed
xclip -selection clipboard < ~/.ssh/id_ed25519.pub

Windows (PowerShell):

# Copy to clipboard
Get-Content ~/.ssh/id_ed25519.pub | Set-Clipboard

Windows (Git Bash):

# Display the key (then manually copy)
cat ~/.ssh/id_ed25519.pub
# Quick WSL Setup (Run as Administrator)

# Check if WSL is installed and list distributions
wsl --list --verbose
# or: wsl -l -v

# Install WSL with Ubuntu (if not installed)
wsl --install -d Ubuntu

# Update WSL to version 2 (if needed)
wsl --set-default-version 2

# Start the default WSL distribution
wsl

# or explicitly Start Ubuntu
wsl -d Ubuntu

Step 5: Add SSH Key to GitHub

  1. Go to GitHub.com and log in

  2. Click profile picture → Settings

  3. Click "SSH and GPG keys" in sidebar

  4. Click "New SSH key"

  5. Title: Enter descriptive name (e.g., "Personal MacBook Pro")

  6. Key type: Keep as "Authentication Key"

  7. Key: Paste your public key

  8. Click "Add SSH key"

  9. Confirm with your GitHub password if prompted

Step 6: Test your SSH connection

# Test the connection
ssh -T git@github.com

# First time connection will show:
# The authenticity of host 'github.com...' can't be established.
# Type 'yes' to continue

# Success message:
# Hi username! You've successfully authenticated, but GitHub does not provide shell access.

Step 7: Update repository URLs to use SSH

If you've already cloned repositories using HTTPS, update them to use SSH:

# Check current remote URL
git remote -v

# If it shows https://github.com/username/repo.git, change to SSH:
git remote set-url origin git@github.com:username/repository.git

# Verify the change
git remote -v

Part 4: Basic GitHub workflow

4.1 Creating a new repository

On GitHub (Remote):

  1. Navigate to repository creation

    • Click "+" icon in top right corner

    • Select "New repository"

  2. Configure repository settings

    • Repository name: Use lowercase with hyphens (e.g., my-awesome-project)

    • Description: Brief explanation of your project

    • Visibility:

      • Public: Anyone can see

      • Private: Only you and collaborators can see

    • Initialize repository:

      • ✅ Add a README file (recommended)

      • Add .gitignore: Select template for your language/framework

      • Choose a license: MIT for open source, or leave blank

    • Click "Create repository"

Locally (on your computer):

# Create a new directory
mkdir my-awesome-project
cd my-awesome-project

# Initialize as a Git repository
git init

# Create a README file
echo "# My Awesome Project" > README.md

# Add and commit
git add README.md
git commit -m "Initial commit"

# Connect to GitHub repository
git branch -M main
git remote add origin git@github.com:username/my-awesome-project.git

# Push to GitHub
git push -u origin main
mkdir my-awesome-project
cd my-awesome-project
git init
git remote add origin git@github.com:username/my-awesome-project.git
# Skip creating new files

git pull origin main
# pull (fetch + merge) from the repo
# You can create new files, modify existing ones
# and start committing

4.2 Cloning a Repository

Cloning creates a local copy of a remote repository:

# Using SSH (recommended if configured)
git clone git@github.com:username/repository.git

# Using HTTPS (with token)
git clone https://github.com/username/repository.git

# Clone into a specific directory
git clone git@github.com:username/repository.git my-custom-folder

# Clone a specific branch
git clone -b branch-name git@github.com:username/repository.git

# Shallow clone (only recent history, faster for large repos)
git clone --depth 1 git@github.com:username/repository.git

4.3 Essential Git commands

Checking repository status

# See what's changed
git status

# Shorter status output
git status -s

# Understanding status indicators:
# ?? - Untracked files (new files)
# A  - Added to staging
# M  - Modified
# D  - Deleted
# R  - Renamed

Adding files to staging area

The staging area is where you prepare changes before committing:

# Add specific file
git add filename.txt

# Add multiple files
git add file1.txt file2.txt

# Add all files in current directory
git add .

# Add all changes in entire repository
git add -A

# Add only modified files (not new ones)
git add -u

# Interactive staging (choose what to stage)
git add -p

Committing changes

# Commit with message
git commit -m "Add user authentication feature"

# Commit with detailed message
git commit -m "Add user authentication" -m "- Implemented login form
- Added password hashing
- Created session management"

# Amend last commit (fix mistakes)
git commit --amend -m "New commit message"

# Add forgotten file to last commit
git add forgotten-file.txt
git commit --amend --no-edit

Working with Remotes

# View remotes
git remote -v

# Add a new remote
git remote add upstream https://github.com/original/repository.git

# Remove a remote
git remote remove upstream

# Rename a remote
git remote rename origin upstream

# Show detailed remote information
git remote show origin

Pushing changes

# Push to default remote and branch
git push

# Push to specific remote and branch
git push origin main

# Push and set upstream (first time pushing a branch)
git push -u origin feature-branch

# Force push (DANGEROUS - overwrites remote)
git push --force
# Safer alternative
git push --force-with-lease

# Push all branches
git push --all

# Push tags
git push --tags

Pulling and Fetching changes

# Fetch changes without merging
git fetch

# Fetch from specific remote
git fetch origin

# Pull (fetch + merge) changes
git pull

# Pull with rebase instead of merge
git pull --rebase

# Pull specific branch
git pull origin main

4.4 Understanding Git's three states

Files in a Git repository can be in one of three states:

  1. Modified: You've changed the file but haven't staged it

  2. Staged: You've marked the file to go into next commit

  3. Committed: The data is safely stored in your local database

Working Directory → Staging Area → Repository
     (edit)           (git add)    (git commit)

Part 5: Branching and Merging

5.1 Understanding Branches

Branches allow you to develop features isolated from the main codebase. Think of them as parallel universes for your code.

# List all branches (* indicates current branch)
git branch

# List all branches including remote
git branch -a

# List remote branches only
git branch -r

# Create a new branch
git branch feature-login

# Switch to a branch
git checkout feature-login

# Create and switch in one command
git checkout -b feature-payment

# Rename current branch
git branch -m new-branch-name

# Delete a local branch (safe - prevents deletion if unmerged)
git branch -d feature-login

# Force delete a branch
git branch -D feature-login

# Delete remote branch
git push origin --delete feature-login

5.2 Merging Branches

# Merge feature branch into current branch
git checkout main
git merge feature-login

# Merge with a commit message
git merge feature-login -m "Merge login feature"

# Abort a merge in progress
git merge --abort

# View merge conflicts
git status

# After resolving conflicts
git add .
git commit -m "Resolve merge conflicts"

Part 6: Team Collaboration Example

6.1 A Real-World Scenario

Let's walk through a typical day for two developers, Alice and Bob, working on an e-commerce website.

Initial Setup

Repository Structure:

ecommerce-site/
├── index.html
├── styles.css
├── app.js
└── README.md

Day 1: Alice Works on Shopping Cart

# Alice clones the repository
git clone git@github.com:company/ecommerce-site.git
cd ecommerce-site

# Alice creates a feature branch for shopping cart
git checkout -b feature/shopping-cart

# Alice adds shopping cart files
echo "// Shopping cart logic" > cart.js
git add cart.js
git commit -m "Add shopping cart functionality"

# Alice modifies existing files
echo "import './cart.js';" >> app.js
git add app.js
git commit -m "Import cart module in main app"

# Alice pushes her branch
git push -u origin feature/shopping-cart

Day 1: Bob Works on User Authentication

# Bob clones the repository
git clone git@github.com:company/ecommerce-site.git
cd ecommerce-site

# Bob creates a feature branch for authentication
git checkout -b feature/user-auth

# Bob adds authentication files
echo "// Authentication logic" > auth.js
git add auth.js
git commit -m "Add user authentication module"

# Bob also modifies app.js
echo "import './auth.js';" >> app.js
git add app.js
git commit -m "Import auth module in main app"

# Bob pushes his branch
git push -u origin feature/user-auth

Day 2: Creating Pull Requests

Alice's Pull Request:

  1. Alice goes to GitHub repository page

  2. Clicks "Pull requests" → "New pull request"

  3. Selects base: main ← compare: feature/shopping-cart

  4. Adds title: "Add shopping cart functionality"

  5. Adds description:

    ## Changes Made- Added cart.js with shopping cart logic- Integrated cart module into main app## Testing- Tested adding/removing items- Verified cart persistence## Screenshots[Attach screenshots]
  6. Assigns Bob as reviewer

  7. Clicks "Create pull request"

Bob Reviews Alice's Code:

# Bob fetches Alice's branch to test locally
git fetch origin
git checkout feature/shopping-cart

# Bob tests the code
npm test

# Bob goes to GitHub and:
# - Reviews changed files
# - Adds inline comments
# - Approves the pull request

Bob's Pull Request:

Bob creates a similar pull request for his authentication feature.

Day 3: Handling Merge Conflicts

Alice's PR gets merged first. Now Bob needs to update his branch:

# Bob switches to his branch
git checkout feature/user-auth

# Bob fetches latest changes
git fetch origin

# Bob merges main into his branch
git merge origin/main

# CONFLICT in app.js! Both modified the same file
# Git shows:
# <<<<<<< HEAD
# import './auth.js';
# =======
# import './cart.js';
# >>>>>>> origin/main

# Bob resolves by keeping both imports
# He edits app.js to include:
# import './cart.js';
# import './auth.js';

# Bob stages the resolved file
git add app.js

# Bob completes the merge
git commit -m "Merge main and resolve conflicts"

# Bob pushes the updated branch
git push origin feature/user-auth

6.2 Best Practices for Team Collaboration

Branch Naming Conventions

# Feature branches
feature/user-authentication
feature/shopping-cart
feature/payment-integration

# Bug fix branches
bugfix/login-error
bugfix/cart-calculation

# Hotfix branches (urgent production fixes)
hotfix/security-patch
hotfix/payment-gateway-error

# Release branches
release/v1.2.0
release/2023-q4

Commit Message Standards

# Format: <type>(<scope>): <subject>

# Examples:
git commit -m "feat(auth): add password reset functionality"
git commit -m "fix(cart): resolve quantity calculation error"
git commit -m "docs(readme): update installation instructions"
git commit -m "style(homepage): improve mobile responsiveness"
git commit -m "refactor(api): optimize database queries"
git commit -m "test(auth): add unit tests for login"
git commit -m "chore(deps): update dependencies"

# Types:
# feat: New feature
# fix: Bug fix
# docs: Documentation changes
# style: Formatting, missing semicolons, etc.
# refactor: Code restructuring without changing behavior
# test: Adding tests
# chore: Maintenance tasks

Part 7: Restoring Files and Undoing Changes

7.1 Restoring a Single File

From the Last Commit

# Discard changes in working directory
git checkout -- filename.txt

# In newer Git versions (2.23+)
git restore filename.txt

# Restore file from specific commit
git checkout abc123 -- filename.txt

# Or with newer syntax
git restore --source=abc123 filename.txt

# Restore file from 3 commits ago
git checkout HEAD~3 -- filename.txt

From Staging Area

# Unstage a file but keep changes
git reset HEAD filename.txt

# In newer Git versions
git restore --staged filename.txt

# Unstage all files
git reset HEAD .

7.2 Restoring the Entire Repository

To a Previous State

# View commit history
git log --oneline

# Soft reset (keeps changes in staging area)
git reset --soft HEAD~1

# Mixed reset (keeps changes in working directory)
git reset HEAD~1

# Hard reset (DISCARDS all changes)
git reset --hard HEAD~1

# Reset to specific commit
git reset --hard abc123

# Reset to remote state (useful when local is messed up)
git fetch origin
git reset --hard origin/main

Creating a Backup Before Reset

# Create a backup branch before dangerous operations
git branch backup-before-reset

# Now safe to reset
git reset --hard HEAD~5

# If something goes wrong, restore from backup
git checkout backup-before-reset

7.3 Recovering Lost Commits

# View history of all references (including deleted commits)
git reflog

# Find the commit you want to recover
# Example output:
# abc123 HEAD@{0}: reset: moving to HEAD~3
# def456 HEAD@{1}: commit: Important feature
# ghi789 HEAD@{2}: commit: Bug fix

# Recover a lost commit
git checkout def456

# Or create a new branch from lost commit
git branch recovered-branch def456

7.4 Viewing File History

# View history of specific file
git log -- filename.txt

# View detailed changes
git log -p -- filename.txt

# View who changed what (blame)
git blame filename.txt

# View file at specific commit
git show abc123:filename.txt

# Compare file between commits
git diff abc123 def456 -- filename.txt

Part 8: Advanced Features and Best Practices

8.1 The .gitignore File

Create a .gitignore file to exclude files from version control:

# .gitignore example

# Dependencies
node_modules/
vendor/

# Build outputs
dist/
build/
*.exe
*.dll

# IDE files
.vscode/
.idea/
*.sublime-workspace

# OS files
.DS_Store
Thumbs.db

# Environment files
.env
.env.local

# Logs
*.log
logs/

# Temporary files
*.tmp
*.temp
~$*

# Personal notes
TODO.md
notes.txt

Global .gitignore

# Create global gitignore
touch ~/.gitignore_global

# Configure Git to use it
git config --global core.excludesfile ~/.gitignore_global

8.2 Stashing Changes

Save work in progress without committing:

# Stash current changes
git stash

# Stash with a message
git stash save "Work in progress on feature X"

# List all stashes
git stash list

# Apply most recent stash
git stash apply

# Apply and remove stash
git stash pop

# Apply specific stash
git stash apply stash@{2}

# Delete a stash
git stash drop stash@{1}

# Clear all stashes
git stash clear

# Stash including untracked files
git stash -u

# Create a branch from stash
git stash branch new-feature-branch

8.3 Cherry-Picking Commits

Apply specific commits from one branch to another:

# Apply a single commit
git cherry-pick abc123

# Apply multiple commits
git cherry-pick abc123 def456

# Apply a range of commits
git cherry-pick abc123..def456

# Cherry-pick without committing
git cherry-pick -n abc123

# If conflicts occur
git cherry-pick --continue  # After resolving
git cherry-pick --abort     # To cancel

8.4 Interactive Rebase

Clean up commit history before merging:

# Interactive rebase last 3 commits
git rebase -i HEAD~3

# In the editor, you can:
# pick   - use commit
# reword - change commit message
# edit   - stop to amend commit
# squash - combine with previous commit
# fixup  - combine, discard message
# drop   - remove commit

# Example: Squashing commits
# Change "pick" to "squash" for commits to combine

8.5 Git Aliases for Efficiency

# Create useful aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

# More complex aliases
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.undo "reset --soft HEAD~1"
git config --global alias.last "log -1 HEAD"
git config --global alias.unstage "reset HEAD --"

# Use aliases
git co main
git br feature-branch
git lg

Part 9: GitHub-Specific Features

9.1 Issues

Issues track tasks, bugs, and feature requests:

  1. Creating an Issue:

    • Go to repository → "Issues" → "New issue"

    • Add descriptive title

    • Use markdown for formatting

    • Assign labels (bug, enhancement, documentation)

    • Assign to team members

    • Link to project boards

  2. Issue Templates: Create .github/ISSUE_TEMPLATE/ directory with templates:

    ---
    name: Bug Report
    about: Report a bug
    labels: bug
    ---
    
    **Describe the bug**
    
    **To Reproduce**
    1. Go to '...'
    2. Click on '...'
    
    **Expected behavior**
    
    **Screenshots**
    
    **Environment:**
    - OS: [e.g., Windows 10]
    - Browser: [e.g., Chrome 99]

9.2 Pull Request Templates

Create .github/pull_request_template.md:

## Description
Brief description of changes

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update

## Testing
- [ ] Unit tests pass
- [ ] Manual testing completed

## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] No console errors

9.3 GitHub Actions (CI/CD)

Create .github/workflows/main.yml:

name: CI Pipeline

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '16'
    
    - name: Install dependencies
      run: npm install
    
    - name: Run tests
      run: npm test
    
    - name: Build
      run: npm run build

9.4 GitHub Pages

Host static websites directly from repositories:

  1. Enable GitHub Pages:

    • Go to Settings → Pages

    • Select source branch (usually main or gh-pages)

    • Select folder (/root or /docs)

    • Save

  2. Access your site:

    • URL: https://username.github.io/repository-name/

9.5 Project Boards

Organize work with Kanban-style boards:

  1. Create a Project:

    • Go to Projects → New Project

    • Choose template (Basic Kanban, Automated Kanban)

    • Add columns: To Do, In Progress, Review, Done

  2. Automation:

    • Auto-move issues when PR created

    • Auto-close issues when PR merged

    • Auto-archive completed items

Last updated

Was this helpful?