[PATCH 34/41] robocopy: add flag to exclude files only found in source / destination (/XX, /XL)

Florian Eder others.meder at gmail.com
Mon Sep 6 09:55:11 CDT 2021


Implements the /XX and /XL flags, which prevent the overwriting / deletion of files
that only exist in the source, but not the destination, or only the destination, but not
the source, by flags like /PURGE or /MOVE

Signed-off-by: Florian Eder <others.meder at gmail.com>
---
 programs/robocopy/main.c     | 26 ++++++++++++++++++++++++--
 programs/robocopy/robocopy.h |  2 ++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 2fc0c39503d..620154b58c8 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -254,6 +254,16 @@ static void parse_arguments(int argc, WCHAR *argv[])
                 /* xd includes all following directories, until the next option / flag */
                 is_xd = TRUE;
             }
+            /* xx - Ignore files in destination that are not also in source */
+            else if (!wcsicmp(argv[i], L"/xx"))
+            {
+                options.exclude_files_not_in_source = TRUE;
+            }
+            /* xl - Create no new files in destination folder */
+            else if (!wcsicmp(argv[i], L"/xl"))
+            {
+                options.create_no_new_files = TRUE;
+            }
             /* lev - Limit depth of subdirectories */
             else if (!wcsnicmp(argv[i], L"/lev:", 5))
             {
@@ -483,6 +493,8 @@ static BOOL is_valid_file(WCHAR *source, WCHAR *destination)
     if (destination_handle == INVALID_HANDLE_VALUE)
     {
         CloseHandle(source_handle);
+        /* ignore file if no file at the destination path exist and no no files should be created */
+        if (options.create_no_new_files) return FALSE;
         return TRUE;
     }
     GetFileTime(destination_handle, &destination_creation_time, &destination_access_time, &destination_modified_time);
@@ -533,7 +545,9 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
         if (PathIsDirectoryW(current_absolute_path))
         {
             /* ignore empty directories if empty subdirectories are not copied */
-            if ((PathIsDirectoryEmptyW(current_absolute_path) && !options.copy_empty_subdirectories)) continue;
+            if ((PathIsDirectoryEmptyW(current_absolute_path) && !options.copy_empty_subdirectories) ||
+                options.create_no_new_files)
+                continue;
 
             /* Create the directory path and then create the directory itself */
             if (!options.dry_run && (!create_directory_path(target_path) ||
@@ -586,7 +600,7 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
         else statistics->extra_files = TRUE;
 
         /* if purge is specified (and xx is not set), we delete the (non-excluded) extra files and folders from the destination */
-        if (options.purge_destination)
+        if (options.purge_destination && !options.exclude_files_not_in_source)
         {
             current_absolute_path = get_combined_path(options.destination, current_path->name);
             /* only files or empty folders */
@@ -662,6 +676,14 @@ static WCHAR *get_option_string(void)
     if (options.dont_overwrite_older_files)
         wcscat(temp_string, L"/XO ");
 
+    /* Ignore files in destination only */
+    if (options.exclude_files_not_in_source)
+        wcscat(temp_string, L"/XX ");
+
+    /* No new files */
+    if (options.create_no_new_files)
+        wcscat(temp_string, L"/XL ");
+
     /* Max File Size */
     if (options.max_size != MAXLONGLONG)
         swprintf(temp_string + wcslen(temp_string), ARRAY_SIZE(temp_string) - wcslen(temp_string),
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index cf396f88dfc..376c466d907 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -52,6 +52,8 @@ struct robocopy_options {
     FILETIME max_time;
     BOOL dont_overwrite_newer_files;
     BOOL dont_overwrite_older_files;
+    BOOL exclude_files_not_in_source;
+    BOOL create_no_new_files;
 };
 
 struct robocopy_statistics {
-- 
2.32.0




More information about the wine-devel mailing list