0 / 0
Skip to content

Working with Git Shallow Clones: From Clone to Commit and Push

Posted on August 21, 2025

Hey there!

So, you've found yourself needing to work on a git project, but you don't want to download the entire history? Or maybe you're working with a massive repository and just need to make a quick fix? That's where shallow clones come in handy!

In this post, I'll walk you through the complete workflow of working with a shallow clone - from the initial clone to making changes and pushing them back to the repository.

What is a Shallow Clone?

A shallow clone is a git clone that only downloads the most recent commit (or a limited number of commits) instead of the entire repository history. This is incredibly useful when:

  • You're working with large repositories with extensive history
  • You only need to make a quick fix or small change
  • You want to save bandwidth and disk space
  • You're working in CI/CD environments where you don't need full history

The Workflow: Step by Step

1. Creating a Shallow Clone

The magic happens with the --depth 1 flag:

bash
git clone --depth 1 https://github.com/username/repository.git
cd repository

This creates a clone with only the latest commit. You can also specify a different depth if you need a few more commits:

bash
git clone --depth 5 https://github.com/username/repository.git

2. Understanding What You Have

After cloning, you'll notice some differences from a full clone:

bash
# Check the git log - you'll see limited history
git log --oneline

# Check if you have a shallow repository
git rev-parse --is-shallow-repository
# Output: true

3. Making Your Changes

Now you can work on the files just like any other git repository:

bash
# Edit your files
vim src/main.js

# Check what you've changed
git status

# See the differences
git diff

4. The Challenge: Pushing from a Shallow Clone

Here's where things get interesting. By default, you can't push from a shallow clone because git doesn't have the full history to create a proper commit chain. But there are several ways to handle this:

If the repository isn't too large, you can fetch the full history:

bash
# Fetch the complete history
git fetch --unshallow

# Now you have a full clone and can push normally
git add .
git commit -m "Fix the bug in main.js"
git push origin main

Option A.1: When Disk Space is Limited

For massive repositories like Linux kernel, Chromium, or large monorepos, git fetch --unshallow might fail due to disk space constraints. Here are your alternatives:

Strategy 1: Push to a New Branch (Recommended)

bash
# Create a new branch from your shallow clone
git checkout -b fix/your-bug-fix

# Make your changes
git add .
git commit -m "Fix the critical bug"

# Push the new branch
git push origin fix/your-bug-fix

Then create a pull request from the web interface. This is the safest approach for open source contributions.

Strategy 2: Use GitHub's Web Editor For simple changes, use GitHub's built-in file editor:

  1. Navigate to the file on GitHub
  2. Click the pencil icon to edit
  3. Make your changes
  4. Commit directly through the web interface

Strategy 3: Patch-based Workflow

bash
# Create a patch file from your changes
git format-patch HEAD~1

# This creates a .patch file you can share
# Others can apply it with: git apply your-changes.patch

Strategy 4: Selective Fetch If you need some history but not all:

bash
# Fetch only recent history (last 100 commits)
git fetch --depth 100 origin main

# Or fetch specific date range
git fetch --shallow-since="2024-01-01" origin main

Option B: Push with Force (Use with Caution)

For quick fixes where you're sure about your changes:

bash
git add .
git commit -m "Quick fix for the issue"
git push --force-with-lease origin main

⚠️ Warning: Only use force push when you're certain no one else has pushed changes since your clone.

Option C: Create a New Branch

A safer approach is to create a new branch:

bash
# Create and switch to a new branch
git checkout -b fix/quick-bug-fix

# Make your changes
git add .
git commit -m "Fix the bug in main.js"

# Push the new branch
git push origin fix/quick-bug-fix

Then create a pull request from the web interface.

Real-World Example

Let me walk you through a real scenario I encountered recently:

bash
# 1. Clone a large repository with shallow depth
git clone --depth 1 https://github.com/some-org/massive-project.git
cd massive-project

# 2. Check what we have
git log --oneline
# Output: abc1234 (HEAD -> main) Latest commit message

# 3. Make a quick fix
echo "// Fixed the bug" >> src/config.js

# 4. Stage and commit
git add src/config.js
git commit -m "Fix configuration issue"

# 5. Push (using force since it's a shallow clone)
git push --force-with-lease origin main

Best Practices

When to Use Shallow Clones

Good use cases:

  • Quick bug fixes
  • Documentation updates
  • CI/CD pipelines
  • Large repositories where you only need recent changes
  • Temporary work that doesn't require full history

Avoid when:

  • You need to understand the project's evolution
  • You're doing major refactoring
  • You need to bisect bugs
  • You're contributing to open source projects (usually)

Disk Space Considerations

Before cloning large repositories:

bash
# Check available disk space
df -h

# Estimate repository size (if possible)
# Most large repos show size on GitHub/GitLab

Repository size guidelines:

  • < 100MB: Safe to use git fetch --unshallow
  • 100MB - 1GB: Consider selective fetch or branch-based workflow
  • > 1GB: Use shallow clone + branch workflow or web-based editing
  • > 10GB: Web-based workflow or patch-based contribution recommended

Safety Tips

  1. Always check the remote status first:

    bash
    git fetch origin
    git status
  2. Use --force-with-lease instead of --force:

    bash
    # Safer than --force
    git push --force-with-lease origin main
  3. Consider creating feature branches:

    bash
    git checkout -b feature/your-change
    # Make changes
    git push origin feature/your-change
  4. Communicate with your team: Let others know when you're working with shallow clones to avoid conflicts.

Troubleshooting Common Issues

Issue: "Shallow update not allowed"

bash
# Error: Shallow update not allowed
git push origin main

Solution: Use one of the methods above (fetch --unshallow, force push, or new branch).

Issue: "Rejected non-fast-forward"

bash
# Error: ! [rejected] main -> main (non-fast-forward)

Solution: Someone else has pushed changes. Fetch the latest and rebase:

bash
git fetch origin
git rebase origin/main
git push origin main

Issue: "Cannot lock ref"

bash
# Error: cannot lock ref 'refs/remotes/origin/main'

Solution: Clean up the repository:

bash
git remote prune origin
git gc --prune=now

Issue: "No space left on device" during fetch --unshallow

bash
# Error: fatal: write error: No space left on device
git fetch --unshallow

Solutions:

  1. Check available disk space:

    bash
    df -h
    du -sh .git
  2. Use alternative strategies:

    • Push to a new branch instead: git push origin your-branch
    • Use GitHub's web editor for simple changes
    • Create a patch file: git format-patch HEAD~1
  3. Clean up git objects:

    bash
    git gc --prune=now
    git remote prune origin
  4. Use selective fetch:

    bash
    # Instead of full history, get recent commits only
    git fetch --depth 100 origin main

Advanced Techniques

Handling Massive Repositories

When working with extremely large repositories (like Linux kernel, Chromium, or large monorepos), disk space becomes a critical constraint. Here are specialized strategies:

Repository Size Examples

  • Linux kernel: ~1.5GB+ (full history)
  • Chromium: ~30GB+ (full history)
  • Large monorepos: Can exceed 50GB+

Strategy: Minimal Working Clone

bash
# Clone with minimal depth and single branch
git clone --depth 1 --single-branch --branch main https://github.com/massive/project.git

# Check disk usage
du -sh .git
# Output: ~50MB instead of ~30GB

Strategy: Web-based Workflow

For simple changes, avoid local cloning entirely:

  1. Fork the repository on GitHub
  2. Use GitHub's web editor for file changes
  3. Create pull request directly from the web interface
  4. Review and merge through GitHub's interface

Strategy: Patch-based Contribution

bash
# Create a minimal clone
git clone --depth 1 https://github.com/massive/project.git
cd project

# Make your changes
vim src/your-file.cpp
git add src/your-file.cpp
git commit -m "Fix critical bug in module"

# Create a patch file
git format-patch HEAD~1
# Creates: 0001-Fix-critical-bug-in-module.patch

# Share the patch file (email, issue, etc.)
# Others can apply: git apply 0001-Fix-critical-bug-in-module.patch

Strategy: Selective History Fetch

If you need some context but not everything:

bash
# Fetch only recent commits
git fetch --depth 50 origin main

# Fetch commits from specific date
git fetch --shallow-since="2024-01-01" origin main

# Fetch specific branch with limited depth
git fetch --depth 10 origin feature-branch

Partial Shallow Clones

You can also create shallow clones of specific branches:

bash
# Clone only the main branch with depth 1
git clone --depth 1 --branch main https://github.com/username/repo.git

# Clone multiple branches with different depths
git clone --depth 1 https://github.com/username/repo.git
cd repo
git fetch --depth 5 origin develop

Converting Shallow to Full

If you later decide you need the full history:

bash
# Fetch all history
git fetch --unshallow

# Or fetch specific branches
git fetch --unshallow origin main
git fetch --unshallow origin develop

The Takeaway

Shallow clones are a powerful tool in your git arsenal, especially when working with large repositories or making quick fixes. The key is understanding the limitations and choosing the right approach for pushing your changes.

Remember:

  • Shallow clones save time and space but limit your git operations
  • Always consider the team when using force pushes
  • Feature branches are often safer than direct pushes to main
  • Know when to convert to a full clone if you need more git functionality

The workflow I've outlined here has saved me countless hours when working with large repositories, especially in CI/CD environments where I only need to make small changes.

Happy coding!


P.S. If you're interested in more advanced git workflows, check out my other posts about automating package publishing with GitHub Actions and working with different git strategies.