5 use std::io::{Result, Error, ErrorKind};
7 use std::process::exit;
11 fn main() -> Result<()> {
12 if let Ok(cwd) = env::current_dir() {
13 if let Err(e) = scan_directories_to_synchronize(&cwd) {
14 eprintln!("Could not check directory for git repositories: {}", e);
18 eprintln!("Could not find current directory.");
24 fn scan_directories_to_synchronize(path: &Path) -> Result<()> {
25 let sync_ignore_file = path.join(".syncignore");
26 if sync_ignore_file.exists() {
29 let git_directory = path.join(".git");
30 if git_directory.exists() {
31 if let Err(e) = synchronize_directory(&path) {
32 let relative_path = get_relative_path(path).unwrap();
33 eprintln!("Sync failed for {:?}. {}", relative_path, e);
36 for entry in fs::read_dir(path)? {
37 let path = entry?.path();
39 scan_directories_to_synchronize(&path)?;
46 fn synchronize_directory(path: &Path) -> Result<()> {
47 let previous_branch = git_save_previous_branch(path)?;
48 git_checkout(path, "main")?;
49 let result = attempt_synchronization(path);
50 git_checkout(path, &previous_branch)?;
54 fn attempt_synchronization(path: &Path) -> Result<()> {
55 let relative_path = get_relative_path(path).unwrap();
56 eprint!("{:?}. ", relative_path);
57 let previous_commit = get_commit(path, "HEAD")?;
59 let remote_commit = get_commit(path, "origin/main")?;
60 if previous_commit == remote_commit {
61 eprintln!("Already up to date.");
64 match git_check_for_conflicts(path) {
68 let new_commit = get_commit(path, "HEAD")?;
69 eprint!("Merged origin {:?}->{:?}. ", previous_commit, new_commit);
73 return Err(Error::new(ErrorKind::Other, "Conflicts detected"));
85 fn get_relative_path(path: &Path) -> Option<String> {
86 let cwd = env::current_dir().unwrap();
87 path.strip_prefix(cwd)
89 .and_then(|p| p.to_str())
90 .map(|s| s.to_string())