Programming (Updated: ) 15 min read

Git & GitHub: A Practical Guide for Beginners (2026)

Suresh S Suresh S
Git & GitHub: A Practical Guide for Beginners (2026)

Here’s what happened to me before I learned Git: I had a project folder with files named app_final.js, app_final_v2.js, app_final_ACTUALLY_FINAL.js, and app_backup_DO_NOT_DELETE.js. Sound familiar?

Git solves this problem permanently. It tracks every change you make to every file, lets you rewind to any previous version, and makes collaboration possible without overwriting each other’s work. GitHub puts your Git repositories online so you can access them from anywhere, share them with others, and build a public portfolio.

If you write code, edit configuration files on Linux servers, manage infrastructure, or contribute to open-source projects — you need to know Git. Let me walk you through it.


Git vs. GitHub — What’s the Difference?

This confuses a lot of beginners, so let’s clear it up:

  • Git is a tool installed on your computer. It tracks file changes locally. It works completely offline.
  • GitHub is a website that hosts Git repositories online. It adds collaboration features — pull requests, issue tracking, project management, CI/CD automation.

You can use Git without GitHub. You cannot use GitHub without Git.

GitGitHub
WhatVersion control toolCloud hosting platform
WhereRuns on your machineWebsite (github.com)
Offline?Yes, fullyNo, needs internet
CostFree, open-sourceFree tier + paid plans
AlternativesNone (it’s the standard)GitLab, Gitea, Forgejo, Bitbucket

Think of Git as the camera taking snapshots of your work, and GitHub as the photo album where you store and share those snapshots.

Self-hosted alternatives like Gitea and Forgejo are popular in home lab setups where teams want full control over their code. You can deploy them with Coolify or Docker Compose in minutes.


Installing Git

Linux

# Ubuntu / Debian / Mint
sudo apt update && sudo apt install -y git

# Fedora / RHEL
sudo dnf install -y git

# Arch / Manjaro
sudo pacman -S git

If you’re new to installing packages on Linux, our guide on how to install software on Linux covers package managers across all major distributions.

macOS

brew install git
# or
xcode-select --install

Windows

Download the installer from git-scm.com or use winget:

winget install Git.Git

Verify Installation

git --version

Set Up Your Identity

Git attaches your name and email to every commit. Set these once:

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

While you’re configuring things, set your preferred text editor for commit messages:

git config --global core.editor "micro"

You can use any terminal editor — Micro for intuitive keybindings, Nano for simplicity, or Vim if you’ve invested in modal editing. Our top 13 Linux CLI text editors comparison helps you decide.


The Core Concept: How Git Tracks Changes

Understanding this mental model makes everything else click.

Git manages your files through four states:

  1. Working Directory → Your files as you’re editing them. Changed but not yet tracked.
  2. Staging Area → Files you’ve marked for the next commit. Think of it as a packing box — you decide what goes in before sealing it.
  3. Local Repository → The permanent history stored in the hidden .git folder on your machine. Every commit lives here forever (well, until you explicitly delete it).
  4. Remote Repository → Your code uploaded to GitHub (or GitLab, Gitea, etc.). Now it’s backed up online and shareable.

The daily workflow moves files through these states:

  • Edit files → git add → git commit → git push

That’s it. Those four commands cover 90% of daily Git usage. Whether you’re editing a Node.js application, tweaking Linux file permissions, or configuring a reverse proxy, Git tracks every change.


Essential Git Commands

Starting a Repository

Turn any folder into a Git-tracked project:

mkdir my-project
cd my-project
git init

Or clone an existing one from GitHub:

git clone https://github.com/username/repo-name.git

Checking Status

Your most-used command. Run it constantly:

git status

This tells you what branch you’re on, which files changed, what’s staged, and what’s untracked.

Staging Changes

Tell Git which files to include in the next commit:

# Stage a specific file
git add index.html

# Stage everything that changed
git add .

Committing

Take a snapshot of your staged changes:

git commit -m "Add responsive navigation bar"

Write clear, descriptive commit messages. Future-you will thank present-you.

Good messages: “Fix login redirect on mobile Safari”, “Add user profile API endpoint”, “Update Nginx config for WebSocket support”

Bad messages: “fix”, “updates”, “stuff”, “wip”, “asdf”

Viewing History

# Full history
git log

# Compact one-line view
git log --oneline

# Show changes in each commit
git log -p

# Graph view of branches
git log --oneline --graph --all

For security auditing, git log is invaluable. It lets you see exactly when a file was modified. If you’re investigating a potential breach after spotting something suspicious in your server logs, git log provides the exact timeline of code changes. To take it further, our Lyins security audit guide covers full system auditing.

Seeing What Changed

# Unstaged changes (what you've modified but not added)
git diff

# Staged changes (what's ready to commit)
git diff --staged

# Changes between two commits
git diff abc123 def456

Reviewing git diff output before committing is a great habit, especially when working on security-sensitive code. It helps catch hardcoded passwords or API keys before they get committed. If you need robust scanning, our guide on OWASP ZAP covers finding vulnerabilities in web applications, and Nikto handles web server scanning.


Branching and Merging

Branching is how you work on features, fixes, or experiments without touching the main codebase. It’s one of Git’s most powerful concepts, and it’s essential for collaboration.

Creating and Switching Branches

# Create a new branch and switch to it
git checkout -b feature/user-auth

# Or using the newer syntax
git switch -c feature/user-auth

# Switch back to main
git checkout main
# or
git switch main

# List all branches
git branch

# Delete a branch (after merging)
git branch -d feature/user-auth

Merging

Bring changes from a feature branch into main:

git checkout main
git merge feature/user-auth

If Git can merge automatically, it creates a merge commit and you’re done. If the same lines were changed in both branches, you’ll get a merge conflict — Git marks the conflicting sections in the file and you resolve them manually.

Handling Merge Conflicts

When a conflict occurs, the affected file will look like this:

<<<<<<< HEAD
const apiUrl = "https://api.production.com";
=======
const apiUrl = "https://api.staging.com";
>>>>>>> feature/user-auth

You decide which version to keep (or combine them), remove the conflict markers, then:

git add resolved-file.js
git commit -m "Resolve API URL merge conflict"

Merge conflicts feel scary at first, but they become routine. The key is reading the markers carefully and understanding what each branch intended.


Working with GitHub

Creating a Repository on GitHub

  1. Log into GitHub → click ”+” → “New repository”
  2. Name it (e.g., my-project)
  3. Choose Public or Private
  4. If pushing an existing local project, don’t initialize with a README
  5. Click “Create repository”

Then connect your local project:

git remote add origin https://github.com/username/my-project.git
git push -u origin main

Pushing and Pulling

# Upload local commits to GitHub
git push

# Download and merge remote changes
git pull origin main

# Download without merging (inspect first)
git fetch origin

GitHub Authentication

GitHub no longer accepts passwords for terminal operations. You need either a Personal Access Token or SSH keys.

Personal Access Token (simpler):

  1. GitHub → Settings → Developer Settings → Personal Access Tokens → Tokens (classic)
  2. Generate a new token with repo scope
  3. Copy it immediately (you won’t see it again)
  4. Use it as your password when Git prompts you

SSH Keys (better for daily use):

# Generate an SSH key pair
ssh-keygen -t ed25519 -C "[email protected]"

# Copy the public key
cat ~/.ssh/id_ed25519.pub

Paste the public key in GitHub → Settings → SSH and GPG keys → New SSH key.

Now you can clone and push using SSH URLs:

git clone [email protected]:username/repo-name.git

For securing SSH keys and managing credentials properly, our SSH hardening guide covers key-based authentication in depth. Store sensitive tokens and passwords in a secrets manager like Vaultwarden rather than plain text files. You can generate strong passwords and tokens with our password generator.


Pull Requests — How Collaboration Actually Works

Pull Requests (PRs) are how changes get reviewed and merged on GitHub. They’re the heart of collaborative development.

The workflow:

  1. Create a feature branch locally
  2. Make your changes and commit them
  3. Push the branch to GitHub: git push -u origin feature/my-feature
  4. On GitHub, click “Compare & pull request”
  5. Write a description of what you changed and why
  6. Request reviews from teammates
  7. Address any feedback with additional commits
  8. Once approved, merge the PR

This is how open-source projects work too. You fork a project, create a branch, make changes, and submit a PR to the original repository. The maintainers review it and decide whether to merge.


The .gitignore File

A .gitignore tells Git which files to completely ignore — secrets, build artifacts, dependencies, OS files. This is critical for security and keeping your repository clean.

Create one in your project root:

touch .gitignore

Common Patterns

# Dependencies
node_modules/
vendor/
__pycache__/
*.pyc

# Environment files (NEVER commit these)
.env
.env.local
.env*.local

# Build output
dist/
build/
out/

# OS files
.DS_Store
Thumbs.db

# IDE config
.idea/
.vscode/
*.swp

# Logs
*.log
npm-debug.log*

The golden rule: never commit .env files containing API keys, database credentials, or secret tokens. If you accidentally commit a secret, assume it’s compromised and rotate it immediately.

Our gitignore generator creates .gitignore templates for common project types — Node.js, Python, Go, Java, and more. For managing environment variables and secrets, the ENV generator scaffolds .env files with proper structure.

If you accidentally commit sensitive data, tools like git filter-branch or BFG Repo-Cleaner can rewrite history to remove it — but you should still rotate any exposed credentials immediately. For managing secrets properly, consider a self-hosted password manager like Vaultwarden or the open-source KeePassDX.


Advanced Git Commands

Once you’re comfortable with the basics, these commands make you significantly more productive.

git stash — Save Work Temporarily

You’re halfway through a feature when an urgent bug report comes in. You’re not ready to commit, but you can’t lose your work:

# Stash current changes
git stash

# Switch to main, fix the bug, commit, push
git checkout main
# ... fix the bug ...
git commit -m "Fix critical login bug"
git push

# Come back and restore your stashed work
git checkout feature/my-feature
git stash pop

Other stash commands:

git stash list              # See all stashes
git stash apply stash@{2}   # Apply a specific stash
git stash drop stash@{0}    # Delete a specific stash

git rebase — Clean Up History

Rebase replays your commits on top of another branch, creating a linear history instead of merge commits:

git checkout feature-branch
git rebase main

Interactive rebase lets you squash multiple messy commits into one clean commit:

git rebase -i HEAD~3

⚠️ Never rebase commits that have been pushed to a shared branch. Rebasing rewrites history, which causes problems for anyone who already pulled those commits.

git cherry-pick — Copy a Specific Commit

Need one specific bug fix from a development branch in production?

git cherry-pick a1b2c3d4

This copies just that commit to your current branch without merging everything else.

git blame — Who Wrote This Line?

git blame filename.py

Shows who last modified each line, when, and in which commit. Invaluable for understanding why code was written a certain way.


Understanding the .git Directory

Every Git repo has a hidden .git folder. This is the repository — everything else is just the working copy.

ls -la .git/

What’s inside:

  • HEAD → Points to the current branch (e.g., ref: refs/heads/main)
  • config → Repository-level settings (remotes, branch tracking)
  • objects/ → The content-addressable database. Every file version, commit, and tree is stored as a SHA-1 hashed object. Git is fundamentally a content store.
  • refs/heads/ → Branch pointers (SHA-1 hashes)
  • refs/remotes/ → Remote-tracked branch pointers
  • hooks/ → Scripts that run on specific events (pre-commit, post-push, etc.)

Understanding this structure demystifies Git. A branch is just a pointer. A commit is just a snapshot with a parent reference. Everything is content-addressed by hash.


GitHub Actions — Automating Your Workflow

GitHub Actions runs automated workflows triggered by events like pushes, pull requests, or schedules. It’s how modern teams implement CI/CD (Continuous Integration / Continuous Deployment).

Example: Testing a Python Project on Every Push

Create .github/workflows/ci.yml:

name: Python Tests

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        run: pytest

Every push to main or PR targeting main spins up a clean Ubuntu container, installs dependencies, and runs your test suite. If tests fail, the PR is blocked from merging.

Example: Testing a Node.js Project

name: Node.js CI

on: [push, pull_request]

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

GitHub Actions is free for public repositories and offers 2,000 minutes/month on the free plan for private repos. For deploying applications after tests pass, our guide on deploying Node.js apps on a Linux VPS covers the deployment side of the pipeline. If you’re using containers, the Docker Compose generator can scaffold your deployment configs.

For scheduling CI runs at specific times, the cron expression generator helps build cron syntax. And if you’re testing across different environments, understanding Python vs Rust tradeoffs and async JavaScript patterns helps you write better test suites.


Real-World Git Workflows

Solo Developer Workflow

For personal projects, keep it simple:

  1. Work directly on main for small projects
  2. Use feature branches for anything experimental
  3. Commit frequently with descriptive messages
  4. Push to GitHub regularly (it’s your backup)

Team Workflow (Feature Branch Model)

The most common professional workflow:

  1. main branch is always deployable
  2. Create feature branches: feature/user-auth, fix/login-bug
  3. Push branches and open Pull Requests
  4. Code review by teammates
  5. Merge after approval
  6. Delete the feature branch

GitFlow (For Larger Projects)

More structured, with dedicated branches:

  • main → Production releases only
  • develop → Integration branch for features
  • feature/* → Individual features
  • release/* → Release preparation
  • hotfix/* → Emergency production fixes

This is common in enterprise teams and works well with SDLC practices.


Git Tips That Save Time

Aliases — Shorten Common Commands

Add these to your ~/.gitconfig:

[alias]
    s = status
    co = checkout
    br = branch
    ci = commit
    lg = log --oneline --graph --all
    last = log -1 HEAD

Now git s replaces git status, git lg shows a visual branch graph, and git last shows your most recent commit.

You can also validate JSON configuration files with our JSON formatter and JSON validator before committing them — catching syntax errors before they hit production.

Fix Your Last Commit Message

git commit --amend -m "Better commit message"

Undo Staged Files

# Unstage a file (keep changes)
git restore --staged filename.js

# Discard all uncommitted changes (DESTRUCTIVE)
git restore .

See What Changed in a Specific Commit

git show abc123

Security and Best Practices

Git is a tool for managing code, but it intersects heavily with security:

  • Never commit secrets → API keys, passwords, tokens, private keys. Use .env files (gitignored) and environment variables. Our password generator creates strong credentials, and Vaultwarden stores them securely.
  • Sign your commits → Use GPG signing to prove commits actually came from you: git config --global commit.gpgsign true
  • Use SSH keys → More secure than PATs for daily use. Store your private key securely and never share it. Our guide on SSH hardening covers key management.
  • Protect your main branch → On GitHub, enable branch protection rules requiring PR reviews and passing CI checks before merging.
  • Audit your history → Use git log and git blame to track who changed what. If you’re managing server infrastructure, pair this with system log analysis for a complete audit trail.
  • Scan for vulnerabilities → Tools like Trivy, Snyk, and GitHub’s Dependabot scan your dependencies for known vulnerabilities. Our Docker container security guide covers image scanning in container workflows.

Git with DevOps Workflows

If you’re using Git to manage infrastructure configurations (not just application code), a few tools integrate naturally:

If you’re running a home lab with Proxmox, version-controlling your VM templates and configuration scripts in Git prevents the “I changed something and now it’s broken, and I don’t remember what I changed” disaster.


GitHub Alternatives

GitHub isn’t the only option for hosting Git repositories:

  • GitLab → Self-hosted or cloud. Includes CI/CD, container registry, and more built in. Popular in enterprises.
  • Gitea → Lightweight, self-hosted Git forge. Written in Go. Perfect for home labs and small teams.
  • Forgejo → Community fork of Gitea with a focus on sustainability and governance.
  • Bitbucket → Atlassian’s offering. Integrates with Jira.

If you self-host your own Git forge, protect it with a reverse proxy and TLS — our Let’s Encrypt guide covers automated certificate setup, and UFW handles firewall rules. For intrusion prevention, Fail2ban or CrowdSec block brute-force attempts against your Git server’s SSH or web interface. The Nginx config generator can create reverse proxy configs for your self-hosted Git instance.

For exploring more open-source tools to complement your Git workflow, our best open-source alternatives guide covers replacements for proprietary software across categories. Hosting your code on your own VPS gives you full control and avoids vendor lock-in — and you can compare cloud providers in our AWS vs Azure vs Google Cloud comparison.


Official Documentation


Frequently Asked Questions

What is Git and why should I learn it?

Git is a distributed version control system that tracks changes to your files over time. It lets you revert to previous versions, collaborate with others without overwriting work, and maintain a complete history of your project. It’s the industry standard for software development and is essential knowledge for any developer, sysadmin, or DevOps engineer.

What’s the difference between Git and GitHub?

Git is a tool installed on your computer that tracks file changes locally. GitHub is a cloud platform that hosts Git repositories online and adds collaboration features like pull requests, issue tracking, and CI/CD automation. You can use Git without GitHub, but not GitHub without Git.

How do I undo the last commit without losing my changes?

Use git reset --soft HEAD~1 to undo the commit while keeping all changes staged. Use git reset HEAD~1 to undo the commit and unstage changes (files remain in your working directory). Use git reset --hard HEAD~1 to permanently delete the commit and all its changes — this is destructive.

What is a pull request?

A pull request (PR) is a GitHub feature for proposing changes. You create a branch, make changes, push it, and open a PR asking the repository maintainer to review and merge your changes. It’s the standard workflow for code review and collaboration, especially in open-source projects.

What’s the difference between git merge and git rebase?

Both integrate changes from one branch into another. git merge creates a merge commit that preserves both branch histories. git rebase replays your commits on top of the target branch, creating a linear history. Rebase produces cleaner logs but should never be used on shared branches.

How do I resolve merge conflicts?

When Git can’t automatically merge changes (because the same lines were modified in both branches), it marks the conflicting sections in the file with <<<<<<<, =======, and >>>>>>> markers. You edit the file to keep the correct version, remove the markers, then stage and commit.

What should I put in .gitignore?

Ignore files that shouldn’t be in version control: dependencies (node_modules/), build output (dist/), environment files (.env), OS files (.DS_Store), IDE settings (.idea/, .vscode/), and log files. Never commit files containing secrets or credentials.

How do I set my default text editor for Git?

Run git config --global core.editor "editor-name". For example, git config --global core.editor "micro" for Micro, or git config --global core.editor "nano" for Nano.

What are GitHub Actions?

GitHub Actions is a CI/CD platform built into GitHub. It runs automated workflows triggered by events like pushes or pull requests. Common uses include running test suites, building Docker images, deploying applications, and checking code quality.

Can I use Git for things other than code?

Yes. Git tracks changes to any text-based file — documentation, configuration files, infrastructure definitions, even writing projects. Many technical writers and system administrators use Git to version-control non-code files.

Suresh S

Written by Suresh S

Systems Engineer & Tech Educator with 8+ years of experience in Linux Administration, Cloud Computing, and Cybersecurity. Founder of FreeTechLearner, dedicated to creating practical tutorials that help students and professionals build real-world skills.

Share this post:

Discussion

Loading comments...