Jim Bolla
Jim Bolla

Reputation: 8295

How to do an MSBuild copy command that doesn't overwrite existing files?

Looking at the documentation for the Copy task, I don't see an obvious way to copy files without overwriting existing files at the destination. I only want to copy new files.

What I have so far:

<ItemGroup> 
  <Packages Include=".nuget-publish\*.*"  />
</ItemGroup>

<Copy SourceFiles="@(Packages)" DestinationFolder="\\server\nuget\packages\" />

Upvotes: 6

Views: 7309

Answers (3)

Raman Zhylich
Raman Zhylich

Reputation: 3697

Condition attribute can be used to filter source files:

<Copy SourceFiles="@(SourceFiles)" DestinationFiles="$(DestinationPath)%(RecursiveDir)%(Filename)%(Extension)" Condition="!Exists('$(DestinationPath)%(RecursiveDir)%(Filename)%(Extension)')" />

Upvotes: 9

user2274318
user2274318

Reputation: 1

The SkipUnchangedFiles="true" option copies files only if a source file is newer than destination file.

Sometimes, you need to copy only files that do not exist in destination folder without any file date comparison. In this case you may use condition on Copy task:

<Copy SourceFiles="%(Packages.Identity)" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" Condition="!(Exists(@(Packages->'$(TargetDir)%(Filename)%(Extension)')))" />

Upvotes: -1

Nicodemeus
Nicodemeus

Reputation: 4083

In your link there is an attribute "SkipUnchangedFiles". Add that to the copy task and set it to "true".

<Copy SourceFiles="@(Packages)" DestinationFolder="\\server\nuget\packages\" SkipUnchangedFiles="true" />  

EDIT: I set up a sample project with the following.

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup> 
        <ExistingPackages Include="dest\*.*" />
        <Packages Include="src\*.*" Exclude="@(ExistingPackages -> 'src\%(FileName)%(Extension)')" />
    </ItemGroup>
    <Target Name="Build">
        <Message Text="PackagesToCopy @(Packages)" Importance="high" />
    </Target>
</Project>

Folder + file taxonomy is:

src\
    doc1.txt
    doc2.txt
    doc3.txt
    doc4.txt
    doc5.txt
    doc6.txt
dest\
    doc2.txt
    doc4.txt
    doc6.txt
CopyNew.proj

When I run msbuild.exe CopyNew.proj, I get the following output:

Build:
  PackagesToCopy src\doc1.txt;src\doc3.txt;src\doc5.txt

So now @(Packages) no longer contains the files that exist in the destination folder!

Upvotes: 6

Related Questions