-
-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
copy.Deep does not follow multiple levels of symbolic links #32
Comments
Hmm, good catch. Thank you! |
I understand this problem as follows, do you think it's right? @ob
|
I think the problem is that Deep copy should keep resolving the symlink until it gets to a file that is not a symlink no? So maybe a loop here? |
I might need to check and structure our issue first. |
I think the symlink copying might be broken completely. https://github.com/otiai10/copy/blob/main/test_setup.go#L13 creates an invalid symlink:
it should be pointing to I started trying to fix this here but haven't fully worked out how to get shallow copies to work correctly. If they're relative anyway, they need to fix the relative path to the destination. |
Thanks! |
There's a very difficult issue with the Shallow copy that I'm not sure how to solve. With case09, you have a symlink to a file in the same directory:
With case03 you have a symlink to a file in a different directory:
In case09's case, I think you would expect the new symlink to be pointing to the copied README.md. With case03 the target of the symlink isn't being copied, so what do you do? Create a broken symlink to |
I think for shallow copies creating broken symlinks is the right answer. I believe that's how rsync works. |
The issue with Shallow copies can be fixed by either making the link src relative to the location of the link itself -- not curent working directory -- or by making the link src absolute. Try making this change in setup.go: `// os.Symlink("test/data/case01", "test/data/case03/case01")
` I also theorized that the link above, being a directory link, might be different, so I created a file link, with the same result (problem + fix): `// os.Symlink("test/data/case01/README.md", "test/data/case03/case01readme")
` The fix would also be needed in lcopy() but computing a relative location dynamically from the destination directory for the link isn't simple to me. It would be simpler to just make it absolute. Also note that test/data.copy/case03/case01 will not be pointing to test/data.copy/case01 because they are not related -- unless you use a relative link. An absolute link would point to test/data/case01. The semantics of copying a directory containing a symbolic link are ambiguous, but could be interpreted as favoring a relative link, so that the structure of the copied directory is the same as the copied directory. |
P.S. NOTE: I had to modify the algorith when the link source path name is already 'relocatable', if strings.HasPrefix(origLinkSrc, ".") Here is Playground solution for Shallow copy: first, try to re-base the link source as a relative path https://play.golang.org/p/QlH-y9MM7zC ` import ( func main() { ` |
Regarding Deep copies, I need to test this to be sure, but the option in my fork called "SymlinkBlissfulIgnorance" actually does what I think you want "Deep" to do: it just treats a Symlink as a regular file and copies the linked-to file. And I read in the Unix/Linux manual (somewhere) that link following halts at 250 to prevent malicous linking. So now that we have established the correct link source path name -- should be relative to the Symlink itself -- everything is set and good to go without Deep having to manually follow a chain of Symlinks. Here is my latest, tested code for "Shallow" Symlink (which I think fixes everything): `
` |
I uploaded my fork: github.com/enthor/kmdrv0 -- my testing is nearing conclusion, leaving tidy up and packaging, etc. See doc.txt for a very thorough review of the differences between it and github.com/otiai10/copy. I view this as experimental code, though I will use it in my own project. It definitely validates the otiai10/copy algorithm and code except for the minor issues mentioned so far. And also, today I confirmed that while PreserveTimes does not (cannot) work for Symlink files, it does work with Named Pipes. So, as a scientific experiment and proof of the otiai10 approach, this is a success. And also very humbling. Working at this low-level of system details is quite different from my work in Applications Programming. I welcome any suggestions (except re: verbosity) within the next couple of weeks. Then back to my project: a bespoke, nano-relational self-defining database system (which is already working except for a few features, like an SQL parser, transaction file updates, and a few other minor details :-) After another 6 months on that I plan to return to kmdrv0 and add compares and compression to the repertoire. BTW, I know bupkus about git and github so I am prone to reloading the entire repository if anything goes wrong. Take care to fork kmdrv0 and and comments if you want to study them because I might mess things up and have to start fresh in github. Thank you for your great work. It has helped educate me, and I appreciate your substantial efforts thus far. |
I guess this is still an issue. Ran into it trying to copy a symlink to a ~/.oh-my-zsh, which itself contains a couple of symlinks down there deep. |
Run the following bash script:
to create the following structure:
Then use the following program:
finally, run it:
The text was updated successfully, but these errors were encountered: