From 5e51f9453e2342a529361c97e55ac5a2181bbd67 Mon Sep 17 00:00:00 2001 From: Roey Darwish Dror Date: Wed, 31 Jul 2019 10:04:16 +0300 Subject: [PATCH] Show what's new in Git repositories (#183) * Show what's new in Git repositories * Check for pull changes using ORIG_HEAD It seems that either `--rebase` or `--autostash` causes ORIG_HEAD not to change. We thought about it further and decided that `--ff-only` is a safer option for git pull --- src/steps/git.rs | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/steps/git.rs b/src/steps/git.rs index 1f668d3d..cc148a39 100644 --- a/src/steps/git.rs +++ b/src/steps/git.rs @@ -23,6 +23,24 @@ pub struct Repositories<'a> { repositories: HashSet, } +/// Checks whether the latest pull command actually pulled something +fn did_pull_change(git: &Path, repo: &str) -> bool { + Command::new(git) + .args(&["rev-parse", "HEAD", "ORIG_HEAD"]) + .current_dir(repo) + .check_output() + .map(|output| { + let mut lines = output.trim().split('\n'); + lines.next().unwrap() != lines.next().unwrap() + }) + .map_err(|e| { + error!("Error getting revision for {}: {}", repo, e); + + e + }) + .unwrap_or(false) +} + impl Git { pub fn new() -> Self { Self { git: which("git") } @@ -83,18 +101,34 @@ impl Git { .map(|repo| { let repo = repo.clone(); let path = format!("{}", HumanizedPath::from(std::path::Path::new(&repo))); - println!("{} {}", style("Pulling").cyan(), path); + let cloned_git = git.to_owned(); + + println!("{} {}", style("Pulling").cyan().bold(), path); + Command::new(git) - .args(&["pull", "--rebase", "--autostash"]) + .args(&["pull", "--ff-only"]) .current_dir(&repo) .output_async() .then(move |result| match result { Ok(output) => { if output.status.success() { - println!("{} {}", style("Pulled").green(), path); + if did_pull_change(&cloned_git, &repo) { + println!("{} {}:", style("Changed").yellow().bold(), path); + Command::new(&cloned_git) + .current_dir(&repo) + .args(&["log", "--no-decorate", "--oneline", "ORIG_HEAD.."]) + .spawn() + .unwrap() + .wait() + .unwrap(); + println!(); + } else { + println!("{} {}", style("Up-to-date").green().bold(), path); + } + Ok(true) as Result } else { - println!("{} pulling {}", style("Failed").red(), path); + println!("{} pulling {}", style("Failed").red().bold(), path); if let Ok(text) = std::str::from_utf8(&output.stderr) { print!("{}", text); } @@ -102,7 +136,7 @@ impl Git { } } Err(e) => { - println!("{} pulling {}: {}", style("Failed").red(), path, e); + println!("{} pulling {}: {}", style("Failed").red().bold(), path, e); Ok(false) } })