I keep a text file on my desktop with Git commands I use daily. Every time I forget something, I add it to the list. This post is that list, organized properly.

This is not a complete reference. It is the commands you will actually use at work, with examples that make sense.

Table of Contents

Setting Up Git

Before you start, configure your identity. This is what shows up in your commits.

1
2
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Check your current configuration:

1
git config --list

Set your default branch name to main (instead of master):

1
git config --global init.defaultBranch main

These are just the basics. For a complete guide covering aliases, credentials, editor setup, and more, see the Git Config Guide.

Starting a Project

You have two options: start fresh or clone an existing repository.

Start a new repository:

1
git init

This creates a .git folder in your current directory. You now have a Git repository.

Clone an existing repository:

1
git clone https://github.com/user/repo.git

To clone into a specific folder:

1
git clone https://github.com/user/repo.git my-folder

The Basic Workflow

Here is what you will do a hundred times a day:

flowchart LR
    A[Working Directory] -->|git add| B[Staging Area]
    B -->|git commit| C[Local Repository]
    C -->|git push| D[Remote Repository]
    D -->|git pull| A
    
    style A fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style B fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style C fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style D fill:#2d3748,stroke:#4a5568,color:#e2e8f0
  1. Make changes to files
  2. Stage the changes you want to commit
  3. Commit the staged changes
  4. Push to the remote repository

Check What Changed

See which files have been modified:

1
git status

See the actual changes line by line:

1
git diff

See changes that are already staged:

1
git diff --staged

Stage Changes

Stage a specific file:

1
git add filename.txt

Stage all changes in current directory:

1
git add .

Stage all changes in the entire repository:

1
git add -A

Stage parts of a file interactively:

1
git add -p filename.txt

This is useful when you have multiple logical changes in one file and want to commit them separately.

Commit Changes

Commit with a message:

1
git commit -m "Add user authentication"

Commit all tracked files (skip staging):

1
git commit -am "Fix login bug"

Note: The -am flag only works for files Git is already tracking. New files still need git add first.

Push to Remote

Push to the remote repository:

1
git push origin main

If the branch does not exist on remote yet:

1
git push -u origin feature-branch

The -u flag sets up tracking so you can just use git push next time.

Pull from Remote

Get the latest changes and merge:

1
git pull origin main

Pull with rebase instead of merge (cleaner history):

1
git pull --rebase origin main

I wrote more about the difference between pull and pull with rebase in Git Command Line Basics.

Branching

Branches let you work on features without affecting the main codebase.

gitGraph
    commit id: "Initial"
    commit id: "Add auth"
    branch feature
    checkout feature
    commit id: "Start feature"
    commit id: "Continue work"
    checkout main
    commit id: "Hotfix"
    checkout feature
    commit id: "Finish feature"
    checkout main
    merge feature id: "Merge"
    commit id: "Release"

Create and Switch Branches

List all branches:

1
git branch

List all branches including remote:

1
git branch -a

Create a new branch:

1
git branch feature-login

Switch to a branch:

1
git switch feature-login

Or the older way:

1
git checkout feature-login

Create and switch in one command:

1
git switch -c feature-login

Or:

1
git checkout -b feature-login

Delete Branches

Delete a local branch (only if merged):

1
git branch -d feature-login

Force delete a local branch:

1
git branch -D feature-login

Delete a remote branch:

1
git push origin --delete feature-login

Rename a Branch

Rename the current branch:

1
git branch -m new-name

Rename a different branch:

1
git branch -m old-name new-name

Merging

Merge brings changes from one branch into another.

Basic Merge

Switch to the target branch first:

1
2
git switch main
git merge feature-login

This creates a merge commit if there are divergent changes.

Fast Forward Merge

If main has not changed since you branched, Git just moves the pointer forward. No merge commit is created.

To always create a merge commit:

1
git merge --no-ff feature-login

Squash Merge

Combine all commits from a branch into a single commit:

1
2
git merge --squash feature-login
git commit -m "Add login feature"

This is useful when a feature branch has messy commit history.

Abort a Merge

If things go wrong during a merge:

1
git merge --abort

This takes you back to before the merge started.

Rebasing

Rebase moves your commits on top of another branch, creating a linear history.

flowchart TB
    subgraph Before["Before Rebase"]
        A1[main: A] --> B1[main: B]
        A1 --> C1[feature: C]
        C1 --> D1[feature: D]
    end
    
    subgraph After["After Rebase"]
        A2[main: A] --> B2[main: B]
        B2 --> C2[feature: C']
        C2 --> D2[feature: D']
    end
    
    Before --> After
    
    style A1 fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style B1 fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style C1 fill:#1a365d,stroke:#2b6cb0,color:#bee3f8
    style D1 fill:#1a365d,stroke:#2b6cb0,color:#bee3f8
    style A2 fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style B2 fill:#2d3748,stroke:#4a5568,color:#e2e8f0
    style C2 fill:#1a365d,stroke:#2b6cb0,color:#bee3f8
    style D2 fill:#1a365d,stroke:#2b6cb0,color:#bee3f8

Rebase onto main

1
2
git switch feature-branch
git rebase main

Interactive Rebase

Edit, squash, or reorder commits:

1
git rebase -i HEAD~3

This opens an editor showing the last 3 commits. You can:

  • pick - keep the commit as is
  • reword - change the commit message
  • squash - combine with previous commit
  • drop - remove the commit

Abort a Rebase

If things go wrong:

1
git rebase --abort

Continue After Fixing Conflicts

After resolving conflicts during rebase:

1
2
git add .
git rebase --continue

Warning: Never rebase commits that have been pushed to a shared branch. It rewrites history and will cause problems for anyone else working on that branch.

Undoing Things

Everyone makes mistakes. Git has your back.

Unstage Files

Remove a file from staging (keep the changes):

1
git restore --staged filename.txt

Or:

1
git reset HEAD filename.txt

Discard Changes

Throw away changes to a file:

1
git restore filename.txt

Or:

1
git checkout -- filename.txt

Throw away all uncommitted changes:

1
git restore .

Undo Commits

Undo the last commit, keep changes staged:

1
git reset --soft HEAD~1

Undo the last commit, keep changes unstaged:

1
git reset HEAD~1

Undo the last commit, throw away changes:

1
git reset --hard HEAD~1

Undo a commit that was already pushed:

1
git revert HEAD

This creates a new commit that undoes the changes. Safe to use on shared branches.

For reverting multiple commits, check out my post on reverting multiple commits in Git.

Recover Deleted Commits

If you accidentally reset and lost commits, they are not gone yet:

1
git reflog

This shows all recent HEAD positions. Find the commit hash you need and:

1
git reset --hard abc1234

Reflog entries expire after about 90 days.

Stashing

Stash saves your uncommitted changes temporarily.

1
git stash

This is useful when you need to switch branches but are not ready to commit.

See all stashes:

1
git stash list

Apply the most recent stash:

1
git stash pop

Apply without removing from stash list:

1
git stash apply

Apply a specific stash:

1
git stash apply stash@{2}

Stash with a message:

1
git stash push -m "Work in progress on login"

Delete a stash:

1
git stash drop stash@{0}

Clear all stashes:

1
git stash clear

Viewing History

Basic Log

1
git log

One line per commit:

1
git log --oneline

Show a graph of branches:

1
git log --oneline --graph --all

This is one of my favorite commands. You can see the entire branch structure.

Search Commits

Find commits by message:

1
git log --grep="login"

Find commits that changed a specific file:

1
git log -- filename.txt

Find commits by author:

1
git log --author="John"

Find commits in a date range:

1
git log --since="2024-01-01" --until="2024-12-31"

Show Commit Details

See what changed in a commit:

1
git show abc1234

See who changed each line of a file:

1
git blame filename.txt

Remote Repositories

View Remotes

1
git remote -v

Add a Remote

1
git remote add origin https://github.com/user/repo.git

Change Remote URL

1
git remote set-url origin https://github.com/user/new-repo.git

Fetch vs Pull

Fetch downloads changes but does not merge:

1
git fetch origin

This updates your remote tracking branches (like origin/main) but leaves your local branches unchanged. Useful when you want to see what others have done before merging.

Pull fetches and merges:

1
git pull origin main

This is equivalent to:

1
2
git fetch origin
git merge origin/main

Clean Up Stale References

Remote branches that no longer exist:

1
git fetch --prune

Or set it to happen automatically:

1
git config --global fetch.prune true

Cherry Picking

Copy a specific commit from one branch to another:

1
git cherry-pick abc1234

Cherry pick without committing:

1
git cherry-pick abc1234 --no-commit

This is useful when you need a bug fix from another branch but do not want to merge everything.

Tags

Tags mark specific points in history, typically releases.

Create Tags

Lightweight tag:

1
git tag v1.0.0

Annotated tag (recommended for releases):

1
git tag -a v1.0.0 -m "Version 1.0.0 release"

Tag a specific commit:

1
git tag -a v1.0.0 abc1234 -m "Version 1.0.0"

Push Tags

Push a single tag:

1
git push origin v1.0.0

Push all tags:

1
git push origin --tags

Delete Tags

Delete local tag:

1
git tag -d v1.0.0

Delete remote tag:

1
git push origin --delete v1.0.0

Cleaning Up

Remove Untracked Files

See what would be removed:

1
git clean -n

Actually remove:

1
git clean -f

Remove directories too:

1
git clean -fd

Remove ignored files as well:

1
git clean -fdx

Be careful with -x. It removes everything not tracked, including build artifacts and dependencies.

Common Workflows

Feature Branch Workflow

This is how most teams work:

sequenceDiagram
    participant Dev as Developer
    participant Local as Local Repo
    participant Remote as GitHub
    
    Dev->>Local: git switch -c feature
    Dev->>Local: Make changes
    Dev->>Local: git add . && git commit
    Dev->>Remote: git push -u origin feature
    Remote->>Remote: Create Pull Request
    Remote->>Remote: Code Review
    Remote->>Remote: Merge PR
    Dev->>Local: git switch main
    Dev->>Local: git pull origin main
    Dev->>Local: git branch -d feature
  1. Create a feature branch
  2. Make commits
  3. Push the branch
  4. Open a pull request
  5. Get review and approval
  6. Merge into main
  7. Delete the feature branch
  8. Pull the latest main

Keeping a Fork Updated

When you fork a repository, you need to keep it in sync with the original:

1
2
3
4
5
6
7
8
9
10
11
12
# Add the original repo as upstream
git remote add upstream https://github.com/original/repo.git

# Fetch changes from upstream
git fetch upstream

# Merge into your main branch
git switch main
git merge upstream/main

# Push to your fork
git push origin main

Fixing a Mistake in Production

When you need to fix something fast:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Create a hotfix branch from main
git switch main
git pull origin main
git switch -c hotfix-login-bug

# Fix the bug
# ...

# Commit and push
git commit -am "Fix login timeout issue"
git push -u origin hotfix-login-bug

# After PR is merged, delete the branch
git switch main
git pull origin main
git branch -d hotfix-login-bug

Git Aliases

Save typing with aliases. Add these to your .gitconfig:

1
2
3
4
5
6
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.last "log -1 HEAD"
git config --global alias.lg "log --oneline --graph --all"

Now you can use:

1
2
3
git st       # instead of git status
git co main  # instead of git checkout main
git lg       # pretty log graph

Quick Reference Table

Task Command
Initialize repository git init
Clone repository git clone <url>
Check status git status
Stage all changes git add .
Commit with message git commit -m "message"
Push to remote git push origin main
Pull from remote git pull origin main
Create branch git switch -c branch-name
Switch branch git switch branch-name
Merge branch git merge branch-name
Delete branch git branch -d branch-name
Stash changes git stash
Apply stash git stash pop
Undo last commit (keep changes) git reset --soft HEAD~1
Undo last commit (discard changes) git reset --hard HEAD~1
Revert pushed commit git revert HEAD
View commit history git log --oneline
Show commit details git show <commit>
Cherry pick commit git cherry-pick <commit>

Next Steps

Once you are comfortable with these commands, look into:

The best way to learn Git is to use it. Make mistakes, undo them, and learn from the process.


Further Reading: