Even though Apple introduced something similar to a “merge” feature in macOS Finder some time ago, you may still want to fall back to a more controllable method for properly merging two folders in macOS. To do so, the built-in rsync
Terminal command comes in handy.
What is rsync
The rsync
function is basically an enhancement of the cp
(aka “copy“) or respectively the rcp
UNIX commands and is shipping out-of-the-box in macOS.
How to use rsync in macOS to merge folders
Here’s an example for how to merge two folders in macOS – let’s say folder “new-files
” and folder “existing-files
” – by not overwriting existing files with the same size and timestamp.
Simply launch the Terminal.app from the Utilities folder in macOS Finder & adapt the following command:
rsync -arv --exclude=.* /path/to/folder/new-files/ /path/to/folder/existing-files/
What’s the meaning of each required rsync command?
-arv
: this is a simplified list for the three individual commands-a
,-r
and-v
:-a
: copies all files by retaining all their original meta data (creation & changed date, permissions, etc.)-r
: copies the given folder directory recursively (all sub-folders and their files will be considered too)-v
: verbose – displays all information about what rsync is doing in the Terminal
--exclude=.*
: files, whose file name start with a dot “.
” (e.g. “.DS_STORE
“) will not be considered
Excluding & including certain files when merging folders using rsync
A very neat feature available with rsync is the possibility to explicitly include or exclude files when merging or copying folders.
As you may have noticed, you can use regex patterns matching only certain file names for inclusion or exclusion in the process – and also chain together multiple exclude or include rules using rsync
, as the following example shows:
rsync -arv --exclude=.* --exclude=*.jpg --include=test.jpg /path/to/folder/new-files/ /path/to/folder/existing-files/
One of the most relevant exclude-options was listed previously with .*
to exclude .DS_STORE
files – but you can enhance it e.g. to exclude all JPEG-image files, except a specific test.jpg
-file – just fine-tune this to whatever needs you have.
In addition to the *
-wildcard placeholder, you can also use other common regex patterns like +
or ?
for matching file names. I recommend using an online tool like regex101 to verify the exclude/include patterns against your list of files, to verify the outcome. Or run the command in dry-run mode, as described in the following paragraph.
Verifying the rsync command before running it for real – using a dry-run
Are you planning on running the merge command for the first time? Or did you change some parameters, exclusions and inclusions, which you are not sure about? There’s a simple solution: verify the command in a sandboxed mode (aka it won’t actually change anything – just showing what would happen) using rsync’s --dry-run
mode:
rsync -arv --exclude=.* --exclude=*.jpg --include=test.jpg --dry-run /path/to/folder/new-files/ /path/to/folder/existing-files/
More infos & commands for rsync
There is much more to rsync than described in this post! To get a full list of all available commands, simply type man rsync
in the Terminal window – or refer to the online manual for rsync.
This article updates a previously published post
This article was originally posted in German on May 27, 2009 and is slightly modified to represent today’s circumstances. You can access the original post still under it’s initially published address: OS X: Inhalte zweier Ordner zusammenführen (aka “merge”)
I wrote Truck.app to make rsync as simple as ‘drag and drop’. Check it out if you want -> bonhardcomputing.com/truck/
Super input! Thanks for sharing your Knowledge!
I also used the “u” Option (update) to update newer files on the target folder, which is in my opinion the desired behaviour:
– Copy new files vom source to target folder
– Do not overwrite newer versions in target with older versions from source folder
– Do overwrite older versions in target with newer versions from source folder
sync -aruv –exclude=.* –dry-run source/ target/
Thanks for this addition, Uwe. That‘s indeed a helpful option for using
rsync
in many use cases 👍