-
-
Notifications
You must be signed in to change notification settings - Fork 109
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
Parent directory appears out of order with contents_first(true)
in certain circumstances
#163
Comments
Actually, if you set |
Well, I have a fix, but I’m not quite sure why it works. The problem seems to be related to not adding the root symlink to In other words, change Lines 844 to 846 in 461f4a8
if md.file_type().is_dir() {
itry!(self.push(&dent));
if self.opts.contents_first {
self.deferred_dirs.push(dent);
return None;
}
} (I suspect that doesn’t match your style, so this is more to make things clear.) |
Thanks for the diagnosis and coming up with a fix! Would you mind submitting a PR? And in particular, it would be good to come up with a comment explaining that branch and why it fixes the bug. I've had a quick look at the code, but unfortunately the |
Sure! Yeah, definitely a little hard to follow. The price of flexibility, I suppose. It will probably be a few days at least — I’d like a better understanding so I can be sure I'm fixing it right. |
This fixes two incorrect behaviors when `contents_first` is on and the root path is a symlink: 1. The root path was returned first in the iterator instead of last. 2. Some subdirectories were returned out of order. The issue was that root symlinks were returned immediately rather than being pushed onto the `deferred_dirs` vec. That lead to `deferred_dirs` and `depth` being out of sync, which lead to deferred directories being processed one ascent too late. TO DO: [ ] Better tests (the current ones are not stable) [ ] Remove FIXME [ ] Consider commenting changed code; it seems somewhat hard to follow to my sleep deprived brain. Fixes: BurntSushi#163
Looks like there’s another bug when both I’m pretty sure I’m not breaking anything on Windows, but I don’t have recent Windows license to check (and even if I did I know nothing about reparse points beyond what I gleaned from rust-lang/rust#46484). |
I’m pretty sure I’m wrong about there being a bug related to |
This fixes two incorrect behaviors when `contents_first` is on and the root path is a symlink: 1. The root path was returned first in the iterator instead of last. 2. Some subdirectories were returned out of order. The issue was that root symlinks were returned immediately rather than being pushed onto the `deferred_dirs` vec. That lead to `deferred_dirs` and `depth` being out of sync, which lead to deferred directories being processed one ascent too late. This also changes the internal handling of the `same_file_system` option slightly. Previously, if a directory was found to be on a different file system it would _not_ be pushed to the stack, but it _would_ be pushed to the deferred list. This did not matter because in those cases `handle_entry()` would return to `next()`, which would immediately pop the directory off the deferred list and return it. This ensures that the directory is returned immediately, and is not pushed to either the stack or the deferred list. (I think this makes the code clearer.) Fixes: BurntSushi#163
This fixes two incorrect behaviors when `contents_first` is on and the root path is a symlink: 1. The root path was returned first in the iterator instead of last. 2. Some subdirectories were returned out of order. The issue was that root symlinks were returned immediately rather than being pushed onto the `deferred_dirs` vec. That lead to `deferred_dirs` and `depth` being out of sync, which lead to deferred directories being processed one ascent too late. TO DO: [ ] Remove FIXME [ ] Consider commenting changed code; it seems somewhat hard to follow to my sleep deprived brain. Fixes: BurntSushi#163
This fixes two incorrect behaviors when `contents_first` is on and the root path is a symlink: 1. The root path was returned first in the iterator instead of last. 2. Some subdirectories were returned out of order. The issue was that root symlinks were returned immediately rather than being pushed onto the `deferred_dirs` vec. That lead to `deferred_dirs` and `depth` being out of sync, which lead to deferred directories being processed one ascent too late. This also changes the internal handling of the `same_file_system` option slightly. Previously, if a directory was found to be on a different file system it would _not_ be pushed to the stack, but it _would_ be pushed to the deferred list. This did not matter because in those cases `handle_entry()` would return to `next()`, which would immediately pop the directory off the deferred list and return it. This ensures that the directory is returned immediately, and is not pushed to either the stack or the deferred list. (I think this makes the code clearer.) Fixes: BurntSushi#163
I’m not sure what’s going on here. I‘m happy to spend some time sorting this out, but I figured I’d report it first to see if it was obvious to you.
This is easier to understand by example than by explanation. Nevertheless, I’ll try to define it first.
Explanation
When:
Walkdir.new()
is passed a symlink to the directory structure.contents_first(true)
and walkdir is ascending out of a certain subdirectory, it will return another entry in the parent directory before the subdirectory itself.
Example
Output:
I would expect walking the symlink to either behave the same as walking the directory, or just refuse to traverse the symlink (since
follow_links
defaults tofalse
).The text was updated successfully, but these errors were encountered: