A compact guide to mastering Git through essential commands, common pitfalls, time-saving shortcuts, expert tips, workflow patterns, and interview preparation.
- Most Used Commands
- Popular Issues
- Well Known Hotkeys
- Some Tips and Tricks
- Interview Questions
- Trunc Based Guide FSM
- Commit Convention
Note
It's really that simple — it covers everything you need to know about Git!
These Git commands follow the typical development workflow—from starting a project to sharing changes. Learning them covers most daily Git usage and boosts your productivity. Ordered by typical workflow.
Initializes a new Git repo in the current directory.
git init
Copies an existing remote repo to your local machine.
git clone <repo-url>
Shows the current state of your workdir.
git status
Stages changes, telling Git which files to include in the next commit.
git add <file> # Add a specific file
git add . # Add all changes
git add -A # Add all changes, including deletions
Shows the difference files.
git diff # Compare working directory to staging
git diff --staged # Compare staging to last commit
git diff <file> # Compare files
Creates a snapshot of the staged changes with a descriptive message.
git commit -m "Commit Header" -m "Commit body"
Displays the history of commits in the current branch.
git log
Lists, creates, or deletes local branches.
git branch -a # List branches
git branch <name> # Create a new branch
git branch -d <name> # Delete a branch
Switches to another branch or restores file changes.
git checkout <branch> # Switch to a branch(creates if not exists)
git checkout -b <name> # Create and switch to a new branch
git checkout -- <file> # Discard local changes
Merge selected branch(its files) into current(git branch
).
git merge <branch>
Fetches the latest changes from the remote and merges them into current branch.
git pull
Sends local branch changes to the remote repo.
git push origin <branch>
Mistakes happens, so this section covers common problems and best solutions for each case.
Issue: Commits are showing the wrong author name/email.
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
If it's a local repo-specific setting:
git config user.name "Your Name"
git config user.email "[email protected]"
Issue: Commit created, but some changes weren’t added.
git add . # add more changes
git commit --amend --no-edit
Issue: You made changes on main
instead of a feature branch.
git checkout -b feature-branch
# or if the branch already exists
# git checkout feature-branch
git cherry-pick <commit_hash>
Issue: Conflicts when merging branches.
Git will highlight conflicts in the files. Manually edit them(Some IDEs may help a lot), then:
git add <resolved-files>
git commit
Use tools like git mergetool
for assistance.
Issue: Deleted a file you didn’t mean to.
git checkout HEAD -- <file>
Issue: You pulled changes and lost your uncommitted local changes.
If not staged:
git fsck --lost-found
For safety, stash changes before pulling:
git stash
Issue: Accidentally added a large file to Git history.
Use BFG Repo-Cleaner
or git filter-branch
.
Issue: Last commit has a mistake.
git reset --soft HEAD~1 # Keeps changes
To discard the commit and changes:
git reset --hard HEAD~1
Issue: You made changes on the wrong branch.
git stash
git checkout correct-branch
git stash pop
Issue: Commits disappeared after a rebase.
git reflog
# Find the commit and recover:
git checkout <commit>
Issue: Files keep showing as changed due to line endings.
Add .gitattributes
with following line:
* text=auto
Or set config:
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # Linux
Issue: You ran git stash
and now your changes are gone.
git stash list
git stash pop stash@{0} # or use apply to keep stash
git stash apply stash@{0}
Issue: A bad commit has already been pushed.
git revert <commit_hash>
Creates a new commit that undoes the bad one.
Issue: You want to combine multiple commits into one.
git rebase -i HEAD~<n> # where <n> amount of commits
Issue: Remote has changes you don't.
git pull --rebase
git push
Issue: The branch name is incorrect.
git branch -m new-name
git push origin :old-name new-name
Issue: Your feature branch was created from the wrong base.
git rebase --onto correct-base wrong-base feature-branch
Issue: You deleted a local or remote branch accidentally.
Fix (local):
git reflog
# Find the branch commit and recreate
Fix (remote): Ask a teammate to push it again if needed.
Issue: You want to track the changes made to a specific file.
git log -- <file>
git blame <file>
Issue: You checked out a commit, not a branch.
git checkout -b new-branch # To save your state
Or just checkout a branch to exit:
git checkout main
Issue: You committed files (e.g., configs or logs), but after pulling, changes don’t sync properly—likely because Git is tracking the file but ignoring internal changes.
Cause: The file was added before updating .gitignore
, or line endings / file permissions confuse Git on some systems. Sometimes it may be useful if you want track the file but not its changes(lines).
- To force Git to track changes again:
git rm --cached <file>
git add <file>
git commit -m "Re-track file changes"
- Double-check
.gitattributes
and.gitignore
to ensure nothing blocks updates.
Here is a list of my shorcuts that i've using each day. It will improve your speed a lot but require some words to memorize.
This repo contains a file named gc
. Add this into your PATH.
You can do this manyally or using gc_install.sh that must be executed via git bash terminal.
gc
Usage: gc [option]
Mandatory arguments:
--setup -s --> git setup and configuration
--init -i --> creation of new project
--add -a --> adding files to git
--delete -d --> deleting files from git
--commit -c --> git commit helper
--branch -b --> git branching info
--merge -m --> git merging info
--rebase -rb --> git rebase info
--update -u --> updating current repo
--stash -st --> stashing in current repo
--inspect -in --> git inspection, log,show...
--remote -r --> git remote helper
--patch -p --> git patching helper
--debug -dg --> git debugging
--email -e --> git email helper
--tags -t --> git tags helper
--reset -rs --> git reset helper
--conflict -cn --> git conflict resolving helper
--revert -rv --> git reverting helper
--fix-mistakes -f --> fix mistakes in git
--submodules -sm --> git submodules helper
--archive -ar --> archive your repo
--help -h ? --> prints usage of git-cheat
--version -v --> prints version of git-cheat
Handy tricks to make you look like a seasoned Git expert—alias setups, stash magic, rebase powers, and much more.
- Use Hooks for Automation
Use.git/hooks/pre-commit
to auto-lint, format, or reject bad commits.
#!/bin/sh
black .
- Compare Any Two Commits (Not Just HEAD)
git diff <commit1> <commit2>
- Show Pretty Commit History
git log --graph --oneline --decorate --all
Great for reviewing merges and diverging branches.
- Prune Deleted Remotes
git remote prune origin
Cleans up remote-tracking branches that no longer exist.
- Ignore Local Changes Without .gitignore
git update-index --assume-unchanged path/to/file
Keeps file tracked but ignores local changes.
- Temporarily Keep Changes Without Committing
git stash push -m "partial work" path/to/file
Experienced users stash selectively—not everything at once.
- Clean All Untracked Files Including Ignored
git clean -xfd
A categorized collection of real Git interview questions, sorted by experience level. Most are from actual interviews.
A VCS tracks changes made by developers, maintaining code history, enabling bug fixes, new code additions, and easy restoration of previous working versions.
Shows the difference between the working directory and the index (staging area), helping track changes that are staged or unstaged.
Adds files or changes to the staging area (index) for the next commit. You can add all changes (git add .
), specific files (git add <file>
), or folders (git add <folder>/
).
A temporary area where changes are formatted and reviewed before committing.
Run git init
in a project folder to create a .git
directory and initialize the repository.
git remote
: Adds a named remote URL to an existing repository.git clone
: Creates a new local repository by copying an existing remote one.
Temporarily saves changes in the working directory to a stack, allowing branch switching without losing edits.
- Locally:
git branch -d <branch_name>
- Remotely:
git push origin --delete <branch_name>
Tracks all changes in branch references (like commits, checkouts), helping recover lost branches or commits.
- Snapshot of project files at a point in time.
- Reference to parent commit(s).
- Unique SHA-1 hash identifier.
- System: Applies to all users on the system (
--system
). - Global: Applies to the current user (
--global
). - Local: Applies to the current repository (
--local
, default).
When HEAD points to a commit or tag instead of a branch, causing "floating" commits not linked to any branch. Avoid by creating a new branch from that commit (git checkout -b <branch>
).
Shows line-by-line commit info for a file, indicating which commit introduced each line.
apply
: Applies stash but keeps it in the stash list.pop
: Applies stash and removes it from the stash list.
git diff
: Shows specific content changes between commits or working directory and index.git status
: Shows which files are staged, unstaged, or untracked.
git fetch
: Downloads changes but doesn’t merge.git pull
: Fetches and merges changes (git fetch + git merge
).
- Powerful branching and merging.
- Distributed system with local and remote repos.
- Pull requests enable collaboration.
- Speeds up release cycles.
Run git rebase -i HEAD~N
to combine the last N commits into a single commit. Use carefully as it rewrites history.
Use git reflog
to find the last commit of the branch and recreate it by checking out that commit as a new branch.
- Identify conflicted files.
- Manually edit to resolve conflicts.
- Stage resolved files (
git add
). - Commit the merge (
git commit
). - Push changes.
git branch --merged
shows branches merged into the current branch. --no-merged
shows unmerged branches.
Prefer creating a new commit to avoid losing history or mixing unrelated changes.
- Fix and commit new changes.
- Or use
git revert <bad_commit>
to create a new commit that undoes the bad one.
Applies specific commits from one branch onto another, useful for backporting or selective changes.
A simplified Finite State Machine diagram to help you follow trunk-based development practices.
stateDiagram-v2
[*] --> Main
%% --- Start feature work ---
Main --> FeatureBranch : create feature branch
FeatureBranch --> Working : modify or create files
Working --> Staging : stage changes (git add)
Staging --> Committing : commit changes (git commit)
Committing --> Working : need more changes
Committing --> Reviewing : ready for review or merge
%% --- Optional PR flow ---
Reviewing --> PullRequest : create pull request
PullRequest --> CodeReview : request review
CodeReview --> ChangesRequested : reviewer requests changes
CodeReview --> Approved : reviewer approves
ChangesRequested --> Working : apply review feedback
Approved --> Merging : merge branch
%% --- Direct merge path (no PR) ---
Reviewing --> Merging : merge without pull request
%% --- Merge and CI ---
Merging --> MergeConflict : merge conflict detected
MergeConflict --> ConflictResolving : resolve conflicts manually
ConflictResolving --> Working : edit and stage again
Merging --> CI : run CI pipeline
CI --> CI_Passed : CI passed
CI --> CI_Failed : CI failed
CI_Passed --> Main : return to trunk
CI_Failed --> Working : fix code
%% --- Commit management ---
Committing --> Amending : amend commit
Amending --> Reviewing : continue review
Committing --> Squashing : squash commits
Squashing --> Reviewing : continue review
Committing --> Reverting : revert commit
Reverting --> Working : reapply or fix
%% --- Undo path ---
Working --> Undoing : discard local changes
Undoing --> Working
%% --- Cancel PR ---
PullRequest --> CancellingPR : cancel pull request
CancellingPR --> Main
%% --- Hotfix path ---
Main --> HotfixBranch : create hotfix branch
HotfixBranch --> Working
%% --- Dirty commit directly to main ---
Main --> DirectCommit : commit directly to main
DirectCommit --> Working
%% --- Closing loop ---
ConflictResolving --> Staging
Reverting --> Staging
Amending --> Staging
Squashing --> Staging
Working --> Staging
CI_Failed --> Staging
Standardizing commit messages improves readability, traceability, and automation (e.g., changelogs, releases). This section outlines a consistent format based on commonly used conventions.
<type>(<optional scope>): <description>
<optional body>
<optional footer>
- Example:
feat(auth): add JWT-based login
-
Initial Commit:
chore: init
-
Merge Commit:
Merge branch 'feature/login'
(Git default) -
Revert Commit:
Revert "feat(auth): add JWT-based login"
Use one of the following types:
feat
New feature added to the API or UI
fix
Bug fix for an existing feature
refactor
Code restructure without changing behavior
perf
Performance-related improvements
style
Code style changes (formatting, spaces, etc.) with no logic impact
test
Adding or correcting tests
docs
Documentation-only changes
build
Changes affecting build tools, CI/CD, dependencies
ops
Operations-related (deployment, infra, monitoring)
chore
Misc tasks like .gitignore
or non-functional changes
The scope adds context to the change (e.g., auth
, db
, ui
):
- Format:
<type>(<scope>): description
- Example:
fix(api): handle empty response case
- Don’t use issue numbers as scope names
If a commit introduces a breaking change:
-
Add an exclamation mark:
feat(api)!: remove deprecated status endpoint
-
In the footer, start with:
BREAKING CHANGE: explain what broke and how to migrate
- Always required
- Use imperative mood, e.g., “add login”, not “added” or “adds”
- Start with lowercase
- No period at the end
Use the body to explain why the change was made and how it differs from prior behavior.
Includes:
- Issue references (e.g.,
Closes #42
) - Details on breaking changes
Example:BREAKING CHANGE: auth service now requires email verification
Used for automating version bumps (e.g., semantic-release):
- Breaking changes → major version
feat
,fix
commits → minor version- Other changes → patch version