git: unable to unlink / path is unmerged / object file is empty (tested)

These three git error messages look related but have three different causes: a permissions problem, an unresolved merge conflict, and a corrupted repository object. We reproduced all three on git 2.47.3 and measured a working fix for each, including a real recovery for the scariest one — a corrupted object file.

1. error: path 'FILE' is unmerged

We created a real merge conflict (two branches editing the same line of the same file) and ran git merge, which correctly stopped with CONFLICT (content): Merge conflict in f.txt. The file now shows as UU (both sides modified) in git status --short. Running git checkout -- f.txt at that point — a common reflex to "just reset the file" — produced:

error: path 'f.txt' is unmerged

Why: during a conflict, git's index holds three versions of the file at once (ours, theirs, and the common ancestor stage), not one. git checkout -- <path> only knows how to restore a single staged version, so it refuses outright rather than guessing which side you want.

The fix depends on which side you actually want to keep:

# keep YOUR side for this file, discard theirs
git checkout --ours -- f.txt
git add f.txt

# keep THEIR side for this file, discard yours
git checkout --theirs -- f.txt
git add f.txt

# or open the file, remove the <<<<<<</=======/>>>>>>> markers by hand, then
git add f.txt
git commit

We confirmed git checkout --ours -- f.txt immediately resolves the conflict for that file and moves it out of unmerged state, letting git commit proceed.

We reproduced this by making a directory read-only (chmod 555) and then asking git to replace a file inside it (git checkout HEAD~1 -- sub/f.txt, which has to delete the current version before writing the old one):

error: unable to unlink old 'sub/f.txt': Permission denied

Why: git's checkout strategy is delete-then-recreate, not edit-in-place. Deleting a file requires write permission on its containing directory, not the file itself — a detail that trips people up. This also surfaces on network filesystems, files locked by another process (a running build, an editor with an open handle, a virus scanner), or files chattr +i-protected on Linux.

The fix we confirmed: restore write permission on the directory, then retry.

chmod 755 sub        # or whatever permission the directory should normally have
git checkout HEAD~1 -- sub/f.txt   # now succeeds

On a shared or CI machine, also check for another process holding the file open (lsof FILE on Linux/macOS) and for directories owned by a different user (ls -la the parent directory) before changing permissions blindly.

3. error: object file ... is empty / fatal: bad object HEAD

This is the serious one: a git object (commit, tree, or blob) on disk has 0 bytes, usually from a killed process, a full disk, or a bad disk/filesystem during a write. We reproduced it by truncating the loose object file for the current HEAD commit:

error: object file .git/objects/46/3fd27... is empty
error: object file .git/objects/46/3fd27... is empty
error: object file .git/objects/46/3fd27... is empty
fatal: bad object HEAD

At this point git log, git status, git show, and even git cat-file -p <sha> on that exact object all fail the same way — the repository is unusable until the object is restored or removed from history. git fsck correctly flags it as object corrupt or missing along with every ref and reflog entry that points to it.

Fix 1 (best): copy the identical object from another clone. Because git object filenames are the content's SHA-1 hash, any other clone, fork, or backup that has the same commit has a byte-identical file at the same path. We confirmed this works end to end: cloning the repo before corrupting it, corrupting the original's object file, then copying the healthy clone's object file over:

cp /path/to/healthy-clone/.git/objects/46/3fd27... .git/objects/46/3fd27...
git log --oneline   # repo is immediately readable again
git fsck            # clean, no errors

Gotcha we hit first: a local git clone hardlinks object files to the source repo by default (same inode) — corrupting the original also silently corrupted our first "backup" clone, since they were the same file on disk. Use git clone --no-hardlinks for any clone you intend to keep as an independent backup, or clone over a network/file transfer (which never hardlinks).

Fix 2 (if no copy of the object exists anywhere): roll the branch back to the last good commit. This discards the corrupted commit (and anything after it) but makes the repository usable again. We confirmed moving the branch ref directly to the last known-good commit works even while HEAD is unreadable:

git update-ref refs/heads/master <parent-sha-of-the-corrupt-commit>
git log --oneline   # repo works again, now at the parent commit

You can find the parent SHA from a teammate's clone, from CI logs, from git reflog entries that predate the corruption, or from the commit hash shown in an old pull request / email / chat message if nothing else survived. Whichever fix you use, immediately run git fsck and, if you have remotes, git fetch --all afterward to confirm nothing else references the lost object.

Frequently asked questions

Why does git say a path is unmerged when I just want to discard my changes to one file?

git checkout -- <path> only works when the index has a single staged version of that file. During a conflict the index holds 3 versions (yours, theirs, and the common ancestor), so it refuses rather than guess. Use git checkout --ours -- <path> or git checkout --theirs -- <path> to pick a side explicitly, then git add it.

I have write access to the file so why does 'unable to unlink' still happen?

Deleting a file needs write permission on its containing directory, not the file itself — we confirmed this by chmod'ing the directory to 555 (read-only) with the file otherwise normal. git's checkout always deletes the old file before writing the new one, so a locked-down or network-mounted parent directory blocks it even if the file's own permissions look fine.

Is 'object file is empty' always unrecoverable?

No — we measured two working recoveries. If any other clone or backup has the same commit, its object file is byte-identical (same SHA = same content) and can simply be copied over. If no copy exists anywhere, moving the branch ref back to the last good commit with git update-ref restores a working repository, at the cost of losing the corrupted commit and anything built on top of it.

What actually causes a git object file to become empty on disk?

A loose object file gets created in one filesystem write. A process kill (OOM, power loss, Ctrl+C at the wrong instant), a full disk mid-write, or underlying disk/filesystem corruption can all leave a 0-byte file where a compressed object should be. It's a storage-layer accident, not something a normal git command causes on its own.

Does a local git clone always share object files with its source repo?

By default, yes — git clone on the same filesystem hardlinks objects for speed, so corrupting one copy corrupts both, since they're literally the same inode. We confirmed this by watching a 'backup' clone go bad along with the original. Pass --no-hardlinks to git clone for a clone meant to serve as an independent backup.

Written with AI assistance. Measured on 2026-10-03 with git version 2.47.3 on Linux, using throwaway repos under /tmp. Every message and exit path below is copy-pasted output from that git binary, not paraphrased or taken from docs. PlainHeaders is our extension; git is free.