diff --git a/src/Framework/Traits.cs b/src/Framework/Traits.cs
index 9be74ea1bc8..6ec7dd3afad 100644
--- a/src/Framework/Traits.cs
+++ b/src/Framework/Traits.cs
@@ -188,6 +188,11 @@ internal class EscapeHatches
///
public readonly bool AlwaysDoImmutableFilesUpToDateCheck = Environment.GetEnvironmentVariable("MSBUILDDONOTCACHEMODIFICATIONTIME") == "1";
+ ///
+ /// When copying over an existing file, copy directly into the existing file rather than deleting and recreating.
+ ///
+ public readonly bool CopyWithoutDelete = Environment.GetEnvironmentVariable("MSBUILDCOPYWITHOUTDELETE") == "1";
+
///
/// Emit events for project imports.
///
diff --git a/src/Tasks/Copy.cs b/src/Tasks/Copy.cs
index 0485ae97b36..606677f3305 100644
--- a/src/Tasks/Copy.cs
+++ b/src/Tasks/Copy.cs
@@ -285,7 +285,10 @@ private void LogAlwaysRetryDiagnosticFromResources(string messageResourceName, p
MakeFileWriteable(destinationFileState, true);
}
- if (ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_8) && destinationFileState.FileExists && !destinationFileState.IsReadOnly)
+ if (ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_8) &&
+ Traits.Instance.EscapeHatches.CopyWithoutDelete != true &&
+ destinationFileState.FileExists &&
+ !destinationFileState.IsReadOnly)
{
FileUtilities.DeleteNoThrow(destinationFileState.Name);
}