aboutsummaryrefslogtreecommitdiff
path: root/src/local/update.rs
diff options
context:
space:
mode:
authorMax Audron <audron@cocaine.farm>2022-06-07 12:28:18 +0200
committerMaximilian Manz <maximilian.manz@de.clara.net>2022-06-20 11:33:04 +0200
commitae13cbecdbeca984e0d389732356c2785eab66d9 (patch)
treeccd76a92e16d47d23530b87ecdf21b57e40917ef /src/local/update.rs
parentfix crash while walking non existing dir (diff)
implement cloning of new repos
Diffstat (limited to 'src/local/update.rs')
-rw-r--r--src/local/update.rs71
1 files changed, 67 insertions, 4 deletions
diff --git a/src/local/update.rs b/src/local/update.rs
index 95057a4..d9c9f3c 100644
--- a/src/local/update.rs
+++ b/src/local/update.rs
@@ -1,4 +1,64 @@
-use std::fmt::Display;
+use std::fmt::{Debug, Display};
+
+use git2::BranchType;
+use tracing::debug;
+
+use super::{Repo, RepoError};
+
+impl Repo {
+ /// Fetch any new state from the remote and fast forward merge changes into local branches
+ #[tracing::instrument(level = "trace")]
+ pub fn update(&mut self) -> Result<UpdateResult, UpdateResult> {
+ let repo_name = self.name.clone();
+ if self.repo.is_some() {
+ self.update_inner()
+ .map_err(|e| UpdateResult::err(repo_name, e.into()))
+ } else {
+ Ok(UpdateResult::err(repo_name, RepoError::NoLocalRepo))
+ }
+ }
+
+ fn update_inner(&mut self) -> Result<UpdateResult, RepoError> {
+ let repo = self.repo.as_ref().unwrap();
+ let mut remote = self.main_remote(repo)?;
+
+ self.fetch(&mut remote)?;
+
+ self.default_branch = remote.default_branch()?.as_str().unwrap().to_string();
+
+ debug!("default branch: {}", self.default_branch);
+
+ if self.is_clean()? {
+ debug!("repo is clean");
+
+ let merged = repo.branches(Some(BranchType::Local))?
+ .filter_map(|x| x.ok())
+ .try_fold(false, |mut merged, (mut branch, _)| {
+ let name = format!("refs/heads/{}", Repo::branch_name(&branch));
+
+ if branch.upstream().is_ok() {
+ let upstream = branch.upstream().unwrap();
+
+ debug!("branch: {}", name);
+
+ merged |= self.merge(repo, &mut branch, &upstream)?;
+ Ok::<bool, RepoError>(merged)
+ } else {
+ debug!("not updating branch: {}: branch does not have upstream tracking branch set", name);
+ Ok(merged)
+ }
+ })?;
+
+ if merged {
+ Ok(UpdateResult::merged(self.name.clone()))
+ } else {
+ Ok(UpdateResult::no_changes(self.name.clone()))
+ }
+ } else {
+ Ok(UpdateResult::dirty(self.name.clone()))
+ }
+ }
+}
#[derive(Debug)]
pub enum UpdateResult {
@@ -49,9 +109,12 @@ impl Display for UpdateResult {
UpdateResult::Merged { name } => {
f.write_fmt(format_args!("{} {}", Green.paint("PULLED "), name))
}
- UpdateResult::Error { name, error } => {
- f.write_fmt(format_args!("{} {} [{}]", Red.paint("ERROR "), name, error))
- }
+ UpdateResult::Error { name, error } => f.write_fmt(format_args!(
+ "{} {} [{}]",
+ Red.paint("ERROR "),
+ name,
+ error
+ )),
}
}
}