The 'refs/heads/main exists; cannot create' error occurs when unbundling a Git bundle file into a repository that already has a reference with the same name. Use git fetch from the bundle instead, or delete the conflicting ref first.
The "error: refs/heads/main exists; cannot create" error in Git occurs when you attempt to unbundle a Git bundle file that contains references (like branch names) that already exist in your target repository. Git bundles are archive files containing Git objects and references. They're useful for transferring repository data when you don't have network access to a remote. When you run `git bundle unbundle`, Git tries to create all the references stored in the bundle file. If a reference like `refs/heads/main` already exists locally, Git refuses to overwrite it and shows this error. This is a safety mechanism - Git won't silently overwrite your existing branches. The error typically occurs when you're restoring from a bundle backup, merging bundle content into an existing repository, or receiving updates via bundle files in an offline workflow.
The recommended way to import bundle content is using git fetch, not git bundle unbundle:
# Fetch from a bundle file (recommended approach)
git fetch /path/to/repo.bundle main:refs/remotes/bundle/main
# Or fetch all refs from the bundle
git fetch /path/to/repo.bundle '*:*'
# Fetch and merge into current branch
git fetch /path/to/repo.bundle main
git merge FETCH_HEADThe git fetch command handles existing refs gracefully by updating them rather than failing. The unbundle command is low-level plumbing that expects refs to not exist.
Inspect the bundle to see what refs it contains:
# List refs in the bundle
git bundle list-heads /path/to/repo.bundle
# Verify bundle integrity and prerequisites
git bundle verify /path/to/repo.bundleExample output:
abc1234567890 refs/heads/main
def0987654321 refs/heads/developThis shows you which refs will conflict with your existing repository.
If you must use unbundle and want to replace existing refs, delete them first:
# Delete a specific branch
git branch -D main
# Or use update-ref to remove the ref directly
git update-ref -d refs/heads/main
# Then unbundle
git bundle unbundle /path/to/repo.bundleWarning: Deleting branches removes their commit history from your local repository. Only do this if you're certain you want to replace local content with the bundle content.
If you're restoring from a bundle backup, clone directly from the bundle:
# Clone directly from a bundle file
git clone /path/to/repo.bundle restored-repo
cd restored-repo
# Or initialize empty and unbundle
mkdir restored-repo && cd restored-repo
git init
git bundle unbundle /path/to/repo.bundle
git checkout mainStarting with an empty repository avoids all ref conflicts since there are no existing refs to collide with.
If you want to keep both your local refs and the bundle refs:
# Rename your local branch first
git branch -m main main-local
# Now unbundle (or fetch) the bundle content
git bundle unbundle /path/to/repo.bundle
# Compare the two versions
git log --oneline main-local..main # commits in bundle not in local
git log --oneline main..main-local # commits in local not in bundle
# Merge or choose which to keep
git checkout main
git merge main-localThis preserves both versions so you can reconcile differences.
Import bundle refs under a different namespace to avoid conflicts:
# Fetch all bundle refs under 'bundle/' prefix
git fetch /path/to/repo.bundle 'refs/heads/*:refs/bundle/*'
# List the imported refs
git show-ref | grep bundle/
# Compare with local
git diff main bundle/main
# Merge specific bundle ref into local branch
git checkout main
git merge bundle/mainThis approach lets you inspect bundle content before integrating it into your branches.
### Understanding git bundle unbundle vs git fetch
The git bundle unbundle command is low-level plumbing that directly creates refs:
| Command | Behavior with existing refs |
|---------|----------------------------|
| git bundle unbundle | Fails if ref exists |
| git fetch <bundle> | Updates existing refs (fast-forward or as configured) |
| git clone <bundle> | Creates new repo, no conflicts possible |
For most use cases, git fetch is the correct choice.
### Creating Incremental Bundles
When creating bundles for ongoing offline sync, use incremental bundles:
# First bundle: full repository
git bundle create full.bundle --all
# Subsequent bundles: only new commits since last sync
git bundle create incremental.bundle main ^last-sync-tag
# Apply incremental bundle (won't have ref conflicts)
git fetch incremental.bundle main:main### Bundle-Based Offline Workflow
A typical offline workflow that avoids ref conflicts:
# On source machine: create bundle with specific ref pattern
git bundle create updates.bundle origin/main..main
# On target machine: fetch bundle content
git fetch updates.bundle main:refs/remotes/offline/main
git merge offline/main### Handling Diverged Histories
If the bundle contains refs that have diverged from your local refs:
# Check if histories have diverged
git fetch /path/to/repo.bundle main:refs/bundle/main
git merge-base --is-ancestor bundle/main main && echo "Bundle is ancestor" || echo "Diverged"
# If diverged, you'll need to merge or rebase
git checkout main
git merge bundle/main --allow-unrelated-histories # if completely unrelated### Working with Multiple Bundle Files
When you have several bundles to import:
# Import each bundle to its own namespace
for bundle in *.bundle; do
name=${bundle%.bundle}
git fetch "$bundle" "refs/heads/*:refs/bundles/$name/*"
done
# List all imported refs
git show-ref | grep bundles/warning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server