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
This commit is contained in:
Roey Darwish Dror
2019-07-31 10:04:16 +03:00
committed by GitHub
parent eec37b043c
commit 5e51f9453e

View File

@@ -23,6 +23,24 @@ pub struct Repositories<'a> {
repositories: HashSet<String>, repositories: HashSet<String>,
} }
/// 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 { impl Git {
pub fn new() -> Self { pub fn new() -> Self {
Self { git: which("git") } Self { git: which("git") }
@@ -83,18 +101,34 @@ impl Git {
.map(|repo| { .map(|repo| {
let repo = repo.clone(); let repo = repo.clone();
let path = format!("{}", HumanizedPath::from(std::path::Path::new(&repo))); 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) Command::new(git)
.args(&["pull", "--rebase", "--autostash"]) .args(&["pull", "--ff-only"])
.current_dir(&repo) .current_dir(&repo)
.output_async() .output_async()
.then(move |result| match result { .then(move |result| match result {
Ok(output) => { Ok(output) => {
if output.status.success() { 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<bool, Error> Ok(true) as Result<bool, Error>
} else { } else {
println!("{} pulling {}", style("Failed").red(), path); println!("{} pulling {}", style("Failed").red().bold(), path);
if let Ok(text) = std::str::from_utf8(&output.stderr) { if let Ok(text) = std::str::from_utf8(&output.stderr) {
print!("{}", text); print!("{}", text);
} }
@@ -102,7 +136,7 @@ impl Git {
} }
} }
Err(e) => { Err(e) => {
println!("{} pulling {}: {}", style("Failed").red(), path, e); println!("{} pulling {}: {}", style("Failed").red().bold(), path, e);
Ok(false) Ok(false)
} }
}) })