acheronfail / repgrep

An interactive replacer for ripgrep that makes it easy to find and replace across files on the command line.
Apache License 2.0
267 stars 4 forks source link

failed to persist temporary file path #65

Closed muralikodali closed 1 year ago

muralikodali commented 2 years ago

replacement fails with following error :

Failed to make all replacements: failed to persist temporary file path: Invalid cross-device link (os error 18)
An error occurred during replacement: Failed to perform all replacements, see log
Logs available at: /tmp/.repgrep

no logs are avaiable at /tmp/.repgrep

dimon4ezzz commented 2 years ago

same

jwest23 commented 1 year ago

Also getting this. I can work around it, though, by setting TMPDIR to point to a directory on the same file system as the files I'm working on.

It might work to swap out NamedTempFile::new() for NamedTempFile::new_in(path_buf.parent.as_path()) but I haven't confirmed this.

acheronfail commented 1 year ago

Interesting - can I get any more information?

muralikodali commented 1 year ago

My OS is Arch Linux

mount | grep 'tmp' 
/dev/disk/by-uuid/3c6182b4-8f62-4c93-aa76-246fbaa495f6 on /tmp type tmpfs (rw,relatime,inode64)
acheronfail commented 1 year ago

Ah, so your /tmp directory is on a separate disk to where you're running rgr? I'll see if I can reproduce it on my machine.

acheronfail commented 1 year ago

I can't seem to reproduce this, I've even tried installing Arch in a VM with /tmp mounted on a separate disk and even with a different filesystem to where rgr is running, and it all just works.

Is there any more information about your system you can give me?

jwest23 commented 1 year ago

My machine is Debian 11, running in a WSL2 VM.

❯ mount | grep '/tmp'
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
tmpfs on /home/jwest/tmp type tmpfs (rw,nosuid,nodev,noatime)

Other non-relevant entries elided.

For clarity, my TMPDIR is normally set to /home/jwest/tmp

The file system that the files on which I'm trying rgr are on:

❯ mount | grep sdc
/dev/sdc on / type ext4 (rw,relatime,discard,errors=remount-ro,data=ordered)

If I run rgr with TMPDIR set to /home/jwest/tmp, I get the same failure the OP did. I also get the same failure the OP did if I set TMPDIR to /tmp before running rgr. A way I've found to succeed is to set TMPDIR=. then run rgr.

Another way I've found is in replace.rs to change line 112 from:

let mut temp_file = NamedTempFile::new()?;

to:

let mut temp_file = NamedTempFile::new_in(path_buf.parent().unwrap())?;

acheronfail commented 1 year ago

Ahh, thanks for bringing that up change again, I looked into it some more and discovered this in the temp_file crate's documentation:

Note: Temporary files cannot be persisted across filesystems. Also neither the file contents nor the containing directory are synchronized, so the update may not yet have reached the disk when persist returns.

Now I know where the error is, I'll see if I can perform the replacement atomically in a different way...

acheronfail commented 1 year ago

After reading tempfile's documentation and their issue tracker, I think @jwest23's suggestion aligns with how that crate should be used, so I'll go with that.

Thanks for all your input!