---
title: "Git"
description: "Git is a distributed version control system for tracking code changes, collaborating with teams, and managing project history."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/cheatsheets/git
---

# Git

Git is a distributed version control system that enables developers to track code changes, collaborate with teams, and manage project history efficiently. It's the foundation of modern software development workflows.

## Key Concepts

- **Distributed**: Every developer has a complete copy of the repository history
- **Branching**: Create isolated lines of development for features and fixes
- **Commits**: Snapshots of changes with descriptive messages
- **Merging**: Combine changes from different branches
- **Tracking**: Monitor changes across files and identify who changed what

## Common Use Cases

1. **Collaborative Development**: Multiple developers working on same project
2. **Version Control**: Track all changes with full history
3. **Branching Strategy**: Feature branches, release branches, hotfix branches
4. **Code Review**: Pull requests and merge reviews before integration
5. **Rollback Capability**: Revert to previous states if needed

## Quick Reference

**Initial Setup**: Configure your identity with `git config --global user.name` and `user.email`

**Start Project**: Use `git init` for new repos or `git clone` to download existing

**Save Work**: `git add` files, then `git commit -m "message"` to create snapshots

**Share Changes**: `git push` to upload, `git pull` to download updates

Browse the sections above to master Git workflows, from basic commands to advanced techniques for managing complex projects.

## Getting Started

Initialize repositories and configure Git for your first use.

### Git Configuration

Set up your Git identity and configure global preferences.

**Keywords:** config, identity, email, username, preferences

#### Set user identity

```bash
# Configure user name and email
git config --global user.name "John Doe"
git config --global user.email "john@example.com"

# Configure for specific project only
git config --local user.name "John Doe"
git config --local user.email "john@example.com"
```

_exec_
```bash
git config --global user.name
```

_output_
```bash
John Doe
```

Sets the name and email used for commit authorship. Use --global for all repositories or --local for specific project.

- Global config is stored in ~/.gitconfig
- Local config overrides global settings
- Required before making your first commit

#### Configure editor and defaults

```bash
# Set default editor for commits
git config --global core.editor "nano"

# Set default branch name for new repositories
git config --global init.defaultBranch "main"

# Configure line ending handling
git config --global core.autocrlf true
```

_exec_
```bash
git config --global --list
```

_output_
```bash
user.name=John Doe
user.email=john@example.com
core.editor=nano
init.defaultBranch=main
```

Customize Git behavior with editor preferences, default branch naming, and line ending handling.

- autocrlf: true (Windows), input (Unix/macOS)
- View all config with --list flag

**Best practices:**

- Set global config once on new machine
- Use local config for work vs personal projects
- Configure proper line endings early to avoid whitespace issues

**Common errors:**

- **Please tell me who you are**: Run git config --global user.name and user.email

### Initialize and Clone

Create new repositories locally or clone existing ones.

**Keywords:** init, clone, repository, remote

#### Initialize a new repository

```bash
# Create new directory and initialize git
mkdir my-project
cd my-project
git init

# Or initialize git in existing directory
cd existing-directory
git init

# Initialize with specific default branch
git init --initial-branch=main
```

_exec_
```bash
git init
```

_output_
```bash
Initialized empty Git repository in /path/to/repo/.git/
```

Creates a new Git repository in current directory with a hidden .git folder containing repository metadata.

- Creates .git directory with Git internals
- Safe to run multiple times
- Default branch is master or configurable as main

#### Clone a remote repository

```bash
# Clone with HTTPS
git clone https://github.com/user/repo.git

# Clone with SSH
git clone git@github.com:user/repo.git

# Clone into specific directory
git clone https://github.com/user/repo.git my-folder

# Clone with limited history
git clone --depth 1 https://github.com/user/repo.git
```

_exec_
```bash
git clone https://github.com/user/repo.git
```

_output_
```bash
Cloning into 'repo'...
remote: Counting objects: 100%
Receiving objects: 100% (150/150), 25.5 KiB | 500 KiB/s
Resolving deltas: 100% (50/50), done.
```

Clones a remote repository to your local machine, including full history and all branches.

- --depth 1 for shallow clone (faster, less history)
- Creates directory with repo name by default
- SSH requires key setup, HTTPS uses credentials

**Best practices:**

- Use SSH for repeated access after key setup
- Clone with HTTPS if SSH is not configured
- Use shallow clone for large repos if history not needed

**Common errors:**

- **Repository not found**: Check URL and repository access permissions

## Basic Commands

Essential commands for daily Git workflow.

### Staging and Committing

Add changes to staging area and create commits.

**Keywords:** add, commit, staging, changes, snapshot

#### Stage and commit changes

```bash
# Check status of repository
git status

# Stage specific file
git add filename.txt

# Stage all changes
git add .

# Commit staged changes
git commit -m "Add new feature"

# Stage and commit in one command
git commit -am "Fix bug"
```

_exec_
```bash
git add . && git commit -m "Update code"
```

_output_
```bash
[main a1b2c3d] Update code
 3 files changed, 45 insertions(+), 10 deletions(-)
```

Adds modified files to staging area and creates a commit with descriptive message.

- git add stages changes for commit
- git commit creates snapshot with message
- -m flag for inline commit message
- -a flag skips staging for tracked files

#### Amend commits

```bash
# Add forgotten file to previous commit
git add forgotten_file.txt
git commit --amend --no-edit

# Change commit message
git commit --amend -m "Better message"

# Amend without changing message
git commit --amend --no-edit

# Amend with timestamp update
git commit --amend --date now
```

_exec_
```bash
git commit --amend -m "Updated message"
```

_output_
```bash
[main 5d4e3c2] Updated message
Date: Fri Feb 28 2025 10:30:00
 2 files changed, 50 insertions(+)
```

Modifies the most recent commit by adding changes or changing the message.

- Only amend unpushed commits to avoid conflicts
- --no-edit keeps original message
- Useful for fixing small mistakes before pushing

**Best practices:**

- Write clear, descriptive commit messages
- Commit logically related changes together
- Use --amend only on unpushed commits

**Common errors:**

- **nothing added to commit**: Stage changes first with git add

### Push and Pull

Synchronize changes with remote repositories.

**Keywords:** push, pull, remote, fetch, merge

#### Push changes to remote

```bash
# Push current branch to remote
git push

# Push to specific remote and branch
git push origin main

# Push all local branches
git push origin --all

# Push with force (only if needed)
git push --force-with-lease

# Push specific tag
git push origin v1.0.0
```

_exec_
```bash
git push origin main
```

_output_
```bash
Enumerating objects: 5, done.
Writing objects: 100% (3/3), 280 bytes
To github.com:user/repo.git
   a1b2c3d..x8y9z0a  main -> main
```

Uploads local commits to the remote repository on the specified branch.

- Default remote is usually 'origin'
- First push may require --set-upstream
- Use --force-with-lease instead of --force

#### Pull changes from remote

```bash
# Fetch and merge remote changes
git pull

# Pull from specific remote and branch
git pull origin main

# Pull with rebase instead of merge
git pull --rebase

# Fetch only (don't merge)
git fetch

# Fetch from all remotes
git fetch --all
```

_exec_
```bash
git pull origin main
```

_output_
```bash
From github.com:user/repo
 * branch            main       -> FETCH_HEAD
Fast-forward
 file.txt | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
```

Downloads and integrates remote changes into the current branch.

- git pull = git fetch + git merge
- Use --rebase for linear history
- Always pull before pushing to avoid conflicts

**Best practices:**

- Pull before pushing to avoid conflicts
- Use --force-with-lease instead of --force
- Keep commits organized before pushing

**Common errors:**

- **Your branch is behind its track**: Run git pull to fetch and merge remote changes

### View Status and History

Check repository status and view change history.

**Keywords:** status, diff, show, history

#### Check repository status

```bash
# View current status
git status

# Short status format
git status -s

# Include untracked files
git status --include-untracked
```

_exec_
```bash
git status -s
```

_output_
```bash
M config.js
A  new-file.txt
?? untracked.txt
```

Shows which files are modified, staged, or untracked in current working directory.

- M = modified, A = added, ?? = untracked
- First letter = staging area, second = working directory

#### View differences in files

```bash
# View unstaged changes
git diff

# View staged changes
git diff --staged

# View changes in specific file
git diff filename.txt

# View changes between commits
git diff HEAD~2 HEAD
```

_exec_
```bash
git diff --staged
```

_output_
```bash
diff --git a/file.txt b/file.txt
index 1234567..abcdefg 100644
--- a/file.txt
+++ b/file.txt
@@ -5,7 +5,7 @@
 old content
-removed line
+added line
```

Shows line-by-line differences between working directory and staging area or between commits.

- Plus sign (+) for added lines
- Minus sign (-) for removed lines
- Use --color-words for word-level diff

**Best practices:**

- Use git status before committing
- Review diffs before staging
- Use git show for viewing specific commits

**Common errors:**

- **No changes added**: Use git diff to see unstaged changes

## Branches

Create, manage, and work with branches for parallel development.

### Create and Delete Branches

Create new branches and delete obsolete ones.

**Keywords:** branch, create, delete, track, upstream

#### Create and switch branches

```bash
# Create new branch
git branch feature-new

# Create and switch in one command
git checkout -b feature-new

# Create branch from specific commit
git branch feature-new a1b2c3d

# Create tracking branch
git branch --track feature origin/feature

# Create branch with no upstream
git branch --no-track feature-local
```

_exec_
```bash
git checkout -b feature-new
```

_output_
```bash
Switched to a new branch 'feature-new'
```

Creates a new branch either from current HEAD or specific commit and optionally switches to it.

- Branch name should use hyphens, not spaces
- New branch contains all commits up to creation point
- Use descriptive names (feature/*, fix/*, etc)

#### Delete branches

```bash
# Delete local branch (safe)
git branch -d feature-new

# Force delete unmerged branch
git branch -D feature-new

# Delete remote branch
git push origin --delete feature-new

# Delete multiple branches
git branch -d feature-1 feature-2 feature-3
```

_exec_
```bash
git branch -d feature-new
```

_output_
```bash
Deleted branch feature-new (was a1b2c3d).
```

Removes branches locally or from remote repository. -d is safe, -D forces deletion.

- -d prevents deleting unmerged branches
- -D forces deletion regardless of merge status
- Deleting remote branch pushes deletion to origin

**Best practices:**

- Use -d for safe deletion
- Merge before deleting branches
- Keep branch names descriptive and consistent

**Common errors:**

- **Branch is not fully merged**: Use git branch -D to force delete, or merge first

### Switch and Merge Branches

Switch between branches and merge changes.

**Keywords:** switch, checkout, merge, rebase

#### Switch between branches

```bash
# Switch to existing branch
git checkout main

# Create and switch in one command
git checkout -b feature

# Switch using new syntax
git switch main

# Create and switch with new syntax
git switch -c feature

# Return to previous branch
git checkout -
```

_exec_
```bash
git switch main
```

_output_
```bash
Switched to branch 'main'
```

Changes working directory to selected branch. Can create new branch at same time.

- git switch is newer, alias for checkout
- Saved uncommitted changes before switching
- Use - to switch to previously checked out branch

#### Merge branches

```bash
# Merge feature branch into current branch
git merge feature

# Merge with no fast-forward
git merge --no-ff feature

# Squash commits before merging
git merge --squash feature

# Abort merge if conflicts
git merge --abort
```

_exec_
```bash
git merge feature
```

_output_
```bash
Merge made by the 'recursive' strategy.
 file.txt | 5 +++--
 1 file changed, 2 insertions(+), 3 deletions(-)
```

Integrates commits from another branch into the current branch. Fast-forward if possible.

- Merge creates merge commit if no fast-forward possible
- --no-ff always creates merge commit
- --squash combines all commits into single commit

**Best practices:**

- Switch to target branch before merging
- Use --no-ff to preserve branch history
- Test before merging to main

**Common errors:**

- **CONFLICT - merge conflict**: Resolve conflicts in editor, then git add and commit

### List and Compare Branches

View and compare branches in repository.

**Keywords:** list, compare, tracking, remote, upstream

#### List branches

```bash
# List local branches
git branch

# List with last commit info
git branch -v

# List remote branches
git branch -r

# List all branches (local and remote)
git branch -a

# List merged branches
git branch --merged

# List unmerged branches
git branch --no-merged
```

_exec_
```bash
git branch -v
```

_output_
```bash
* main       a1b2c3d Update README
  feature    x8y9z0a Add new feature
  bugfix     p5q6r7s Fix critical bug
```

Lists all branches with option to show last commit for each branch.

- Asterisk (*) marks current branch
- -r shows remote branches
- -a shows both local and remote

**Best practices:**

- Delete merged branches regularly
- Keep active development on feature branches
- Use --merged to find branches to delete

**Common errors:**

- **No such branch**: Use git branch -a to list all available branches

## Logs & History

View, search, and analyze commit history.

### View Commit History

Display commit history with various formats and filters.

**Keywords:** log, history, commits, graph, format

#### View commit history

```bash
# View commit history
git log

# View in one-line format
git log --oneline

# View with branch graph
git log --graph --all --oneline --decorate

# View recent commits
git log -n 5

# View with statistics
git log --stat
```

_exec_
```bash
git log --oneline -n 5
```

_output_
```bash
a1b2c3d Update documentation
x8y9z0a Add authentication
p5q6r7s Fix login bug
m3n4o5p Refactor database
i1j2k3l Initial commit
```

Shows commit history in selected format. Use --oneline for concise view, --graph for branch visualization.

- Without arguments shows full commit info
- --stat shows file changes per commit
- --graph helps visualize branching

#### Filter and format logs

```bash
# View commits by author
git log --author="John Doe"

# View commits since date
git log --since="2025-01-01"

# View commits until date
git log --until="2025-02-01"

# Custom format
git log --pretty=format:"%h %s by %an"

# View specific file history
git log -- filename.txt
```

_exec_
```bash
git log --author="John" --oneline --graph
```

_output_
```bash
* a1b2c3d Update code
* x8y9z0a Fix bug
* p5q6r7s Add feature
```

Filters log by author, date range, or custom format for precise history searching.

- Useful for tracking specific changes
- Custom format strings available in docs
- Filter by file to track changes in specific files

**Best practices:**

- Use meaningful commit messages for better log readability
- Filter logs by author or date for debugging
- Use --graph for visualizing complex histories

**Common errors:**

- **No commits yet**: Make first commit before viewing history

### Advanced Log Filtering

Use revisions and ranges to explore commit history.

**Keywords:** revision, range, HEAD, branches, tags

#### Reference commits with revisions

```bash
# HEAD references
git show HEAD           # Most recent commit
git show HEAD~1         # One commit before HEAD
git show HEAD~2         # Two commits before HEAD
git show HEAD^          # Parent of HEAD
git show HEAD^^         # Grandparent of HEAD

# Show specific commit
git show a1b2c3d

# Show commit from tag
git show v1.0.0
```

_exec_
```bash
git show HEAD~1
```

_output_
```bash
commit a1b2c3d3f4g5h6i7j8k9l0m1n
Author: John Doe <john@example.com>
Date: Fri Feb 27 2025

Previous commit message
```

Shows specific commits using HEAD references and relative positioning.

- HEAD~n counts back n commits in history
- HEAD^ refers to parent commit
- Use with show, log, diff for detailed exploration

#### Use commit ranges

```bash
# Commits in feature but not main (two-dot)
git log main..feature

# Commits in either branch (three-dot)
git log main...feature

# Commits reachable from branch
git log feature

# Commits in range
git log a1b2c3d..x8y9z0a
```

_exec_
```bash
git log main..feature --oneline
```

_output_
```bash
p5q6r7s Add feature implementation
m3n4o5p Update tests
```

Shows commits within specified ranges, useful for comparing branches.

- Two-dot: commits in first branch only
- Three-dot: commits in either branch, not both

**Best practices:**

- Use HEAD references for recent commits
- Use ranges to compare branches before merging
- Combine with --oneline for cleaner output

**Common errors:**

- **bad revision**: Check revision syntax and available commits

## Undoing Changes

Revert, reset, and restore changes in various scenarios.

### Reset and Revert

Move HEAD and undo commits permanently or safely.

**Keywords:** reset, revert, undo, HEAD, commits

#### Reset changes

```bash
# Undo last commit, keep changes staged
git reset --soft HEAD~1

# Undo last commit, keep changes in working dir
git reset --mixed HEAD~1

# Discard last commit and all changes
git reset --hard HEAD~1

# Unstage file
git reset HEAD filename.txt

# Reset to specific commit
git reset --hard a1b2c3d
```

_exec_
```bash
git reset --soft HEAD~1
```

Moves HEAD to previous state. --soft keeps changes staged, --mixed unstages, --hard discards all.

- DANGEROUS if commits pushed to shared branch
- Use on local commits only
- --hard irreversibly deletes changes

#### Safely revert commits

```bash
# Create new commit reversing changes
git revert HEAD

# Revert specific commit
git revert a1b2c3d

# Revert multiple commits
git revert --no-edit HEAD~3..HEAD

# Revert without committing
git revert -n HEAD
```

_exec_
```bash
git revert HEAD
```

_output_
```bash
[main b3c4d5e] Revert "Add feature"
 1 file changed, 10 deletions(-)
```

Creates new commit that undoes changes from specified commit. Safe for shared branches.

- Creates new commit (preserve history)
- Safe for pushed commits
- Opposite changes in new commit

**Best practices:**

- Use revert for shared branches
- Use reset only on local commits
- Never --hard reset unless certain

**Common errors:**

- **Cannot revert without resolving conflicts**: Resolve conflicts manually, then complete revert

### Restore and Checkout Files

Restore files to previous states without moving HEAD.

**Keywords:** restore, checkout, discard, file, changes

#### Discard changes in files

```bash
# Discard changes to file (checkout)
git checkout -- filename.txt

# Discard changes (restore)
git restore filename.txt

# Discard all changes
git restore .

# Restore from specific commit
git checkout a1b2c3d -- filename.txt

# Restore to previous version
git restore --source=HEAD~1 filename.txt
```

_exec_
```bash
git restore filename.txt
```

Restores files to their last committed state, discarding local changes.

- Does not affect commit history
- Useful for discarding accidental changes
- --source specifies which commit to restore from

#### Unstage files

```bash
# Unstage file (restore --staged)
git restore --staged filename.txt

# Unstage all files
git restore --staged .

# Alternative: reset
git reset HEAD filename.txt

# Unstage but keep changes
git reset HEAD filename.txt
```

_exec_
```bash
git restore --staged filename.txt
```

Removes files from staging area while keeping changes in working directory.

- Changes remain in working directory
- Allows re-staging with modifications

**Best practices:**

- Use restore for file-level changes
- Review changes before discarding
- Commit important work before discarding

**Common errors:**

- **pathspec did not match**: Check file path and filename spelling

## Advanced

Complex operations for power users and advanced workflows.

### Rebase and Cherry Pick

Rewrite history and apply selective commits.

**Keywords:** rebase, cherry-pick, interactive, history, commit

#### Rebase branch over another

```bash
# Rebase current branch onto main
git rebase main

# Interactive rebase for last 3 commits
git rebase -i HEAD~3

# Rebase and squash commits
git rebase -i HEAD~3
# In editor: keep first 'pick', change others to 'squash'

# Abort rebase if problems
git rebase --abort

# Continue after resolving conflicts
git rebase --continue
```

_exec_
```bash
git rebase main
```

_output_
```bash
First, rewinding head to replay your work on top of it...
Applying: Add feature
Applying: Fix tests
```

Replays commits on top of another branch creating linear history instead of merge.

- Creates new commit objects (changes hashes)
- Never rebase pushed commits in shared branches
- Interactive rebase (-i) allows editing commits

#### Cherry pick commits

```bash
# Apply specific commit to current branch
git cherry-pick a1b2c3d

# Pick multiple commits
git cherry-pick a1b2c3d x8y9z0a

# Pick range of commits
git cherry-pick a1b2c3d..x8y9z0a

# Cherry-pick without committing
git cherry-pick -n a1b2c3d

# Abort if conflicts
git cherry-pick --abort
```

_exec_
```bash
git cherry-pick a1b2c3d
```

_output_
```bash
[main p3q4r5s] Add feature
 1 file changed, 25 insertions(+)
```

Applies changes from specific commit to current branch, creating new commit.

- Useful for backporting fixes
- Creates new commits (different hashes)
- Resolve conflicts same as merge

**Best practices:**

- Rebase only on local commits
- Use interactive rebase to clean history before pushing
- Cherry-pick for backporting fixes

**Common errors:**

- **Cannot rebase with unresolved conflicts**: Resolve conflicts and run git rebase --continue

### Stash and Merge

Temporarily save work and integrate branches.

**Keywords:** stash, merge, temporary, storage, conflicts

#### Stash changes

```bash
# Stash current changes
git stash

# Stash with message
git stash save "my work in progress"

# Stash including untracked files
git stash -u

# List all stashes
git stash list

# Apply latest stash
git stash apply

# Apply and remove stash
git stash pop

# Apply specific stash
git stash apply stash@{0}
```

_exec_
```bash
git stash
```

_output_
```bash
Saved working directory and index state WIP on main: a1b2c3d Update docs
```

Temporarily saves uncommitted changes, cleaning working directory.

- Stash stores changes in temporary storage
- list shows all saved stashes
- pop applies and removes stash

#### Handle merge conflicts

```bash
# Start merge (may hit conflicts)
git merge feature

# View conflicted files
git status

# View specific conflict
git diff

# After solving in editor:
git add resolved-file.txt
git commit -m "Merge feature branch"

# Abort merge if necessary
git merge --abort
```

_exec_
```bash
git merge feature
```

_output_
```bash
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
```

Handles merge conflicts by manual resolution and recommit.

- Conflict markers indicate conflict regions
- Edit files to remove markers and pick resolution
- Stage and commit after resolution

**Best practices:**

- Stash for switching context temporarily
- Commit instead of stash when possible
- Resolve conflicts carefully

**Common errors:**

- **Your local changes would be overwritten**: Stash changes or commit before switching branches

## Remote Tracking

Manage remote repositories and tracking branches.

### Configure Remotes and Fetch

Set up and work with remote repositories.

**Keywords:** remote, add, fetch, tracking, upstream

#### Manage remote repositories

```bash
# List all remotes
git remote

# List with URLs
git remote -v

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

# Remove remote
git remote remove origin

# Rename remote
git remote rename origin old-origin

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

_exec_
```bash
git remote -v
```

_output_
```bash
origin https://github.com/user/repo.git (fetch)
origin https://github.com/user/repo.git (push)
upstream https://github.com/original/repo.git (fetch)
```

Adds, removes, and manages remote repository references.

- origin is default remote (clone source)
- upstream common for forked repositories
- Separate fetch and push URLs possible

#### Fetch from remotes

```bash
# Fetch from default remote
git fetch

# Fetch from specific remote
git fetch origin

# Fetch from all remotes
git fetch --all

# Fetch specific branch
git fetch origin main

# Prune deleted remote branches
git fetch --prune

# Fetch and fast-forward
git fetch origin && git merge
```

_exec_
```bash
git fetch --all
```

_output_
```bash
Fetching origin
remote: Counting objects: 5, done.
Unpacking objects: 100% (3/3), done.
From github.com:user/repo
   a1b2c3d..x8y9z0a  main       -> origin/main
```

Downloads remote branch updates without merging. Safe operation for syncing.

- Fetch updates remote tracking branches
- --all fetches from all remotes
- --prune removes deleted remote branches

**Best practices:**

- Fetch before pushing to check for conflicts
- Use --prune to keep local cache clean
- Maintain upstream reference in forks

**Common errors:**

- **Authentication failed**: Check remote URL and credentials/SSH keys

### Tracking Branch Configuration

Set up and manage upstream tracking relationships.

**Keywords:** tracking, upstream, set-upstream, branch, relationship

#### Set up tracking branches

```bash
# Set upstream for current branch
git branch -u origin/main

# Set upstream when pushing new branch
git push -u origin feature

# Create tracking branch from remote
git checkout --track origin/feature

# Create with specific local name
git checkout -b my-feature origin/feature

# View tracking status
git branch -vv
```

_exec_
```bash
git branch -vv
```

_output_
```bash
main    a1b2c3d [origin/main] Update docs
feature x8y9z0a [origin/feature] Add feature
```

Establishes connection between local and remote branches for tracking.

- Tracking enables git pull to work without arguments
- Shows ahead/behind status
- -vv shows verbose with tracking branch

#### Update tracking branches

```bash
# Pull current branch (requires tracking)
git pull

# Pull specific branch
git pull origin main

# Pull with rebase
git pull --rebase

# See what will be pulled
git fetch && git log --oneline origin/main..main
```

_exec_
```bash
git pull --rebase
```

_output_
```bash
From github.com:user/repo
   a1b2c3d..x8y9z0a  main       -> origin/main
Fast-forward
```

Pulls and integrates remote changes using tracking relationship.

- Tracking branch simplifies pull/push
- --rebase preferred for linear history

**Best practices:**

- Use -u when pushing new branches
- Keep tracking branches updated
- Use pull rebase for merging updates

**Common errors:**

- **No tracking information for branch**: Set upstream with git branch -u or git push -u

## Extras & Tips

Advanced utilities and best practices for Git workflows.

### Bisect and Debugging

Find problematic commits using binary search.

**Keywords:** bisect, debug, find, regression, blame

#### Use git bisect

```bash
# Start bisect session
git bisect start

# Mark current commit as bad
git bisect bad

# Mark known good commit
git bisect good a1b2c3d

# Test current state and mark
git bisect good  # or git bisect bad

# Continue until found
# ... (git will narrow down)

# Reset after finding bad commit
git bisect reset
```

_exec_
```bash
git bisect start
```

_output_
```bash
Bisecting: 5 revisions left to test after this (roughly 2 steps)
[a1b2c3d] Commit message
```

Binary search through commits to find where bug was introduced.

- Efficient Way to find regression
- Automatically narrows search space
- Mark commits as good or bad

#### Find changes with blame

```bash
# Show who changed each line
git blame filename.txt

# Show abbreviated blame
git blame -s filename.txt

# Show blame for specific range
git blame -L 10,20 filename.txt

# Show blame with commit date
git blame --date=short filename.txt
```

_exec_
```bash
git blame filename.txt
```

_output_
```bash
a1b2c3d (John Doe 2025-01-15 10:30:00 +0000) line content
x8y9z0a (Jane Smith 2025-02-01 14:22:00 +0000) line content
```

Annotates each line with commit hash, author, and date that changed it.

- Useful for tracking origin of bugs
- Helps understand code history

**Best practices:**

- Use bisect for large histories
- Write good commit messages for blame readability
- Use blame to understand code context

**Common errors:**

- **No commits marked good**: Mark at least one good and one bad commit

### Signing and Maintenance

GPG signing commits and repository cleanup.

**Keywords:** sign, gpg, verify, cleanup, garbage

#### Sign commits with GPG

```bash
# Configure GPG signing
git config --global user.signingkey YOUR_GPG_KEY_ID

# Sign individual commit
git commit -S -m "Signed commit"

# Sign all commits by default
git config --global commit.gpgSign true

# Verify signed commit
git verify-commit a1b2c3d

# Show GPG signature in log
git log --show-signature
```

_exec_
```bash
git commit -S -m "Signed commit"
```

_output_
```bash
[main a1b2c3d] Signed commit
 1 file changed, 10 insertions(+)
```

Signs commits with GPG key for authentication and verification.

- Requires GPG key setup
- -S flag signs commit
- GitHub shows verification badge for signed commits

#### Repository maintenance

```bash
# Remove empty commits
git gc

# Run full optimization
git gc --aggressive

# Clean untracked files
git clean -fd

# View repo size
git count-objects -v

# Remove large files from history
git filter-branch --tree-filter 'rm -f large-file.bin'
```

_exec_
```bash
git gc
```

_output_
```bash
Counting objects, done.
```

Performs repository maintenance and cleanup operations.

- gc compresses repository (safe)
- clean removes untracked files
- filter-branch rewrites history (careful!)

**Best practices:**

- Sign commits in professional projects
- Run gc periodically for optimization
- Use clean carefully to avoid deleting files

**Common errors:**

- **no default secret key**: Configure GPG key with git config user.signingkey

### Aliases and Shortcuts

Create custom commands and optimize workflows.

**Keywords:** alias, shortcut, custom, workflow, productivity

#### Create command aliases

```bash
# Create short alias
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit

# Create complex aliases
git config --global alias.log-graph \
'log --graph --all --oneline --decorate'

# Create unstage alias
git config --global alias.unstage 'restore --staged'

# Create last-commit alias
git config --global alias.last 'log -1 HEAD'
```

_exec_
```bash
git config --global alias.st status
```

Creates shorthand commands for frequently used git operations.

- Aliases stored in ~/.gitconfig
- Saves time on repetitive commands
- Can create very complex aliases

#### Useful workflow aliases

```bash
# Amend without editing message
git config --global alias.amend 'commit --amend --no-edit'

# Pull with rebase
git config --global alias.pr 'pull --rebase'

# List branches by date
git config --global alias.branches \
'branch -a --sort=-committerdate'

# Show recent branches
git config --global alias.recent 'for-each-ref --sort=-committerdate'
```

_exec_
```bash
git amend
```

_output_
```bash
[main a1b2c3d] Commit message
```

Streamlines common workflows with custom commands.

- Create aliases for operations you use frequently
- Improves productivity and reduces errors

**Best practices:**

- Create aliases for your most used commands
- Share useful aliases with team
- Keep simple short, complex ones explicit

**Common errors:**

- **unknown command**: Check alias is defined with git config --list
