- Git Basics
- Repository Setup
- Basic Workflow
- Branching & Merging
- Remote Repositories
- Commit Management
- Cherry Picking
- Authorship & Attribution
- Advanced Commands
- GitHub Integration
- Useful Tricks & Tips
- Troubleshooting
Git is a distributed version control system that tracks changes in files and coordinates work between multiple people. It's essential for software development and project management.
- Version Control: Track all changes to your code over time
- Collaboration: Multiple developers can work on the same project
- Backup: Distributed nature provides automatic backups
- Branching: Create separate lines of development
- History: Complete audit trail of all changes
# Create a new Git repository in current directory
git init
# Create a new directory and initialize Git
git init my-project
cd my-project# Clone from GitHub/GitLab/etc.
git clone https://github.com/username/repository.git
# Clone to a specific directory
git clone https://github.com/username/repository.git my-folder
# Clone only specific branch
git clone -b branch-name https://github.com/username/repository.git
# Shallow clone (only recent history)
git clone --depth 1 https://github.com/username/repository.git# Set global user information
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Set local user information (for current repo only)
git config user.name "Your Name"
git config user.email "your.email@example.com"
# View current configuration
git config --list
git config user.name
git config user.email
# Set default editor
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim" # Vim
# Set default branch name
git config --global init.defaultBranch main# Check repository status
git status
# Short status format
git status -s
# Check ignored files too
git status --ignored# Add specific file
git add filename.txt
# Add multiple files
git add file1.txt file2.txt
# Add all files in current directory
git add .
# Add all modified files
git add -u
# Add all files (new, modified, deleted)
git add -A
# Interactive adding
git add -i
# Add parts of a file (patch mode)
git add -p filename.txt# Basic commit
git commit -m "Your commit message"
# Commit with detailed message
git commit -m "Short description" -m "Longer explanation of changes"
# Add and commit in one step (tracked files only)
git commit -am "Commit message"
# Amend the last commit
git commit --amend -m "New commit message"
# Commit with different author
git commit --author="Name <email@example.com>" -m "Message"
# Empty commit (useful for triggering CI)
git commit --allow-empty -m "Trigger build"# View commit history
git log
# Compact one-line format
git log --oneline
# Show last N commits
git log -n 5
# Show commits with file changes
git log --stat
# Show commits with full diff
git log -p
# Graphical representation
git log --graph --oneline --all
# Filter by author
git log --author="John Doe"
# Filter by date
git log --since="2023-01-01" --until="2023-12-31"
# Filter by message
git log --grep="bug fix"
# Show commits that modified specific file
git log -- filename.txt# List all branches
git branch
# List all branches (including remote)
git branch -a
# Create new branch
git branch new-feature
# Create and switch to new branch
git checkout -b new-feature
# Modern way to create and switch
git switch -c new-feature
# Switch to existing branch
git checkout main
git switch main
# Rename current branch
git branch -m new-name
# Rename specific branch
git branch -m old-name new-name
# Delete branch
git branch -d feature-branch
# Force delete branch
git branch -D feature-branch
# Delete remote branch
git push origin --delete feature-branch# Merge branch into current branch
git merge feature-branch
# Merge with no fast-forward (always create merge commit)
git merge --no-ff feature-branch
# Merge with squash (combine all commits into one)
git merge --squash feature-branch
# Abort merge if conflicts
git merge --abort# Rebase current branch onto main
git rebase main
# Interactive rebase (last 3 commits)
git rebase -i HEAD~3
# Continue rebase after resolving conflicts
git rebase --continue
# Skip current commit during rebase
git rebase --skip
# Abort rebase
git rebase --abort
# Rebase onto specific commit
git rebase commit-hash# List remotes
git remote -v
# Add remote
git remote add origin https://github.com/username/repository.git
# Change remote URL
git remote set-url origin https://github.com/username/new-repository.git
# Remove remote
git remote remove origin
# Rename remote
git remote rename origin upstream# Fetch changes from remote
git fetch origin
# Fetch all remotes
git fetch --all
# Pull changes (fetch + merge)
git pull origin main
# Pull with rebase instead of merge
git pull --rebase origin main
# Set upstream branch
git push -u origin main
git branch --set-upstream-to=origin/main main# Push to remote
git push origin main
# Push all branches
git push --all origin
# Push tags
git push --tags
# Force push (dangerous!)
git push --force origin main
# Force push with lease (safer)
git push --force-with-lease origin main
# Push and set upstream
git push -u origin feature-branch# Show unstaged changes
git diff
# Show staged changes
git diff --cached
# Show changes between commits
git diff commit1 commit2
# Show changes in specific file
git diff filename.txt
# Show changes between branches
git diff main..feature-branch
# Word-level diff
git diff --word-diff# Unstage file
git reset HEAD filename.txt
# Discard unstaged changes
git checkout -- filename.txt
git restore filename.txt
# Discard all unstaged changes
git checkout -- .
git restore .
# Reset to last commit (keep changes staged)
git reset --soft HEAD~1
# Reset to last commit (unstage changes)
git reset HEAD~1
# Reset to last commit (discard all changes)
git reset --hard HEAD~1
# Reset to specific commit
git reset --hard commit-hash# Stash current changes
git stash
# Stash with message
git stash save "Work in progress"
# List stashes
git stash list
# Apply most recent stash
git stash apply
# Apply specific stash
git stash apply stash@{1}
# Apply and remove from stash list
git stash pop
# Drop specific stash
git stash drop stash@{1}
# Clear all stashes
git stash clear
# Stash including untracked files
git stash -uCherry picking allows you to apply specific commits from one branch to another without merging the entire branch.
# Cherry pick a specific commit
git cherry-pick commit-hash
# Cherry pick multiple commits
git cherry-pick commit1 commit2 commit3
# Cherry pick a range of commits
git cherry-pick commit1..commit3
# Cherry pick without committing
git cherry-pick --no-commit commit-hash# Cherry pick and edit commit message
git cherry-pick -e commit-hash
# Cherry pick without changing author
git cherry-pick -x commit-hash
# Cherry pick and sign off
git cherry-pick -s commit-hash
# Continue cherry pick after resolving conflicts
git cherry-pick --continue
# Abort cherry pick
git cherry-pick --abort
# Skip current commit
git cherry-pick --skip# Cherry pick from another branch
git cherry-pick feature-branch~2
# Cherry pick merge commit (specify parent)
git cherry-pick -m 1 merge-commit-hash
# Cherry pick and change author
git cherry-pick --author="New Author <email@example.com>" commit-hash# Set author for next commit only
git -c user.name="John Doe" -c user.email="john@example.com" commit -m "Message"
# Commit with specific author
git commit --author="John Doe <john@example.com>" -m "Message"
# Commit on behalf of someone (co-authored)
git commit -m "Fix bug
Co-authored-by: Jane Smith <jane@example.com>"# Change author of last commit
git commit --amend --author="New Author <email@example.com>"
# Change author of multiple commits (interactive rebase)
git rebase -i HEAD~3
# In the editor, change 'pick' to 'edit' for commits to modify
# For each commit:
git commit --amend --author="New Author <email@example.com>"
git rebase --continue# Show commits with author info
git log --pretty=format:"%h %an %ae %ad %s"
# Show commits by specific author
git log --author="John Doe"
# Show commits with committer vs author
git log --pretty=format:"%h %an %cn %ad %cd %s"
# Shortlog grouped by author
git shortlog# Multiple co-authors
git commit -m "Implement feature X
Co-authored-by: Alice <alice@example.com>
Co-authored-by: Bob <bob@example.com>"# Create lightweight tag
git tag v1.0.0
# Create annotated tag
git tag -a v1.0.0 -m "Version 1.0.0"
# Tag specific commit
git tag -a v1.0.0 commit-hash
# List tags
git tag
# Show tag information
git show v1.0.0
# 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# Show who last modified each line
git blame filename.txt
# Show blame for specific lines
git blame -L 10,20 filename.txt
# Show blame ignoring whitespace changes
git blame -w filename.txt# Start bisect
git bisect start
# Mark current commit as bad
git bisect bad
# Mark known good commit
git bisect good commit-hash
# Mark current as good/bad and continue
git bisect good
git bisect bad
# End bisect session
git bisect reset
# Automate bisect with script
git bisect run test-script.sh# Create new worktree
git worktree add ../feature-branch feature-branch
# List worktrees
git worktree list
# Remove worktree
git worktree remove ../feature-branch
# Prune deleted worktrees
git worktree prune# Install: https://cli.github.com/
# Authenticate
gh auth login
# Create repository
gh repo create my-project
# Clone your repositories
gh repo clone username/repository
# Create pull request
gh pr create --title "Feature X" --body "Description"
# List pull requests
gh pr list
# View pull request
gh pr view 123
# Merge pull request
gh pr merge 123# Fetch pull request locally
git fetch origin pull/123/head:pr-123
git checkout pr-123
# Push branch for pull request
git push origin feature-branch
# Then create PR on GitHub web interface# Trigger workflow with empty commit
git commit --allow-empty -m "Trigger CI"
# Push specific branch to trigger workflow
git push origin feature-branch# Create useful 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'
git config --global alias.hist 'log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short'
# Use aliases
git st # Same as git status
git co main # Same as git checkout main
git hist # Pretty formatted log# Show files changed in last commit
git diff-tree --no-commit-id --name-only -r HEAD
# Count commits by author
git shortlog -sn
# Find commits that added or removed specific text
git log -S "function_name" --oneline
# Show commits not yet pushed
git log origin/main..HEAD --oneline
# Show commits in main that aren't in current branch
git log HEAD..origin/main --oneline
# Undo last commit but keep changes
git reset --soft HEAD~1
# Create patch file
git diff > changes.patch
# Apply patch file
git apply changes.patch
# Show current branch name
git rev-parse --abbrev-ref HEAD# Create .gitignore file
echo "node_modules/" >> .gitignore
echo "*.log" >> .gitignore
echo ".env" >> .gitignore
# Common .gitignore patterns
*.log # Ignore all .log files
/node_modules # Ignore node_modules directory in root
*.tmp # Ignore all .tmp files
!important.log # Don't ignore important.log
build/ # Ignore build directory
.env* # Ignore all .env files
# Check if file is ignored
git check-ignore filename.txt
# Track previously ignored file
git add -f filename.txt# Remove untracked files
git clean -f
# Remove untracked files and directories
git clean -fd
# Dry run (show what would be deleted)
git clean -n
# Remove ignored files too
git clean -fx
# Prune remote branches
git remote prune origin
# Delete merged branches
git branch --merged | grep -v "\*\|main\|master" | xargs -n 1 git branch -d# When merge conflicts occur:
# 1. Open conflicted files and resolve conflicts
# 2. Mark as resolved
git add conflicted-file.txt
# 3. Complete merge
git commit
# Or use merge tools
git mergetool# Move commits to correct branch
git log --oneline -n 3 # Note commit hashes
git reset --hard HEAD~3 # Remove commits from current branch
git checkout correct-branch
git cherry-pick commit1 commit2 commit3# Find lost commits
git reflog
# Recover lost commit
git checkout commit-hash
git branch recovered-branch # Create branch to save it# Remove large file from history
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch largefile.zip' \
--prune-empty --tag-name-filter cat -- --all
# Or use BFG Repo-Cleaner (recommended)
# https://rtyley.github.io/bfg-repo-cleaner/# When push is rejected due to non-fast-forward:
# Option 1: Pull and merge
git pull origin main
# Option 2: Pull with rebase
git pull --rebase origin main
# Option 3: Force push (dangerous!)
git push --force-with-lease origin main# View reference log
git reflog
# Recover deleted branch
git checkout -b recovered-branch HEAD@{1}
# Undo last action
git reset HEAD@{1}
# Find dangling commits
git fsck --lost-found- Use imperative mood ("Add feature" not "Added feature")
- Keep first line under 50 characters
- Separate subject from body with blank line
- Explain what and why, not how
- Use descriptive branch names (feature/user-auth, bugfix/login-error)
- Keep branches short-lived
- Regularly sync with main branch
- Delete merged branches
- Never commit sensitive information (passwords, API keys)
- Use .gitignore for sensitive files
- Review commits before pushing
- Use signed commits for important repositories
# Enable commit signing
git config --global commit.gpgsign true
git config --global user.signingkey YOUR_GPG_KEY_IDThis guide covers the essential Git commands and concepts you'll need for effective version control and collaboration. Keep practicing these commands to build muscle memory and become proficient with Git!