Available for day contractsFrom 21st September I have availability for day and half day contracts. Please contact for more information.

Contact →
mikepreston.org

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.

Local Repositorygit addgit commitgit pushgit pullgit fetchWorking DirectoryStaging AreaLocal RepositoryRemote RepositoryLocal Repositorygit addgit commitgit pushgit pullgit fetchWorking DirectoryStaging AreaLocal RepositoryRemote Repository

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.

maindevelopfeatureInitialDev workFeature AFeature Bv1.0maindevelopfeatureInitialDev workFeature AFeature Bv1.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

maindevelopfeature/authrelease/1.0InitDevAuthRelease prepv1.0maindevelopfeature/authrelease/1.0InitDevAuthRelease prepv1.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

mainshort-lived-featureanother-featureInitSmall changeDirect commitQuick fixmainshort-lived-featureanother-featureInitSmall changeDirect commitQuick fix
  • 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.

NoYesMerge/RebaseConflicts?Auto-merge CompleteManual ResolutionEdit ConflictedFilesRemove ConflictMarkersStage Resolved FilesCompleteMerge/RebaseNoYesMerge/RebaseConflicts?Auto-merge CompleteManual ResolutionEdit ConflictedFilesRemove ConflictMarkersStage Resolved FilesCompleteMerge/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.

Uncommitted changesNoYesCommitted locallyNoYesPushed commitsNeed to Undo?What to undo?Staged?git checkout/restoregit reset HEADShared?git resetgit revertUncommitted changesNoYesCommitted locallyNoYesPushed commitsNeed to Undo?What to undo?Staged?git checkout/restoregit reset HEADShared?git resetgit revert

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