6.6 KiB
| title | aliases | tags | sources | created | updated | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| iCloud Sync — Git Repository Corruption via Conflict Files |
|
|
|
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 2is an invalid git ref name — git rejects any ref containing a space;git status,git log, andgit pullall fail withfatal: 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
* 2files from.git/refs/heads/, then merge the diverged histories withgit 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:
- Vault is open on Device A (Mac) and Device B (iPhone/iPad) simultaneously
- Both devices make changes that result in different git commits (Device A via shell, Device B via Obsidian's git plugin)
- iCloud syncs
.git/refs/heads/mainfrom both devices — they have different SHA hashes - iCloud detects a conflict and creates
.git/refs/heads/main 2alongside the original.git/refs/heads/main - 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 |
Related Concepts
- wiki/concepts/memory-compiler-mac-migration — Obsidian vault and git repository migration context
- wiki/concepts/git-includeif-per-remote — git configuration for multiple identities across repos
- wiki/concepts/fish-fisher-conf-d-conflict — similar "file managed by tool X corrupted by external copy" pattern (Fisher vs manual conf.d copy)
Sources
- daily/2026-04-27.md — Obsidian vault git repo on iCloud failed with
badRefName; root cause was iCloud creatingmain 2andORIG_HEAD 2in.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