Introduction
Git is one of the most important tools for software developers. Whether you are working alone or with a team, Git helps you track code changes, manage versions, collaborate with others, and safely experiment with new features.
In this tutorial, we will learn Git from basic concepts to slightly advanced topics in a simple and practical way.
What is Git?
Git is a distributed version control system. It allows developers to track changes in source code over time.
With Git, you can:
- Save different versions of your code
- Go back to an older version if something breaks
- Work on new features without disturbing the main code
- Collaborate with multiple developers
- Review who changed what and when
Git is widely used in real-world software development and is commonly used with platforms like GitHub, GitLab, and Bitbucket.
Git vs GitHub
Many beginners confuse Git and GitHub.
Git is a tool installed on your computer to manage version control.
GitHub is an online platform where you can store Git repositories and collaborate with others.
Simple example:
Git = Version control tool
GitHub = Online hosting platform for Git repositories
You can use Git without GitHub, but GitHub needs Git to manage code versions.
Basic Git Workflow
A typical Git workflow looks like this:
Working Directory → Staging Area → Local Repository → Remote Repository
1. Working Directory
This is where you write or modify your code.
2. Staging Area
This is where you prepare files before saving them permanently in Git.
3. Local Repository
This is your local Git database where commits are stored.
4. Remote Repository
This is the online repository hosted on GitHub, GitLab, or Bitbucket.
Common Git Commands
Check Git Version
git --version
This command checks whether Git is installed on your system.
Initialize a Git Repository
git init
This creates a new Git repository in your project folder.
Check File Status
git status
This shows which files are modified, staged, or untracked.
Add Files to Staging Area
git add filename
To add all changed files:
git add .
Commit Changes
git commit -m "Initial commit"
A commit is like a snapshot of your project at a specific point in time.
View Commit History
git log
For a shorter history:
git log --oneline
Working with Remote Repository
Add Remote Repository
git remote add origin https://github.com/username/repository-name.git
Push Code to Remote
git push origin main
Pull Latest Changes
git pull origin main
Clone Existing Repository
git clone https://github.com/username/repository-name.git
Cloning downloads a remote repository to your local machine.
Git Branching
Branching is one of the most powerful features of Git. A branch allows you to work on a new feature without affecting the main code.
Create a New Branch
git branch feature-login
Switch to a Branch
git checkout feature-login
Modern Git also supports:
git switch feature-login
Create and Switch Together
git checkout -b feature-login
or
git switch -c feature-login
List Branches
git branch
Merge Branch into Main
First switch to main:
git switch main
Then merge:
git merge feature-login
Git Merge Conflict
A merge conflict happens when Git cannot automatically decide which code change should be kept.
Example:
Developer A changes the same line in a file.
Developer B also changes the same line.
When both changes are merged, Git asks you to manually resolve the conflict.
Steps to Resolve Merge Conflict
- Open the conflicted file
- Choose the correct code
- Remove conflict markers
- Add the resolved file
- Commit the changes
git add filename
git commit -m "Resolved merge conflict"
Git Stash
Git stash is useful when you are working on something but need to quickly switch branches without committing incomplete work.
Save Current Work Temporarily
git stash
View Stash List
git stash list
Apply Latest Stash
git stash apply
Apply and Remove Stash
git stash pop
Git Rebase
Git rebase is used to move or replay commits from one branch onto another branch.
Example:
git switch feature-login
git rebase main
This makes your feature branch updated with the latest changes from main.
Merge vs Rebase
Merge keeps the history as it happened.
Rebase creates a cleaner, linear history.
For beginners, merge is safer. Rebase should be used carefully, especially when working with shared branches.
Git Reset
Git reset is used to undo changes.
Unstage a File
git reset filename
Reset Last Commit but Keep Changes
git reset --soft HEAD~1
Reset Last Commit and Remove Changes
git reset --hard HEAD~1
Be careful with --hard because it can permanently remove local changes.
Git Revert
Git revert is safer than reset for shared branches.
git revert commit-id
It creates a new commit that reverses the changes of an older commit.
Use revert when the code is already pushed to a shared remote repository.
Git Tags
Tags are used to mark important versions of your project, such as releases.
Create a Tag
git tag v1.0
Push Tag to Remote
git push origin v1.0
View Tags
git tag
Git Ignore
The .gitignore file tells Git which files or folders should not be tracked.
Example .gitignore file:
target/
node_modules/
.env
*.log
.idea/
.DS_Store
You should not commit sensitive files like passwords, API keys, private keys, or environment files.
Best Practices for Using Git
Use meaningful commit messages.
Good example:
git commit -m "Add user login validation"
Bad example:
git commit -m "changes"
Create separate branches for new features or bug fixes.
Pull the latest code before starting work.
Do not commit passwords or secret keys.
Use .gitignore properly.
Review your changes before committing:
git diff
Keep commits small and focused.
Do not force push on shared branches unless you clearly understand the impact.
Common Git Mistakes Beginners Should Avoid
Do not work directly on the main branch for every change.
Do not commit generated files unnecessarily.
Do not use git reset --hard without checking your changes.
Do not push broken code to shared branches.
Do not ignore merge conflicts.
Do not store secrets in Git repositories.
Useful Git Commands Summary
git init
git status
git add .
git commit -m "message"
git log --oneline
git branch
git switch branch-name
git switch -c new-branch
git merge branch-name
git pull origin main
git push origin main
git stash
git stash pop
git revert commit-id
git tag v1.0
Git Squash Merge: What It Is and When to Use It
What is a Squash Merge?
A Squash Merge combines all commits from a feature branch into a single commit before merging it into the target branch.
Suppose you are working on a feature branch and make multiple commits:
feature/login
Commit 1 - Create login page
Commit 2 - Fix validation bug
Commit 3 - Update CSS
Commit 4 - Fix review comments
Commit 5 - Add unit tests
When performing a normal merge, all five commits appear in the main branch history:
main
Create login page
Fix validation bug
Update CSS
Fix review comments
Add unit tests
With a Squash Merge, Git combines them into a single commit:
main
Add Login Feature
This keeps the commit history clean and easy to understand.
How Squash Merge Works
Feature Branch:
A --- B --- C --- D --- E
Main Branch:
M --- N
After Squash Merge:
M --- N --- S
Where S contains all the changes from commits A, B, C, D, and E.
Performing a Squash Merge Using Git
Switch to the target branch:
git switch main
Perform squash merge:
git merge --squash feature/login
Commit the squashed changes:
git commit -m "Add Login Feature"
Squash Merge in GitHub
When creating a Pull Request in GitHub, you may see three options:
- Create a Merge Commit
- Squash and Merge
- Rebase and Merge
Selecting Squash and Merge combines all commits from the Pull Request into a single commit before merging.
This is the most commonly used option in many enterprise projects.
Benefits of Squash Merge
Cleaner Git History
Instead of:
Fix typo
Fix typo again
Fix build failure
Review comments
Code cleanup
You get:
Implement User Login Feature
Easier Code Review
Reviewers focus on the final feature instead of dozens of intermediate commits.
Simpler Rollback
If the feature causes problems, you can revert one commit instead of multiple commits.
Better Release Tracking
Each feature or bug fix appears as a single logical unit in Git history.
When Should You Use Squash Merge?
Use Squash Merge When
- Feature branches contain many small commits.
- Developers commit frequently during development.
- You want a clean and readable Git history.
- Working in teams that follow feature-based development.
- Merging Pull Requests into main or master.
Example:
Feature Branch:
15 small commits
Result:
1 clean commit in main
This is the most common enterprise use case.
When Should You Avoid Squash Merge?
Avoid Squash Merge when individual commits carry important historical information.
Examples:
- Open-source projects where commit history matters.
- Large refactoring efforts where each commit represents a meaningful step.
- Audit-heavy environments where every change must remain traceable.
Squash Merge vs Normal Merge
| Feature | Normal Merge | Squash Merge |
|---|---|---|
| Preserves all commits | Yes | No |
| Creates merge commit | Usually Yes | No |
| Cleaner history | No | Yes |
| Easier rollback | Moderate | Easy |
| Best for feature branches | Sometimes | Yes |
Squash Merge vs Rebase
Squash Merge
Feature commits
A B C D E
Result
S
All commits become one commit.
Rebase
Feature commits
A B C D E
Result
A B C D E
Commits remain separate but are replayed on top of the latest branch.
Real-World Example
Imagine a developer creates a feature branch and makes 20 commits over a week:
Initial implementation
Fix bug
Fix another bug
Address review comments
Update tests
Improve logging
Fix build issue
The final feature is just “User Registration”.
Using Squash Merge:
Add User Registration Feature
The Git history remains clean and future developers can easily understand project evolution.
Best Practice
For most enterprise applications using GitHub Pull Requests:
- Create a feature branch.
- Commit as often as needed during development.
- Open a Pull Request.
- Use Squash and Merge when the feature is approved.
This provides a clean, maintainable, and professional Git history.
FAQs About Git
Is Git only for developers?
No. Git is mainly used by developers, but writers, DevOps engineers, testers, and technical teams can also use it to manage version history.
Is GitHub required to use Git?
No. Git can be used locally without GitHub. GitHub is used to host repositories online.
What is the difference between Git pull and Git fetch?
git fetch downloads changes from the remote repository but does not merge them.
git pull downloads and merges the changes into your current branch.
Should beginners use Git rebase?
Beginners should first become comfortable with merge. Rebase is useful but should be used carefully.
Can I delete Git history?
Yes, but it should be done carefully. Rewriting Git history can affect other team members if the branch is shared.
Conclusion
Git is an essential skill for every developer. It helps you manage code safely, collaborate with teams, and maintain a proper history of your project.
Start with basic commands like git init, git add, git commit, git push, and git pull. Once you are comfortable, learn branching, merging, stash, rebase, tags, reset, and revert.
The more you use Git in real projects, the more confident you will become.