pub fn write(path: &Path, contents: &[u8]) -> Result<()>Expand description
Writes contents to path, replacing it in one step.
The temporary file lives beside the target, because rename across
filesystems is not a rename at all and would fall back to a copy.
Three limits worth knowing rather than discovering.
A target that is a symlink is replaced by a regular file, where fs::write
would have followed the link — .gitattributes under a dotfile manager is
the case where that shows. A target that is one of several hard links to the
same inode loses the link for the same reason. And the temporary file is only
cleaned up on a returned error, so a process killed outright can leave one
behind.
That last one is not always harmless. unlock replaces working-tree files
through here, so on that path the leftover holds a decrypted secret under
a name no .git-xcrypt pattern was written for — secrets/ still covers it,
*.env does not. It inherits the target’s permissions, which for a file git
checked out means it is no more readable than the file it replaces, but a
later git add -A could store it in the clear. There is no portable way to
clean up after SIGKILL; the residue is recorded here rather than hidden.
Every such file is recognised by strip_temporary_suffix, which is what the
user documentation has to tell people to look for after a killed unlock —
and what lock sweeps before it encrypts, since a plaintext leftover would
otherwise survive the one command whose job is to leave none.
§Errors
Error::Io when the temporary file cannot be created, written, flushed or
renamed. On failure the target is left exactly as it was.