
Git is one of those tools every developer uses daily but many people only learn in fragments: clone, add, commit, push, then panic when a branch is wrong or a commit needs undoing. This post fixes that by turning the old command list into a workflow-first tutorial you can actually use while coding.
If you spend a lot of time in the terminal, pair this guide with Basic Linux Commands Every Developer Must Know and Basic Docker Commands Every Developer Should Know. If your team also works outside Git, Perforce MCP Server VS Code Integration shows how a different version-control workflow looks in practice. For more tooling posts, browse the DevOps tag archive.
Table of Contents
Open Table of Contents
- How to Use This Git Guide
- The Daily Git Workflow in 60 Seconds
- Git Workflow Diagram
- First-Time Setup Commands
- Create or Copy a Repository
- Inspect What Changed
- Stage and Commit Changes
- Branching and Switching Work
- Sync with a Remote Repository
- Undo Mistakes Safely
- Stash Temporary Work
- Read History and Compare Changes
- Quick Command Reference by Task
- Real-World Scenarios
- Interview Questions
- 1. What is the difference between
git fetchandgit pull? - 2. When would you use
git revertinstead ofgit reset? - 3. Why is
git add -puseful in large feature branches? - 4. What problem does
git stashsolve, and what is its limitation? - 5. Why do many teams prefer
git pull --rebasefor local feature branches? - 6. What is the practical difference between
git switchandgit checkout?
- 1. What is the difference between
- Conclusion
- References
- YouTube Videos
How to Use This Git Guide
This is not a “memorize 40 commands in order” article. It is organized around what developers actually do:
- Set Git up once.
- Clone or initialize a repository.
- Inspect changes before doing anything destructive.
- Stage and commit with intention.
- Branch for isolated work.
- Pull, push, merge, or rebase when collaborating.
- Recover from mistakes without making the situation worse.
You do not need every command every day. You do need the right mental model for the command you are about to run.
The Daily Git Workflow in 60 Seconds
The most common day-to-day loop looks like this:
git status
git pull --rebase origin main
git switch -c feature/login-improvements
# edit files
git status
git add src/auth.ts
git commit -m "Improve login validation"
git push -u origin feature/login-improvements
That sequence covers most normal work:
- Check repository state.
- Sync with the latest remote work.
- Create or switch to your feature branch.
- Stage only the changes you mean to keep.
- Commit with a useful message.
- Push the branch and open a review.
Git Workflow Diagram
This is the simplest mental model for how Git moves your work from edited files to shared history:
flowchart TD
A[Working Directory\nedited files] -->|git add| B[Staging Area\nindex]
B -->|git commit| C[Local Repository\ncommit history]
C -->|git push| D[Remote Repository\norigin]
D -->|git pull or git fetch| C
C -->|git restore or git checkout| A
B -->|git restore --staged| A
C -->|git switch| E[Another Branch]
E -->|git merge or git rebase| C
classDef git fill:#e8f0fe,stroke:#1a73e8,stroke-width:2px,color:#000000;
class A,B,C,D,E git;
Read the diagram from left to right:
- You edit files in the working directory.
git addmoves selected changes into the staging area.git committurns staged changes into a local snapshot.git pushsends commits to the remote repository.git pullorgit fetchbrings remote work back into your local repository.- Branching lets you create isolated lines of development before merging them back.
First-Time Setup Commands
Before you create commits, tell Git who you are:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global core.editor "code --wait"
Useful inspection commands:
git config --list
git config --global --get user.name
git config --global --get user.email
Why these matter:
user.nameanduser.emailare attached to commits.init.defaultBranch mainavoids older defaults likemaster.pull.rebase truekeeps local history cleaner for many teams.core.editormatters the first time Git opens an editor for merge messages or rebases.
Create or Copy a Repository
Start a new repository
git init
Use this when a local folder is not under Git yet.
Clone an existing repository
git clone https://github.com/example/project.git
Use this when the remote already exists and you want its full history locally.
Add or inspect remotes
git remote -v
git remote add origin https://github.com/example/project.git
git remote set-url origin https://github.com/example/new-project.git
Real-world tip: run git remote -v before a push if you work across personal forks, upstream repos, or multiple company remotes.
Inspect What Changed
Good Git usage starts with inspection, not commands that modify history.
Check file state
git status
git status --short
This tells you:
- which files changed
- which files are staged
- which branch you are on
- whether your branch is ahead or behind the remote
Compare working tree vs staged content
git diff
git diff --staged
Use:
git difffor unstaged changesgit diff --stagedfor what will go into the next commit
That simple habit catches a lot of bad commits before they happen.
Stage and Commit Changes
Stage files
git add src/app.ts
git add .
git add -p
What each form is for:
git add src/app.tsstages one file.git add .stages everything under the current directory.git add -pstages changes interactively hunk by hunk.
For production teams, git add -p is one of the highest-value commands in Git. It lets you split one messy working session into clean, reviewable commits.
Commit changes
git commit -m "Fix null check in login flow"
git commit --amend
git commit --amend --no-edit
Practical guidance:
- Write commit messages that explain the change outcome, not just the file touched.
- Use
--amendonly for your latest local commit that has not been pushed or reviewed yet. - Avoid amending shared commits unless your team explicitly expects rewritten history.
Bad commit message:
update stuff
Better commit message:
Improve login validation for empty password edge case
Branching and Switching Work
List, create, and delete branches
git branch
git branch feature/api-cleanup
git branch -d feature/api-cleanup
git branch -D feature/api-cleanup
Use -d for safe delete after merge. Use -D only when you are sure you want to force deletion.
Switch branches
Modern Git prefers switch for changing branches:
git switch main
git switch -c feature/profile-page
Older Git tutorials often use:
git checkout main
git checkout -b feature/profile-page
Both work, but git switch is clearer because it does one job: branch switching.
Merge another branch
git merge feature/profile-page
Use merge when you want to bring another branch’s history into your current branch. Whether your team prefers merge commits, squash merges, or rebases depends on workflow, not Git correctness.
Sync with a Remote Repository
Fetch first when you want visibility
git fetch origin
fetch downloads remote updates without changing your current branch. It is the safest way to inspect incoming work before integrating it.
Pull when you want local branch updated
git pull origin main
git pull --rebase origin main
In many teams, git pull --rebase is cleaner because it replays your local commits on top of the updated remote branch instead of creating an extra merge commit.
Push your branch
git push origin main
git push -u origin feature/profile-page
-u sets the upstream branch so later git push and git pull commands can omit the remote and branch names.
Delete a remote branch after merge
git push origin --delete feature/profile-page
That is clearer than the older git push origin :branch-name syntax.
Undo Mistakes Safely
This is the section developers usually need under pressure.
Unstage a file without losing edits
git restore --staged src/app.ts
Older equivalent:
git reset src/app.ts
restore --staged is easier to understand because it says exactly what it does.
Discard local working tree changes
git restore src/app.ts
git restore .
Only do this when you are sure your local edits are disposable.
Revert a bad commit with a new commit
git revert <commit-hash>
This is the safest option after a commit has already been pushed to a shared branch. It preserves history and makes the rollback explicit.
Move HEAD and rewrite local history
git reset --soft HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1
What each one does:
--softremoves the commit but keeps changes staged.--mixedremoves the commit and unstages changes.--hardremoves the commit and discards local changes.
git reset --hard is powerful and dangerous. Use it only when you clearly understand that uncommitted work will be lost.
Stash Temporary Work
Stash is useful when you need to switch context without committing half-finished work.
git stash push -m "wip login refactor"
git stash list
git stash show -p stash@{0}
git stash apply stash@{0}
git stash pop
git stash drop stash@{0}
Practical pattern:
- You are halfway through a refactor.
- Production bug appears on another branch.
- Stash your work.
- Switch branches and fix the bug.
- Come back and re-apply the stash.
Do not use stash as a long-term storage system. If work matters, prefer a proper branch and commit.
Read History and Compare Changes
Show history
git log
git log --oneline --graph --decorate --all
git log --follow -- src/auth.ts
These help you answer different questions:
- What happened recently?
- How do branches relate?
- Who changed this file across renames?
Inspect a specific commit
git show <commit-hash>
Good when reviewing exactly what a commit introduced, including metadata and patch content.
Compare branches or commits
git diff main..feature/profile-page
git diff <old-commit> <new-commit>
This is useful before a merge, during code review, or when confirming whether a bug fix actually landed in a branch.
Tag a release point
git tag v1.0.0
git tag
git push origin v1.0.0
Tags are usually used for releases, milestones, or stable reference points.
Quick Command Reference by Task
| Task | Command | When to use it |
|---|---|---|
| Check repo state | git status | Before almost every Git action |
| Stage one file | git add file | Small focused commit |
| Stage interactively | git add -p | Split mixed changes cleanly |
| Commit staged work | git commit -m "message" | Save meaningful checkpoint |
| Create and switch branch | git switch -c branch-name | Start isolated work |
| Update local branch | git pull --rebase origin main | Bring latest remote changes |
| Push branch | git push -u origin branch-name | Publish branch for review |
| Unstage file | git restore --staged file | Remove file from staging area |
| Restore discarded file | git restore file | Throw away local edits |
| Revert pushed commit | git revert <hash> | Safest rollback on shared history |
| View clean history | git log --oneline --graph --decorate --all | Understand branch structure |
| Save temporary work | git stash push -m "wip" | Switch tasks quickly |
Real-World Scenarios
Scenario 1: You committed to the wrong branch
If the commit is still local:
git reset --soft HEAD~1
git switch correct-branch
git commit -m "Your original message"
This moves the commit back into your staging area so you can re-commit it on the correct branch.
Scenario 2: You need the latest main before opening a pull request
git switch feature/profile-page
git fetch origin
git rebase origin/main
This keeps your branch history linear and makes the review diff cleaner.
Scenario 3: You pulled and now there is a merge conflict
Git will mark the files with conflict markers. Your job is to:
- open the conflicted files
- decide which code should stay
- remove conflict markers
- stage the resolved files
- continue the merge or rebase
Typical rebase flow:
git add src/app.ts
git rebase --continue
Scenario 4: You want to remove a bad commit from a shared branch
Use:
git revert <commit-hash>
Do not reach for reset --hard on a shared branch. That rewrites history and causes collaboration pain unless everyone expects a force-push workflow.
Interview Questions
1. What is the difference between git fetch and git pull?
git fetch downloads new commits and refs from the remote but does not modify your current working branch. git pull is effectively fetch plus integration, usually a merge or rebase depending on configuration.
In interviews, I explain fetch as the safer inspection step and pull as the convenience step. If a team wants tighter control, they fetch first and then decide how to integrate.
2. When would you use git revert instead of git reset?
Use git revert when the commit is already shared with other developers because revert creates a new commit that undoes the change without rewriting history. Use git reset when you are cleaning up local history that has not been safely shared yet.
This distinction matters in real teams. Reset is local-history surgery. Revert is collaborative rollback.
3. Why is git add -p useful in large feature branches?
Because developers rarely make perfectly isolated edits in one session. You might fix a bug, rename a variable, and reformat unrelated lines in the same file. git add -p lets you stage only the intentional chunk for one commit.
That produces smaller reviews, clearer history, and easier cherry-picking later.
4. What problem does git stash solve, and what is its limitation?
Stash helps when you need to temporarily set aside uncommitted work to switch branches or address an urgent task. It is fast and convenient for short interruptions.
Its limitation is that stash is easy to forget and poor as a long-term workflow. If the work matters for more than a quick context switch, a branch and real commit are usually better.
5. Why do many teams prefer git pull --rebase for local feature branches?
Because it replays your local commits on top of the updated remote branch and avoids extra merge commits in personal branch history. That usually makes the history easier to read and the pull request diff cleaner.
The trade-off is that rebasing rewrites local commit hashes, so teams need to be careful once commits are already shared broadly.
6. What is the practical difference between git switch and git checkout?
git checkout historically did too many jobs: switching branches, creating branches, and restoring files. git switch focuses only on branch changes, while git restore handles file restoration.
That split reduces confusion, especially for beginners who would otherwise accidentally overwrite files while trying to change branches.
Conclusion
The best Git users are not the people who memorize the longest list of commands. They are the ones who understand which commands inspect state, which commands create history, and which commands rewrite history.
If you remember only one rule from this cheat sheet, make it this: inspect first, then edit history carefully. git status, git diff, and git log prevent far more problems than any recovery command.
References
- Git Documentation
https://git-scm.com/docs - Pro Git Book
https://git-scm.com/book/en/v2 - GitHub Docs: Set Up Git
https://docs.github.com/en/get-started/git-basics/set-up-git - Atlassian Git Tutorials
https://www.atlassian.com/git/tutorials
YouTube Videos
- “Git and GitHub Tutorial for Beginners” - Kevin Stratvert
https://www.youtube.com/watch?v=tRZGeaHPoaw - “Git Tutorial for Beginners: Learn Git in 1 Hour” - Programming with Mosh
https://www.youtube.com/watch?v=8JJ101D3knE - “Git & GitHub Crash Course 2025” - Traversy Media
https://www.youtube.com/watch?v=vA5TTz6BXhY