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:
committed by
GitHub
parent
eec37b043c
commit
5e51f9453e
@@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user