Skip to content

Conversation

@Forgind
Copy link
Contributor

@Forgind Forgind commented Apr 20, 2023

Fixes #8684
Fixes #8273

Context

After #8275, we delete any destination file as part of the Copy task if we determine that we really should copy onto it. Unfortunately, if we try to copy a file onto itself, we delete it before we can copy onto itself, which just means it's gone. Fortunately, we have a check earlier that ensures that we skip any copy operation from a location to the same location. Unfortunately, it's a direct string comparison that doesn't evaluate to full paths first, so it misses slightly more complicated examples.

Changes Made

Take into account full paths

Testing

Unit tests + manual test that it doesn't delete the file anymore

Notes

This implementation tries to remove now-unnecessary full path derivations downstream, hence some added complexity, but it still means extra computation on the happy path if we end up creating a hard/symbolic link. An alternate direction eliminating any full path derivations on the happy path would save about 4% of Copy's execution time, per a quick perf test. (With how many samples I used, "no change" is within a standard deviation.)

JaynieBai pushed a commit that referenced this pull request Apr 23, 2023
This reverts commit a93882f.

This is a temporary fix for #8684

The current plan is to revert #8275 in 17.6, as it caused some difficulties, and try to bring it back in 17.7 via #8685.

Summary

#8275 fixed a longstanding confusing and unfortunate behavior in MSBuild in which passing the Copy task a symlink as its destination would copy the source file onto the destination of the symlink rather than overwriting the symlink. Unfortunately, it also introduced a new issue in which copying a file onto itself could often just delete the file instead of copying anything. Customers reported this issue.

Customer Impact

Projects that copy a file onto itself using the Copy task without passing identical paths for source and destination instead delete the file without necessarily even logging an error.

Regression?
Yes, from #8275.

Testing

Unit tests and manually tested that the repro described in #8684 no longer works.

Risk
Minimal (straight revert of the commit that caused the bug)
---------

Co-authored-by: Forgind <[email protected]>
@Forgind Forgind marked this pull request as ready for review May 4, 2023 17:41
internal delegate bool? CopyFileWithState(FileState source, FileState destination);
/// <param name="sourceFileFullPath">Source file's full path</param>
/// <param name="destinationFileFullPath">Destination file's full path</param>
internal delegate bool? CopyFileWithState(FileState source, FileState destination, string sourceFileFullPath, string destinationFileFullPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Should this go into the FileState itself so as to not carry around this related-but-disconnected arg everywhere?

Copy link
Member

@rainersigwald rainersigwald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the test you worked out in #8684?

@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label May 5, 2023
@Forgind Forgind merged commit 0809a23 into dotnet:main May 5, 2023
@Forgind Forgind deleted the copy-onto-self branch May 5, 2023 21:49
rainersigwald added a commit to rainersigwald/msbuild that referenced this pull request Sep 22, 2023
This allows an opt-in workaround for dotnet#9250 that affected deployment
processes can use, mitigating the risk of entirely reverting dotnet#8685.
rainersigwald added a commit that referenced this pull request Sep 22, 2023
This allows an opt-in workaround for #9250 that affected deployment
processes can use, mitigating the risk of entirely reverting #8685.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Copying a file onto itself deletes the file Usage of hard or symbolic linking leads to NuGet cache corruption

2 participants