- Introduction
- What is Git?
- What is GitHub?
- Key Differences Between Git and GitHub
- Installing Git
- Git Configuration
- Basic Git Concepts
- Git Commands Reference
- Working with Branches
- Remote Repositories
- GitHub Features
- Collaboration Workflow
- Best Practices
- Troubleshooting Common Issues
- Advanced Git Topics
- Conclusion
Version control is essential for modern software development. It allows developers to track changes, collaborate effectively, and maintain a complete history of their project. Git is the most popular version control system in the world, and GitHub is the leading platform for hosting Git repositories and collaborating on code.
This comprehensive guide covers everything you need to know about Git and GitHub, from basic concepts to advanced workflows.
Git is a distributed version control system created by Linus Torvalds in 2005. It allows developers to track changes in their code, collaborate with others, and maintain different versions of their projects.
- Distributed Architecture: Every developer has a complete copy of the repository history
- Speed: Git operations are performed locally, making them extremely fast
- Branching and Merging: Create isolated development environments easily
- Data Integrity: Every file and commit is checksummed using SHA-1 hash
- Staging Area: Review changes before committing them
- Free and Open Source: Available for everyone to use and modify
- Track every change made to your project
- Revert to previous versions when needed
- Work on multiple features simultaneously using branches
- Collaborate with team members without conflicts
- Maintain a complete audit trail of your project
- Work offline and sync changes later
GitHub is a cloud-based hosting service for Git repositories. It was founded in 2008 and acquired by Microsoft in 2018. GitHub provides a web-based interface for Git repositories along with additional collaboration features.
- Repository Hosting: Store unlimited public and private repositories
- Collaboration Tools: Pull requests, code reviews, and issue tracking
- Social Coding: Follow developers, star repositories, and fork projects
- GitHub Actions: Automate workflows with CI/CD pipelines
- GitHub Pages: Host static websites directly from repositories
- Project Management: Kanban boards, milestones, and project tracking
- Security Features: Vulnerability scanning, Dependabot, and secret scanning
- Documentation: Built-in wiki and README rendering
While GitHub is the most popular, other Git hosting platforms include:
- GitLab: Offers built-in CI/CD and DevOps features
- Bitbucket: Integrates well with Atlassian tools
- Gitea: Self-hosted, lightweight option
- SourceForge: One of the oldest hosting platforms
| Feature | Git | GitHub |
|---|---|---|
| Type | Version control system (software) | Hosting service (platform) |
| Installation | Installed locally on your computer | Cloud-based, accessed via browser |
| Purpose | Track and manage code changes | Host repositories and facilitate collaboration |
| Usage | Command-line or GUI tools | Web interface with additional features |
| Cost | Free and open source | Free tier with paid plans for advanced features |
| Offline Work | Works completely offline | Requires internet connection |
| Collaboration | Basic (local sharing) | Advanced (pull requests, issues, discussions) |
- Download the installer from git-scm.com
- Run the executable file
- Follow the installation wizard (recommended: use default settings)
- Verify installation by opening Command Prompt and typing:
git --version
Option 1: Using Homebrew
brew install gitOption 2: Using Xcode Command Line Tools
xcode-select --installOption 3: Download installer from git-scm.com
Debian/Ubuntu:
sudo apt update
sudo apt install gitFedora:
sudo dnf install gitArch Linux:
sudo pacman -S gitgit --versionYou should see output like: git version 2.40.0
After installing Git, configure your identity. This information is used in every commit.
# Set your name
git config --global user.name "Your Name"
# Set your email
git config --global user.email "your.email@example.com"
# Set default branch name to 'main'
git config --global init.defaultBranch main
# Set default editor (optional)
git config --global core.editor "code --wait" # For VS Code
git config --global core.editor "vim" # For Vim# View all configuration
git config --list
# View specific configuration
git config user.name
git config user.emailGit has three configuration levels:
- System (
--system): Applies to all users on the system - Global (
--global): Applies to all repositories for current user - Local (
--local): Applies only to current repository (default)
# Enable color output
git config --global color.ui auto
# Set up 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
# Configure line endings
git config --global core.autocrlf input # For macOS/Linux
git config --global core.autocrlf true # For WindowsA repository is a directory that contains your project files and the complete history of all changes. It includes a hidden .git folder that stores all version control information.
A commit is a snapshot of your repository at a specific point in time. Each commit has:
- A unique SHA-1 hash identifier
- Author information
- Timestamp
- Commit message describing the changes
- Reference to parent commit(s)
The working directory is where you modify files. It contains the current version of your project files.
The staging area is an intermediate area where you prepare changes before committing them. It allows you to selectively choose which changes to include in the next commit.
A branch is a parallel version of your repository. It allows you to work on different features or fixes without affecting the main codebase.
HEAD is a pointer that refers to the current branch or commit you're working on. It typically points to the tip of the current branch.
A remote is a version of your repository hosted on a server (like GitHub). You can push changes to and pull changes from remotes.
- Modified: You have changed files but haven't committed them yet
- Staged: You have marked modified files to go into the next commit
- Committed: The changes are safely stored in your local repository
# Initialize a new Git repository
git init
# Clone an existing repository
git clone <repository-url>
# Clone with a different directory name
git clone <repository-url> <directory-name>
# Clone a specific branch
git clone -b <branch-name> <repository-url># Check status of your repository
git status
# Add files to staging area
git add <file-name>
git add . # Add all files
git add *.js # Add all JavaScript files
git add src/ # Add entire directory
# Remove files from staging area
git reset <file-name>
git reset # Unstage all files
# Commit changes
git commit -m "Commit message"
git commit -am "Message" # Add and commit in one step (tracked files only)
# View commit history
git log
git log --oneline # Compact view
git log --graph # Show branch structure
git log --all --decorate --oneline --graph # Detailed graph view# View unstaged changes
git diff
# View staged changes
git diff --staged
# View changes in a specific file
git diff <file-name>
# Compare branches
git diff <branch1> <branch2>
# Show commit details
git show <commit-hash># Discard changes in working directory
git checkout -- <file-name>
git restore <file-name> # Newer syntax
# Unstage files
git reset HEAD <file-name>
git restore --staged <file-name> # Newer syntax
# Amend last commit
git commit --amend -m "New message"
# Revert a commit (creates new commit)
git revert <commit-hash>
# Reset to a previous commit
git reset --soft <commit-hash> # Keep changes staged
git reset --mixed <commit-hash> # Keep changes unstaged (default)
git reset --hard <commit-hash> # Discard all changes (dangerous!)# List branches
git branch # Local branches
git branch -r # Remote branches
git branch -a # All branches
# Create a new branch
git branch <branch-name>
# Switch to a branch
git checkout <branch-name>
git switch <branch-name> # Newer syntax
# Create and switch to a new branch
git checkout -b <branch-name>
git switch -c <branch-name> # Newer syntax
# Rename a branch
git branch -m <old-name> <new-name>
git branch -m <new-name> # Rename current branch
# Delete a branch
git branch -d <branch-name> # Safe delete (merged only)
git branch -D <branch-name> # Force delete
# Merge branches
git merge <branch-name>
# Rebase current branch
git rebase <branch-name># View remote repositories
git remote
git remote -v # Show URLs
# Add a remote
git remote add <name> <url>
git remote add origin https://github.com/user/repo.git
# Remove a remote
git remote remove <name>
# Rename a remote
git remote rename <old-name> <new-name>
# Fetch changes from remote
git fetch <remote>
git fetch origin
# Pull changes (fetch + merge)
git pull <remote> <branch>
git pull origin main
# Push changes to remote
git push <remote> <branch>
git push origin main
git push -u origin main # Set upstream and push
# Push all branches
git push --all origin
# Delete remote branch
git push origin --delete <branch-name># Save changes temporarily
git stash
git stash save "Message"
# List stashes
git stash list
# Apply most recent stash
git stash apply
git stash pop # Apply and remove
# Apply specific stash
git stash apply stash@{2}
# Show stash changes
git stash show
git stash show -p # Show diff
# Delete stash
git stash drop stash@{0}
git stash clear # Delete all stashes# List tags
git tag
# Create lightweight tag
git tag <tag-name>
# Create annotated tag
git tag -a v1.0.0 -m "Version 1.0.0"
# Tag specific commit
git tag <tag-name> <commit-hash>
# Show tag details
git show <tag-name>
# Push tags to remote
git push origin <tag-name>
git push origin --tags # Push all tags
# Delete tag
git tag -d <tag-name> # Delete local
git push origin --delete <tag-name> # Delete remoteBranches allow you to develop features, fix bugs, or experiment with new ideas in isolated environments.
1. Git Flow
main: Production-ready codedevelop: Integration branch for featuresfeature/*: New featuresrelease/*: Release preparationhotfix/*: Emergency production fixes
2. GitHub Flow
main: Always deployable- Feature branches: Created from and merged back to main
- Simple and suitable for continuous deployment
3. GitLab Flow
- Combines feature-driven development with issue tracking
- Environment branches:
production,staging,development
- Use descriptive names:
feature/user-authentication,bugfix/login-error - Keep branches short-lived: Merge frequently to avoid conflicts
- One branch per feature: Don't mix unrelated changes
- Delete merged branches: Keep repository clean
- Regularly sync with main: Prevent merge conflicts
Fast-Forward Merge
git merge feature-branchMoves the branch pointer forward (no merge commit).
Three-Way Merge
git merge --no-ff feature-branchCreates a merge commit even if fast-forward is possible.
Squash Merge
git merge --squash feature-branch
git commit -m "Add feature"Combines all commits into one before merging.
When Git cannot automatically merge changes:
- Git marks conflicts in files:
<<<<<<< HEAD
Your changes
=======
Their changes
>>>>>>> branch-name
- Edit files to resolve conflicts
- Remove conflict markers
- Stage resolved files:
git add <file> - Complete merge:
git commit
Rebasing rewrites commit history by moving or combining commits.
# Rebase current branch onto main
git checkout feature-branch
git rebase main
# Interactive rebase (edit history)
git rebase -i HEAD~3When to Rebase:
- Clean up local commits before pushing
- Keep linear history
- Update feature branch with latest main
When NOT to Rebase:
- Never rebase public/shared commits
- Can cause conflicts for collaborators
A remote repository is a version of your project hosted on a server. Common scenarios:
- Origin: The default name for the remote you cloned from
- Upstream: The original repository you forked from
- Multiple remotes: Work with multiple servers
# Add GitHub remote
git remote add origin https://github.com/username/repo.git
# Verify remote
git remote -v
# Push to GitHub
git push -u origin main
# Pull from GitHub
git pull origin main1. HTTPS (Personal Access Token)
git clone https://github.com/username/repo.git
# Use token as password when prompted2. SSH
# Generate SSH key
ssh-keygen -t ed25519 -C "your.email@example.com"
# Add key to ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Clone with SSH
git clone git@github.com:username/repo.gitForking Workflow:
- Fork repository on GitHub (creates your copy)
- Clone your fork locally
git clone https://github.com/your-username/repo.git- Add upstream remote
git remote add upstream https://github.com/original-owner/repo.git- Create feature branch and make changes
git checkout -b feature-branch
# Make changes
git commit -am "Add feature"- Push to your fork
git push origin feature-branch-
Create Pull Request on GitHub
-
Sync with upstream
git fetch upstream
git checkout main
git merge upstream/main
git push origin mainCreating a Repository:
- Click "New" on GitHub
- Choose name, description, and visibility
- Initialize with README (optional)
- Add .gitignore and license (optional)
Repository Settings:
- Collaborators and teams
- Branch protection rules
- Webhooks and integrations
- Deploy keys
Pull Requests are proposals to merge changes from one branch to another.
Creating a Pull Request:
- Push your branch to GitHub
- Click "Pull Request" button
- Select base and compare branches
- Add title and description
- Request reviewers
- Submit for review
Pull Request Features:
- Code review and comments
- Inline discussions
- Automated checks (CI/CD)
- Approval workflows
- Merge strategies
Issues are used to track bugs, enhancements, and tasks.
Creating an Issue:
- Go to "Issues" tab
- Click "New Issue"
- Add title and description
- Assign labels, milestones, and assignees
Issue Features:
- Labels (bug, enhancement, documentation)
- Milestones (group related issues)
- Assignees (who's working on it)
- Projects (Kanban boards)
- Templates (standardize issue creation)
Automate workflows with GitHub Actions (CI/CD, testing, deployment).
Example Workflow (.github/workflows/ci.yml):
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: npm testHost static websites directly from repositories.
Enabling GitHub Pages:
- Go to repository Settings
- Navigate to "Pages"
- Select source branch (usually
mainorgh-pages) - Your site will be at
https://username.github.io/repo-name
Built-in wiki for project documentation.
Kanban-style project management boards to organize issues and pull requests.
- Dependabot: Automatic dependency updates
- Security Advisories: Private vulnerability reporting
- Code Scanning: Detect vulnerabilities in code
- Secret Scanning: Find exposed credentials
1. Repository Setup
- Create clear README with project overview
- Add CONTRIBUTING.md with guidelines
- Include LICENSE file
- Set up .gitignore
2. Branch Protection
- Require pull request reviews
- Require status checks to pass
- Enforce linear history
- Restrict who can push to main
3. Code Review Process
- Review code promptly
- Provide constructive feedback
- Approve when ready
- Request changes if needed
4. Communication
- Write clear commit messages
- Provide detailed PR descriptions
- Comment on specific code lines
- Use issue references (#123)
Good Commit Messages:
feat: add user authentication
fix: resolve login timeout issue
docs: update API documentation
style: format code with prettier
refactor: simplify database queries
test: add unit tests for payment module
chore: update dependencies
Conventional Commits Format:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Create .github/pull_request_template.md:
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
How have you tested this?
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex code
- [ ] Documentation updated
- [ ] No new warnings generated
- [ ] Tests added/updated
- [ ] All tests pass- Commit Often: Make small, focused commits
- Write Meaningful Messages: Describe what and why, not how
- Use Branches: Never commit directly to main
- Pull Before Push: Stay synced with remote
- Review Before Committing: Use
git diffandgit status - Keep Commits Atomic: One logical change per commit
- Don't Commit Generated Files: Use .gitignore
- Test Before Committing: Ensure code works
- Document Your Code: Update README and comments
- Be Consistent: Follow team conventions
The .gitignore file specifies files Git should ignore.
Example .gitignore:
# Dependencies
node_modules/
vendor/
# Environment variables
.env
.env.local
# Build outputs
dist/
build/
*.log
# IDE files
.vscode/
.idea/
*.swp
# OS files
.DS_Store
Thumbs.db
# Test coverage
coverage/
Tips:
- Add .gitignore before first commit
- Use templates from gitignore.io
- Don't commit sensitive data (API keys, passwords)
- Never Commit Secrets: Use environment variables
- Use SSH Keys: More secure than HTTPS
- Enable Two-Factor Authentication: On GitHub
- Review Dependencies: Check for vulnerabilities
- Use Branch Protection: Prevent force pushes to main
- Sign Commits: Use GPG keys for verification
- Audit Access: Regularly review collaborators
- Keep Git Updated: Latest version has security fixes
- Use .gitattributes: Configure line endings and diff
- Shallow Clone: For large repositories (
git clone --depth 1) - Git LFS: For large binary files
- Prune Regularly: Remove outdated references (
git prune) - Garbage Collection: Optimize repository (
git gc)
Problem: Remote contains commits you don't have locally.
Solution:
# Pull and merge
git pull origin main
# Or pull and rebase
git pull --rebase origin main
# Then push
git push origin mainProblem: Git cannot automatically merge changes.
Solution:
- Open conflicted files
- Resolve conflicts manually
- Remove conflict markers
- Stage files:
git add <file> - Complete merge:
git commit
Solution:
# Move commit to new branch
git branch new-branch
git reset --hard HEAD~1
git checkout new-branchKeep changes:
git reset --soft HEAD~1Discard changes:
git reset --hard HEAD~1Create reverse commit:
git revert HEADSolution (use with caution):
# Using filter-branch (older method)
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch path/to/file" \
--prune-empty --tag-name-filter cat -- --all
# Using BFG Repo-Cleaner (recommended)
bfg --delete-files sensitive-file.txt
git reflog expire --expire=now --all
git gc --prune=now --aggressiveThen force push:
git push origin --force --allProblem: HEAD is not pointing to a branch tip.
Solution:
# Create branch from current position
git checkout -b new-branch-name
# Or return to branch
git checkout mainProblem: SSH key not configured or recognized.
Solution:
# Test SSH connection
ssh -T git@github.com
# Check SSH key
cat ~/.ssh/id_ed25519.pub
# Add key to ssh-agent
ssh-add ~/.ssh/id_ed25519Problem: File exceeds GitHub's 100MB limit.
Solution:
# Use Git LFS
git lfs install
git lfs track "*.psd"
git add .gitattributes
git add large-file.psd
git commit -m "Add large file with LFS"Hooks are scripts that run automatically at certain points in the Git workflow.
Common Hooks:
pre-commit: Run before commit is createdprepare-commit-msg: Modify commit message templatecommit-msg: Validate commit messagepre-push: Run before pushpost-merge: Run after successful merge
Example pre-commit hook (.git/hooks/pre-commit):
#!/bin/sh
# Run tests before commit
npm testInclude other Git repositories within your repository.
# Add submodule
git submodule add https://github.com/user/repo.git path/to/submodule
# Clone repository with submodules
git clone --recursive https://github.com/user/repo.git
# Update submodules
git submodule update --remote
# Remove submodule
git submodule deinit path/to/submodule
git rm path/to/submoduleWork on multiple branches simultaneously.
# Create worktree
git worktree add ../project-feature feature-branch
# List worktrees
git worktree list
# Remove worktree
git worktree remove ../project-featureApply specific commits from one branch to another.
# Cherry-pick single commit
git cherry-pick <commit-hash>
# Cherry-pick range
git cherry-pick <start-hash>..<end-hash>
# Cherry-pick without committing
git cherry-pick -n <commit-hash>Find which commit introduced a bug using binary search.
# Start bisect
git bisect start
# Mark current commit as bad
git bisect bad
# Mark known good commit
git bisect good <commit-hash>
# Git will checkout middle commit - test it
# Then mark as good or bad
git bisect good # or git bisect bad
# Repeat until bug is found
# Reset when done
git bisect resetRecovery tool that records when branch tips are updated.
# View reflog
git reflog
# Recover lost commit
git checkout <commit-hash>
git checkout -b recovered-branch
# Undo reset
git reset 'HEAD@{1}'Merge with Custom Strategy:
# Use ours strategy
git merge -X ours branch-name
# Use theirs strategy
git merge -X theirs branch-nameRerere (Reuse Recorded Resolution):
# Enable rerere
git config --global rerere.enabled true
# Git will remember conflict resolutionsConfigure behavior per path using .gitattributes.
# Set line endings
*.txt text eol=lf
*.sh text eol=lf
*.bat text eol=crlf
# Mark files as binary
*.png binary
*.jpg binary
# Custom diff for specific files
*.md diff=markdown
# Git LFS
*.psd filter=lfs diff=lfs merge=lfs -text
Git and GitHub are powerful tools that have revolutionized software development and collaboration. This guide covered:
- Git Fundamentals: Version control concepts, repositories, commits, and branches
- GitHub Platform: Cloud hosting, collaboration features, and project management
- Practical Commands: Everyday Git operations and workflows
- Best Practices: Professional development standards and conventions
- Advanced Topics: Hooks, submodules, bisect, and recovery techniques
- Troubleshooting: Common issues and their solutions
Resources:
- Official Git Documentation
- GitHub Guides
- Pro Git Book (free online)
- GitHub Learning Lab
- Git Cheat Sheet
Practice:
- Contribute to open-source projects
- Create personal projects on GitHub
- Practice different workflows
- Experiment with advanced features
- Join developer communities
- Start Simple: Master basics before advancing
- Practice Regularly: Use Git for all projects
- Read Commit History: Learn from others
- Don't Fear Mistakes: Git can recover most things
- Ask Questions: Developer communities are helpful
- Stay Updated: Git evolves with new features
- Document Your Work: Good README files matter
- Collaborate Often: Best way to learn
Remember, becoming proficient with Git and GitHub takes time and practice. Don't be discouraged by mistakes—they're part of the learning process. The more you use these tools, the more natural they'll become.
Happy coding and version controlling!