Hard Links – How to Break a Hard-Link In-Place

hard link

I am keeping my dotfiles under version control and the script deploying them creates hard links. I also use etckeeper to put my /etc under version control. Recently I have gotten warnings like this:

warning: hard-linked files could cause problems with bzr

A simple copy (cp filename.ext filename.ext) will not work:

cp: `filename.ext' and `filename.ext' are the same file

Renaming/moving a file – except across volumes – also doesn't break the hard-link.

So my question is: is there a way to break a hard-link to a file without actually having to know where the other hard-link/s to that file is/are?

Best Answer

cp -p filename filename.tmp
mv -f filename.tmp filename

Making it scriptable:

dir=$(dirname -- "$filename")
tmp=$(TMPDIR=$dir mktemp)
cp -p -- "$filename" "$tmp"
mv -f -- "$tmp" "$filename"

Doing the copy first, then moving it into place, has the advantage that the file atomically changes from being a hard link to being a separate copy (there is no point in time where filename is partial or missing).