Для всех, кто сталкивается с этим и нуждается в коде, здесь есть задача синхронизации одного местоположения с другим на основе содержимого, а не метки времени, он использует модифицированный селектор , а не другой селектор в другом ответе, чтобы дать больше контроля над тем, как рассчитываются различия файлов:
<project name="Demo" default="newSync">
<description>
Sync from ${foo} to ${bar}
</description>
<macrodef name="syncContents">
<attribute name="from"/>
<attribute name="to"/>
<sequential>
<fileset id="selectCopyFiles" dir="@{from}">
<modified algorithm="hashvalue"/>
</fileset>
<fileset id="selectDeleteFiles" dir="@{to}">
<not>
<present targetdir="@{from}"/>
</not>
</fileset>
<copy overwrite="true" todir="@{to}">
<fileset refid="selectCopyFiles"/>
</copy>
<delete includeEmptyDirs="true">
<fileset refid="selectDeleteFiles"/>
</delete>
</sequential>
</macrodef>
<target name="newSync">
<syncContents from="${foo}" to="${bar}"/>
</target>
</project>
Обратите внимание, что это делает зеркальное отображение foo (синхронизация A-> B), если вы хотите двунаправленную синхронизацию, вы можете заменить удаление копией из B-> A и предоставить задачу concat для работы с изменениями того же самого файл в обоих местах.