diff --git a/src/vcs.rs b/src/vcs.rs index 76415e5..dabfd50 100644 --- a/src/vcs.rs +++ b/src/vcs.rs @@ -193,55 +193,40 @@ impl Vcs { return Ok(()); } - let current_profile = self.current_profile()?; - - for project in &mut self.projects { - let mut stashed_changes = false; - if let Some(current_profile_name) = ¤t_profile { - stashed_changes = project.repo.stash_changes(current_profile_name)?; - } - - let ref_name = project.switch_to_profile(profile_name)?; - let unstashed_changes = project.repo.unstash_changes(profile_name)?; - - println!( - "{} set to {} {}{}", - project.name().bold().with(PROJECT_COLOR), - ref_name.with(REFS_COLOR), - if stashed_changes { - "«".cyan() - } else { - "".bold() - }, - if unstashed_changes { - "»".dark_blue() - } else { - "".bold() - }, - ); - } - - Ok(()) + self.set_projects_using(profile_name, |project| { + project.switch_to_profile(profile_name) + }) } pub fn set_branch(&mut self, branch_name: &str) -> Result<(), Error> { + self.set_projects_using(branch_name, |project| project.repo.checkout(branch_name)) + } + + fn set_projects_using(&mut self, dest_name: &str, setter: F) -> Result<(), Error> + where + F: Fn(&mut Project) -> Result, + { for project in &mut self.projects { let current_ref = project.repo.current_ref()?; + // stash changes before moving project off to a new ref let stashed_changes = project.repo.stash_changes(¤t_ref)?; - let new_ref = match project.repo.checkout(branch_name) { + // try to switch to new ref using provided setter + let new_ref = match setter(project) { Ok(val) => val, Err(err) => { eprintln!( "{} unable to set {} ({})", project.name().bold().with(PROJECT_COLOR), - branch_name.with(REFS_COLOR), + dest_name.with(REFS_COLOR), err.to_string().with(ERROR_COLOR), ); continue; } }; - let unstashed_changes = project.repo.unstash_changes(branch_name)?; + + // unstash changes if we had previously stashed any on this ref + let unstashed_changes = project.repo.unstash_changes(&new_ref)?; println!( "{} set to {} {}{}", @@ -259,6 +244,7 @@ impl Vcs { }, ); } + Ok(()) } diff --git a/src/vcs/systems/git.rs b/src/vcs/systems/git.rs index 760aa7c..8e32290 100644 --- a/src/vcs/systems/git.rs +++ b/src/vcs/systems/git.rs @@ -39,8 +39,22 @@ impl Repository for GitRepository { return Ok(false); } - let repo_signature = self.repo.signature()?; + let mut err = None; let stash_name = self.stash_name(name); + self.repo.stash_foreach(|_, name, _| { + if name.contains(&stash_name) { + err = Some(Error::project_error("Existing stashed changes found")); + false + } else { + true + } + })?; + + if let Some(err) = err { + return Err(err); + } + + let repo_signature = self.repo.signature()?; self.repo.stash_save(&repo_signature, &stash_name, None)?; Ok(true)