Skip to content

Instantly share code, notes, and snippets.

@raspberrypisig
Last active July 5, 2026 21:13
Show Gist options
  • Select an option

  • Save raspberrypisig/c7354878d74bf6a5af508c79ccec2506 to your computer and use it in GitHub Desktop.

Select an option

Save raspberrypisig/c7354878d74bf6a5af508c79ccec2506 to your computer and use it in GitHub Desktop.
# Single line comments start with a hash symbol.
####################################################
## 1. Setup and Configuration
####################################################
# Before doing anything, tell Git who you are.
# This information is used for commit authorship.
# Set your name
git config --global user.name "Your Name"
# Set your email
git config --global user.email "your.email@example.com"
# Set default branch name to 'main' (modern standard)
git config --global init.defaultBranch main
# View all configuration settings
git config --list
# => user.name=Your Name
# => user.email=your.email@example.com
# => init.defaultbranch=main
# Edit the global .gitconfig file directly
git config --global --edit
####################################################
## 2. Starting a Project
####################################################
# You can either start a new repository from scratch
# or copy an existing one.
# Initialize a new Git repository in the current directory
git init
# Initialize a new repository in a specific directory
git init my-project
# Clone an existing repository (creates a local copy with full history)
git clone https://github.com/user/repo.git
# Clone into a specific folder
git clone https://github.com/user/repo.git my-folder
# Clone a specific branch
git clone -b <branch-name> https://github.com/user/repo.git
####################################################
## 3. The Core Workflow (The Three Trees)
####################################################
# Git manages three "trees":
# 1. Working Directory (your files)
# 2. Staging Area / Index (what will go in the next commit)
# 3. Repository / HEAD (the last commit)
# Check the status of your files (which tree they are in)
git status
# => On branch main
# => nothing to commit, working tree clean
# Show brief status
git status -s
# Stage a specific file (Working Dir -> Staging Area)
git add filename.txt
# Stage all modified and new files
git add .
# Stage all tracked, modified files (ignores untracked files)
git add -u
# Interactively stage parts of a file (patch mode)
git add -p filename.txt
# Commit the staged changes (Staging Area -> Repository)
git commit -m "Descriptive message of what changed and why"
# Commit and automatically stage all tracked, modified files
git commit -am "Quick commit message"
# Amend the last commit (useful for fixing typos or adding forgotten files)
# WARNING: This rewrites history. Do not amend pushed commits.
git commit --amend -m "New corrected message"
####################################################
## 4. Ignoring Files
####################################################
# Tell Git which files to ignore (e.g., build artifacts, secrets, IDE settings).
# Create a .gitignore file in the root of your repo.
# Example .gitignore contents:
# node_modules/
# *.log
# .env
# dist/
# If a file is already tracked, .gitignore won't affect it.
# To untrack it without deleting the local file:
git rm --cached filename.txt
####################################################
## 5. Branching and Merging
####################################################
# Branches are lightweight pointers to a specific commit.
# List local branches (* indicates current branch)
git branch
# => * main
# => feature-branch
# List all branches (local and remote)
git branch -a
# Create a new branch (does not switch to it)
git branch feature-branch
# Switch to an existing branch
git switch feature-branch
# (Legacy equivalent: git checkout feature-branch)
# Create a new branch AND switch to it
git switch -c new-feature
# (Legacy equivalent: git checkout -b new-feature)
# Switch back to the previous branch
git switch -
# Merge a branch into your current branch
git switch main
git merge feature-branch
# Delete a local branch (safe: refuses if not merged)
git branch -d feature-branch
# Force delete a local branch (even if not merged)
git branch -D feature-branch
# --- Resolving Merge Conflicts ---
# If Git can't automatically merge changes, it pauses and marks conflicts
# in the files with <<<<<<<, =======, and >>>>>>>.
# 1. Open the conflicted files in your editor and resolve the markers.
# 2. Stage the resolved files.
git add resolved-file.txt
# 3. Complete the merge commit.
git commit -m "Resolve merge conflict between main and feature"
# Abort a merge in progress
git merge --abort
# --- Rebasing ---
# Rebasing rewrites history by moving your branch to start at the tip
# of another branch. It creates a linear history.
# Rebase current branch onto main
git switch feature-branch
git rebase main
# Interactive rebase (allows you to squash, edit, reorder commits)
git rebase -i HEAD~3 # Edit the last 3 commits
####################################################
## 6. Remote Repositories
####################################################
# Remotes are URLs to other versions of your repository
# (usually on GitHub, GitLab, etc.).
# List configured remotes
git remote -v
# => origin https://github.com/user/repo.git (fetch)
# => origin https://github.com/user/repo.git (push)
# Add a remote
git remote add origin https://github.com/user/repo.git
# Rename a remote
git remote rename origin upstream
# Remove a remote
git remote remove upstream
# Fetch all branches and history from the remote (does NOT merge)
git fetch origin
# Fetch a specific remote branch
git fetch origin feature-branch
# Pull = Fetch + Merge (updates your current branch from the remote)
git pull origin main
# Push your local branch to the remote
git push origin main
# Push and set the upstream tracking branch
# (so you can just type 'git push' later)
git push -u origin feature-branch
# Force push (OVERWRITES remote history. Use with extreme caution!)
git push --force origin feature-branch
# Safer force push: only pushes if it doesn't overwrite others' work
git push --force-with-lease origin feature-branch
####################################################
## 7. Undoing Changes
####################################################
# Git provides multiple ways to undo things.
# --- Unstaging and Discarding Local Changes ---
# Unstage a file (Staging Area -> Working Dir)
git restore --staged filename.txt
# (Legacy: git reset HEAD filename.txt)
# Discard local changes in a file (Working Dir -> Last Commit state)
# WARNING: Destroys uncommitted changes permanently!
git restore filename.txt
# (Legacy: git checkout -- filename.txt)
# --- Rewriting History (Local) ---
# Reset the staging area and working directory to match a past commit.
# --soft: Keep changes in Staging Area
git reset --soft HEAD~1
# --mixed (default): Keep changes in Working Directory, unstage them
git reset --mixed HEAD~1
# --hard: DESTROY all changes. Working Dir and Staging Area match the commit.
git reset --hard HEAD~1
# --- Reverting (Safe for Shared History) ---
# Create a NEW commit that undoes the changes of a specific past commit.
# This is the safe way to undo a commit that has already been pushed.
git revert <commit-hash>
# Revert a merge commit (requires specifying the parent number, usually -m 1)
git revert -m 1 <merge-commit-hash>
####################################################
## 8. Stashing
####################################################
# Temporarily shelve changes you've made to your working copy so you can
# work on something else, then come back and re-apply them later.
# Save local modifications to a new stash
git stash
# Save with a descriptive message
git stash push -m "WIP: fixing login bug"
# Include untracked files in the stash
git stash -u
# List all stashes
git stash list
# => stash@{0}: WIP on main: 1234567 Initial commit
# Apply the most recent stash (doesn't remove it from the list)
git stash apply
# Apply a specific stash
git stash apply stash@{2}
# Apply and remove the most recent stash from the list
git stash pop
# Drop a specific stash
git stash drop stash@{0}
# Clear all stashes
git stash clear
####################################################
## 9. Viewing History and Inspecting
####################################################
# View commit history
git log
# One-line format, graphical branch representation, all branches
git log --oneline --graph --all
# => * 1234567 (HEAD -> main) Fix bug
# => * 89abcde Initial commit
# Show history for a specific file
git log -- filename.txt
# Show commits by a specific author
git log --author="Name"
# Search commit messages for a string
git log --grep="search term"
# Show the changes introduced in a specific commit
git show <commit-hash>
# Show line-by-line differences between two commits
git diff <commit1> <commit2>
# Show differences between working directory and staging area
git diff
# Show differences between staging area and last commit
git diff --staged
# Show who last modified each line of a file (blame)
git blame filename.txt
####################################################
## 10. Tags
####################################################
# Tags are fixed pointers to specific commits, usually used for releases.
# List tags
git tag
# Create a lightweight tag (just a pointer)
git tag v1.0.0
# Create an annotated tag (recommended: contains author, date, message)
git tag -a v1.0.0 -m "Release version 1.0.0"
# Tag a past commit
git tag -a v0.9.0 <commit-hash>
# Push a specific tag to remote
git push origin v1.0.0
# Push all local tags to remote
git push origin --tags
# Delete a local tag
git tag -d v1.0.0
# Delete a remote tag
git push origin --delete v1.0.0
####################################################
## 11. Advanced / Power User Features
####################################################
# --- Cherry-Picking ---
# Apply the changes introduced by specific existing commits onto your current branch.
# Apply a single commit
git cherry-pick <commit-hash>
# Apply multiple commits
git cherry-pick <hash1> <hash2>
# Apply without committing (stages the changes for you to amend/commit manually)
git cherry-pick --no-commit <commit-hash>
# --- The Reflog (Your Lifesaver) ---
# The reflog records every time the tip of a branch changes, even if it wasn't
# a commit (e.g., resets, rebases, checkouts). If you "lost" a commit, it's here.
# View the reference log
git reflog
# => 1234567 HEAD@{0}: commit: Fix bug
# => 89abcde HEAD@{1}: checkout: moving from main to feature
# Recover a "lost" commit or branch by resetting to its reflog hash
git reset --hard HEAD@{5}
# or
git switch -c recovered-branch <hash-from-reflog>
# --- Bisect (Find the bug) ---
# Use binary search to find which commit introduced a bug.
# Start bisecting
git bisect start
# Mark current commit as bad
git bisect bad
# Mark a known good commit (e.g., an old tag)
git bisect good v1.0.0
# Git will checkout a middle commit. Test your code.
# If it's bad:
git bisect bad
# If it's good:
git bisect good
# Repeat until Git finds the exact commit that broke it.
# End the bisect session:
git bisect reset
# --- Worktrees ---
# Allow you to check out multiple branches simultaneously in different directories.
# Create a new working tree for a specific branch
git worktree add ../my-project-hotfix hotfix-branch
# List all worktrees
git worktree list
# Remove a worktree (after deleting the directory)
git worktree prune
# --- Submodules ---
# Allow you to keep a Git repository as a subdirectory of another Git repository.
# Add a submodule
git submodule add https://github.com/user/library.git libs/library
# Clone a repo with submodules
git clone --recurse-submodules <url>
# Initialize and update submodules in an existing clone
git submodule update --init --recursive
####################################################
## 12. Git Plumbing (Under the Hood)
####################################################
# Git's user commands are "porcelain". The underlying system is "plumbing".
# Everything in Git is an Object stored in .git/objects/:
# 1. Blob: Stores file data (no filename, just content).
# 2. Tree: Acts like a directory. Maps filenames to blobs and other trees.
# 3. Commit: Points to a top-level tree, and has metadata.
# 4. Tag: Points to a commit (or other object) with extra metadata.
# Inspect the type of an object (blob, tree, commit, tag)
git cat-file -t <object-hash>
# Pretty-print the contents of an object
git cat-file -p <object-hash>
# Check the integrity of the repository (finds corrupted objects)
git fsck
# Pack loose objects into a single binary file for efficiency
git gc
####################################################
## 13. Aliases and Automation
####################################################
# Create an alias for 'git co' to mean 'git checkout'
git config --global alias.co checkout
# Create an alias for a complex log command
git config --global alias.lg "log --oneline --graph --all --decorate"
# Run an external command as an alias (using '!' to run shell)
git config --global alias.publish "!git push -u origin $(git branch --show-current)"
# Git Hooks: Scripts that run automatically on certain events
# (located in .git/hooks/).
# Example: Create a pre-commit hook to run linters
# 1. Create the file and make it executable
touch .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
# 2. Add your script (e.g., npm run lint)
echo '#!/bin/sh\nnpm run lint' > .git/hooks/pre-commit
# Now, 'git commit' will fail if the linter fails!
####################################################
## 14. Sparse Checkout (For massive repos)
####################################################
# If you only need a specific folder from a massive repository.
# Enable sparse checkout
git sparse-checkout init
# Define the folders you want to check out
git sparse-checkout set src/components docs
# Disable sparse checkout (get everything back)
git sparse-checkout disable
####################################################
## 15. Bare Repositories
####################################################
# A "bare" repository is a Git repository that does not have a working
# directory (no checked-out files). It only contains the contents of the
# .git folder (the object database, refs, config, etc.).
# They are typically used as a central, shared remote repository on a server
# (like a self-hosted Git server) because they prevent users from accidentally
# committing directly to the checked-out branch of the central repo.
# Initialize a new bare repository
# (Conventionally, bare repos end with .git)
git init --bare my-project.git
# Clone an existing repository as a bare repository
git clone --bare https://github.com/user/repo.git my-project.git
# Push to a bare repository
# (Since there is no working directory, you cannot 'git commit' here.
# You must push changes from a standard, non-bare clone).
git push /path/to/my-project.git main
# Clone FROM a bare repository (creates a standard working copy)
git clone /path/to/my-project.git my-local-clone
# Note: If you ever need to convert a standard repo to a bare one,
# you can move the .git folder to the root and change the config:
# mv my-repo/.git my-repo.git
# git config --file=my-repo.git/config core.bare true
# rm -rf my-repo
####################################################
## 15. Bare Repositories
####################################################
# A "bare" repository is a Git repository that does not have a working
# directory (no checked-out files). It only contains the contents of the
# .git folder (the object database, refs, config, etc.).
# They are typically used as a central, shared remote repository on a server
# (like a self-hosted Git server) because they prevent users from accidentally
# committing directly to the checked-out branch of the central repo.
# Initialize a new bare repository
# (Conventionally, bare repos end with .git)
git init --bare my-project.git
# Clone an existing repository as a bare repository
git clone --bare https://github.com/user/repo.git my-project.git
# Push to a bare repository
# (Since there is no working directory, you cannot 'git commit' here.
# You must push changes from a standard, non-bare clone).
git push /path/to/my-project.git main
# Clone FROM a bare repository (creates a standard working copy)
git clone /path/to/my-project.git my-local-clone
# Note: If you ever need to convert a standard repo to a bare one,
# you can move the .git folder to the root and change the config:
# mv my-repo/.git my-repo.git
# git config --file=my-repo.git/config core.bare true
# rm -rf my-repo
extra
# --- The Reflog (Your Ultimate Lifesaver) ---
# The reflog records every time the tip of a branch changes, even if it wasn't
# a commit (e.g., resets, rebases, checkouts). If you "lost" a commit, it's here.
# View the reference log for the current branch (HEAD)
git reflog
# => 1234567 HEAD@{0}: commit: Fix bug
# => 89abcde HEAD@{1}: checkout: moving from main to feature
# => f1e2d3c HEAD@{2}: commit (initial): Initial commit
# View the reflog for a specific branch (not just HEAD)
git reflog show main
# => 1234567 main@{0}: commit: Update README
# Time-travel using the reflog!
# See where HEAD was with ISO dates
git reflog show --date=iso
# Checkout the state of main exactly as it was 3 days ago
git checkout main@{3.days.ago}
# --- Reflog Recovery Scenarios ---
# Scenario 1: You accidentally deleted a branch.
# Find the commit hash of the deleted branch's tip in the reflog:
git reflog | grep "branch-name"
# Recreate the branch pointing to that lost commit:
git branch recovered-branch <hash-from-reflog>
# Scenario 2: You messed up an interactive rebase and lost commits.
# Find the state right *before* you started the rebase:
git reflog
# => a1b2c3d HEAD@{0}: rebase (finish): ...
# => ...
# => e4f5g6h HEAD@{5}: rebase (start): ...
# => z9y8x7w HEAD@{6}: commit: My lost commit!
# Reset back to the state before the rebase started:
git reset --hard HEAD@{6}
# Scenario 3: You accidentally dropped a stash.
# Stashes are just commits! Find the dropped stash in the reflog:
git reflog | grep "WIP on"
# Recreate and apply the dropped stash:
git stash apply <hash-of-dropped-stash>
# --- Worktrees (Concurrency & Agents) ---
# Allow you to check out multiple branches simultaneously in different
# directories, sharing the same .git database.
# Create a new working tree for a specific branch
git worktree add ../my-project-hotfix hotfix-branch
# Create a detached HEAD worktree (useful for CI/CD or agents
# that just need to build/test without creating a local branch)
git worktree add --detach ../agent-build-dir origin/main
# List all worktrees
git worktree list
# => /path/to/main-repo 1234567 [main]
# => /path/to/../hotfix 89abcde [hotfix-branch]
# Remove a worktree (safely deletes the directory and git metadata)
git worktree remove ../my-project-hotfix
# Clean up stale worktree metadata if directories were deleted manually
git worktree prune
# --- Using Worktrees with AI Agents or CI ---
# When multiple AI coding agents (or CI jobs) need to work on the same
# repository concurrently, they can't share the main working directory.
# Worktrees give each agent its own isolated filesystem space.
# 1. Orchestrator creates an isolated workspace for an AI agent's task
git worktree add ../agent-task-1 feature-ai-task-1
# 2. Lock the worktree to prevent automated cleanup scripts (or `git gc`)
# from pruning it while the agent is actively working on long-running tasks
git worktree lock ../agent-task-1 --reason "AI Agent 1 working on task"
# 3. Agent finishes its work, pushes the branch, and cleans up its workspace
git worktree unlock ../agent-task-1
git worktree remove ../agent-task-1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment