obsidian/wiki/concepts/icloud-git-sync-conflict.md
2026-04-28 21:49:41 +01:00

6.6 KiB

title aliases tags sources created updated
iCloud Sync — Git Repository Corruption via Conflict Files
icloud-git-conflict
icloud-obsidian-git
git-badrefname-icloud
icloud-git-sync
icloud
git
obsidian
sync
homelab
dotfiles
conflict
daily/2026-04-27.md
2026-04-27 2026-04-27

iCloud Sync — Git Repository Corruption via Conflict Files

iCloud Drive creates conflict copies of files by appending a space and number to the filename (e.g., main 2, ORIG_HEAD 2) when two devices have modified the same file simultaneously. If the .git/ directory of a repository is stored inside an iCloud-synced folder, these conflict files appear inside .git/refs/heads/ and git fails with fatal: 'badRefName' because git ref names cannot contain spaces. The repository becomes unusable until the conflict files are removed manually.

Key Points

  • iCloud conflict file naming: when a sync conflict occurs, iCloud creates original_name 2 (space + number) in the same directory — this is not user-visible in Finder but exists on the filesystem
  • .git/refs/heads/main 2 is an invalid git ref name — git rejects any ref containing a space; git status, git log, and git pull all fail with fatal: bad ref 'main 2'
  • Root cause: two devices with an Obsidian vault (or any git repo) open simultaneously editing the same files — when both commit and iCloud syncs, diverged histories create a conflict in .git/refs/heads/
  • Fix: delete all * 2 files from .git/refs/heads/, then merge the diverged histories with git merge
  • Prevention: either exclude .git/ from iCloud sync, keep Obsidian open on only one device at a time, or use Obsidian Sync instead of git

Details

How the Corruption Happens

The sequence that leads to this state:

  1. Vault is open on Device A (Mac) and Device B (iPhone/iPad) simultaneously
  2. Both devices make changes that result in different git commits (Device A via shell, Device B via Obsidian's git plugin)
  3. iCloud syncs .git/refs/heads/main from both devices — they have different SHA hashes
  4. iCloud detects a conflict and creates .git/refs/heads/main 2 alongside the original .git/refs/heads/main
  5. When either device runs any git command, git enumerates refs, encounters main 2, and fails:
    fatal: 'refs/heads/main 2' is not a valid ref name
    

Git's ref naming rules prohibit spaces (and several other characters) — this is enforced at the filesystem level in git check-ref-format. A space in a ref name is unconditionally rejected.

Diagnosing the Problem

# Inside the git repo (.git is the vault's .git directory)
git status
# fatal: 'refs/heads/main 2' is not a valid ref name

# Find all iCloud conflict files in .git
find .git/refs -name "* 2" -o -name "*ORIG*"
# .git/refs/heads/main 2
# .git/refs/heads/ORIG_HEAD 2   (sometimes, if a merge was in progress)

# Check if history has diverged
git log --oneline --graph --all
# Shows two branches diverging at a common ancestor

The Fix

# Step 1: Remove iCloud conflict files
rm ".git/refs/heads/main 2"
rm ".git/refs/heads/ORIG_HEAD 2"   # if present

# Step 2: Verify git is functional again
git status
# Will show: "Your branch and 'origin/main' have diverged"

# Step 3: Merge the diverged histories
git merge origin/main
# Or if origin/main was the "other" device's version:
git pull --no-rebase

# Step 4: Resolve any content conflicts (if files were edited on both devices)
# git will report conflicted files if any
# Edit them to resolve, then:
git add .
git commit -m "Merge diverged device histories"

# Step 5: Push
git push

If ORIG_HEAD also has a conflict copy, git may be in an interrupted merge state. Check:

git status
# "You have unmerged paths" → resolve conflicts and commit
# Or abort: git merge --abort

Prevention Options

Option 1: Exclude .git/ from iCloud sync

Add a .nosync extension or use an iCloud exclusion mechanism:

# Rename .git directory to bypass iCloud (not recommended — breaks git)
# Better: move the entire repo outside iCloud Drive

# For Obsidian vault: keep vault in iCloud but move .git outside
# (Not straightforward with standard git)

The cleanest solution for Obsidian: store the vault in iCloud (for Obsidian's own sync of notes) but use Obsidian Sync (Obsidian's paid service) instead of git for device sync.

Option 2: Use Obsidian Sync instead of git-based sync

Obsidian Sync handles device conflicts at the application level — it understands markdown notes and syncs them without creating filesystem-level conflicts. Downside: costs $10/month. Upside: no git conflict corruption possible.

Option 3: Single commit source

Designate one device as the git commit device (e.g., only the Mac commits). Other devices open the vault read-only or in Obsidian without the git plugin active. iCloud still syncs the files, but only one device creates git commits — no diverged histories.

Option 4: .gitignore-based partial solution

Cannot ignore .git/ itself (git always tracks .git/), but can exclude files that iCloud conflict-copies more aggressively:

# This does NOT help — git itself needs .git/refs/heads/main
# and cannot ignore files in its own metadata directory

This option doesn't work — the .git/ directory is not tracked by git and cannot be gitignored; iCloud syncs it regardless.

Obsidian + iCloud + Git Compatibility Matrix

Setup Risk Notes
Obsidian Sync only (no git) Low Paid; no conflict files in .git/
git in iCloud vault, single device Low No simultaneous edits
git in iCloud vault, 2+ devices High Conflict files in .git/ on simultaneous edits
git repo outside iCloud None Vault not synced by iCloud
iCloud vault + Obsidian git plugin + 2 devices Very high Both git and iCloud create conflicts

Sources

  • daily/2026-04-27.md — Obsidian vault git repo on iCloud failed with badRefName; root cause was iCloud creating main 2 and ORIG_HEAD 2 in .git/refs/heads/ after simultaneous edits on two devices; fix was deleting conflict files and merging diverged histories; lesson: don't keep vault open on two devices simultaneously with git sync