5

This is my current situation (simplified, in fact of course many and large files):

Dir1/
  a b c
Dir2/
  a b c d

This has happened before:

  • a b c were copied from Dir1 to Dir2.
  • Within Dir2 the timestamps of a b c got modified accidentally.
  • d got added to Dir2 intentionally.

Now I want to do this: Sync Dir2 back to Dir1. (To whom it concerns: I use rsync)

  • d is new and hence should get copied.
  • a b c in Dir2 and Dir1 are identical in size and data content, but their filestamps differ. Hence they would be unnecessarily copied.

I know that rsync can either compare files by --checksum or --size-only. But this disk/cpu intensive check would have to be repeated in every future sync. Instead I rather want to once and for all correct my mistake by restoring the original file timestamps from those in Dir1 to those in Dir2 with a tool. Then my mistake is corrected, and future syncs can run efficiently.

On Windows these tools are able to copy timestamps only (without copying data):

Does anyone know an appropriate CLI / GUI tool for Mac OS X?

1
  • As mentioned, in the past I already accomplished exactly this task on Windows. I am now curious wether such a tool exists for Mac OS X! Else I will simply (wastefully) copy all data instead of filesystem metadata only.
    – porg
    Aug 27, 2011 at 21:20

3 Answers 3

1

The --size-only flag in rsync is neither CPU nor disk intensive compared to the standard rsync check, in fact it is faster because normally rsync will check both the file size AND the timestamp. You could use the touch command to explicitly match up the timestamps on abc in Dir2. You could delete the files in dir2 and rsync again. These suggestions are great if it's a ton of files so you could wrap them in a script or find. Note that if you just run rsync again, in a typical mode but with the --partial optinoal as well (say rsync -az --partial Dir1 Dir2) it will not copy the files over again, instead it will try to intelligently synchronize them which would I believe would end up transfering over just the timestamps in this case.

4
  • Thanks for the good idea, but sadly rsync with --partial in a local send/receive situation (no network involved) does not result in an intelligent transfer (metadata only) but rather does a complete data transfer. Additionally I tried both with and without --compress. It changed nothing. So rsync seems not to be the "transfer metadata only" tool on Mac OS X, that I am looking for.
    – porg
    Aug 28, 2011 at 12:20
  • Years later: --size-only solves your situation, at least under certain circumstances: If the source timestamps are corrupted and you don't mind getting them into the destination, but at least spare yourself unnecessary data transfers. Solution: Run your rsync once with --size-only. Your destination files' timestamps get updated (metadata only, permanent at destination) from the source indicated by .f..t......n besides their filename! Then run rsync again without --size-only and rsync will tell you everything is properly synced, nil transfers necessary!
    – porg
    Dec 29, 2013 at 17:05
  • @porg you are referring to yourself in the third person here?
    – Ram
    Dec 30, 2013 at 4:55
  • 1
    "you" and "your" as in the generic form "one" and "one's" rather than 3rd person. But sometimes in written form I indeed refer to myself in the 3rd person.
    – porg
    Dec 30, 2013 at 22:44
0

Is it possible that the timestamps aren't important for you? It isn't clear from the question if you are more interested in preserving them or in doing rsyncs without having to copy all that data. If you don't care about the timestamps you can use the touch command to set a specific date on all the files on both machines so they are the same. Something like:

find dirX -type f -print | xargs touch -t 201108250000

Then running the rsync should work without having to worry as the timestamps will be the same on both boxes. I am not near my OS X box to test if this works but I have done this in Linux before.

1
  • I had this idea too. But thanks no, I really want the original timestamps back, without re-copying (unnecessarily!).
    – porg
    Aug 26, 2011 at 22:07
0

I'm not sure of a nice way to do this with rsync, nor do I have any experience with max osx, following is an attempt on linux though and I hope it will either work for you or be 'close enough'.

Warning: This is most certainly the least elegant way to achieve this :)

We need to go through each file in dir1 that is also in dir2, and perform our black magic on it

#!/bin/bash
# warning, really inelegant bash follows
FROMDIR='dir1'
TODIR='dir2'

for FROMFILE in `find $FROMDIR -type f`; do
        TOFILE=`echo "$FROMFILE" | sed "s/^$FROMDIR/$TODIR/"`
        echo "trying $FROMFILE to $TOFILE"

        if [ -e "$TOFILE" ]; then
                NEWDATE=$(stat -c %y $FROMFILE | awk '{print $2, $1}')
                echo "would perform 'touch -d '$NEWDATE' $TOFILE'"
                #touch -d "$NEWDATE" $TOFILE # uncomment me if you want to perform changes
        fi  
done

when you first run this it will make no modifications and instead just echo what it would do, if you feel this is what you want then uncomment the line #touch -d "$NEWDATE" $TOFILE


explanation

stat -c %y filename

gives us the modified time of a file in a human readable format

touch -d "timestamp" filename

will set the modified date of filename to timestamp, however touch seems to be fussy over the time format it takes (it doesnt quite match the output of stat %y, and doesnt seem to allow epoch either).

awk '{print $2,$1}'

will rearrange the output from stat -c %y so that it can be taken by touch -d

putting this together we get

NEWDATE=$(stat -c %y fromfile | awk '{print $2, $1}')
touch -d "$NEWDATE" tofile
4
  • Hi! That solutions sounds sophisticated, and I want to test it. However, I receive following error: syncdate2.sh: line 6: syntax error near unexpected token do$' syncdate2.sh: line 6: for FROMFILE in find $FROMDIR -type f; do$'
    – Burcardo
    Feb 9, 2016 at 17:58
  • @Burcardo thanks for catching that, the 'do$' was a typo and the '$' should not have been there, fixed.
    – cjh
    Feb 10, 2016 at 0:21
  • Thanks for the fix! What about folder names with a dash in between two spaces? e.g. FROMDIR="/media/extHD/my\ folder\ -\ (2016)". I receive error "find: unknown predicate `-\'"
    – Burcardo
    Feb 26, 2016 at 0:30
  • @cjh Thanks in retrospective. Back then I gave up. Now I have a similar project at hand. I plan to convert my screenshot library from pure .png files to .snagit files (= XML file with PNG in blob + metadata + editing markup). Luckily Snagit uses FS timestamps for sorting (not dates in XML). But during import each file gets creation+mod timestamps set freshly. I'd like to run a batch which copies the timestamps if the basename of source and direction matches. So ~/Screenshots/Particular Name.png -> ~/Snagit/Particular Name.snagit. So the script should be whitespace save too.
    – porg
    Oct 29, 2021 at 15:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .