Skip to content
ExponaBLOG
GIT & GITHUB FOR PROFESSIONAL DEVELOPERS · DAY 083 / 100

Git commands you will use every day: a step-by-step guide

The essential set.

Expona Admin7 min read

Introduction

By day 83 of your Git journey, you've moved past the basics. But mastering the essential set of Git commands you will use every day: a step-by-step guide is what separates developers who understand version control from those who merely survive it. In production environments across e-commerce platforms, SaaS applications, and distributed teams, knowing which commands to reach for—and when—directly impacts your ability to ship reliable code and collaborate effectively.

This guide walks through the commands that will become muscle memory: the ones you'll type dozens of times each week, the ones that solve real problems, and the ones that save you from disaster.

Status, add, commit, push, pull: Your daily workflow

These five commands form the backbone of your daily interaction with Git. They handle the core cycle: checking what's changed, staging your work, recording it, and synchronizing with your team.

git status

Always start here. git status tells you exactly where you stand: which files are tracked, which are staged, and which are untracked. It's not optional—it's a habit.

bash
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to stage)
        modified:   src/auth.js
        modified:   tests/auth.test.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        src/config.local.js

The output tells you everything: your current branch, how far ahead or behind you are, and the state of every file. Get comfortable reading this output; it prevents mistakes before they happen.

git add

Staging is deliberate. You don't commit everything at once—you select the changes that belong together.

bash
$ git add src/auth.js tests/auth.test.js
$ git status

Or stage everything in the current directory:

bash
$ git add .

In practice, we often stage incrementally. If you've fixed a bug and refactored unrelated code in the same file, use:

bash
$ git add -p

This enters interactive mode, letting you approve or reject hunks one at a time. This discipline keeps commits atomic and reviewable.

git commit

A commit is a snapshot with a message. Write messages that future you—and your teammates—will understand. The first line should complete this sentence: "If applied, this commit will [your message]."

bash
$ git commit -m "Fix JWT expiration validation in auth middleware"

For longer context, omit the flag:

bash
$ git commit

This opens your editor for a full message: a short summary, blank line, then detailed explanation. This matters when you're investigating why a change was made months later.

git push

Send your commits to the remote repository. Typically origin is the central repo your team uses.

bash
$ git push origin main

On modern Git, you can set the upstream once and then simply:

bash
$ git push

If your push is rejected because the remote has newer commits, Git tells you to pull first. Don't force-push to shared branches; that breaks your team's history.

git pull

Fetch and merge remote changes in one command.

bash
$ git pull origin main

This runs git fetch (updating your local remote-tracking branches) followed by git merge. It's the safest way to integrate changes from teammates. If there are conflicts, Git pauses and asks you to resolve them.

Switch, branch, merge, rebase: Managing feature work

Most of your work happens on branches. You create a branch, build your feature, then integrate it back to main. These commands orchestrate that flow.

git switch and git branch

Create a branch and move to it:

bash
$ git switch -c feature/user-preferences

The -c flag creates and switches. Without it, git switch moves to an existing branch. (Older codebases use git checkout, which does both, but switch is clearer.)

List all branches:

bash
$ git branch -a

The -a flag shows local and remote-tracking branches. This is essential when you're working with a distributed team and need to see what's been pushed.

git merge

Integrate one branch into another. Move to your target branch first:

bash
$ git switch main
$ git pull origin main
$ git merge feature/user-preferences

Git creates a merge commit that combines both histories. If there are no conflicts, this succeeds immediately. If there are conflicts, Git pauses:

bash
$ git status
On branch main
You have unmerged paths.
  (use "git add/rm <file>..." as appropriate to mark resolution)
        both modified:   src/settings.js

Open the file, resolve the conflict (Git marks sections with <<<<<<< and >>>>>>>), then:

bash
$ git add src/settings.js
$ git commit -m "Merge feature/user-preferences into main"

git rebase

Rebase replays your commits on top of another branch. It's an alternative to merge that produces a linear history.

bash
$ git switch feature/user-preferences
$ git rebase main

This replays every commit from your branch onto the tip of main. If conflicts occur, Git stops at the offending commit, and you resolve it, then:

bash
$ git rebase --continue

Rebase is powerful for keeping your branch's history clean before you merge. But never rebase commits that are already pushed to a shared branch; it rewrites history and confuses your team. Use rebase for local, feature-branch work only.

Log, diff, restore: Inspecting and undoing

These commands let you see what happened, understand changes, and reverse mistakes.

git log

View the commit history:

bash
$ git log --oneline -10

The --oneline flag shows one commit per line with its hash and message. -10 limits to the last 10 commits. This is your primary tool for understanding what's been done.

See what changed in a specific commit:

bash
$ git log -p -1

The -p flag shows the full diff for each commit. -1 shows just the most recent. This is invaluable when investigating why a line of code exists.

For a graphical view of branches:

bash
$ git log --graph --oneline --all

git diff

Compare files between commits, branches, or the working directory. Before committing, always check what you're about to stage:

bash
$ git diff src/auth.js

This shows unstaged changes. To see staged changes:

bash
$ git diff --staged

Compare two branches:

bash
$ git diff main feature/new-api

This shows every file that differs and the exact changes. Essential before merging.

git restore

Discard changes in the working directory:

bash
$ git restore src/auth.js

This reverts the file to its last committed state. Be careful—this is irreversible. If you want to unstage a file:

bash
$ git restore --staged src/auth.js

This removes it from the staging area but keeps your changes in the working directory, giving you a chance to review them again.

Stash and reflog for recovery

Mistakes happen. These commands are your safety net.

git stash

Save uncommitted work temporarily. You're in the middle of a feature when an urgent bug appears on main. Stash your current work:

bash
$ git stash

Your working directory is now clean. Switch to main, fix the bug, then return to your feature:

bash
$ git switch feature/user-preferences
$ git stash pop

The pop applies the stash and removes it. If you want to apply without removing:

bash
$ git stash apply

List all stashes:

bash
$ git stash list

git reflog

The reflog is Git's internal journal of every action. If you accidentally reset a branch or lose commits, reflog is your recovery tool.

bash
$ git reflog
a1b2c3d HEAD@{0}: rebase: Fast-forwarded
e4f5g6h HEAD@{1}: reset: moving to e4f5g6h
i7j8k9l HEAD@{2}: commit: Add user profile page

Each entry is tagged by position (HEAD@{0}, HEAD@{1}, etc.). If you reset too far and lost commits:

bash
$ git reset --hard i7j8k9l

This recovers your work. Reflog entries are kept for 90 days by default, so you have a generous window to recover mistakes.

Common mistakes

  • Force-pushing to shared branches: git push -f rewrites history and breaks your team's work. Only force-push to your own branches, and only when necessary.
  • Committing sensitive data: Once a secret is in the history, it's exposed. Use a .gitignore file to exclude sensitive files before they're committed. Tools like git-secrets can scan for patterns.
  • Merging without pulling first: Always pull before pushing. This avoids unnecessary merge commits and keeps your history clean.
  • Writing vague commit messages: "Fixed stuff" doesn't help anyone. Take 30 seconds to write a clear message—future you will be grateful.
  • Rebasing shared commits: Rebase only commits you haven't pushed. Once they're on the remote, rebase is off-limits.

Key takeaways

  • git status is your constant companion. Run it before every action.
  • Use git add -p to stage changes deliberately and keep commits atomic.
  • git push and git pull keep you synchronized with your team.
  • git switch and git branch manage your feature work; use branches extensively.
  • git merge integrates changes; git rebase cleans up local history (but never on shared branches).
  • git log and git diff reveal what happened; use them before every commit.
  • git stash saves incomplete work; git reflog recovers from disasters.
  • Commit messages matter. Write as if someone else will read your code in production at 3 AM.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles