Git
Distributed Version Control System
What is Git?
Git is a distributed version control system (DVCS) that tracks changes in any set of files. Unlike centralized systems, every developer has a full copy of the repository history. This makes operations fast, enables offline work, and provides redundancy. Git's branching model is lightweight and encourages experimentation.
Think of Git like a time machine for your code
Imagine you're writing a book. Git lets you save snapshots at any point, so you can always go back to any previous version. You can also create parallel universes (branches) to try different story directions, then merge the best parts together. Every collaborator has their own complete copy of the entire history.
Key Features
Distributed Architecture
Every clone is a full backup. Work offline, sync when ready.
Lightning Fast
Nearly all operations are local. Branching and merging in milliseconds.
Branching & Merging
Create branches instantly. Merge strategies for any workflow.
Data Integrity
SHA-1 hashing ensures complete history integrity and authenticity.
When to Use
- Any software development project (solo or team)
- Tracking changes to configuration files
- Collaborating with distributed teams
- Managing documentation and technical writing
- Infrastructure as Code (Terraform, Ansible, etc.)
- Open source contributions
When Not to Use
- Large binary files (use Git LFS instead)
- Sensitive secrets or credentials (use secret managers)
- Real-time collaborative editing (use Google Docs, etc.)
- Database version control (use migrations instead)
- Very large monorepos without optimization (consider sparse checkout)
Prerequisites
- Terminal/command line basics
- A text editor or IDE
- GitHub, GitLab, or Bitbucket account (for remote repos)
Installation
sudo apt install gitDebian/Ubuntu
sudo dnf install gitFedora/RHEL
brew install gitxcode-select --installComes with Xcode CLI tools
winget install Git.Gitchoco install gitVerify installation: git --version
Quick Start Steps
Configure your identity
Set your name and email for commits
git config --global user.name "Your Name" git config --global user.email "you@example.com"
Initialize a repository
Create a new Git repository in your project folder
mkdir my-project && cd my-project git init
Create your first commit
Add files and create your first snapshot
echo "# My Project" > README.md git add README.md git commit -m "Initial commit"
Connect to remote
Link to GitHub/GitLab and push
git remote add origin https://github.com/user/repo.git git push -u origin main
git initInitialize a new Git repository
git clone <url>Clone a repository from remote
git statusShow working tree status
git add <file>Stage changes for commit
git add .Stage all changes
git commit -m '<message>'Create a commit with message
git pushUpload local commits to remote
git pullFetch and merge remote changes
git branchList, create, or delete branches
git checkout <branch>Switch branches
git merge <branch>Merge branch into current branch
git log --onelineShow commit history (compact)
Commands by Category
Pro Tips15
Write meaningful commit messages
best-practiceUse conventional commits format: type(scope): description. Good messages explain WHY, not just what.
feat(auth): add password reset flow
Users can now reset their password via email link.fixed stuffCommit early, commit often
workflowSmall, focused commits are easier to review, revert, and understand. Don't wait for 'perfect' code.
Never force push to main/master
gotchaForce pushing to shared branches rewrites history and breaks everyone's workflow. Use --force-with-lease on feature branches only.
git push --force-with-lease origin feature-branchgit push --force origin mainUse pull --rebase for cleaner history
workflowgit pull --rebase keeps your commits on top, avoiding unnecessary merge commits.
git pull --rebase origin mainReview staged changes before committing
best-practiceAlways run git diff --staged before committing. Catch accidental debug code, console.logs, or sensitive data.
Never commit directly to main
workflowAlways work on feature branches. This enables code review, CI checks, and easy rollback.
Set up Git aliases for common commands
automationSave time with aliases: git config --global alias.co checkout, alias.br branch, alias.st status
Set up .gitignore before first commit
best-practiceIt's much harder to remove files from history than to never commit them. Set up ignores immediately.
Fetch/pull before starting new work
workflowAlways sync with remote before creating branches or making changes to avoid conflicts.
Know when to use reset vs revert
gotchaUse reset to undo local commits (rewrites history). Use revert for commits already pushed (creates new commit).
git revert abc123 (for shared commits)git reset --hard abc123 && git push --force (destroys team's work)Always add a message when stashing
best-practicegit stash save 'WIP: feature description' makes it easier to find stashes later.
Keep commits atomic and focused
best-practiceEach commit should represent one logical change. Mix of refactoring + feature + bug fix = hard to review.
Use SSH keys instead of HTTPS passwords
securitySSH keys are more secure and don't require entering credentials repeatedly.
Sign commits with GPG for verification
securitySigned commits prove you're the author. Required for some organizations and open source projects.
Use Git LFS for large binary files
performanceRegular Git is inefficient with large files. Git LFS stores them separately and keeps your repo fast.
Key Facts10
Git uses SHA-1 hashes for commit IDs
Every commit, tree, and blob is identified by a 40-character SHA-1 hash. This ensures data integrity.
HEAD is a pointer to the current commit
HEAD usually points to a branch, which points to a commit. Detached HEAD means HEAD points directly to a commit.
The staging area (index) is between working dir and repository
git add stages changes to the index. git commit creates a commit from the index, not the working directory.
Branches are just pointers (41 bytes)
Creating a branch doesn't copy anything. It's just a file containing a commit hash. Create them freely!
Commits are immutable
You can't change a commit. 'Amending' creates a new commit with a new hash. Old commit still exists (in reflog).
Fast-forward merge moves pointer, no merge commit
When the target branch has no new commits, Git just moves the pointer forward. Use --no-ff to force merge commit.
Reflog entries expire after 90 days by default
Unreachable commits are garbage collected eventually. Reflog keeps references temporarily for recovery.
Detached HEAD means you're not on a branch
Commits made in detached HEAD state will be lost unless you create a branch before switching away.
origin is just a naming convention for the default remote
You can name remotes anything. 'origin' is convention for the main remote, 'upstream' for the original repo of a fork.
Merge preserves history, rebase rewrites it
Merge creates a merge commit showing branches joined. Rebase moves commits, creating linear history but new hashes.
Interview & Exam Practice5
Your team is debating whether to use merge or rebase when integrating feature branches.
What are the key differences and when would you recommend each approach?
You need to undo the last 3 commits on your local branch. The changes include bug fixes you want to keep working on.
Which git reset option should you use?
After checking out a specific commit to debug an issue, you realize you're in 'detached HEAD' state. You've made a fix and committed it.
What happens if you checkout main without doing anything else?
A bug was introduced somewhere in the last 500 commits. You have a test that can detect the bug.
What's the most efficient way to find when the bug was introduced?
You accidentally committed and pushed an API key to a public repository.