# Git Split Push

**Split large git pushes into smaller batches** — no LFS required.

When `git push` fails with "pack exceeds maximum allowed size" or "remote end hung up unexpectedly", this tool automatically splits your changes into smaller batches and pushes them sequentially.

## Quick Start

```bash
# Run when push fails
python3 ~/.claude/skills/git-split-push/scripts/batch-push.py

# Or add an alias
alias git-split='python3 ~/.claude/skills/git-split-push/scripts/batch-push.py'
git-split
```

## How It Works

1. Detects all files that need to be pushed (staged, untracked, modified)
2. Groups them into batches (default: 20MB per batch)
3. Creates commits: `[split-push] Batch 1/5`
4. Pushes each batch sequentially
5. Reports success/failure for each batch

## Common Errors It Fixes

```
fatal: the remote end hung up unexpectedly
pack exceeds maximum allowed size
RPC failed; HTTP 413
error: packfile is too large
413 Request Entity Too Large
```

## Examples

### Check Size First

```bash
$ git-split --check-size

📊 Push Size Analysis:
   Total files: 116
   Total size: 91.2 MB
   Batches needed (at 20MB): 5
```

### Dry Run (Preview)

```bash
$ git-split --dry-run

🔍 Dry run - showing what would happen:

Batch 1: ✓ (18.5 MB)
   - node_modules/large-file.js (5.2 MB)
   - assets/videos/demo.mp4 (4.1 MB)
   ...

Batch 2: ✓ (19.2 MB)
   ...
```

### Custom Batch Size

```bash
# Use 30MB per batch (for servers with higher limits)
git-split --max-size 30
```

## Options

| Option | Description |
|--------|-------------|
| `--max-size N` | Max MB per batch (default: 20) |
| `--dry-run` | Preview batches without pushing |
| `--check-size` | Show size analysis and exit |
| `--untracked-only` | Only push untracked files |

## Files Too Large

If a single file exceeds the batch limit (e.g., 100MB video), it will be skipped with instructions:

```
⚠️  Batch 3 SKIPPED (file too large)
   - video.mp4 (105.3 MB)

💡 To push this file, either:
   1. Split the file: split --bytes=40M video.mp4 part-
   2. Use Git LFS (requires server support)
   3. Remove from git: git rm --cached video.mp4
```

## How Batching Works

Files are sorted by size (largest first) and grouped until reaching the max size:

```
Files: [50MB, 30MB, 20MB, 15MB, 10MB, 8MB, 5MB, 3MB, 2MB]
Max batch: 20MB

Batch 1: [50MB]  ← single file too large, skipped
Batch 2: [30MB]  ← single file too large, skipped
Batch 3: [20MB]  ← 20MB exactly
Batch 4: [15MB, 3MB]  ← 18MB total
Batch 5: [10MB, 8MB]   ← 18MB total
Batch 6: [5MB, 2MB]    ← 7MB total
```

Skipped files (those exceeding `--max-size`) need manual handling.

## Why Not LFS?

Git LFS requires:
- Server support (Gitea/GitHub/GitLab)
- Additional setup
- Separate storage quotas

This tool works with **any git server** without configuration.

## Safety Features

- ✅ Never loses your work
- ✅ Soft reset on push failure
- ✅ Per-batch commits (can cherry-pick)
- ✅ Dry run mode (preview first)

## Requirements

- Python 3.6+
- Git (obviously)

## Install

The skill is already installed. To use from anywhere, add to your shell config:

```bash
# ~/.bashrc or ~/.zshrc
export PATH="$HOME/.claude/skills/git-split-push/scripts:$PATH"
```

Or create an alias:

```bash
alias git-split='python3 ~/.claude/skills/git-split-push/scripts/batch-push.py'
```

## Troubleshooting

### "Not in a git repository"

Make sure you're in a directory with a `.git` folder:

```bash
cd ~/projects/my-repo
git-split
```

### "Could not determine current branch"

Make sure you have an active branch:

```bash
git checkout main  # or master, develop, etc.
git-split
```

### Push still failing after split

The server may have a lower limit. Try smaller batches:

```bash
git-split --max-size 10  # 10MB per batch
```

### All batches fail

Check your network connection and remote URL:

```bash
git remote -v
git push -u origin main  # verify credentials work
```