A complete, scenario-based guide to mastering Git — from setup and local commits to advanced branching, conflict resolution, and CI/CD automation.
- Level 1: Git installation, setup, and first repository
- Level 2: Local development, branching, and change tracking
- Level 3: Team collaboration and remote workflows
- Level 4: Advanced operations (rebase, cherry-pick, recovery)
- Level 5: Repository maintenance and optimization
- Level 6: DevOps integration and real-world scenarios
- Prerequisites
- Quick Start
- Level 1 — Getting Started with Git
- Level 2 — Working Locally (Snapshotting & Branching)
- Level 3 — Team Collaboration & Remote Work
- Level 4 — Advanced Git (Rebase, Cherry-pick, Recovery)
- Level 5 — Repository Maintenance, Cleanup & Optimization
- Level 6 — DevOps & Real-World Git Scenarios
- License
- Final Note
- Basic command line knowledge
- A computer with internet access
- (Optional) GitHub/GitLab/Bitbucket account for remote repositories
# 1. Check if Git is installed
git --version
# 2. Configure your identity
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 3. Initialize a new repository
git init
# 4. Make your first commit
git add .
git commit -m "Initial commit"💡 New to Git? Start with Level 1 for a complete walkthrough.
Git is a distributed version control system (DVCS) that tracks code changes, allows collaboration, and keeps a complete history of your project.
This level covers installation, setup, and initializing your first repository, including connecting to remote repositories like GitHub, GitLab, or Bitbucket.
Check if Git is installed and set up your identity for commits:
# Check Git version
git --version
# Configure global username
git config --global user.name "Your Name"
# Configure global email
git config --global user.email "you@example.com"
# Verify configuration
git config --listExplanation:
user.nameanduser.emailare used to identify commits you make.git config --listshows all Git configurations, including system, global, and local.
Pro Tip: For project-specific settings, you can override global config:
git config user.name "Project Name"
git config user.email "project@example.com"git init- Creates a
.gitfolder in your project — this is your local repository. - Use
git statusto check the state of your repository.
git statusScenario:
You have a folder my-app and want to start tracking it with Git:
cd my-app
git init
git statusgit clone <repo-url>- Copies a remote repository to your local machine.
- Automatically sets up a remote called
origin.
git clone https://github.com/username/repo.git
cd repo
git remote -v # check remote URLIf you initialized a repository locally first, you can add a remote:
git remote add origin https://github.com/username/repo.git
git remote -v # verifyUpdate or change remote URL:
git remote set-url origin https://github.com/username/new-repo.gitPro Tip:
originis just a conventional name — you can name it anything.- Use multiple remotes if pushing to multiple servers (e.g., GitHub + GitLab).
git add <file> # stage a single file
git add . # stage all files in current folder
git add -p # stage changes interactivelygit commit -m "Initial commit"-madds a commit message.- Commit messages should be short, descriptive, and imperative (e.g., “Add login page” not “Added login page”).
git branch -M maingit push -u origin main-usets upstream for future pushes, so next time you can just rungit push.
mkdir my-project
cd my-project
git init
touch README.md
git add README.md
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/username/my-project.git
git push -u origin maingit clone https://github.com/username/my-project.git
cd my-project
echo "console.log('Hello Git');" > index.js
git add index.js
git commit -m "Add initial JS file"
git push origin main# You have an existing project folder
cd existing-project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/existing-project.git
git branch -M main
git push -u origin main| Command | Description |
|---|---|
git status |
Show repository status |
git log |
View commit history |
git log --oneline |
Compact commit history |
git config --global core.editor "code --wait" |
Set VSCode as commit editor |
git help <command> |
Show help for any Git command |
git rm --cached <file> |
Stop tracking a file but keep it locally |
At this level, we focus on tracking changes, committing snapshots, and managing branches locally. This is critical for safe development, experimentation, and preparing for collaboration.
git status-
Shows:
- Untracked files
- Modified files
- Staged files ready for commit
| Command | Description |
|---|---|
git add <file> |
Stage a specific file |
git add . |
Stage all files in the current folder |
git add -p |
Stage changes interactively (line by line) |
Scenario:
You modified app.js and index.html, but only want to commit app.js now:
git add app.js
git commit -m "Fix login bug"git commit -m "Descriptive commit message"- Each commit is a snapshot of the project at a point in time.
- Best practice: commit small, logical units.
- Example:
git commit -m "Add input validation to login form"git commit --amend -m "Updated commit message"- Useful if you forgot to include a file or want to update a typo in the last commit.
- Warning: don’t amend commits that have been pushed to shared branches.
git rm <file>
git commit -m "Remove unnecessary file"- Use
--cachedto remove it from tracking but keep it locally:
git rm --cached <file>Branches allow you to develop features independently without affecting the main code.
git branch # Local branches
git branch -a # Local + remote branchesgit branch feature/login # Create a branch
git checkout feature/login # Switch to branch
git checkout -b feature/login # Create + switch in one command
git checkout -b feature/login origin/feature/login # Track remote branchgit branch -m old-name new-namegit checkout main
git merge feature/login- Merges changes from a branch into current branch.
- Merge conflicts may appear if the same lines were modified.
# Git will mark conflict in file
nano app.js # edit conflict manually
git add app.js
git commit -m "Resolve merge conflict in app.js"git branch -d feature/login # delete local branch
git push origin --delete feature/login # delete remote branchgit stash # save uncommitted changes temporarily
git stash list # list all stashes
git stash pop # apply last stash
git stash apply stash@{2} # apply a specific stash
git stash drop stash@{2} # remove a stash
git stash clear # remove all stashesScenario: You are mid-way through a feature but need to switch branches for a hotfix:
git stash
git checkout hotfix/header
# fix hotfix
git checkout feature/login
git stash popgit log # full log
git log --oneline # compact view
git log --graph --oneline --all # visual commit treegit diff # unstaged changes
git diff --staged # staged changes vs last commit
git diff branchA..branchB # compare two branches
git show <commit> # view specific commit changes
git blame <file> # see who changed each linegit checkout -b feature/search
# work on search feature
git add .
git commit -m "Implement basic search"
git push -u origin feature/searchgit checkout main
git pull origin main
git merge feature/search
# conflict occurs
# edit conflicting files
git add .
git commit -m "Resolve merge conflicts for search feature"git stash
git checkout hotfix/button
# fix urgent button bug
git add .
git commit -m "Hotfix button bug"
git checkout feature/search
git stash pop| Command | Description |
|---|---|
git reflog |
Show history of HEAD movements |
git reset --soft HEAD~1 |
Undo last commit but keep changes staged |
git reset --hard HEAD~1 |
Undo last commit and discard changes |
git restore <file> |
Restore file to last committed state |
git tag <name> |
Tag current commit |
git tag -a <name> -m "message" |
Annotated tag |
git push origin <tag> |
Push tag to remote |
Working in a team introduces challenges like synchronizing code, handling conflicts, and maintaining a clean history. This level covers remote repositories, pushing, pulling, fetching, and collaboration workflows.
A remote repository is a version of your project hosted on GitHub, GitLab, Bitbucket, or another server.
git remote -v- Lists configured remote repositories along with fetch/push URLs.
originis the default name for the main remote.
git remote add origin <repo-url> # add remote
git remote set-url origin <new-url> # change remote URL
git remote remove origin # remove remotegit push origin <branch> # push a local branch
git push -u origin <branch> # push and set upstream
git push origin --delete <branch> # delete remote branch
git push --all origin # push all branches
git push --tags origin # push all tagsPro Tip:
- Use
-uwhen first pushing a branch to set the upstream for futuregit push/git pull.
git pull # fetch + merge from current upstream
git pull origin main # pull a specific branch
git pull --rebase # fetch + reapply your commits on topScenario:
Before starting work, always sync your local main with remote:
git checkout main
git pull origin maingit fetch # get latest changes from remote
git fetch --all # fetch all branches from all remotesgit fetchdownloads updates without changing your local files.- Good for checking for updates before merging.
git checkout -b featureX origin/featureX- Creates a local branch tracking a remote branch.
- Useful when starting work on a branch already existing on the server.
git checkout main
git fetch
git merge origin/main- Alternative:
git pull(fetch + merge) - Avoid unnecessary merge commits using
git pull --rebase.
# conflict occurs during merge
nano app.js # manually resolve
git add app.js
git commit -m "Resolve merge conflict in app.js"Pro Tip: Use small, frequent commits to minimize conflicts.
git branch -r # list remote branches
git branch -a # list local + remote branchesgit fetch
git log main..origin/main # commits in remote not in local
git diff main..origin/main # see actual changesgit checkout -b feature/login
# develop feature
git add .
git commit -m "Add login page"
git push -u origin feature/login
# open Pull Request for reviewgit checkout main
git pull --rebase origin main
git checkout -b feature/search- Ensures your new branch is up-to-date with latest
main.
git checkout main
git pull origin main
git checkout feature/login
git rebase main
# fix any conflicts
git add .
git rebase --continue
git push -f origin feature/login✅ Best Practice: Only force push (
-f) to your feature branch, never tomainor shared branches.
git push origin --delete feature/login| Command | Description |
|---|---|
git fetch --prune |
Remove remote-tracking branches that no longer exist on remote |
git remote show origin |
Show detailed info about remote branches |
git pull --rebase origin main |
Reapply your local commits on top of upstream changes |
git cherry -v |
See which commits are not yet merged |
git shortlog |
Summary of commits per author |
Advanced Git operations allow you to manipulate history safely, recover lost work, and keep a clean repository, especially in large teams or production environments.
Rebasing allows you to reapply commits from one branch onto another. It keeps history linear and clean.
git checkout feature/login
git rebase main- Moves
feature/logincommits on top ofmain. - No merge commits — cleaner history.
git rebase -i HEAD~3-
Opens last 3 commits in editor.
-
Options:
pick— keep commitsquash— combine commit with previousedit— modify commit message or contentdrop— remove commit
Scenario:
Clean up messy commits before merging to main:
git rebase -i HEAD~5
# squash small fixes into main commitsPro Tip:
- Never rebase shared branches that others work on.
- Rebase is ideal for feature branches before merging.
Apply a specific commit from one branch to another.
git checkout main
git cherry-pick a1b2c3d- Useful for hotfixes or selective changes.
- Can cherry-pick multiple commits:
git cherry-pick a1b2c3d e4f5g6hScenario:
Critical bug fix on dev branch must go to main immediately.
| Command | Description |
|---|---|
git reset --soft HEAD~1 |
Undo last commit, keep changes staged |
git reset --mixed HEAD~1 |
Undo last commit, unstaged changes remain |
git reset --hard HEAD~1 |
Undo last commit and discard changes permanently |
Scenario: You accidentally committed debug code:
git reset --soft HEAD~1
git edit files
git commit -m "Remove debug code"git restore <file> # restore file to last commit
git restore --staged <file> # unstage file
git restore <file> --source HEAD~1 # restore file from specific commitgit stash list # list stashes
git stash show -p stash@{0} # preview stash changes
git stash branch feature/temp stash@{0} # create branch from stash
git stash drop stash@{0} # delete a stash
git stash clear # remove all stashesScenario: You’re mid-feature but need to fix production immediately:
git stash
git checkout hotfix/header
# fix production issue
git add .
git commit -m "Hotfix header"
git checkout feature/login
git stash popgit reflog tracks all HEAD movements — your safety net.
git reflog
git checkout -b recover-branch HEAD@{3} # recover lost commitScenario: You accidentally deleted a branch:
git branch -d feature/search
# oops
git reflog
git checkout -b feature/search HEAD@{2}Pro Tip:
- Always check
reflogbefore panicking — almost every commit can be recovered.
- Reset changes history — dangerous on shared branches.
- Revert adds a new commit that undoes changes — safe for production.
git revert <commit> # undo commit safelyScenario: Production branch has a bad commit:
git checkout main
git revert a1b2c3d
git push origin maingit checkout feature/login
git fetch origin
git rebase origin/main
# fix conflicts if any
git push -f origin feature/logingit checkout main
git cherry-pick e4f5g6h
git push origin maingit reflog
git checkout -b recover-feature HEAD@{5}git reset --soft HEAD~2 # undo last 2 commits but keep changes staged
git commit -m "Fixed commit"
git push -f origin feature/login| Command | Description |
|---|---|
git bisect |
Find the commit that introduced a bug using binary search |
git clean -fd |
Remove untracked files/directories |
git gc --aggressive |
Cleanup and optimize repo |
git reflog expire --expire=now --all && git gc --prune=now --aggressive |
Aggressive cleanup |
git tag -a v1.0 -m "Release" |
Create annotated tag |
git push origin --tags |
Push all tags |
git blame <file> |
See author of each line |
git show <commit> |
Show changes in a commit |
Over time, repositories can accumulate untracked files, dangling commits, and unnecessary objects, which can slow down operations and increase size. This level teaches how to clean, prune, and optimize your Git repo safely.
git clean -f-f= force (required)- Removes files not tracked by Git in the working directory.
git clean -fd-d= remove directories- Safely removes folders not tracked by Git.
git clean -n
git clean -nd-n= dry-run; shows what will be deleted without actually deleting.
Scenario:
Your node_modules/ and temporary logs are cluttering the repo:
git clean -fdgit gc- Runs garbage collection, compresses objects, and cleans up unnecessary files.
git gc --aggressive --prune=now- Optimizes repo further, useful for very large repos.
- Compresses objects for storage efficiency.
git prune- Deletes unreachable objects from the object database.
- Should be used with caution.
git fetch --prune- Removes remote-tracking branches that no longer exist on the remote.
- Keeps local branch list clean.
git branch -r # list remote branches
git branch -a # list all branchesScenario: After a major release, old feature branches are merged and deleted from remote:
git fetch --prunegit filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch secret.txt" \
--prune-empty --tag-name-filter cat -- --all- Removes sensitive files from history.
- Follow up with:
git push origin --force --all
git push origin --force --tagsPro Tip:
- Use BFG Repo Cleaner for large history rewrites.
- Rewriting history affects collaborators; coordinate with team.
git rebase -i HEAD~10- Squash minor/fix commits into meaningful units.
- Keeps repository clean and easier to navigate.
git clean -fd # remove untracked files & folders
git gc --aggressive # optimize repository
git status # verify clean working directory
git push origin maingit prune
git gc --aggressive
du -sh .git # check size reductiongit fetch --prune
git branch -r # verify stale branches removed| Command | Description |
|---|---|
git fsck |
Verify integrity of objects in repository |
git reflog expire --expire=now --all |
Expire all reflog entries |
git repack -a -d --depth=250 --window=250 |
Repack objects to reduce repo size |
git verify-pack -v .git/objects/pack/pack-*.idx |
Analyze packed objects |
git count-objects -v |
Show number of loose objects and disk usage |
In professional environments, Git is not just about commits — it’s a key tool for team workflows, releases, and automated pipelines. This level covers branching strategies, hotfixes, tagging releases, and CI/CD integration tips.
main
├─ develop
│ ├─ feature/login
│ └─ feature/search
└─ hotfix/header
- main: production-ready code
- develop: integration branch
- feature/: new features
- hotfix/: urgent fixes for production
Commands:
# Create and switch to feature branch
git checkout -b feature/login develop
# Push feature branch
git push -u origin feature/login- All development occurs on feature branches
- Merged into
mainvia Pull Requests - Ideal for CI/CD pipelines
git checkout -b feature/signup
git add .
git commit -m "Add signup feature"
git push -u origin feature/signup
# open PR for reviewgit tag v1.0 # lightweight tag
git tag -a v1.0 -m "Release v1.0" # annotated taggit push origin v1.0
git push origin --tags # push all tagsScenario: Mark production-ready commit with a tag:
git checkout main
git tag -a v2.0 -m "Release version 2.0"
git push origin v2.0# Checkout main
git checkout main
# Create hotfix branch
git checkout -b hotfix/header
# Fix issue
git add .
git commit -m "Fix header bug"
# Merge hotfix into main and develop
git checkout main
git merge hotfix/header
git push origin main
git checkout develop
git merge hotfix/header
git push origin develop
# Delete hotfix branch
git branch -d hotfix/header
git push origin --delete hotfix/header- Ensures fix is applied to both production and development branches.
- Feature Branches → run automated tests
- PR Merges → trigger build pipeline
- Tags → trigger deployment pipeline
- Hotfix Branches → urgent deployment
Commands / Scenarios:
# Before merging to main
git checkout feature/login
git pull origin main --rebase # keep branch up-to-date
git push origin feature/login
# Open PR → CI runs tests → merge on successPro Tip:
- Keep
mainalways deployable. - Use protected branches on GitHub/GitLab to prevent direct push.
git fetch origin
git rebase origin/main- Avoids messy merge commits.
- Keeps your feature branch current with team changes.
# After rebase
# Fix conflicts
git add .
git rebase --continue
git push -f origin feature/logingit branch -d feature/login
git push origin --delete feature/login- Keeps repo clean.
- Helps avoid confusion in CI/CD pipelines.
git checkout main
git pull origin main
git checkout -b feature/paymentgit add .
git commit -m "Add payment module"
git push -u origin feature/payment
# Open PR → CI/CD runs tests → Mergegit checkout main
git pull origin main
git checkout -b hotfix/api
# Fix bug
git add .
git commit -m "Fix API issue"
git push origin hotfix/api
# Merge hotfix
git checkout main
git merge hotfix/api
git push origin maingit checkout main
git tag -a v2.1 -m "Release v2.1 with payment module"
git push origin v2.1| Command | Description |
|---|---|
git branch --merged |
List branches already merged into current branch |
git branch --no-merged |
List branches not yet merged |
git push origin --tags |
Push all tags to remote |
git log --oneline --graph --decorate --all |
Visualize history and branch merges |
git reflog |
Track HEAD movement, useful for recovery |
git reset --hard origin/main |
Reset local branch to remote state |
git fetch --prune |
Remove deleted remote branches locally |
This project is open source and available under the MIT License.
This document covers Git usage from local development to CI/CD pipelines — the way professional teams handle version control.
- Practice: Create a test repository and try all the commands
- Explore: Learn about Git hooks, submodules, and advanced workflows
- Contribute: Use these skills in open source projects
- Teach: Share your knowledge with others
Found an error or want to improve this guide?
- Fork this repository
- Create a feature branch:
git checkout -b feature/improvement - Make your changes and commit:
git commit -m "Add improvement" - Push to your branch:
git push origin feature/improvement - Open a Pull Request
💡 Remember: Keep experimenting! The more you practice branching, merging, and rebasing, the more intuitive Git becomes.
Happy coding! 🚀