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
sync: don't set dir modtimes if already set #7657
Conversation
a5c9771
to
4ea5697
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really nice - thank you :-)
I put some specific nits inline.
General comments:
- Please kill
path.ToSlash
with fire :-) These should not appear in core sync routines - they are supposed to translated to/
at the edges and be/
within rclone. If\
are getting in to the core then that needs fixing, but not here! - The bisync tests are quite annoying aren't they!
- I wonder if we could combine the
s.modifiedDirs
ands.setDirModTimes
somehow... We are storing a lot of directory objects we don't need to potentially. Perhaps we don't know until the end of the sync.
fs/sync/sync.go
Outdated
@@ -399,6 +402,11 @@ func (s *syncCopyMove) pairChecker(in *pipe, out *pipe, fraction int, wg *sync.W | |||
fs.Errorf(pair.Dst, "Source and destination exist but do not match: %v", err) | |||
s.processError(err) | |||
} else { | |||
if pair.Dst != nil { | |||
s.markDirModified(path.Dir(filepath.ToSlash(pair.Dst.Remote()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not need filepath.ToSlash
here - all paths should be unix /
delimited in rclone internals.
If they aren't then that is a bug somewhere else :-)
Please remove them all from this file! Also see later suggestion for a function markDirModifiedObject
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed all the filepath
usages here :) I think the error I was seeing the other day may just have been a transient fluke of GitHub Actions (I've been seeing more of those lately)
Here is an example of what I mean though about the path
library causing issues on Windows with rclone's unix paths: this test fails only on Windows. (And I confirmed it also fails on a real PC, not just GH Actions)
I think the issue in this particular case is path.Join
removing the double //
and then rclone adding it back incorrectly. But there may be other issues as well.
I think it would be really handy to have a more comprehensive library of rclone-safe path manipulation functions!
Haha, will do! There definitely is some issue, I think specific to Windows -- I've run into it multiple times on this and other projects. But I agree this is not the proper fix for it. I'll take these out and try to see if I can find the true cause.
They sure are! I would estimate that my time on this PR was maybe 10% writing code and 90% debugging the bisync tests. But on the other hand, this is a good example of an issue worth knowing about that a more conventional unit test would probably miss.
Yeah, that is basically the problem. At the point that |
ac733f1
to
ca616d7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is looking great except for fspath.Dir
which isn't correct!
See suggestions inline - thank you :-)
Before this change, directory modtimes (and metadata) were always synced from src to dst, even if already in sync (i.e. their modtimes already matched.) This potentially required excessive API calls, made logs noisy, and was potentially problematic for backends that create "versions" or otherwise log activity updates when modtime/metadata is updated. After this change, a new DirsEqual function is added to check whether dirs are equal based on a number of factors such as ModifyWindow and sync flags in use. If the dirs are equal, the modtime/metadata update is skipped. For backends that require setDirModTimeAfter, the "after" sync is performed only for dirs that could have been changed by the sync (i.e. dirs containing files that were created/updated.) Note that dir metadata (other than modtime) is not currently considered by DirsEqual, consistent with how object metadata is synced (only when objects are unequal for reasons other than metadata). To sync dir modtimes and metadata unconditionally (the previous behavior), use --ignore-times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect - thank you :-)
I'll merge this now.
What is the purpose of this change?
Before this change, directory modtimes (and metadata) were always synced from src to dst, even if already in sync (i.e. their modtimes already matched.) This potentially required excessive API calls, made logs noisy, and was potentially problematic for backends that create "versions" or otherwise log activity updates when modtime/metadata is updated.
After this change, a new
DirsEqual
function is added to check whether dirs are equal based on a number of factors such as ModifyWindow and sync flags in use. If the dirs are equal, the modtime/metadata update is skipped.For backends that require
setDirModTimeAfter
, the "after" sync is performed only for dirs that could have been changed by the sync (i.e. dirs containing files that were created/updated.)Note that dir metadata (other than modtime) is not currently considered by DirsEqual, consistent with how object metadata is synced (only when objects are unequal for reasons other than metadata).
To sync dir modtimes and metadata unconditionally (the previous behavior), use
--ignore-times
.Was the change discussed in an issue or in the forum before?
Checklist