Version Control
Understanding Git, branching strategies and collaborative development workflows
Last updated: 8/15/2025
Master the essential tool that enables teams to collaborate on code, track changes and maintain project history effectively.
What is Version Control?
The Core Concept
Tracking changes to your code over time
Version control is like having a time machine for your code. Every change you make is recorded, so you can go back to any previous version, see who made what changes and collaborate with others without overwriting each other's work.
Real-world analogy: Think of version control like writing a book with multiple authors. Each person can work on different chapters, you can see who wrote what and if someone makes a mistake, you can easily revert to the previous version.
Git Fundamentals
What is Git?
Distributed version control system
Git is the most popular version control system, created by Linus Torvalds (the same person who created Linux). It's distributed, meaning every developer has a complete copy of the project history on their local machine.
Key benefits:
- Work offline
- Fast operations
- Branch and merge easily
- Complete project history
Basic Git Concepts
Repository
The project folder with version control
A repository (or "repo") is a directory that contains your project files and the complete history of all changes.
# Create a new repository
git init
# Clone an existing repository
git clone https://github.com/username/project.git
Commit
A snapshot of your code at a point in time
Each commit represents a complete snapshot of your project. Think of it like taking a photo - you capture the current state of everything.
# Stage files for commit
git add filename.js
git add . # Add all files
# Create a commit with a message
git commit -m "Add user authentication feature"
Branch
A separate line of development
Branches let you work on features without affecting the main code. It's like having multiple copies of your project that can evolve independently.
# Create and switch to a new branch
git checkout -b feature/new-feature
# Switch between branches
git checkout main
git checkout feature/new-feature
# Modern Git syntax (Git 2.23+)
git switch -c feature/new-feature
git switch main
Essential Git Commands
Daily Workflow Commands
# Check status of your repository
git status
# See what files have changed
git diff
# View commit history
git log
# See a compact history
git log --oneline
Working with Remote Repositories
# Download latest changes
git pull origin main
# Upload your changes
git push origin feature/new-feature
# See remote repositories
git remote -v
Undoing Changes
# Discard changes in working directory
git checkout -- filename.js
# Reset to last commit (keeps changes staged)
git reset HEAD filename.js
# Reset to last commit (discards all changes)
git reset --hard HEAD
# Go back to a specific commit
git reset --hard abc1234
Branching Strategies
Git Flow
Structured branching model for teams
main (production)
↓
develop (integration)
├── feature/user-auth
├── feature/payment
└── feature/search
hotfix/critical-bug → main & develop
release/v2.0 → main & develop
When to use: Large teams, complex projects, strict release cycles
GitHub Flow
Simplified workflow for continuous deployment
main
├── feature-branch-1
├── feature-branch-2
└── feature-branch-3
1. Create branch from main
2. Make changes
3. Open pull request
4. Review and test
5. Merge to main
6. Deploy immediately
When to use: Small teams, web applications, frequent deployments
GitLab Flow
Environment-based workflow
main
↓
pre-production
↓
production
Features merge to main
Main deploys to pre-production
Pre-production promotes to production
When to use: Teams with multiple environments, staged deployments
Collaborative Workflows
Pull Requests and Merge Requests
Code review and collaboration
Pull requests (GitHub) or merge requests (GitLab) are the primary way teams collaborate on code changes.
Best practices:
- Write clear descriptions
- Reference related issues
- Request specific reviewers
- Keep changes focused and small
Code Review Process
# Create a pull request
git push origin feature/new-feature
# On GitHub/GitLab:
# 1. Create pull request
# 2. Add description and reviewers
# 3. Address feedback
# 4. Merge when approved
Resolving Conflicts
When changes overlap
Conflicts happen when two people modify the same part of the same file.
# Pull latest changes
git pull origin main
# Git will show conflict markers
<<<<<<< HEAD
console.log("Hello from main");
=======
console.log("Hello from feature branch");
>>>>>>> feature/new-feature
# Edit file to resolve conflict
# Remove conflict markers
# Stage resolved file
git add filename.js
git commit -m "Resolve merge conflict"
Advanced Git Features
Stashing
Save work in progress
Stashing lets you temporarily save changes without committing them.
# Save current work
git stash
# List stashes
git stash list
# Apply most recent stash
git stash pop
# Apply specific stash
git stash apply stash@{1}
# Drop a stash
git stash drop stash@{0}
Cherry-picking
Select specific commits
Cherry-picking lets you apply specific commits from one branch to another.
# Apply a specific commit to current branch
git cherry-pick abc1234
# Cherry-pick multiple commits
git cherry-pick abc1234 def5678
Rebase vs Merge
Two ways to integrate changes
Merge: Creates a merge commit, preserves history
git merge feature-branch
Rebase: Replays commits on top of target branch, linear history
git rebase main
Git Hooks
Automated scripts
Git hooks are scripts that run automatically at certain points in the Git workflow.
Common hooks:
pre-commit: Run tests before commitpost-commit: Send notificationspre-push: Validate code quality
# Example pre-commit hook
#!/bin/sh
npm test
if [ $? -ne 0 ]; then
echo "Tests must pass before commit"
exit 1
fi
Git Configuration
User Setup
# Set your name and email
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Set default editor
git config --global core.editor "code --wait"
Aliases
Shortcuts for common commands
# Create useful aliases
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
# Now you can use:
git st # instead of git status
git co # instead of git checkout
Best Practices
Commit Messages
Clear, descriptive messages
# Good commit messages
git commit -m "Add user authentication with JWT tokens"
git commit -m "Fix login form validation bug"
git commit -m "Update API documentation for v2 endpoints"
# Bad commit messages
git commit -m "stuff"
git commit -m "fix"
git commit -m "wip"
Branch Naming
Consistent naming conventions
feature/user-authentication
bugfix/login-validation
hotfix/security-patch
release/v2.1.0
Regular Commits
Small, focused changes
- Commit often
- One logical change per commit
- Test before committing
- Use meaningful commit messages
Troubleshooting
Common Issues
"I made a commit to the wrong branch":
# Move commit to correct branch
git checkout correct-branch
git cherry-pick wrong-branch
git checkout wrong-branch
git reset --hard HEAD~1
"I need to undo my last commit":
# Undo commit but keep changes
git reset --soft HEAD~1
# Undo commit and discard changes
git reset --hard HEAD~1
"I lost my work":
# Find lost commits
git reflog
# Recover lost commit
git checkout -b recovery abc1234
Git Log Analysis
# See detailed history
git log --graph --oneline --all
# Find commits by author
git log --author="John Doe"
# Find commits containing text
git log -S "function name"
Integration with IDEs
Visual Studio Code
- Built-in Git support
- Source control panel
- Diff viewer
- Git blame information
JetBrains IDEs
- Comprehensive Git integration
- Visual merge tool
- Git tool window
- Advanced refactoring support
Command Line Tools
- Git Bash (Windows)
- Terminal (macOS/Linux)
- PowerShell with Git
Getting Started
Your First Repository
Step 1: Create a new project
mkdir my-project
cd my-project
git init
Step 2: Add some files
echo "# My Project" > README.md
git add README.md
git commit -m "Initial commit with README"
Step 3: Create a feature branch
git checkout -b feature/awesome-feature
# Make changes
git add .
git commit -m "Add awesome feature"
Step 4: Push to remote
git remote add origin https://github.com/username/my-project.git
git push -u origin feature/awesome-feature
Learning Resources
Documentation
- Git Official Documentation
- GitHub Guides
- GitLab Documentation
Interactive Learning
- GitHub Learning Lab
- Git Branching tutorials
- Oh My Git! interactive tutorials
Books
- Pro Git
- Git for Humans
- Version Control with Git
Summary
Version control with Git is essential for modern software development. It enables collaboration, tracks changes and provides a safety net for your code.
Key takeaways:
- Git tracks every change to your code
- Branches enable parallel development
- Regular commits create a clear history
- Pull requests facilitate code review
- Git hooks automate workflows
- Good practices make collaboration easier
Remember: Version control isn't just about tracking changes - it's about enabling teams to work together effectively while maintaining code quality and project history!