From 794ac35b2167e678ea20b29312786d75ab22a7b4 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 21 Jul 2016 04:58:32 -0700 Subject: [PATCH] checkout: Support checking out a series from git-series/* with no internals A series copied via "git branch git-series/newname git-series/oldname" will not have any corresponding git-series-internals branches. In that case, checkout should populate those internals from the committed version of the series. In the process, since Internals::read_series now supports reading the git-series ref as a fallback, change Internals::exists accordingly to treat that as the series existing, and simplify its callers, who both wanted that anyway. --- src/main.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9610cf5164b192a1e858f2977d33fd182bf18612..00ec7b4f08e796400f7d1533f38a95d29025d7f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -161,8 +161,9 @@ impl<'repo> Internals<'repo> { } fn read_series(repo: &'repo Repository, series_name: &str) -> Result { + let committed_id = try!(notfound_to_none(repo.refname_to_id(&format!("{}{}", SERIES_PREFIX, series_name)))); let maybe_get_ref = |prefix: &str| -> Result> { - match try!(notfound_to_none(repo.refname_to_id(&format!("{}{}", prefix, series_name)))) { + match try!(notfound_to_none(repo.refname_to_id(&format!("{}{}", prefix, series_name)))).or(committed_id) { Some(id) => { let c = try!(repo.find_commit(id)); let t = try!(c.tree()); @@ -178,7 +179,7 @@ impl<'repo> Internals<'repo> { } fn exists(repo: &'repo Repository, series_name: &str) -> Result { - for prefix in [STAGED_PREFIX, WORKING_PREFIX].iter() { + for prefix in [SERIES_PREFIX, STAGED_PREFIX, WORKING_PREFIX].iter() { let prefixed_name = format!("{}{}", prefix, series_name); if try!(notfound_to_none(repo.refname_to_id(&prefixed_name))).is_some() { return Ok(true); @@ -342,12 +343,10 @@ fn series(out: &mut Output, repo: &Repository) -> Result<()> { fn start(repo: &Repository, m: &ArgMatches) -> Result<()> { let name = m.value_of("name").unwrap(); - let prefixed_name = &[SERIES_PREFIX, name].concat(); - let branch_exists = try!(notfound_to_none(repo.refname_to_id(&prefixed_name))).is_some() - || try!(Internals::exists(repo, name)); - if branch_exists { + if try!(Internals::exists(repo, name)) { return Err(format!("Series {} already exists.\nUse checkout to resume working on an existing patch series.", name).into()); } + let prefixed_name = &[SERIES_PREFIX, name].concat(); try!(repo.reference_symbolic(SHEAD_REF, &prefixed_name, true, &format!("git series start {}", name))); let internals = try!(Internals::read(repo)); @@ -408,16 +407,12 @@ fn checkout(repo: &Repository, m: &ArgMatches) -> Result<()> { s => { return Err(format!("{:?} in progress; cannot checkout patch series", s).into()); } } let name = m.value_of("name").unwrap(); - let prefixed_name = &[SERIES_PREFIX, name].concat(); - // Make sure the ref exists - let branch_exists = try!(notfound_to_none(repo.refname_to_id(&prefixed_name))).is_some() - || try!(Internals::exists(repo, name)); - if !branch_exists { + if !try!(Internals::exists(repo, name)) { return Err(format!("Series {} does not exist.\nUse \"git series start \" to start a new patch series.", name).into()); } let internals = try!(Internals::read_series(repo, name)); - let new_head_id = try!(try!(internals.working.get("series")).ok_or(format!("Could not find \"series\" in working version of \"{}\"", name))).id(); + let new_head_id = try!(try!(internals.working.get("series")).ok_or(format!("Could not find \"series\" in \"{}\"", name))).id(); let new_head = try!(repo.find_commit(new_head_id)).into_object(); try!(checkout_tree(repo, &new_head)); @@ -427,7 +422,9 @@ fn checkout(repo: &Repository, m: &ArgMatches) -> Result<()> { let head_id = head_commit.as_object().id(); println!("Previous HEAD position was {}", try!(commit_summarize(&repo, head_id))); + let prefixed_name = &[SERIES_PREFIX, name].concat(); try!(repo.reference_symbolic(SHEAD_REF, &prefixed_name, true, &format!("git series checkout {}", name))); + try!(internals.write(repo)); // git status parses this reflog string; the prefix must remain "checkout: moving from ". try!(repo.reference("HEAD", new_head_id, true, &format!("checkout: moving from {} to {} (git series checkout {})", head_id, new_head_id, name)));