Git fails to create AppleDouble files (prefixed with '._') that macOS uses to store extended attributes and resource forks. This typically happens when checking out files from a repository that was created on macOS and contains these metadata files. The fix involves configuring Git to ignore these files or cleaning the repository.
This error occurs when Git attempts to create or modify AppleDouble metadata files—those with the `._` prefix—during checkout, merge, or other operations. These files are a macOS-specific artifact used to store extended attributes (like Finder comments, custom icons, and file labels) and resource forks when files are copied to file systems that don't natively support them. When macOS writes files to network drives, USB drives formatted as FAT32/exFAT, or archives, it creates companion `._*` files to preserve metadata. For example, copying `document.pdf` might create both `document.pdf` and `._document.pdf`. The problem arises when: 1. Someone commits these `._*` files to a Git repository (usually unintentionally) 2. Another user (often on a different OS) clones or pulls the repository 3. Git cannot create these files due to filename restrictions, case sensitivity issues, or file system limitations On Windows, these files may fail to create because `._` prefixed files can conflict with system restrictions. On Linux, they're often unnecessary but can cause conflicts. Even on macOS, Git may struggle with these files if they're malformed or if the working directory is on a non-HFS+ volume.
macOS provides a built-in utility to merge resource forks back into their parent files:
# Navigate to your repository
cd /path/to/repository
# Clean AppleDouble files recursively
dot_clean .
# This merges ._* files back into their parent files
# or removes them if the parent doesn't existThe dot_clean command:
- Merges ._file.txt metadata back into file.txt's extended attributes
- Removes orphaned ._* files with no corresponding parent
- Works recursively through all subdirectories
After running this, check Git status:
git status
# The ._* files should no longer appearIf AppleDouble files are already committed, remove them from the repository:
# Find all tracked ._* files
git ls-files | grep '^\.\?\._'
# Remove them from Git (but keep local copies if they exist)
git rm --cached '._*'
git rm --cached '**/._*'
# Or remove them recursively using find (more thorough)
find . -name '._*' -exec git rm --cached {} \;
# Commit the removal
git commit -m "Remove macOS AppleDouble resource fork files"This removes the files from Git's index but doesn't delete your local copies. Push the changes so other team members get a clean repository.
Prevent macOS metadata files from being tracked in the future:
# Add to your project's .gitignore
echo "._*" >> .gitignore
echo ".DS_Store" >> .gitignore
echo ".AppleDouble" >> .gitignore
echo ".LSOverride" >> .gitignore
# Commit the updated .gitignore
git add .gitignore
git commit -m "Ignore macOS metadata files"A comprehensive macOS section for .gitignore:
# macOS metadata
.DS_Store
.AppleDouble
.LSOverride
._*
# Icon files
Icon
# Thumbnails
._*
# Files on external disks
.Spotlight-V100
.Trashes
.fseventsd
# Network drives
.apdiskYou can also use a global gitignore for your machine:
# Create global gitignore
echo "._*" >> ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
# Configure Git to use it
git config --global core.excludesfile ~/.gitignore_globalIf you're stuck in a failed checkout state, reset and try again:
# Abort any in-progress operations
git merge --abort 2>/dev/null || true
git rebase --abort 2>/dev/null || true
git cherry-pick --abort 2>/dev/null || true
# Reset to the last good state
git reset --hard HEAD
# Clean untracked files (including ._* files)
git clean -fd
# On macOS, also clean AppleDouble files
dot_clean . 2>/dev/null || true
# Now retry your checkout/merge
git checkout <branch-name>Warning: git reset --hard and git clean -fd will discard uncommitted changes. Make sure to stash or commit any work you want to keep first.
If removing the files from the repository isn't an option, exclude them from your checkout:
# Enable sparse checkout
git config core.sparseCheckout true
# Create sparse-checkout file (exclude ._* files)
echo "/*" > .git/info/sparse-checkout
echo "!._*" >> .git/info/sparse-checkout
echo "!**/._*" >> .git/info/sparse-checkout
# Update working directory
git read-tree -mu HEADWith Git 2.25+, you can use the new sparse-checkout command:
# Initialize sparse checkout
git sparse-checkout init --cone
# Add patterns to exclude
git sparse-checkout set --no-cone '/*' ':!._*' ':!**/._*'This lets you work with the repository without checking out the problematic AppleDouble files.
For a thorough cleanup, remove these files from the entire Git history:
Using git-filter-repo (recommended):
# Install git-filter-repo
pip install git-filter-repo
# or: brew install git-filter-repo
# Remove ._* files from all history
git filter-repo --path-glob '._*' --invert-paths
# Also remove them from subdirectories
git filter-repo --path-glob '**/._*' --invert-pathsUsing BFG Repo Cleaner:
# Download BFG
brew install bfg
# Remove ._* files from history
bfg --delete-files '._*' --no-blob-protection
# Clean up
git reflog expire --expire=now --all
git gc --prune=now --aggressiveImportant: History rewriting requires a force push and coordination with your team:
git push --force-with-leaseAll team members will need to re-clone or carefully rebase their local branches.
Prevent macOS from creating AppleDouble files on network volumes:
# Disable .DS_Store and AppleDouble files on network volumes
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
# Disable on USB drives too
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
# Restart Finder to apply changes
killall FinderThis prevents future ._* files from being created when working on network shares or external drives.
Note: This doesn't affect local HFS+ or APFS drives, where extended attributes are stored natively in the file system rather than in companion files.
### Understanding AppleDouble Format
macOS uses extended attributes (xattrs) to store metadata like:
- Finder info (color labels, comments)
- Resource forks (legacy, rarely used today)
- Quarantine flags (downloaded file warnings)
- Custom icons
On HFS+ and APFS file systems, this metadata is stored natively. On other file systems (FAT32, exFAT, NTFS, NFS), macOS creates AppleDouble companion files with the ._ prefix to preserve this metadata.
### The ._* File Format
AppleDouble files contain:
- A magic number header (0x00051607)
- Finder info
- Resource fork data (if any)
- Extended attribute data
You can inspect them:
# View extended attributes on a file
xattr -l filename
# View the binary content of an AppleDouble file
xxd ._filename | head
# List all files with extended attributes
find . -exec xattr -l {} \; 2>/dev/null### Cross-Platform Issues
The ._* files cause problems across platforms:
Windows:
- May interpret ._ as a special prefix
- Some applications choke on these files
- They clutter directories visibly
Linux:
- They're useless (no program reads them)
- Take up extra space
- Can cause archive extraction issues
macOS (different volume):
- May fail to merge back correctly
- Can become orphaned if parent is renamed
### Git's Case Sensitivity Problems
On case-insensitive file systems (macOS default, Windows), Git may struggle when both:
- ._File.txt
- ._file.txt
exist in the repository. This causes the "unable to create file" error because the file system treats them as the same file.
Check for case conflicts:
# Find potential case conflicts
git ls-files | sort -f | uniq -di### Archiving Repositories Without AppleDouble Files
When creating archives from macOS:
# Use tar with --disable-copyfile to skip resource forks
COPYFILE_DISABLE=1 tar -cvzf archive.tar.gz folder/
# Or set the environment variable globally
export COPYFILE_DISABLE=1
# For zip, use the -x flag to exclude
zip -r archive.zip folder/ -x "*/._*" -x ".DS_Store"### CI/CD Considerations
If your CI fails due to ._* files:
# GitHub Actions example - clean before build
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Remove AppleDouble files
run: find . -name '._*' -delete
- name: Build
run: make build### Checking If Resource Forks Are Present
# List files with resource forks
find . -type f -exec sh -c '
if [ -s "$1/..namedfork/rsrc" ] 2>/dev/null; then
echo "$1 has resource fork"
fi
' _ {} \;
# Check a specific file
ls -l filename/..namedfork/rsrc 2>/dev/null && echo "Has resource fork"### Recovering Data from ._* Files
If you need to restore metadata from orphaned AppleDouble files:
# dot_clean can merge if the parent exists
dot_clean /path/to/folder
# For manual recovery, use ditto
ditto --rsrc ._filename filename### Git LFS and AppleDouble Files
If using Git LFS, AppleDouble files can cause additional issues:
- They may be tracked by LFS unintentionally
- They can balloon repository size
- LFS filters may not handle them correctly
Check your .gitattributes:
# See if ._* files are tracked by LFS
git lfs ls-files | grep '\._'
# Exclude from LFS if present
echo '._* !filter !diff !merge !text' >> .gitattributeskex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git