Though not fully documented, starting with 27.0.1 aka platform tools r27 (not before) the following can be used:
adb push --sync local/ device/
# adb pull --sync -a device/. local/
(note the trailing dot on
adb pull; without that you'd end up with
local/device/*, see here; also the
-a is needed only here to keep the timestamps of the files intact)
Not directly related to
adb push: file permissions are not kept, which is probably due to the file system used. Files pushed to the internal SD card will always be set to
0660 and on the external card to
0771, which I could not even change using
adb shell chmod on the device itself (though I received no error either on trying).
If you need more options as you might know them from
--exclude), you can also take a look at the Python script better-adb-sync.
Update: running a few tests it seems
--sync is simply ignored with
adb pull even if no error is thrown: newer files on target have been overwritten! Not sure if implementation is planned, but with r27 being released in 2018 I'd not place a bet on that. With
push it works as advertized, though.