Skip to content

Instantly share code, notes, and snippets.

@samsonjs
Created January 18, 2011 04:00
Show Gist options
  • Select an option

  • Save samsonjs/783965 to your computer and use it in GitHub Desktop.

Select an option

Save samsonjs/783965 to your computer and use it in GitHub Desktop.
poor man's bi-directional sync
#!/usr/bin/env node
// Sync two dirs giving precedence to the machine with the most recently modified files.
// After the first sync we sync again with the opposite precedence to make sure files
// deleted on either machine stay gone.
//
// The (primary) problem with this approach is that the newest changes always win. If
// you edit a file on both machines the latest changes will be the *only* remaining
// changes. Be careful if you actually use this!
var spawn = require('child_process').spawn
, N = 2
, Local = 0
, Remote = 1
, latestUpdates = []
, localDir = process.argv[2]
, remoteDir = process.argv[3]
if (!(localDir && remoteDir)) {
console.warn('usage: sync.js <local> <remote>')
process.exit(1)
}
function checkIfDone() {
if (latestUpdates.length < N) return
function done(e) { console.log(e ? 'fail' : 'ok') }
if (latestUpdates[Local] > latestUpdates[Remote]) {
sync(localDir, remoteDir, done)
} else {
sync(remoteDir, localDir, done)
}
}
function sync(src, dest, cb) {
var child = spawn('rsync', ['-avu', '--delete', src, dest])
, out = []
, err = []
child.stdout.on('data', function(buf) { out.push(buf) })
child.stderr.on('data', function(buf) { err.push(buf) })
child.on('exit', function(code) {
if (code !== 0) {
console.warn('STDOUT:')
console.warn(out.join('\n'))
console.warn('STDERR:')
console.warn(err.join('\n'))
console.warn('!! sync failed with exit code ' + code)
}
cb(code !== 0)
})
}
// mtime of most recently modified file with zsh: stat -f %m **/*(.om[1])
// find mtime of most recently modified local file
var local = spawn('zsh', ['-fc', 'cd \'' + localDir + '\'; stat -f %m **/*(.om[1])'])
local.stdout.on('data', function(buf) { latestUpdates[Local] = Number(buf.toString()) })
local.on('exit', checkIfDone)
// find mtime of most recently modified remote file
var parts = remoteDir.split(':')
, host = parts[0]
, dir = parts[1].replace('~', '$HOME')
, remote = spawn('ssh', [host, 'zsh -fc "cd \'' + dir + '\'; stat -f %m **/*(.om[1])"'])
remote.stdout.on('data', function(buf) { latestUpdates[Remote] = Number(buf.toString()) })
remote.on('exit', checkIfDone)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment