Git
Distributed version control system for tracking changes in source code during software development.
Git
Distributed version control system for tracking changes in source code during software development.
Overview
Git is a distributed version control system that enables multiple developers to work on a project simultaneously. It tracks changes, maintains history, and facilitates collaboration through branching and merging. Git's distributed nature means every developer has a complete copy of the repository, enabling offline work and reducing single points of failure.
flowchart LR
subgraph "Local Repository"
A[Working Directory] -->|git add| B[Staging Area]
B -->|git commit| C[Local Repository]
end
C -->|git push| D[Remote Repository]
D -->|git pull| A
D -->|git fetch| C
Core Workflow
The fundamental operations for daily git usage.
Initialising and Cloning
# Initialise a new repository in current directory
git init
# Initialise with a specific branch name
git init --initial-branch=main
# Clone a remote repository
git clone https://github.com/user/repo.git
# Clone to a specific directory
git clone https://github.com/user/repo.git my-project
# Clone with limited history (shallow clone)
git clone --depth 1 https://github.com/user/repo.git
# Clone a specific branch
git clone --branch develop https://github.com/user/repo.git
Staging Changes
# Stage a specific file
git add filename.txt
# Stage multiple files
git add file1.txt file2.txt
# Stage all changes in current directory
git add .
# Stage all changes in repository
git add -A
# Stage parts of a file interactively
git add -p filename.txt
# Stage all tracked files (ignores new files)
git add -u
Committing Changes
# Commit with message
git commit -m "Add user authentication feature"
# Commit with multi-line message
git commit -m "Add user authentication" -m "- Implement login endpoint
- Add password hashing
- Create JWT tokens"
# Stage and commit tracked files in one step
git commit -am "Fix validation bug"
# Amend the last commit (don't use if already pushed)
git commit --amend -m "Updated commit message"
# Commit with empty message (not recommended)
git commit --allow-empty-message -m ""
Pushing and Pulling
# Push to remote
git push origin main
# Push and set upstream tracking
git push -u origin feature-branch
# Push all branches
git push --all origin
# Pull changes (fetch + merge)
git pull origin main
# Pull with rebase instead of merge
git pull --rebase origin main
# Force push (use with caution)
git push --force-with-lease origin feature-branch
Branching Strategies
Managing parallel lines of development effectively.
gitGraph
commit id: "Initial"
branch develop
checkout develop
commit id: "Dev work"
branch feature
checkout feature
commit id: "Feature A"
commit id: "Feature B"
checkout develop
merge feature
checkout main
merge develop tag: "v1.0"
Creating and Switching Branches
# Create a new branch
git branch feature-login
# Create and switch to new branch
git checkout -b feature-login
# Modern way to switch branches (Git 2.23+)
git switch feature-login
# Create and switch using switch
git switch -c feature-login
# Create branch from specific commit
git branch hotfix abc1234
# Create branch from remote branch
git checkout -b local-branch origin/remote-branch
Listing and Managing Branches
# List local branches
git branch
# List all branches (local and remote)
git branch -a
# List remote branches only
git branch -r
# List branches with last commit info
git branch -v
# List merged branches
git branch --merged
# List unmerged branches
git branch --no-merged
Merging Branches
# Merge branch into current branch
git merge feature-login
# Merge with commit message
git merge feature-login -m "Merge feature-login into develop"
# Merge without fast-forward (creates merge commit)
git merge --no-ff feature-login
# Abort a merge in progress
git merge --abort
# Squash merge (combine all commits into one)
git merge --squash feature-login
git commit -m "Add login feature"
Deleting Branches
# Delete local branch (safe - prevents deleting unmerged)
git branch -d feature-login
# Force delete local branch
git branch -D feature-login
# Delete remote branch
git push origin --delete feature-login
# Alternative syntax for deleting remote branch
git push origin :feature-login
# Prune stale remote-tracking branches
git fetch --prune
Common Branching Strategies
GitFlow
gitGraph
commit id: "Init"
branch develop
checkout develop
commit id: "Dev"
branch feature/auth
commit id: "Auth"
checkout develop
merge feature/auth
branch release/1.0
commit id: "Release prep"
checkout main
merge release/1.0 tag: "v1.0"
checkout develop
merge release/1.0
- main: Production-ready code
- develop: Integration branch for features
- feature/: New features branch from develop
- release/: Preparation for production release
- hotfix/: Emergency fixes for production
Trunk-Based Development
gitGraph
commit id: "Init"
branch short-lived-feature
commit id: "Small change"
checkout main
merge short-lived-feature
commit id: "Direct commit"
branch another-feature
commit id: "Quick fix"
checkout main
merge another-feature
- Single main branch (trunk)
- Short-lived feature branches (hours to days)
- Frequent integration to main
- Feature flags for incomplete features
Remote Management
Working with remote repositories and collaborating with others.
Adding and Removing Remotes
# Add a remote repository
git remote add origin https://github.com/user/repo.git
# Add additional remote (e.g., for upstream)
git remote add upstream https://github.com/original/repo.git
# Remove a remote
git remote remove upstream
# Rename a remote
git remote rename origin main-repo
# Change remote URL
git remote set-url origin https://github.com/user/new-repo.git
Viewing Remote Information
# List remotes
git remote
# List remotes with URLs
git remote -v
# Show detailed remote info
git remote show origin
# List remote branches
git ls-remote origin
Fetching and Synchronising
# Fetch all branches from remote
git fetch origin
# Fetch a specific branch
git fetch origin develop
# Fetch all remotes
git fetch --all
# Fetch and prune deleted branches
git fetch --prune
# Fetch tags
git fetch --tags
Push and Pull Operations
# Push to specific remote and branch
git push origin feature-branch
# Push to upstream (after -u flag set)
git push
# Pull from specific remote
git pull origin main
# Pull from upstream (fork workflow)
git pull upstream main
# Push tags to remote
git push origin --tags
# Push a specific tag
git push origin v1.0.0
Conflict Resolution
Handling merge conflicts when changes overlap.
flowchart TD
A[Merge/Rebase] --> B{Conflicts?}
B -->|No| C[Auto-merge Complete]
B -->|Yes| D[Manual Resolution]
D --> E[Edit Conflicted Files]
E --> F[Remove Conflict Markers]
F --> G[Stage Resolved Files]
G --> H[Complete Merge/Rebase]
Identifying Conflicts
# Check for conflicts during merge
git merge feature-branch
# Output: CONFLICT (content): Merge conflict in file.txt
# List conflicted files
git status
# Show conflicts in detail
git diff --name-only --diff-filter=U
Resolving Conflicts
Conflict markers in files look like this:
<<<<<<< HEAD
Current branch content
=======
Incoming branch content
>>>>>>> feature-branch
# After manually editing files to resolve conflicts:
# Stage the resolved file
git add resolved-file.txt
# Continue the merge
git commit
# Or abort the merge
git merge --abort
Using Merge Tools
# Open merge tool for all conflicts
git mergetool
# Configure default merge tool
git config --global merge.tool vimdiff
# Use specific merge tool
git mergetool --tool=meld
# Accept current branch version
git checkout --ours filename.txt
# Accept incoming branch version
git checkout --theirs filename.txt
Rebase Conflict Resolution
# During rebase conflicts
git rebase main
# Resolve conflicts in files
# Stage resolved files
git add .
# Continue rebase
git rebase --continue
# Skip current commit
git rebase --skip
# Abort rebase
git rebase --abort
Stashing Changes
Temporarily save uncommitted changes.
Basic Stash Operations
# Stash current changes
git stash
# Stash with descriptive message
git stash push -m "Work in progress: user validation"
# Stash including untracked files
git stash -u
# Stash including ignored files
git stash -a
# Stash specific files
git stash push -m "Partial stash" file1.txt file2.txt
Managing Stashes
# List all stashes
git stash list
# Show stash contents
git stash show
# Show stash contents with diff
git stash show -p stash@{0}
# Apply most recent stash (keep in stash list)
git stash apply
# Apply specific stash
git stash apply stash@{2}
# Apply and remove from stash list
git stash pop
# Pop specific stash
git stash pop stash@{1}
Deleting Stashes
# Drop specific stash
git stash drop stash@{0}
# Clear all stashes
git stash clear
# Create branch from stash
git stash branch new-branch stash@{0}
Viewing History
Examining repository history and changes.
Git Log
# Basic log
git log
# One-line format
git log --oneline
# Graph view
git log --oneline --graph --all
# Limited number of commits
git log -5
# Log with file changes
git log --stat
# Log with full diff
git log -p
# Log for specific file
git log -- filename.txt
# Log by author
git log --author="John"
# Log by date range
git log --since="2024-01-01" --until="2024-06-30"
# Log with custom format
git log --pretty=format:"%h %ad | %s%d [%an]" --date=short
# Search commit messages
git log --grep="bugfix"
# Search code changes
git log -S "function_name"
Git Diff
# Show unstaged changes
git diff
# Show staged changes
git diff --staged
# Compare branches
git diff main..feature-branch
# Compare specific files
git diff HEAD -- filename.txt
# Show only file names
git diff --name-only
# Show stat summary
git diff --stat
# Compare commits
git diff abc1234 def5678
# Compare with remote
git diff origin/main
# Word-level diff
git diff --word-diff
Git Show
# Show commit details
git show abc1234
# Show specific file at commit
git show abc1234:path/to/file.txt
# Show tag details
git show v1.0.0
# Show only file names in commit
git show --name-only abc1234
Git Blame
# Show line-by-line authorship
git blame filename.txt
# Blame specific lines
git blame -L 10,20 filename.txt
# Ignore whitespace changes
git blame -w filename.txt
# Detect lines moved or copied from other files
git blame -C filename.txt
# Show email instead of name
git blame -e filename.txt
Undoing Changes
Reverting and resetting to previous states.
flowchart TD
A[Need to Undo?] --> B{What to undo?}
B -->|Uncommitted changes| C{Staged?}
C -->|No| D[git checkout/restore]
C -->|Yes| E[git reset HEAD]
B -->|Committed locally| F{Shared?}
F -->|No| G[git reset]
F -->|Yes| H[git revert]
B -->|Pushed commits| H
Discarding Uncommitted Changes
# Discard changes in working directory (old way)
git checkout -- filename.txt
# Discard changes (modern way, Git 2.23+)
git restore filename.txt
# Discard all changes in working directory
git restore .
# Unstage a file (keep changes)
git reset HEAD filename.txt
# Unstage using restore
git restore --staged filename.txt
# Discard all uncommitted changes
git reset --hard HEAD
Git Reset
# Soft reset - keep changes staged
git reset --soft HEAD~1
# Mixed reset - keep changes unstaged (default)
git reset HEAD~1
# Hard reset - discard all changes
git reset --hard HEAD~1
# Reset to specific commit
git reset --hard abc1234
# Reset single file to previous state
git reset HEAD~1 -- filename.txt
Git Revert
# Revert a commit (creates new commit)
git revert abc1234
# Revert without committing
git revert --no-commit abc1234
# Revert multiple commits
git revert abc1234 def5678
# Revert a merge commit
git revert -m 1 merge_commit_hash
# Abort revert in progress
git revert --abort
Recovering Lost Commits
# View reflog (history of HEAD changes)
git reflog
# Recover commit from reflog
git checkout abc1234
# Create branch from recovered commit
git branch recovered-branch abc1234
# Show all unreachable objects
git fsck --lost-found
Tags
Marking specific points in history.
Creating Tags
# Create lightweight tag
git tag v1.0.0
# Create annotated tag (recommended)
git tag -a v1.0.0 -m "Release version 1.0.0"
# Tag specific commit
git tag -a v0.9.0 -m "Beta release" abc1234
# Create signed tag (requires GPG)
git tag -s v1.0.0 -m "Signed release"
Listing and Viewing Tags
# List all tags
git tag
# List tags matching pattern
git tag -l "v1.*"
# Show tag details
git show v1.0.0
# Sort tags by version
git tag --sort=-v:refname
Pushing Tags
# Push specific tag
git push origin v1.0.0
# Push all tags
git push origin --tags
# Push only annotated tags
git push origin --follow-tags
Deleting Tags
# Delete local tag
git tag -d v1.0.0
# Delete remote tag
git push origin --delete v1.0.0
# Alternative syntax for remote deletion
git push origin :refs/tags/v1.0.0
Checking Out Tags
# Checkout tag (detached HEAD state)
git checkout v1.0.0
# Create branch from tag
git checkout -b hotfix-1.0.1 v1.0.0
.gitignore Patterns
Excluding files from version control.
Common Patterns
# Ignore specific file
secrets.env
# Ignore all files with extension
*.log
*.tmp
*.pyc
# Ignore directory
node_modules/
__pycache__/
.venv/
dist/
build/
# Ignore files in any directory
**/logs/
**/*.backup
# Ignore files in root only
/config.local.json
# Negate pattern (don't ignore)
!important.log
# Ignore everything except
*
!.gitignore
!src/
!src/**
Language-Specific Examples
# Python
__pycache__/
*.py[cod]
*.egg-info/
.venv/
.env
# JavaScript/Node.js
node_modules/
npm-debug.log
.env.local
# Java
*.class
*.jar
target/
# Go
bin/
pkg/
# IDE files
.idea/
.vscode/
*.swp
*.swo
Managing .gitignore
# Check why file is ignored
git check-ignore -v filename.txt
# List all ignored files
git status --ignored
# Force add ignored file
git add -f ignored-file.txt
# Remove file from tracking but keep locally
git rm --cached filename.txt
Global Gitignore
# Set global gitignore file
git config --global core.excludesfile ~/.gitignore_global
# Common global ignores
# ~/.gitignore_global
.DS_Store
Thumbs.db
*.swp
*~
Useful Aliases and Shortcuts
Streamlining common git operations.
Essential Aliases
# Add aliases to git config
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
# Prettier log
git config --global alias.lg "log --oneline --graph --all --decorate"
# Show branches sorted by last commit
git config --global alias.recent "branch --sort=-committerdate --format='%(committerdate:relative)%09%(refname:short)'"
# Amend without editing message
git config --global alias.amend 'commit --amend --no-edit'
# Undo last commit (keep changes)
git config --global alias.undo 'reset HEAD~1 --mixed'
# List aliases
git config --global alias.aliases "config --get-regexp ^alias\."
Advanced Aliases
# Interactive rebase last n commits
git config --global alias.ri '!f() { git rebase -i HEAD~$1; }; f'
# Delete merged branches
git config --global alias.cleanup '!git branch --merged | grep -v "\\*\\|main\\|master\\|develop" | xargs -n 1 git branch -d'
# Show contributors
git config --global alias.contributors 'shortlog -sn --no-merges'
# Find commits by message
git config --global alias.find '!f() { git log --all --grep="$1"; }; f'
# Show diff stat for last commit
git config --global alias.stat 'diff --stat HEAD~1 HEAD'
Shell Aliases
# Add to ~/.bashrc or ~/.zshrc
alias g='git'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git pull'
alias gs='git status'
alias gd='git diff'
alias gco='git checkout'
alias gb='git branch'
alias glog='git log --oneline --graph --all'
Quick Reference
Most Common Commands
| Command | Description |
|---|---|
git init |
Initialise new repository |
git clone <url> |
Clone remote repository |
git add . |
Stage all changes |
git commit -m "msg" |
Commit with message |
git push |
Push to remote |
git pull |
Pull from remote |
git status |
Show working tree status |
git log --oneline |
Compact history view |
git diff |
Show unstaged changes |
git branch |
List branches |
git checkout -b <name> |
Create and switch branch |
git merge <branch> |
Merge branch into current |
git stash |
Stash current changes |
git stash pop |
Apply and remove stash |
Common Workflows
# Start new feature
git checkout -b feature/new-feature
# ... make changes ...
git add .
git commit -m "Add new feature"
git push -u origin feature/new-feature
# Update feature branch with main
git checkout feature/my-feature
git pull origin main
# or
git rebase main
# Squash commits before merge
git rebase -i HEAD~3
# Change 'pick' to 'squash' for commits to combine
# Clean up after merge
git checkout main
git pull
git branch -d feature/merged-feature
git fetch --prune
Common Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
fatal: not a git repository |
Not in a git repository | Run git init or navigate to correct directory |
error: failed to push some refs |
Remote has changes not in local | Run git pull before pushing |
CONFLICT: Merge conflict |
Overlapping changes in same file | Manually resolve conflicts, then git add and git commit |
fatal: refusing to merge unrelated histories |
Merging repos with no common ancestor | Use git pull origin main --allow-unrelated-histories |
error: Your local changes would be overwritten |
Uncommitted changes conflict with pull | Stash changes: git stash, pull, then git stash pop |
HEAD detached at |
Checked out a commit, not a branch | Create branch: git checkout -b new-branch |
Permission denied (publickey) |
SSH key not configured | Add SSH key to Git hosting service |
fatal: remote origin already exists |
Remote already configured | Use git remote set-url origin <new-url> |
| Large file prevents push | File exceeds size limit | Add to .gitignore, use Git LFS, or remove from history |
| Accidentally committed secrets | Sensitive data in commit | Remove from history with git filter-branch or BFG Repo-Cleaner |
Fixing Common Mistakes
# Committed to wrong branch
git reset HEAD~1 --soft
git stash
git checkout correct-branch
git stash pop
git commit
# Need to change last commit message
git commit --amend -m "New message"
# Forgot to add file to last commit
git add forgotten-file.txt
git commit --amend --no-edit
# Remove file from last commit
git reset HEAD~1 --soft
git reset HEAD unwanted-file.txt
git commit -c ORIG_HEAD
# Revert to previous version of file
git checkout HEAD~1 -- filename.txt
Related Topics
To build on your git knowledge, consider exploring these related topics:
- Jenkins - CI/CD automation server that integrates with git for automated builds, tests, and deployments
- ArgoCD - GitOps continuous delivery tool for Kubernetes that uses git as the source of truth
- CI/CD Patterns - Pipeline design patterns, branching strategies, and deployment workflows that complement git usage
- GitHub Actions / GitLab CI - Native CI/CD platforms that trigger workflows based on git events
- Container Security - Scanning and securing containerised applications in your git-based pipelines
- Helm - Kubernetes package manager often used alongside git for GitOps workflows