Skip to content

Lecture Notes: Git by Example — Interactive Guide

Author: Anton Zhiyanov Source: Git by Example — Interactive Reference Category: Programming

Overview

Git by Example is an interactive reference guide that covers Git operations from the absolute basics to advanced workflows. Designed as a practical reference to eliminate repeated Git command searches, it provides clear, concrete examples for every major Git operation.

Anton Zhiyanov is a software developer and writer known for clear technical tutorials. His Git guide is structured as a progressive reference — you can dip in at any level and find exactly the command you need with a working example.

Git Concepts

Before commands, the guide establishes the core mental model:

The Four Areas

Area Description Git Name
Working Tree Your actual files on disk, the directory you work in Working directory
Staging Area Proposed next commit — files you've marked to include Index / staging area
Repository The .git directory containing all history Repository / history
Remote Another repository (usually on a server) Remote

Key References

  • Branch — A movable pointer to a commit
  • Tag — A fixed pointer to a commit (usually for releases)
  • HEAD — A special pointer indicating where you are right now (usually the tip of the current branch)
  • ORIG_HEAD — Saved position before a potentially destructive operation (rebase, merge, reset)

Basic Operations

Initialization and Configuration

# Create a new repository
git init

# Configure user identity (per-repo)
git config user.name "Your Name"
git config user.email "your@email.com"

# Configure globally
git config --global user.name "Your Name"
git config --global user.email "your@email.com"

# View configuration
git config --list

File Operations

# Check file status
git status

# Add files to staging area
git add file.txt              # Single file
git add .                     # All files in current directory
git add -A                    # All files in the entire working tree

# Commit staged changes
git commit -m "Descriptive message"

# Commit all tracked file changes directly (skip staging)
git commit -a -m "Message"

# View commit history
git log                       # Full history
git log --oneline             # Compact one-line format
git log --graph --oneline     # With branch graph

Status and History

# See what changed but not staged
git diff

# See what's staged (will be in next commit)
git diff --staged

# See what was changed in a specific commit
git show <commit-hash>

# See who changed what in each line of a file
git blame file.txt

Branch and Merge

Creating and Switching Branches

# List branches
git branch                    # Local branches only
git branch -a                 # All branches (local + remote)

# Create a new branch
git branch feature-x

# Switch to a branch
git checkout feature-x

# Create and switch (combined)
git checkout -b feature-x

# Modern alternative (git 2.23+)
git switch feature-x
git switch -c feature-x       # Create and switch

Merging

# Merge feature-x into current branch
# First, switch to the target branch (e.g., main)
git checkout main
git merge feature-x

# Fast-forward merge (if linear history)
# No merge commit needed — just moves the pointer forward
git merge --ff-only feature-x

# No-fast-forward merge (always creates a merge commit)
git merge --no-ff feature-x

# Squash merge (combine all feature commits into one)
git merge --squash feature-x
git commit -m "Add feature-x as a single commit"

Rebasing

# Rebase current branch onto main
git checkout feature-x
git rebase main

# Interactive rebase (edit, reorder, squash commits)
git rebase -i HEAD~5          # Last 5 commits
git rebase -i main            # All commits since branching from main

# Abort a rebase that went wrong
git rebase --abort

Cherry-Picking

# Apply a specific commit from another branch onto current
git cherry-pick <commit-hash>

# Cherry-pick multiple commits
git cherry-pick <hash1> <hash2> <hash3>

# Cherry-pick without committing (edit first)
git cherry-pick -n <commit-hash>

Local and Remote

Cloning

# Clone a repository
git clone https://github.com/user/repo.git

# Clone into a specific directory
git clone https://github.com/user/repo.git my-folder

# Clone a specific branch
git clone --branch main https://github.com/user/repo.git

Pushing and Pulling

# Push local branch to remote
git push origin main

# Set upstream and push (first time)
git push -u origin feature-x

# Pull latest changes from remote
git pull                      # Fetch + merge
git pull --rebase             # Fetch + rebase (cleaner history)

# Fetch changes without merging
git fetch origin

# View remote branches
git remote -v

Conflict Resolution

When a merge or rebase results in conflicts:

  1. Git marks conflicted files with <<<<<<<, =======, >>>>>>>
  2. Edit the files to resolve conflicts manually
  3. Stage the resolved files: git add file.txt
  4. Complete the merge: git commit (for merge) or git rebase --continue (for rebase)
# See files with conflicts
git status

# Use a merge tool
git mergetool

# Abort the merge and go back
git merge --abort

Tags

# Create a lightweight tag
git tag v1.0.0

# Create an annotated tag (recommended)
git tag -a v1.0.0 -m "Release version 1.0.0"

# Push tags to remote
git push origin v1.0.0
git push --tags              # Push all tags

Undo Operations

Amend the Last Commit

# Change the last commit message
git commit --amend -m "New message"

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

Unstaging and Discarding

# Unstage a file (keep changes in working tree)
git reset HEAD file.txt
git restore --staged file.txt   # Modern syntax (git 2.23+)

# Discard changes in working tree (permanent!)
git checkout -- file.txt
git restore file.txt            # Modern syntax

# Discard all unstaged changes
git restore .

# Remove untracked files
git clean -n                   # Dry run (preview)
git clean -fd                  # Force remove files and directories

Reset (Moving the Branch Pointer)

# Soft reset — move HEAD, keep all changes staged
git reset --soft HEAD~1

# Mixed reset (default) — move HEAD, unstage changes
git reset HEAD~1

# Hard reset — move HEAD, discard all changes (⚠️ destructive)
git reset --hard HEAD~1

# Reset to a remote branch state
git reset --hard origin/main

Revert (Safe Undo)

# Create a new commit that undoes a previous commit
git revert <commit-hash>

# Revert multiple commits
git revert <hash1>..<hash2>

# Revert without committing (edit first)
git revert -n <commit-hash>

Reflog (The Safety Net)

The reflog records every movement of HEAD. Even after a hard reset, you can find lost commits:

# View the reflog
git reflog

# Restore to a previous state
git reset --hard HEAD@{2}     # The state 2 moves ago
git checkout <lost-commit-hash>

Stash (Temporary Storage)

# Save current changes temporarily
git stash push -m "WIP: feature work"

# List stashes
git stash list

# Apply the most recent stash
git stash pop                 # Apply and remove from stash
git stash apply               # Apply but keep in stash

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

# Drop a stash
git stash drop stash@{2}

# Clear all stashes
git stash clear

Advanced Topics

Bisect (Finding the Broken Commit)

# Start bisect
git bisect start
git bisect bad                # Current commit is broken
git bisect good <hash>        # This commit was working

# Git checks out a middle commit. Test it, then mark:
git bisect good               # If this commit is good
git bisect bad                # If this commit is bad

# Continue until git identifies the first bad commit
# End the bisect session
git bisect reset

Worktrees (Working on Multiple Branches Simultaneously)

# Create a new worktree for a branch
git worktree add ../project-feature feature-x

# List worktrees
git worktree list

# Remove a worktree
git worktree remove ../project-feature

Submodules

# Add a submodule
git submodule add https://github.com/user/library.git lib/

# Clone a repository with submodules
git clone --recurse-submodules https://github.com/user/project.git

# Update submodules
git submodule update --init --recursive

Custom Aliases

# Create a shortcut
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --graph --oneline --all"

# Now you can use: git co, git br, git ci, git st, git lg

Common Workflows

Feature Branch Workflow

# Start a new feature
git checkout -b feature-x
# ... work, commit, repeat ...
git commit -m "Implement feature X"

# When ready to merge:
git checkout main
git pull --rebase origin main
git merge feature-x
git push origin main

Fixing a Mistake on the Wrong Branch

# Oops — committed to main instead of feature-x
git branch feature-x          # Create the feature branch here
git reset --hard HEAD~1       # Remove the commit from main
git checkout feature-x        # Continue on the right branch

Interactive Rebase to Clean Up History

# Before sharing your branch, clean up commits
git rebase -i HEAD~4

# Options in interactive mode:
# - pick: keep the commit as-is
# - reword: change the commit message
# - squash: combine with previous commit
# - fixup: combine with previous, discarding this message
# - edit: stop to amend
# - drop: remove the commit

Key Takeaways

  • Git by Example is a structured, progressive reference — ideal for both beginners and experienced users
  • Covers the full range: concepts → basics → branching → remotes → undo → advanced
  • The reflog is the ultimate safety net — even destructive operations can be recovered
  • Modern Git (2.23+) introduces git switch and git restore as clearer alternatives to git checkout
  • Interactive rebase is the primary tool for cleaning up commit history before sharing
  • The guide's strength is its concreteness: every operation includes the exact command, not just a description
  • Anton Zhiyanov's style emphasizes practical utility over theoretical depth — learn by doing

References