Skip to main content

write

Function write 

Source
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.