Git with PowerShell
Note
A practical guide to running Git commands in PowerShell — from daily workflows like branching and pushing to recovering from mistakes with resets and reverts.
Overview
Git is the most widely used version control system. You can run all Git commands directly in PowerShell with no special modules required. This guide covers the commands you'll reach for most often — organized by task so you can find what you need fast.
Basic Syntax
# Most git commands follow this structure:
git <command> [options] [arguments]
# Check your git version
git --version
# Get help on any command
git <command> --help
Key Points
- Git commands run natively in PowerShell — no extra modules needed
- Commands behave the same in PowerShell, CMD, or Bash
- Use
git <command> --helpfor built-in docs on any command
Common Use Cases
Status & Log
What it does: Check what's changed in your working directory and review commit history.
# See modified, staged, and untracked files
git status
# Compact version
git status -s
# View commit history
git log
# Compact one-line log
git log --oneline
# Visual branch graph
git log --oneline --graph --all
# See unstaged changes
git diff
# See staged changes only
git diff --staged
Commits
What it does: Stage changes and save snapshots of your work.
# Stage a specific file
git add FileName.ps1
# Stage everything in the current directory
git add .
# Stage changes interactively (choose which parts to include)
git add -p FileName.ps1
# Commit with a message
git commit -m "Your commit message here"
# Stage all tracked files and commit in one step
git commit -am "Your commit message here"
# Amend the last commit (fix message or add a forgotten file)
git add ForgottenFile.ps1
git commit --amend -m "Updated commit message"
Amend with Caution
git commit --amend rewrites history. Only use it on commits that have not been pushed to a shared remote.
Branches & Switching
What it does: Create isolated lines of development and move between them.
# List local branches (* = current)
git branch
# List all branches including remote
git branch -a
# Create a new branch
git branch feature/my-new-feature
# Switch to a branch
git switch feature/my-new-feature
# Create AND switch in one step
git switch -c feature/my-new-feature
# Rename the current branch
git branch -m new-name
# Delete a branch (must be merged first)
git branch -d feature/old-feature
# Force delete (even if not merged)
git branch -D feature/old-feature
switch vs checkout
git switch is the modern replacement for git checkout when changing branches. It's clearer and less error-prone. Use git restore if you need to discard file changes instead.
Remotes
What it does: Manage connections to remote repositories like GitHub or GitLab.
# List remotes and their URLs
git remote -v
# Add a remote
git remote add origin https://github.com/YourUsername/YourRepo.git
# Remove a remote
git remote remove origin
# Rename a remote
git remote rename origin upstream
# Download changes from remote without merging
git fetch origin
# Fetch and clean up deleted remote branches
git fetch --prune
Push & Pull
What it does: Upload local commits to a remote, or download remote commits locally.
# Push to the tracked remote branch
git push
# Push and set tracking for a new branch
git push -u origin feature/my-new-feature
# Pull (fetch + merge) from tracked remote
git pull
# Pull from a specific branch
git pull origin main
# Pull using rebase for cleaner history
git pull --rebase
Force Push
Avoid git push --force — it overwrites remote history. Use git push --force-with-lease instead. It does the same thing but fails safely if someone else has pushed changes you haven't seen.
Merging & Conflicts
What it does: Combine changes from one branch into another and sort out any conflicts.
# Merge a branch into your current branch
git merge feature/my-new-feature
# Merge and keep the merge commit (no fast-forward)
git merge --no-ff feature/my-new-feature
# Abort a merge gone wrong
git merge --abort
# After resolving conflicts manually, stage the fixed files
git add ConflictedFile.ps1
# Then complete the merge
git commit
Resolving a Merge Conflict
Scenario: You merged feature/login into main and auth.ps1 has a conflict.
git merge feature/login
# CONFLICT (content): Merge conflict in auth.ps1
# Open auth.ps1 — you'll see conflict markers:
# <<<<<<< HEAD
# (your code on main)
# =======
# (incoming code from feature/login)
# >>>>>>> feature/login
# Edit the file, decide what to keep, remove the markers
# Then:
git add auth.ps1
git commit
Stashes
What it does: Temporarily shelve uncommitted changes so you can switch context without committing half-done work.
# Stash your changes
git stash
# Stash with a descriptive message
git stash push -m "WIP: login feature"
# List all stashes
git stash list
# Apply the most recent stash (keeps it in the list)
git stash apply
# Apply a specific stash
git stash apply stash@{2}
# Apply and remove the most recent stash
git stash pop
# Drop a stash without applying
git stash drop stash@{1}
# Clear all stashes
git stash clear
# Include untracked files in the stash
git stash push -u -m "Including new files"
Stashes Are Short-Term
If you're holding onto a stash for more than a day or two, commit to a feature branch instead. Stashes are easy to lose track of.
Undoing Changes
What it does: Discard or reverse changes at different stages — working directory, staging area, or already committed.
# Discard changes to a file (not yet staged)
git restore FileName.ps1
# Discard ALL unstaged changes
git restore .
# Unstage a file (keep changes, remove from staging)
git restore --staged FileName.ps1
# Revert a commit safely (creates a new "undo" commit)
git revert abc1234
# Remove untracked files
git clean -f
# Remove untracked files AND directories
git clean -fd
# Dry run — preview what clean would delete
git clean -n
restore vs revert vs reset
These three get confused constantly:
git restore— fixes your working directory or staging area (nothing committed yet)git revert— creates a new commit that undoes a previous one (safe on pushed commits)git reset— moves the branch pointer to a different commit (see Resets — careful on pushed commits)
Resets
What it does: Move your branch pointer to a previous commit, with control over what happens to your changes.
# Soft — move HEAD back, keep changes staged
git reset --soft HEAD~1
# Mixed (default) — move HEAD back, unstage changes but keep them
git reset HEAD~1
# Hard — move HEAD back and DISCARD changes
git reset --hard HEAD~1
# Reset to a specific commit hash
git reset --hard abc1234
# Go back 3 commits (soft)
git reset --soft HEAD~3
The Three Resets at a Glance
Think of it as how far back the reset reaches:
- Soft — moves the pointer only. Changes stay staged, ready to re-commit.
- Mixed — moves the pointer and unstages. Changes still exist in your files.
- Hard — moves the pointer and wipes your files clean. Changes are gone.
Hard Reset Is Destructive
git reset --hard discards changes permanently. If you do it by accident, git reflog may save you — but act fast. Never hard reset pushed commits on a shared branch.
Cherry-Pick
What it does: Grab a single commit from another branch and apply it to your current branch — without merging everything.
# Apply one specific commit
git cherry-pick abc1234
# Apply without auto-committing (lets you edit first)
git cherry-pick --no-commit abc1234
# Apply multiple commits
git cherry-pick abc1234 def5678
# Abort if something goes wrong
git cherry-pick --abort
Cherry-Pick a Bugfix
Scenario: You fixed a bug on feature/hotfix but only need that one commit on main.
Real-World Examples
Example: Full Feature Branch Workflow
Scenario: You need to build and ship a new PowerShell module without touching main until it's ready.
# Start from an up-to-date main
git switch main
git pull
# Create your feature branch
git switch -c feature/new-module
# Work and commit as you go
git add NewModule.ps1
git commit -m "Add initial module scaffold"
# Push your branch to remote
git push -u origin feature/new-module
# When it's ready, merge to main
git switch main
git pull # Stay up to date
git merge feature/new-module
git push
# Clean up
git branch -d feature/new-module
git push origin --delete feature/new-module
Example: Oops — Undo That Last Commit
Scenario: You committed to main by accident and it hasn't been pushed yet.
Important Parameters
| Command | Flag | Description | Example |
|---|---|---|---|
git log | --oneline | Compact single-line format | git log --oneline |
git log | --graph --all | Visual branch graph | git log --oneline --graph --all |
git push | -u | Set upstream tracking | git push -u origin main |
git push | --force-with-lease | Safe force push | git push --force-with-lease |
git stash push | -u | Include untracked files | git stash push -u -m "msg" |
git reset | --soft | Move HEAD, keep staged | git reset --soft HEAD~1 |
git reset | --hard | Move HEAD, discard changes | git reset --hard HEAD~1 |
git clean | -n | Dry run preview | git clean -n |
git clean | -fd | Remove untracked files+dirs | git clean -fd |
git branch | -a | Show local + remote | git branch -a |
git cherry-pick | --no-commit | Apply without committing | git cherry-pick --no-commit abc1234 |
git fetch | --prune | Remove stale remote refs | git fetch --prune |
Common Patterns
# Pattern 1: Quick save and context switch
git stash push -m "mid-feature work"
git switch main
# ... handle something on main ...
git switch feature/my-feature
git stash pop
# Pattern 2: Nuke all local changes and start fresh
git restore --staged .
git restore .
# Pattern 3: See what a branch changed before merging
git log main..feature/my-branch --oneline
git diff main..feature/my-branch
# Pattern 4: Rebase your branch on top of main (clean history)
git switch feature/my-branch
git pull --rebase origin main
# Pattern 5: See who changed what in a file
git log -p FileName.ps1 # Full diff history
git blame FileName.ps1 # Line-by-line authorship
Tips & Tricks
Set Up Git Aliases
Cut down on repetitive typing with git's built-in aliases:
git config --global alias.st "status -s"
git config --global alias.lg "log --oneline --graph --all"
git config --global alias.co "switch"
git lg gives you a full branch graph at a glance. Reflog Is Your Safety Net
Accidentally hard reset or lost a commit? git reflog shows everywhere HEAD has been — even after resets:
Don't Force Push Shared Branches