Follow AiTechWorlds on LinkedIn for professional AI content!Follow Now →
18 minLesson 36 of 40
Deployment & DevOps

Git & GitHub for Developers

Git and GitHub for Developers

Git is the version control system every professional developer uses daily. It tracks changes to your code, lets you experiment safely, and makes collaboration with a team possible. GitHub is where teams share code, review changes, and manage projects. This lesson covers the essential workflows you'll use in every professional job.

Core Concepts

Repository (repo): A folder tracked by Git. Contains all your project files and the complete history of every change.

Commit: A snapshot of your code at a moment in time. Every commit has a unique ID, a message, and a parent commit. Commits form a chain — the complete history.

Branch: A parallel version of your code. The main branch is the production-ready code. Feature branches are where new work happens.

Remote: A copy of your repo on another server (GitHub, GitLab). origin is the standard name for the main remote.

Daily Git Workflow

# Check what's changed
git status

# See the actual changes
git diff                    # unstaged changes
git diff --staged           # staged changes

# Stage specific files
git add src/components/Button.tsx
git add src/             # all files in src/

# Never use git add . without checking git status first
# (might accidentally commit .env, node_modules, etc.)

# Commit with a meaningful message
git commit -m "feat: add enrollment button to course page"

# Push to GitHub
git push origin main
git push origin feature/user-dashboard   # push a feature branch

Commit Message Convention

Consistent commit messages make the history readable. The most widely used convention:

type: short description (under 72 characters)

Optional longer explanation.

Types:

feat:     New feature
fix:      Bug fix
docs:     Documentation only
style:    Formatting, no logic change
refactor: Code change, no feature or fix
test:     Adding or updating tests
chore:    Build, tooling, deps

Real examples:

feat: add dark mode toggle to navigation
fix: prevent duplicate enrollment when clicking twice
refactor: extract PaymentForm into its own component
chore: upgrade Next.js to 15.2

Branching Strategy

Never commit directly to main. Use branches:

# Create and switch to a new branch
git checkout -b feature/enrollment-flow

# Do your work, commit...
git add .
git commit -m "feat: add enrollment modal"
git commit -m "feat: add payment form validation"

# Push the branch to GitHub
git push origin feature/enrollment-flow

# Open a pull request on GitHub, get it reviewed, merge it

# Back to main, pull the latest changes
git checkout main
git pull origin main

# Delete the merged branch
git branch -d feature/enrollment-flow

Resolving Merge Conflicts

Conflicts happen when two branches changed the same lines. Git marks them:

<<<<<<< HEAD
const buttonColor = "blue";
=======
const buttonColor = "indigo";
>>>>>>> feature/redesign

To resolve:

  1. Edit the file to keep the correct version (delete the conflict markers)
  2. git add the resolved file
  3. git commit to complete the merge
# Check which files have conflicts
git status

# After resolving, mark as resolved
git add src/components/Button.tsx
git commit -m "merge: resolve button color conflict"

Undo Operations

# Unstage a file (before commit)
git restore --staged src/components/Button.tsx

# Discard changes to a file (back to last commit)
git restore src/components/Button.tsx

# Undo last commit, keep changes staged
git reset --soft HEAD~1

# Undo last commit, keep changes unstaged
git reset HEAD~1

# View the git history
git log --oneline --graph

# Revert a specific commit (creates a new commit that undoes it — safe for shared branches)
git revert abc1234

Never use git reset --hard on commits that have been pushed — it rewrites history that others may have pulled.

Stashing

Stash saves your work-in-progress without committing it:

# Stash current changes
git stash

# Switch branches, do something else, come back

# Restore your stashed work
git stash pop

# See what's stashed
git stash list

# Stash with a description
git stash push -m "half-done enrollment flow"

# Apply a specific stash
git stash apply stash@{1}

Pull Requests on GitHub

A pull request (PR) is a request to merge your feature branch into main. It's also a code review opportunity.

Good PR habits:

  • Keep PRs small — under 400 lines changed is reviewable, 1000+ lines gets rubber-stamped
  • Write a clear description: what changed, why, how to test it
  • Link to the issue it closes: "Closes #42"
  • Respond to review comments quickly

From the command line with GitHub CLI:

# Install GitHub CLI
gh auth login

# Create a PR
gh pr create --title "feat: add enrollment flow" \
    --body "Adds the full enrollment modal with Stripe payment integration.

Closes #42

## Changes
- New EnrollmentModal component
- Stripe payment form
- Success/error states

## Testing
1. Click 'Enroll Now' on any course page
2. Fill in the payment form with test card 4242 4242 4242 4242
3. Verify redirect to dashboard"

# View open PRs
gh pr list

# Check out a PR to review locally
gh pr checkout 42

The .gitignore File

Tell Git what to ignore:

# .gitignore

# Dependencies
node_modules/

# Environment variables — NEVER commit these
.env
.env.local
.env.production

# Build output
.next/
dist/
build/

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*

# IDE settings
.vscode/settings.json
.idea/

# Upload directories
public/uploads/

Create a sensible .gitignore at project start. Accidentally committing .env with API keys is a common and painful mistake — if it happens, rotate all your keys immediately.

Git Aliases

Speed up common commands:

# Add to ~/.gitconfig or run as git config --global
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --decorate --all"

GitHub Actions (CI/CD Overview)

Automate tests and deployments on every push:

# .github/workflows/ci.yml
name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

Every PR now runs your tests automatically. Merging a broken PR becomes much harder.

Next lesson: Deploying to Vercel and Netlify — getting your app live on the internet.

📱

Get this course's notes on Telegram!

Free cheat sheets, summaries & practice exercises

Get Notes Free →
!