Skip to content

Git Tutorial

Learn Git version control system from basics to advanced workflows, including branching strategies, collaboration, and best practices for modern development.

Overview

Git is a distributed version control system that tracks changes in source code during software development. It's designed for coordinating work among programmers and tracking changes in any set of files.

Git Fundamentals

What is Git?

  • Distributed Version Control: Every developer has a complete copy of the project history
  • Branching and Merging: Lightweight branching for parallel development
  • Data Integrity: Everything is checksummed using SHA-1 hash
  • Speed: Most operations are local and fast
  • Staging Area: Intermediate area for preparing commits

Git Workflow

Working Directory → Staging Area → Local Repository → Remote Repository
     (git add)        (git commit)      (git push)

Installation

bash
# Ubuntu/Debian
sudo apt update
sudo apt install git

# macOS (using Homebrew)
brew install git

# Windows
# Download from https://git-scm.com

# Verify installation
git --version

Initial Configuration

bash
# Set global username and email
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Set default branch name
git config --global init.defaultBranch main

# Set default editor
git config --global core.editor "code --wait"

# View configuration
git config --list
git config --global --list

Basic Git Commands

Repository Initialization

bash
# Initialize new repository
git init

# Clone existing repository
git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-project

# Clone specific branch
git clone -b develop https://github.com/user/repo.git

Basic Workflow

bash
# Check repository status
git status

# Add files to staging area
git add file.txt
git add .                    # Add all files
git add *.js                 # Add all JavaScript files
git add src/                 # Add entire directory

# Commit changes
git commit -m "Add new feature"
git commit -am "Update and commit all tracked files"

# View commit history
git log
git log --oneline
git log --graph --oneline --all

Working with Files

bash
# View differences
git diff                     # Working directory vs staging area
git diff --staged           # Staging area vs last commit
git diff HEAD               # Working directory vs last commit
git diff commit1 commit2    # Between two commits

# Remove files
git rm file.txt             # Remove from working directory and staging
git rm --cached file.txt    # Remove from staging only

# Move/rename files
git mv old-name.txt new-name.txt

# Restore files
git restore file.txt        # Discard changes in working directory
git restore --staged file.txt  # Unstage file
git checkout -- file.txt    # Old syntax for restore

Branching and Merging

Branch Management

bash
# List branches
git branch                  # Local branches
git branch -r              # Remote branches
git branch -a              # All branches

# Create branch
git branch feature-branch
git checkout -b feature-branch  # Create and switch
git switch -c feature-branch    # New syntax

# Switch branches
git checkout main
git switch main            # New syntax

# Delete branch
git branch -d feature-branch    # Safe delete
git branch -D feature-branch    # Force delete
git push origin --delete feature-branch  # Delete remote branch

Merging Strategies

bash
# Fast-forward merge
git checkout main
git merge feature-branch

# No fast-forward merge (creates merge commit)
git merge --no-ff feature-branch

# Squash merge (combine all commits into one)
git merge --squash feature-branch
git commit -m "Add feature from feature-branch"

# Rebase (replay commits on top of another branch)
git checkout feature-branch
git rebase main

Merge Conflicts

bash
# When conflicts occur during merge
git status                 # See conflicted files

# Edit conflicted files manually, then:
git add conflicted-file.txt
git commit                 # Complete the merge

# Abort merge if needed
git merge --abort

# Use merge tools
git mergetool

Remote Repositories

Remote Management

bash
# List remotes
git remote
git remote -v

# Add remote
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git

# Change remote URL
git remote set-url origin https://github.com/user/new-repo.git

# Remove remote
git remote remove origin

Push and Pull

bash
# Push to remote
git push origin main
git push -u origin main    # Set upstream tracking
git push --all             # Push all branches
git push --tags            # Push all tags

# Pull from remote
git pull origin main       # Fetch and merge
git pull --rebase origin main  # Fetch and rebase

# Fetch without merging
git fetch origin
git fetch --all

Tracking Branches

bash
# Set upstream branch
git branch --set-upstream-to=origin/main main
git push -u origin main

# Create tracking branch
git checkout -b local-branch origin/remote-branch
git switch -c local-branch origin/remote-branch

Advanced Git Features

Stashing

bash
# Stash changes
git stash
git stash push -m "Work in progress"
git stash -u               # Include untracked files

# List stashes
git stash list

# Apply stash
git stash apply            # Apply latest stash
git stash apply stash@{2}  # Apply specific stash
git stash pop              # Apply and remove latest stash

# Drop stash
git stash drop stash@{1}
git stash clear            # Remove all stashes

Tagging

bash
# Create lightweight tag
git tag v1.0.0

# Create annotated tag
git tag -a v1.0.0 -m "Version 1.0.0 release"

# Tag specific commit
git tag -a v1.0.0 9fceb02 -m "Version 1.0.0"

# List tags
git tag
git tag -l "v1.*"

# Push tags
git push origin v1.0.0
git push origin --tags

# Delete tag
git tag -d v1.0.0
git push origin --delete v1.0.0

Rewriting History

bash
# Interactive rebase
git rebase -i HEAD~3       # Rebase last 3 commits

# Amend last commit
git commit --amend -m "Updated commit message"
git commit --amend --no-edit  # Add changes to last commit

# Reset commits
git reset --soft HEAD~1    # Keep changes staged
git reset --mixed HEAD~1   # Keep changes unstaged (default)
git reset --hard HEAD~1    # Discard changes completely

# Cherry-pick commits
git cherry-pick commit-hash
git cherry-pick commit1..commit3

Searching and Debugging

bash
# Search in code
git grep "function"
git grep -n "TODO"         # Show line numbers

# Find when bug was introduced
git bisect start
git bisect bad             # Current commit is bad
git bisect good v1.0.0     # Known good commit
# Git will checkout commits for testing
git bisect good            # Mark as good
git bisect bad             # Mark as bad
git bisect reset           # End bisect session

# Show commit that last modified each line
git blame file.txt
git blame -L 10,20 file.txt  # Specific lines

Git Workflows

Feature Branch Workflow

bash
# 1. Create feature branch
git checkout main
git pull origin main
git checkout -b feature/user-authentication

# 2. Work on feature
git add .
git commit -m "Add user login functionality"
git push -u origin feature/user-authentication

# 3. Create pull request (on GitHub/GitLab)
# 4. After review, merge to main
git checkout main
git pull origin main
git branch -d feature/user-authentication

Gitflow Workflow

bash
# Initialize gitflow
git flow init

# Start new feature
git flow feature start new-feature

# Finish feature
git flow feature finish new-feature

# Start release
git flow release start 1.0.0

# Finish release
git flow release finish 1.0.0

# Start hotfix
git flow hotfix start critical-fix

# Finish hotfix
git flow hotfix finish critical-fix

Forking Workflow

bash
# 1. Fork repository on GitHub
# 2. Clone your fork
git clone https://github.com/yourusername/repo.git
cd repo

# 3. Add upstream remote
git remote add upstream https://github.com/original/repo.git

# 4. Create feature branch
git checkout -b feature-branch

# 5. Make changes and commit
git add .
git commit -m "Add new feature"

# 6. Push to your fork
git push origin feature-branch

# 7. Create pull request
# 8. Keep fork updated
git fetch upstream
git checkout main
git merge upstream/main
git push origin main

Git Configuration

Global Configuration

bash
# User information
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Editor and diff tool
git config --global core.editor "code --wait"
git config --global merge.tool vimdiff

# Line ending handling
git config --global core.autocrlf true    # Windows
git config --global core.autocrlf input   # macOS/Linux

# Default branch name
git config --global init.defaultBranch main

# 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 --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'

Repository-specific Configuration

bash
# Set configuration for current repository only
git config user.email "work@company.com"
git config core.filemode false

# View configuration
git config --list
git config user.name

.gitignore File

bash
# Create .gitignore file
touch .gitignore

# Common .gitignore patterns
echo "node_modules/" >> .gitignore
echo "*.log" >> .gitignore
echo ".env" >> .gitignore
echo "dist/" >> .gitignore
echo ".DS_Store" >> .gitignore

Example .gitignore:

gitignore
# Dependencies
node_modules/
npm-debug.log*

# Production builds
dist/
build/

# Environment variables
.env
.env.local
.env.production

# IDE files
.vscode/
.idea/
*.swp
*.swo

# OS generated files
.DS_Store
Thumbs.db

# Logs
*.log
logs/

# Runtime data
pids/
*.pid
*.seed

Git Hooks

Client-side Hooks

bash
# Navigate to hooks directory
cd .git/hooks

# Pre-commit hook example
cat > pre-commit << 'EOF'
#!/bin/sh
# Run tests before commit
npm test
if [ $? -ne 0 ]; then
    echo "Tests failed. Commit aborted."
    exit 1
fi
EOF

chmod +x pre-commit

Server-side Hooks

bash
# Pre-receive hook (runs on server)
cat > pre-receive << 'EOF'
#!/bin/sh
# Reject pushes to main branch
while read oldrev newrev refname; do
    if [ "$refname" = "refs/heads/main" ]; then
        echo "Direct pushes to main branch are not allowed"
        exit 1
    fi
done
EOF

chmod +x pre-receive

Git Best Practices

Commit Messages

bash
# Good commit message format
git commit -m "feat: add user authentication system

- Implement JWT token generation
- Add login/logout endpoints
- Create user session management
- Add password hashing with bcrypt

Closes #123"

# Conventional commit types
# feat: new feature
# fix: bug fix
# docs: documentation changes
# style: formatting changes
# refactor: code refactoring
# test: adding tests
# chore: maintenance tasks

Branch Naming

bash
# Good branch names
feature/user-authentication
bugfix/login-error
hotfix/security-patch
release/v1.2.0
docs/api-documentation

# Avoid
fix
new-stuff
temp

Repository Organization

bash
# Good repository structure
project/
├── .gitignore
├── README.md
├── package.json
├── src/
   ├── components/
   ├── utils/
   └── index.js
├── tests/
├── docs/
└── scripts/

Troubleshooting

Common Issues

bash
# Undo last commit (keep changes)
git reset --soft HEAD~1

# Undo last commit (discard changes)
git reset --hard HEAD~1

# Fix wrong commit message
git commit --amend -m "Correct message"

# Remove file from last commit
git reset --soft HEAD~1
git reset HEAD file-to-remove.txt
git commit -c ORIG_HEAD

# Recover deleted branch
git reflog
git checkout -b recovered-branch commit-hash

# Clean untracked files
git clean -n               # Dry run
git clean -f               # Remove files
git clean -fd              # Remove files and directories

Performance Optimization

bash
# Garbage collection
git gc --aggressive

# Prune remote branches
git remote prune origin

# Reduce repository size
git filter-branch --tree-filter 'rm -rf large-file' HEAD
git push --force

# Use shallow clone for large repositories
git clone --depth 1 https://github.com/user/large-repo.git

Security

bash
# Sign commits with GPG
git config --global user.signingkey YOUR_GPG_KEY_ID
git config --global commit.gpgsign true
git commit -S -m "Signed commit"

# Verify signatures
git log --show-signature

# Remove sensitive data
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch secrets.txt' \
--prune-empty --tag-name-filter cat -- --all

# Use credential helper
git config --global credential.helper store
git config --global credential.helper cache

Git GUI Tools

Command Line Tools

bash
# Git built-in GUI
gitk                       # Repository browser
git gui                    # Staging and commit GUI

# Third-party CLI tools
tig                        # Text-mode interface
lazygit                    # Terminal UI

Desktop Applications

  • GitHub Desktop: User-friendly Git client
  • SourceTree: Free Git client by Atlassian
  • GitKraken: Cross-platform Git client
  • Tower: Professional Git client (macOS/Windows)
  • Fork: Fast and friendly Git client

IDE Integration

  • VS Code: Built-in Git support with extensions
  • IntelliJ IDEA: Comprehensive Git integration
  • Sublime Text: Git plugins available
  • Atom: Git and GitHub integration

This comprehensive Git tutorial covers version control from basics to advanced workflows. Practice with real projects to master these concepts and improve your development workflow.

VitePress Development Guide