291 def status(options: String = ""): List[String] = |
291 def status(options: String = ""): List[String] = |
292 hg.command("status", options = options).check.out_lines |
292 hg.command("status", options = options).check.out_lines |
293 |
293 |
294 def known_files(): List[String] = status(options = "--modified --added --clean --no-status") |
294 def known_files(): List[String] = status(options = "--modified --added --clean --no-status") |
295 |
295 |
296 def sync(target: String, |
296 def sync(context: Rsync.Context, target: String, |
297 progress: Progress = new Progress, |
|
298 port: Int = SSH.default_port, |
|
299 verbose: Boolean = false, |
297 verbose: Boolean = false, |
300 thorough: Boolean = false, |
298 thorough: Boolean = false, |
301 dry_run: Boolean = false, |
299 dry_run: Boolean = false, |
302 filter: List[String] = Nil, |
300 filter: List[String] = Nil, |
303 contents: List[File.Content] = Nil, |
301 contents: List[File.Content] = Nil, |
304 rev: String = "" |
302 rev: String = "" |
305 ): Unit = { |
303 ): Unit = { |
306 require(ssh == SSH.Local, "local repository required") |
304 require(ssh == SSH.Local, "local repository required") |
307 |
305 |
308 Isabelle_System.with_tmp_dir("sync") { tmp_dir => |
306 Isabelle_System.with_tmp_dir("sync") { tmp_dir => |
309 Rsync.rsync_init(target, port = port) |
307 Rsync.rsync_init(context, target) |
310 |
308 |
311 val list = |
309 val list = |
312 Rsync.rsync(port = port, list = true, |
310 Rsync.rsync(context, list = true, |
313 args = List("--", Rsync.terminate(target)) |
311 args = List("--", Rsync.terminate(target)) |
314 ).check.out_lines.filterNot(_.endsWith(" .")) |
312 ).check.out_lines.filterNot(_.endsWith(" .")) |
315 if (list.nonEmpty && !list.exists(_.endsWith(Hg_Sync._NAME))) { |
313 if (list.nonEmpty && !list.exists(_.endsWith(Hg_Sync._NAME))) { |
316 error("No .hg_sync meta data in " + quote(target)) |
314 error("No .hg_sync meta data in " + quote(target)) |
317 } |
315 } |
320 val is_changed = id_content.endsWith("+") |
318 val is_changed = id_content.endsWith("+") |
321 val log_content = if (is_changed) "" else log(rev = rev, options = "-l1") |
319 val log_content = if (is_changed) "" else log(rev = rev, options = "-l1") |
322 val diff_content = if (is_changed) diff(rev = rev, options = "--git") else "" |
320 val diff_content = if (is_changed) diff(rev = rev, options = "--git") else "" |
323 val stat_content = if (is_changed) diff(rev = rev, options = "--stat") else "" |
321 val stat_content = if (is_changed) diff(rev = rev, options = "--stat") else "" |
324 |
322 |
325 Rsync.rsync_init(target, port = port, |
323 Rsync.rsync_init(context, target, |
326 contents = |
324 contents = |
327 File.Content(Hg_Sync.PATH_ID, id_content) :: |
325 File.Content(Hg_Sync.PATH_ID, id_content) :: |
328 File.Content(Hg_Sync.PATH_LOG, log_content) :: |
326 File.Content(Hg_Sync.PATH_LOG, log_content) :: |
329 File.Content(Hg_Sync.PATH_DIFF, diff_content) :: |
327 File.Content(Hg_Sync.PATH_DIFF, diff_content) :: |
330 File.Content(Hg_Sync.PATH_STAT, stat_content) :: contents) |
328 File.Content(Hg_Sync.PATH_STAT, stat_content) :: contents) |
346 File.write(exclude_path, cat_lines(exclude.map("/" + _))) |
344 File.write(exclude_path, cat_lines(exclude.map("/" + _))) |
347 |
345 |
348 val protect = |
346 val protect = |
349 (Hg_Sync.PATH :: contents.map(_.path)) |
347 (Hg_Sync.PATH :: contents.map(_.path)) |
350 .map(path => "protect /" + File.standard_path(path)) |
348 .map(path => "protect /" + File.standard_path(path)) |
351 Rsync.rsync( |
349 Rsync.rsync(context, |
352 progress = progress, port = port, verbose = verbose, thorough = thorough, |
350 verbose = verbose, |
|
351 thorough = thorough, |
353 dry_run = dry_run, |
352 dry_run = dry_run, |
354 clean = true, |
353 clean = true, |
355 prune_empty_dirs = true, |
354 prune_empty_dirs = true, |
356 filter = protect ::: filter, |
355 filter = protect ::: filter, |
357 args = List("--exclude-from=" + exclude_path.implode, "--", |
356 args = List("--exclude-from=" + exclude_path.implode, "--", |
604 val hg = |
603 val hg = |
605 root match { |
604 root match { |
606 case Some(dir) => repository(dir) |
605 case Some(dir) => repository(dir) |
607 case None => the_repository(Path.current) |
606 case None => the_repository(Path.current) |
608 } |
607 } |
609 hg.sync(target, progress = progress, port = port, verbose = verbose, thorough = thorough, |
608 val context = Rsync.Context(progress, port = port) |
|
609 hg.sync(context, target, verbose = verbose, thorough = thorough, |
610 dry_run = dry_run, filter = filter, rev = rev) |
610 dry_run = dry_run, filter = filter, rev = rev) |
611 } |
611 } |
612 ) |
612 ) |
613 } |
613 } |