Skip to content

[Bug]: Copying a file onto itself deletes the file #8684

@Forgind

Description

@Forgind

Issue Description

When calling the Copy task, we now delete the destination file (if present) before copying the source file to that location:
#8275

That ensures that if the destination file is actually a symbolic link pointing to, say, the user's nuget cache, we don't write through the link and corrupt the file at the other end.

However, that causes a problem when the source file and destination file are the same. We delete the source file, and then there's no file to copy to the destination location!

Confusingly, this doesn't even throw an exception when the real problem occurs because we're already past the existence checks in Copy, and File.Copy doesn't know how to get its exception to MSBuild loggers. An exception is thrown on the second build when the Copy task is invoked with a file that never existed or during the first build if the copied file is subsequently used.

Steps to Reproduce

Create a new console app with dotnet new console. Add this target:

<Target Name="BadCopy">
  <Copy SourceFiles=".\Program.cs" DestinationFiles="Program.cs" />
</Target>

Execute the target with msbuild <project> /t:BadCopy

Expected Behavior

Copies Program.cs on top of itself

Actual Behavior

Deletes Program.cs

Analysis

The .\ in the Target is intentional and necessary. We have a check earlier in Copy that the SourceFile and DestinationFile have different "Name"s. This is the path passed in, however, not the full path. This can also occur if someone wants to copy a relative path on top of a full path or vice versa.

Versions & Configurations

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions