Git

Git is a distributed version control system that helps track changes in source code during software development. Here's a comprehensive guide to get you started with Git.

Basic Concepts

  1. Repository (Repo): A storage location for your project containing all files and version history

  2. Commit: A snapshot of your changes at a specific point in time

  3. Branch: A separate line of development

  4. Remote: A repository hosted on the internet (like GitHub, GitLab)

  5. Working Directory: Your local project folder

  6. Staging Area: A place where changes are prepared before committing

Essential Commands

Setup and Configuration

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

Starting a Project

# Initialize a new repository
git init

# Initialize a bare repository (for servers)
git init --bare
# A bare repository contains no working directory and is typically used as a remote repository

# Clone an existing repository
git clone <repository-url>

Basic Workflow

# Check status of your files
git status

# Add files to staging area
git add <filename>    # Add specific file
git add .            # Add all files

# Commit changes
git commit -m "Your commit message"

# View commit history
git log

# View condensed commit history (one line per commit)
git log --oneline

# Show only the names of files that changed in each commit
git log --name-only

# Show branch and merge history as a text-based graph
git log --graph --decorate

# Combine options for a nice branch visualization
git log --graph --decorate --oneline --all

Working with Branches

# Create a new branch
git branch <branch-name>

# Switch to a branch
git checkout <branch-name>

# Create and switch to a new branch
git checkout -b <branch-name>

# List all branches
git branch

Remote Operations

# Add a remote repository
git remote add origin <repository-url>

# Push changes to remote
git push origin <branch-name>

# Pull changes from remote
git pull origin <branch-name>

# Fetch changes without merging
git fetch

Common Operations

# View differences
git diff

# Discard changes in working directory
git checkout -- <filename>

# Remove files from staging area
git reset HEAD <filename>

# Merge branches
git merge <branch-name>
# Fast-forward merge (default when possible)
git merge <branch-name>
# Creates a linear history, moving the base branch pointer forward

# No-fast-forward merge (forces a merge commit)
git merge --no-ff <branch-name>
# Always creates a merge commit, preserving branch history

Git Objects and Internals

# Blob Objects - Store file content
git hash-object <file>     # Calculate hash of file content
git hash-object -w <file>  # Write blob object to Git database

# Tree Objects - Store directory structure
git write-tree            # Write current index as tree object
git ls-tree <tree-hash>   # List contents of a tree object

# Commit Objects - Store commit information
git commit-tree <tree-hash> -m "message"  # Create commit object
git cat-file -p <hash>    # Show object content
git cat-file -t <hash>    # Show object type

# Object Types
# - blob: File content
# - tree: Directory listing
# - commit: Commit information
# - tag: Annotated tag

# View object database
git count-objects         # Count objects in database
git verify-pack -v .git/objects/pack/pack-*.idx  # List packed objects

# Pack Objects
git gc                    # Pack loose objects
git prune                 # Remove unreachable objects

# References
git show-ref             # List all references
git update-ref refs/heads/master <commit-hash>  # Update reference

# Low-level object manipulation
git mktree < <file>      # Create tree from listing
git read-tree <tree-hash>  # Read tree into index

Stashing and Recovery

# Basic stash operations
git stash                    # Stash changes (same as git stash push)
git stash save "message"     # Stash with a descriptive message
git stash list              # List all stashes
git stash show stash@{n}    # Show contents of specific stash
git stash pop               # Apply and remove latest stash
git stash apply stash@{n}   # Apply specific stash without removing it
git stash drop stash@{n}    # Delete a specific stash
git stash clear             # Remove all stashes

# Stash including untracked files
git stash -u
# or
git stash --include-untracked

# Stash partial changes
git stash -p               # Interactively choose which changes to stash

# Create a branch from stash
git stash branch <branch-name> stash@{n}

Reflog - Recovery and History

# View reflog
git reflog
# Shows a log of all HEAD changes including resets, merges, rebases

# Detailed reflog
git reflog --date=iso      # Show dates in ISO format
git reflog show <branch>   # Show reflog for specific branch

# Recover lost commits
git reset --hard HEAD@{n}  # Reset to nth reflog entry
git checkout HEAD@{n}      # Checkout specific reflog state

# Recover after hard reset
git reset --hard HEAD@{1}  # Go back to state before reset

# Recover deleted branch
git reflog                 # Find hash of branch tip
git checkout -b <branch-name> <hash>  # Recreate branch

# Clean up old reflog entries
git reflog expire --expire=30.days.ago
git gc --prune=now        # Remove unreachable objects

Reset and History Changes

# Soft reset - keeps changes in staging area
git reset --soft HEAD~1
# Undoes last commit but keeps changes staged

# Mixed reset (default) - keeps changes in working directory
git reset HEAD~1
# or
git reset --mixed HEAD~1
# Undoes last commit and unstages changes

# Hard reset - discards all changes
git reset --hard HEAD~1
# WARNING: Permanently removes commits and all changes

# Reset to specific commit
git reset --hard <commit-hash>
# WARNING: Discards all commits after specified commit

# Reset a specific file from staging area
git reset HEAD <filename>
# Unstages the file but keeps changes

# Show reflog (useful for recovering lost commits)
git reflog
# Shows history of HEAD changes

Rebasing and History Manipulation

# Basic rebase
git rebase <branch-name>
# Moves your commits to the tip of the specified branch

# Interactive rebase
git rebase -i HEAD~n  # n is the number of commits to show
# Opens editor to modify the last n commits

# Common interactive rebase commands:
# pick (p)   - keep the commit as is
# squash (s) - combine commit with previous commit
# drop (d)   - remove the commit
# edit (e)   - pause for amending
# reword (r) - change commit message

# Example of squashing last 3 commits
git rebase -i HEAD~3

# Cherry-pick a specific commit
git cherry-pick <commit-hash>
# Applies changes from a specific commit to current branch

# Abort a rebase if you run into conflicts
git rebase --abort

# Continue rebase after resolving conflicts
git rebase --continue

Best Practices

  1. Write clear, descriptive commit messages

  2. Commit frequently with logical chunks of work

  3. Keep your branches up to date

  4. Use meaningful branch names

  5. Review changes before committing

  6. Don't commit sensitive information

Advanced Topics

  • Interactive rebase

  • Resolving merge conflicts

  • Git hooks

  • Git workflows (like Git Flow)

Additional Resources

Last updated

Was this helpful?