Formatting improvements, based partly on rustfmt

Josh Triplett created

Change summary

src/main.rs | 505 ++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 372 insertions(+), 133 deletions(-)

Detailed changes

src/main.rs 🔗

@@ -200,9 +200,15 @@ impl<'repo> Internals<'repo> {
         for prefix in [SERIES_PREFIX, STAGED_PREFIX, WORKING_PREFIX].iter() {
             let prefixed_source = format!("{}{}", prefix, source);
             if let Some(r) = notfound_to_none(repo.find_reference(&prefixed_source))? {
-                let oid = r.target().ok_or(format!("Internal error: \"{}\" is a symbolic reference", prefixed_source))?;
+                let oid = r.target()
+                    .ok_or(format!("Internal error: \"{}\" is a symbolic reference", prefixed_source))?;
                 let prefixed_dest = format!("{}{}", prefix, dest);
-                repo.reference(&prefixed_dest, oid, false, &format!("copied from {}", prefixed_source))?;
+                repo.reference(
+                    &prefixed_dest,
+                    oid,
+                    false,
+                    &format!("copied from {}", prefixed_source),
+                )?;
                 copied_any = true;
             }
         }
@@ -258,7 +264,14 @@ impl<'repo> Internals<'repo> {
             let parents_ref: Vec<&_> = parents.iter().collect();
             let commit_id = repo.commit(None, &author, &committer, &refname, &tree, &parents_ref)?;
             repo.reference_ensure_log(&refname)?;
-            reference_matching_opt(repo, &refname, commit_id, true, old_commit_id, &format!("commit: {}", refname))?;
+            reference_matching_opt(
+                repo,
+                &refname,
+                commit_id,
+                true,
+                old_commit_id,
+                &format!("commit: {}", refname),
+            )?;
             Ok(())
         };
         maybe_commit(STAGED_PREFIX, &self.staged)?;
@@ -275,7 +288,9 @@ fn add(repo: &Repository, m: &ArgMatches) -> Result<()> {
     let mut internals = Internals::read(repo)?;
     for file in m.values_of_os("change").unwrap() {
         match internals.working.get(file)? {
-            Some(entry) => { internals.staged.insert(file, entry.id(), entry.filemode())?; }
+            Some(entry) => {
+                internals.staged.insert(file, entry.id(), entry.filemode())?;
+            }
             None => {
                 if internals.staged.get(file)?.is_some() {
                     internals.staged.remove(file)?;
@@ -303,7 +318,9 @@ fn unadd(repo: &Repository, m: &ArgMatches) -> Result<()> {
                 Some(entry) => {
                     internals.staged.insert(file, entry.id(), entry.filemode())?;
                 }
-                None => { internals.staged.remove(file)?; }
+                None => {
+                    internals.staged.remove(file)?;
+                }
             }
         }
     } else {
@@ -372,13 +389,23 @@ fn start(repo: &Repository, m: &ArgMatches) -> Result<()> {
         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();
-    repo.reference_symbolic(SHEAD_REF, &prefixed_name, true, &format!("git series start {}", name))?;
+    repo.reference_symbolic(
+        SHEAD_REF,
+        &prefixed_name,
+        true,
+        &format!("git series start {}", name),
+    )?;
 
     let internals = Internals::read(repo)?;
     internals.write(repo)?;
 
     // git status parses this reflog string; the prefix must remain "checkout: moving from ".
-    repo.reference("HEAD", head_id, true, &format!("checkout: moving from {} to {} (git series start {})", head_id, head_id, name))?;
+    repo.reference(
+        "HEAD",
+        head_id,
+        true,
+        &format!("checkout: moving from {} to {} (git series start {})", head_id, head_id, name),
+    )?;
     println!("HEAD is now detached at {}", commit_summarize(&repo, head_id)?);
     Ok(())
 }
@@ -432,7 +459,7 @@ fn checkout_tree(repo: &Repository, treeish: &Object) -> Result<()> {
 fn checkout(repo: &Repository, m: &ArgMatches) -> Result<()> {
     match repo.state() {
         git2::RepositoryState::Clean => (),
-        s => { return Err(format!("{:?} in progress; cannot checkout patch series", s).into()); }
+        s => return Err(format!("{:?} in progress; cannot checkout patch series", s).into()),
     }
     let name = m.value_of("name").unwrap();
     if !Internals::exists(repo, name)? {
@@ -440,7 +467,9 @@ fn checkout(repo: &Repository, m: &ArgMatches) -> Result<()> {
     }
 
     let internals = Internals::read_series(repo, name)?;
-    let new_head_id = internals.working.get("series")?.ok_or(format!("Could not find \"series\" in \"{}\"", name))?.id();
+    let new_head_id = internals.working.get("series")?
+        .ok_or(format!("Could not find \"series\" in \"{}\"", name))?
+        .id();
     let new_head = repo.find_commit(new_head_id)?.into_object();
 
     checkout_tree(repo, &new_head)?;
@@ -451,11 +480,21 @@ fn checkout(repo: &Repository, m: &ArgMatches) -> Result<()> {
     println!("Previous HEAD position was {}", commit_summarize(&repo, head_id)?);
 
     let prefixed_name = &[SERIES_PREFIX, name].concat();
-    repo.reference_symbolic(SHEAD_REF, &prefixed_name, true, &format!("git series checkout {}", name))?;
+    repo.reference_symbolic(
+        SHEAD_REF,
+        &prefixed_name,
+        true,
+        &format!("git series checkout {}", name),
+    )?;
     internals.write(repo)?;
 
     // git status parses this reflog string; the prefix must remain "checkout: moving from ".
-    repo.reference("HEAD", new_head_id, true, &format!("checkout: moving from {} to {} (git series checkout {})", head_id, new_head_id, name))?;
+    repo.reference(
+        "HEAD",
+        new_head_id,
+        true,
+        &format!("checkout: moving from {} to {} (git series checkout {})", head_id, new_head_id, name),
+    )?;
     println!("HEAD is now detached at {}", commit_summarize(&repo, new_head_id)?);
 
     Ok(())
@@ -485,9 +524,16 @@ fn base(repo: &Repository, m: &ArgMatches) -> Result<()> {
         let base_object = repo.revparse_single(base)?;
         let base_commit = base_object.peel(ObjectType::Commit)?;
         let base_id = base_commit.id();
-        let s_working_series = internals.working.get("series")?.ok_or("Could not find entry \"series\" in working vesion of current series")?;
-        if base_id != s_working_series.id() && !repo.graph_descendant_of(s_working_series.id(), base_id)? {
-            return Err(format!("Cannot set base to {}: not an ancestor of the patch series {}", base, s_working_series.id()).into());
+        let s_working_series = internals.working.get("series")?
+            .ok_or("Could not find entry \"series\" in working vesion of current series")?;
+        if base_id != s_working_series.id()
+            && !repo.graph_descendant_of(s_working_series.id(), base_id)?
+        {
+            return Err(format!(
+                "Cannot set base to {}: not an ancestor of the patch series {}",
+                base,
+                s_working_series.id(),
+            ).into());
         }
         base_id
     };
@@ -517,7 +563,7 @@ fn base(repo: &Repository, m: &ArgMatches) -> Result<()> {
 fn detach(repo: &Repository) -> Result<()> {
     match repo.find_reference(SHEAD_REF) {
         Ok(mut r) => r.delete()?,
-        Err(_) => { return Err("No current patch series to detach from.".into()); }
+        Err(_) => return Err("No current patch series to detach from.".into()),
     }
     Ok(())
 }
@@ -527,7 +573,10 @@ fn delete(repo: &Repository, m: &ArgMatches) -> Result<()> {
     if let Ok(shead) = repo.find_reference(SHEAD_REF) {
         let shead_target = shead_series_name(&shead)?;
         if shead_target == name {
-            return Err(format!("Cannot delete the current series \"{}\"; detach first.", name).into());
+            return Err(format!(
+                "Cannot delete the current series \"{}\"; detach first.",
+                name,
+            ).into());
         }
     }
     if Internals::delete(repo, name)? == false {
@@ -593,18 +642,17 @@ fn get_pager(config: &Config, for_cmd: &str, default: bool) -> Option<OsString>
     if !cmd_want_pager {
         return None;
     }
-    let pager =
-        if let Some(e) = env::var_os("GIT_PAGER") {
-            Some(e)
-        } else if let Some(p) = cmd_pager {
-            Some(p.into())
-        } else if let Ok(e) = config.get_path("core.pager") {
-            Some(e.into())
-        } else if let Some(e) = env::var_os("PAGER") {
-            Some(e)
-        } else {
-            Some("less".into())
-        };
+    let pager = if let Some(e) = env::var_os("GIT_PAGER") {
+        Some(e)
+    } else if let Some(p) = cmd_pager {
+        Some(p.into())
+    } else if let Ok(e) = config.get_path("core.pager") {
+        Some(e.into())
+    } else if let Some(e) = env::var_os("PAGER") {
+        Some(e)
+    } else {
+        Some("less".into())
+    };
     pager.and_then(|p| if p.is_empty() || p == "cat" { None } else { Some(p) })
 }
 
@@ -668,7 +716,13 @@ impl Output {
     // command: the git command to act like.
     // slot: the color "slot" of that git command to act like.
     // default: the color to use if not configured.
-    fn get_color(&self, config: &Config, command: &str, slot: &str, default: &str) -> Result<Style> {
+    fn get_color(
+        &self,
+        config: &Config,
+        command: &str,
+        slot: &str,
+        default: &str,
+    ) -> Result<Style> {
         if !cfg!(unix) {
             return Ok(Style::new());
         }
@@ -688,7 +742,7 @@ impl Output {
         let cfg = format!("color.{}.{}", command, slot);
         let color = notfound_to_none(config.get_str(&cfg))?.unwrap_or(default);
         colorparse::parse(color).map_err(|e| format!("Error parsing {}: {}", cfg, e).into())
-   }
+    }
 
     fn write_err(&mut self, msg: &str) {
         if self.include_stderr {
@@ -734,18 +788,32 @@ fn get_signature(config: &Config, which: &str) -> Result<git2::Signature<'static
     let which_lc = which.to_lowercase();
     let name = env::var(&name_var)
         .or_else(|_| config.get_string("user.name"))
-        .or_else(|_| Err(format!("Could not determine {} name: checked ${} and user.name in git config", which_lc, name_var)))?;
+        .or_else(|_| Err(format!(
+            "Could not determine {} name: checked ${} and user.name in git config",
+            which_lc, name_var,
+        )))?;
     let email = env::var(&email_var)
         .or_else(|_| config.get_string("user.email"))
         .or_else(|_| env::var("EMAIL"))
-        .or_else(|_| Err(format!("Could not determine {} email: checked ${}, user.email in git config, and $EMAIL", which_lc, email_var)))?;
+        .or_else(|_| Err(format!(
+            "Could not determine {} email: checked ${}, user.email in git config, and $EMAIL",
+            which_lc, email_var,
+        )))?;
     Ok(git2::Signature::now(&name, &email)?)
 }
 
-fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status: bool) -> Result<()> {
+fn commit_status(
+    out: &mut Output,
+    repo: &Repository,
+    m: &ArgMatches,
+    do_status: bool,
+) -> Result<()> {
     let config = repo.config()?.snapshot()?;
     let shead = match notfound_to_none(repo.find_reference(SHEAD_REF))? {
-        None => { println!("No series; use \"git series start <name>\" to start"); return Ok(()); }
+        None => {
+            println!("No series; use \"git series start <name>\" to start");
+            return Ok(());
+        }
         Some(result) => result,
     };
     let series_name = shead_series_name(&shead)?;
@@ -765,7 +833,14 @@ fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status:
     let color_updated = get_color(out, "updated", "green")?;
     let color_changed = get_color(out, "changed", "red")?;
 
-    let write_status = |status: &mut Vec<ansi_term::ANSIString>, diff: &Diff, heading: &str, color: &Style, show_hints: bool, hints: &[&str]| -> Result<bool> {
+    let write_status = |
+        status: &mut Vec<ansi_term::ANSIString>,
+        diff: &Diff,
+        heading: &str,
+        color: &Style,
+        show_hints: bool,
+        hints: &[&str],
+    | -> Result<bool> {
         let mut changes = false;
 
         diff.foreach(&mut |delta, _| {
@@ -780,7 +855,11 @@ fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status:
                 status.push(color_normal.paint("\n"));
             }
             status.push(color_normal.paint("        "));
-            status.push(color.paint(format!("{:?}:   {}\n", delta.status(), delta.old_file().path().unwrap().to_str().unwrap())));
+            status.push(color.paint(format!(
+                "{:?}:   {}\n",
+                delta.status(),
+                delta.old_file().path().unwrap().to_str().unwrap(),
+            )));
             true
         }, None, None, None)?;
 
@@ -814,22 +893,41 @@ fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status:
 
     let (changes, tree) = if commit_all {
         let diff = repo.diff_tree_to_tree(shead_tree.as_ref(), Some(&working_tree), None)?;
-        let changes = write_status(&mut status, &diff, "Changes to be committed:", &color_normal, false, &[])?;
+        let changes = write_status(
+            &mut status,
+            &diff,
+            "Changes to be committed:",
+            &color_normal,
+            false,
+            &[],
+        )?;
         if !changes {
             status.push(color_normal.paint("nothing to commit; series unchanged\n"));
         }
         (changes, working_tree)
     } else {
         let diff = repo.diff_tree_to_tree(shead_tree.as_ref(), Some(&staged_tree), None)?;
-        let changes_to_be_committed = write_status(&mut status, &diff,
-                "Changes to be committed:", &color_updated, do_status,
-                &["use \"git series commit\" to commit",
-                  "use \"git series unadd <file>...\" to undo add"])?;
+        let changes_to_be_committed = write_status(
+            &mut status,
+            &diff,
+            "Changes to be committed:",
+            &color_updated,
+            do_status,
+            &[
+                "use \"git series commit\" to commit",
+                "use \"git series unadd <file>...\" to undo add",
+            ],
+        )?;
 
         let diff_not_staged = repo.diff_tree_to_tree(Some(&staged_tree), Some(&working_tree), None)?;
-        let changes_not_staged = write_status(&mut status, &diff_not_staged,
-                "Changes not staged for commit:", &color_changed, do_status,
-                &["use \"git series add <file>...\" to update what will be committed"])?;
+        let changes_not_staged = write_status(
+            &mut status,
+            &diff_not_staged,
+            "Changes not staged for commit:",
+            &color_changed,
+            do_status,
+            &["use \"git series add <file>...\" to update what will be committed"],
+        )?;
 
         if !changes_to_be_committed {
             if changes_not_staged {
@@ -854,9 +952,13 @@ fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status:
 
     // Check that the commit includes the series
     let series_id = match tree.get_name("series") {
-        None => { return Err(concat!("Cannot commit: initial commit must include \"series\"\n",
-                                     "Use \"git series add series\" or \"git series commit -a\"").into()); }
-        Some(series) => series.id()
+        None => {
+            return Err(concat!(
+                "Cannot commit: initial commit must include \"series\"\n",
+                "Use \"git series add series\" or \"git series commit -a\"",
+            ).into());
+        }
+        Some(series) => series.id(),
     };
 
     // Check that the base is still an ancestor of the series
@@ -864,13 +966,16 @@ fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status:
         if base.id() != series_id && !repo.graph_descendant_of(series_id, base.id())? {
             let (base_short_id, base_summary) = commit_summarize_components(&repo, base.id())?;
             let (series_short_id, series_summary) = commit_summarize_components(&repo, series_id)?;
-            return Err(format!(concat!(
-                       "Cannot commit: base {} is not an ancestor of patch series {}\n",
-                       "base   {} {}\n",
-                       "series {} {}"),
-                       base_short_id, series_short_id,
-                       base_short_id, base_summary,
-                       series_short_id, series_summary).into());
+            return Err(format!(
+                concat!(
+                    "Cannot commit: base {} is not an ancestor of patch series {}\n",
+                    "base   {} {}\n",
+                    "series {} {}"
+                ),
+                base_short_id, series_short_id,
+                base_short_id, base_summary,
+                series_short_id, series_summary,
+            ).into());
         }
     }
 
@@ -889,7 +994,13 @@ fn commit_status(out: &mut Output, repo: &Repository, m: &ArgMatches, do_status:
             }
             if m.is_present("verbose") {
                 writeln!(file, "{}\n{}", SCISSOR_LINE, SCISSOR_COMMENT)?;
-                write_series_diff(&mut file, repo, &DiffColors::plain(), shead_tree.as_ref(), Some(&tree))?;
+                write_series_diff(
+                    &mut file,
+                    repo,
+                    &DiffColors::plain(),
+                    shead_tree.as_ref(),
+                    Some(&tree),
+                )?;
             }
             drop(file);
             run_editor(&config, &filename)?;
@@ -1001,7 +1112,12 @@ fn cp_mv(repo: &Repository, m: &ArgMatches, mv: bool) -> Result<()> {
     if mv {
         if update_shead {
             let prefixed_dest = &[SERIES_PREFIX, dest].concat();
-            repo.reference_symbolic(SHEAD_REF, &prefixed_dest, true, &format!("git series mv {} {}", source, dest))?;
+            repo.reference_symbolic(
+                SHEAD_REF,
+                &prefixed_dest,
+                true,
+                &format!("git series mv {} {}", source, dest),
+            )?;
         }
         Internals::delete(&repo, &source)?;
     }
@@ -1010,7 +1126,7 @@ fn cp_mv(repo: &Repository, m: &ArgMatches, mv: bool) -> Result<()> {
 }
 
 fn date_822(t: git2::Time) -> String {
-    let offset = chrono::offset::fixed::FixedOffset::east(t.offset_minutes()*60);
+    let offset = chrono::offset::fixed::FixedOffset::east(t.offset_minutes() * 60);
     let datetime = offset.timestamp(t.seconds(), 0);
     datetime.to_rfc2822()
 }
@@ -1021,7 +1137,8 @@ fn shortlog(commits: &mut [Commit]) -> String {
 
     for commit in commits {
         let author = commit.author().name().unwrap().to_string();
-        author_map.entry(author).or_insert(Vec::new()).push(commit.summary().unwrap().to_string());
+        author_map.entry(author).or_insert(Vec::new())
+            .push(commit.summary().unwrap().to_string());
     }
 
     let mut authors: Vec<_> = author_map.keys().collect();
@@ -1139,11 +1256,16 @@ impl DiffColors {
 
 fn diffstat(diff: &Diff) -> Result<String> {
     let stats = diff.stats()?;
-    let stats_buf = stats.to_buf(git2::DiffStatsFormat::FULL|git2::DiffStatsFormat::INCLUDE_SUMMARY, 72)?;
+    let stats_buf = stats.to_buf(git2::DiffStatsFormat::FULL | git2::DiffStatsFormat::INCLUDE_SUMMARY, 72)?;
     Ok(stats_buf.as_str().unwrap().to_string())
 }
 
-fn write_diff<W: IoWrite>(f: &mut W, colors: &DiffColors, diff: &Diff, simplify: bool) -> Result<usize> {
+fn write_diff<W: IoWrite>(
+    f: &mut W,
+    colors: &DiffColors,
+    diff: &Diff,
+    simplify: bool,
+) -> Result<usize> {
     let mut err = Ok(());
     let mut lines = 0;
     let normal = Style::new();
@@ -1151,10 +1273,10 @@ fn write_diff<W: IoWrite>(f: &mut W, colors: &DiffColors, diff: &Diff, simplify:
         err = || -> Result<()> {
             let o = l.origin();
             let style = match o {
-                '-'|'<' => colors.old,
-                '+'|'>' => colors.new,
+                '-' | '<' => colors.old,
+                '+' | '>' => colors.new,
                 _ if simplify => normal,
-                ' '|'=' => colors.context,
+                ' ' | '=' => colors.context,
                 'F' => colors.meta,
                 'H' => colors.frag,
                 _ => normal,
@@ -1170,7 +1292,10 @@ fn write_diff<W: IoWrite>(f: &mut W, colors: &DiffColors, diff: &Diff, simplify:
                     lines += 1;
                 } else if o == 'F' {
                     for line in l.content().split(|c| *c == b'\n') {
-                        if !line.is_empty() && !line.starts_with(b"diff --git") && !line.starts_with(b"index ") {
+                        if !line.is_empty()
+                            && !line.starts_with(b"diff --git")
+                            && !line.starts_with(b"index ")
+                        {
                             v.push(normal.paint(line.to_owned()));
                             v.push(normal.paint("\n".as_bytes()));
                             lines += 1;
@@ -1183,15 +1308,23 @@ fn write_diff<W: IoWrite>(f: &mut W, colors: &DiffColors, diff: &Diff, simplify:
             } else if o == 'H' {
                 // Split frag and func
                 let line = l.content();
-                let at = &|&(_,&c): &(usize, &u8)| c == b'@';
-                let not_at = &|&(_,&c): &(usize, &u8)| c != b'@';
-                match line.iter().enumerate().skip_while(at).skip_while(not_at).skip_while(at).nth(1).unwrap_or((0,&b'\n')) {
-                    (_,&c) if c == b'\n' => v.push(style.paint(&line[..line.len()-1])),
-                    (pos,_) => {
-                        v.push(style.paint(&line[..pos-1]));
+                let at = &|&(_, &c): &(usize, &u8)| c == b'@';
+                let not_at = &|&(_, &c): &(usize, &u8)| c != b'@';
+                match line
+                    .iter()
+                    .enumerate()
+                    .skip_while(at)
+                    .skip_while(not_at)
+                    .skip_while(at)
+                    .nth(1)
+                    .unwrap_or((0, &b'\n'))
+                {
+                    (_, &c) if c == b'\n' => v.push(style.paint(&line[..line.len() - 1])),
+                    (pos, _) => {
+                        v.push(style.paint(&line[..pos - 1]));
                         v.push(normal.paint(" ".as_bytes()));
-                        v.push(colors.func.paint(&line[pos..line.len()-1]));
-                    },
+                        v.push(colors.func.paint(&line[pos..line.len() - 1]));
+                    }
                 }
                 v.push(normal.paint("\n".as_bytes()));
             } else {
@@ -1217,7 +1350,7 @@ fn write_diff<W: IoWrite>(f: &mut W, colors: &DiffColors, diff: &Diff, simplify:
 
 fn get_commits(repo: &Repository, base: Oid, series: Oid) -> Result<Vec<Commit>> {
     let mut revwalk = repo.revwalk()?;
-    revwalk.set_sorting(git2::Sort::TOPOLOGICAL|git2::Sort::REVERSE);
+    revwalk.set_sorting(git2::Sort::TOPOLOGICAL | git2::Sort::REVERSE);
     revwalk.push(series)?;
     revwalk.hide(base)?;
     revwalk.map(|c| {
@@ -1227,7 +1360,13 @@ fn get_commits(repo: &Repository, base: Oid, series: Oid) -> Result<Vec<Commit>>
     }).collect()
 }
 
-fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &DiffColors, (base1, series1): (Oid, Oid), (base2, series2): (Oid, Oid)) -> Result<()> {
+fn write_commit_range_diff<W: IoWrite>(
+    out: &mut W,
+    repo: &Repository,
+    colors: &DiffColors,
+    (base1, series1): (Oid, Oid),
+    (base2, series2): (Oid, Oid),
+) -> Result<()> {
     let mut commits1 = get_commits(repo, base1, series1)?;
     let mut commits2 = get_commits(repo, base2, series2)?;
     for commit in commits1.iter().chain(commits2.iter()) {
@@ -1236,7 +1375,9 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
             return Ok(());
         }
     }
-    let ncommon = commits1.iter().zip(commits2.iter()).take_while(|&(ref c1, ref c2)| c1.id() == c2.id()).count();
+    let ncommon = commits1.iter().zip(commits2.iter())
+        .take_while(|&(ref c1, ref c2)| c1.id() == c2.id())
+        .count();
     drop(commits1.drain(..ncommon));
     drop(commits2.drain(..ncommon));
     let ncommits1 = commits1.len();
@@ -1248,7 +1389,11 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
     let commit_text = &|commit: &Commit| {
         let parent = commit.parent(0)?;
         let author = commit.author();
-        let diff = repo.diff_tree_to_tree(Some(&parent.tree().unwrap()), Some(&commit.tree().unwrap()), None)?;
+        let diff = repo.diff_tree_to_tree(
+            Some(&parent.tree().unwrap()),
+            Some(&commit.tree().unwrap()),
+            None,
+        )?;
         let mut v = Vec::new();
         v.write_all(b"From: ")?;
         v.write_all(author.name_bytes())?;
@@ -1263,12 +1408,12 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
     let texts1: Vec<_> = commits1.iter().map(commit_text).collect::<Result<_>>()?;
     let texts2: Vec<_> = commits2.iter().map(commit_text).collect::<Result<_>>()?;
 
-    let mut weights = Vec::with_capacity(n*n);
+    let mut weights = Vec::with_capacity(n * n);
     for i1 in 0..ncommits1 {
         for i2 in 0..ncommits2 {
             let patch = git2::Patch::from_buffers(&texts1[i1].0, None, &texts2[i2].0, None, None)?;
             let (_, additions, deletions) = patch.line_stats()?;
-            weights.push(additions+deletions);
+            weights.push(additions + deletions);
         }
         let w = texts1[i1].1 / 2;
         for _ in ncommits2..n {
@@ -1308,10 +1453,10 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
         while commits1_state_index < ncommits1 {
             match commits1_state[commits1_state_index] {
                 CommitState::Unhandled => { break }
-                CommitState::Handled => {},
+                CommitState::Handled => {}
                 CommitState::Deleted => {
                     commit_pairs.push((Some(commits1_state_index), None));
-                },
+                }
             }
             commits1_state_index += 1;
         }
@@ -1338,20 +1483,26 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
     let nwidth = max(ncommits1 + offset, ncommits2 + offset).to_string().len();
     let commits1_summaries: Vec<_> = commits1.iter_mut().map(commit_obj_summarize_components).collect::<Result<_>>()?;
     let commits2_summaries: Vec<_> = commits2.iter_mut().map(commit_obj_summarize_components).collect::<Result<_>>()?;
-    let idwidth = commits1_summaries.iter().chain(commits2_summaries.iter()).map(|&(ref short_id, _)| short_id.len()).max().unwrap();
+    let idwidth = commits1_summaries.iter().chain(commits2_summaries.iter())
+        .map(|&(ref short_id, _)| short_id.len())
+        .max().unwrap();
     for commit_pair in commit_pairs {
         match commit_pair {
             (None, None) => unreachable!(),
             (Some(i1), None) => {
                 let (ref c1_short_id, ref c1_summary) = commits1_summaries[i1];
-                v.push(colors.old.paint(format!("{:nwidth$}: {:idwidth$} < {:-<nwidth$}: {:-<idwidth$} {}",
-                                                i1 + offset, c1_short_id, "", "", c1_summary, nwidth=nwidth, idwidth=idwidth).as_bytes().to_owned()));
+                v.push(colors.old.paint(format!(
+                    "{:nwidth$}: {:idwidth$} < {:-<nwidth$}: {:-<idwidth$} {}",
+                    i1 + offset, c1_short_id, "", "", c1_summary, nwidth=nwidth, idwidth=idwidth,
+                ).as_bytes().to_owned()));
                 nl(&mut v);
             }
             (None, Some(i2)) => {
                 let (ref c2_short_id, ref c2_summary) = commits2_summaries[i2];
-                v.push(colors.new.paint(format!("{:-<nwidth$}: {:-<idwidth$} > {:nwidth$}: {:idwidth$} {}",
-                                                "", "", i2 + offset, c2_short_id, c2_summary, nwidth=nwidth, idwidth=idwidth).as_bytes().to_owned()));
+                v.push(colors.new.paint(format!(
+                    "{:-<nwidth$}: {:-<idwidth$} > {:nwidth$}: {:idwidth$} {}",
+                    "", "", i2 + offset, c2_short_id, c2_summary, nwidth=nwidth, idwidth=idwidth,
+                ).as_bytes().to_owned()));
                 nl(&mut v);
             }
             (Some(i1), Some(i2)) => {
@@ -1371,8 +1522,8 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
                 patch.print(&mut |_, _, l| {
                     let o = l.origin();
                     let style = match o {
-                        '-'|'<' => old,
-                        '+'|'>' => new,
+                        '-' | '<' => old,
+                        '+' | '>' => new,
                         _ => normal,
                     };
                     if o == '+' || o == '-' || o == ' ' {
@@ -1392,7 +1543,13 @@ fn write_commit_range_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &
     Ok(())
 }
 
-fn write_series_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &DiffColors, tree1: Option<&Tree>, tree2: Option<&Tree>) -> Result<()> {
+fn write_series_diff<W: IoWrite>(
+    out: &mut W,
+    repo: &Repository,
+    colors: &DiffColors,
+    tree1: Option<&Tree>,
+    tree2: Option<&Tree>,
+) -> Result<()> {
     let diff = repo.diff_tree_to_tree(tree1, tree2, None)?;
     write_diff(out, colors, &diff, false)?;
 
@@ -1402,7 +1559,13 @@ fn write_series_diff<W: IoWrite>(out: &mut W, repo: &Repository, colors: &DiffCo
     let series2 = tree2.and_then(|t| t.get_name("series"));
 
     if let (Some(base1), Some(series1), Some(base2), Some(series2)) = (base1, series1, base2, series2) {
-        write_commit_range_diff(out, repo, colors, (base1.id(), series1.id()), (base2.id(), series2.id()))?;
+        write_commit_range_diff(
+            out,
+            repo,
+            colors,
+            (base1.id(), series1.id()),
+            (base2.id(), series2.id()),
+        )?;
     } else {
         writeln!(out, "Can't diff series: both versions must have base and series to diff")?;
     }
@@ -1438,18 +1601,23 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     let shead_commit = repo.find_reference(SHEAD_REF)?.resolve()?.peel_to_commit()?;
     let stree = shead_commit.tree()?;
 
-    let series = stree.get_name("series").ok_or("Internal error: series did not contain \"series\"")?;
-    let base = stree.get_name("base").ok_or("Cannot format series; no base set.\nUse \"git series base\" to set base.")?;
+    let series = stree.get_name("series")
+        .ok_or("Internal error: series did not contain \"series\"")?;
+    let base = stree.get_name("base")
+        .ok_or("Cannot format series; no base set.\nUse \"git series base\" to set base.")?;
 
     let mut revwalk = repo.revwalk()?;
-    revwalk.set_sorting(git2::Sort::TOPOLOGICAL|git2::Sort::REVERSE);
+    revwalk.set_sorting(git2::Sort::TOPOLOGICAL | git2::Sort::REVERSE);
     revwalk.push(series.id())?;
     revwalk.hide(base.id())?;
     let mut commits: Vec<Commit> = revwalk.map(|c| {
         let id = c?;
         let commit = repo.find_commit(id)?;
         if commit.parent_ids().count() > 1 {
-            return Err(format!("Error: cannot format merge commit as patch:\n{}", commit_summarize(repo, id)?).into());
+            return Err(format!(
+                "Error: cannot format merge commit as patch:\n{}",
+                commit_summarize(repo, id)?,
+            ).into());
         }
         Ok(commit)
     }).collect::<Result<_>>()?;
@@ -1460,15 +1628,20 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     let committer = get_signature(&config, "COMMITTER")?;
     let committer_name = committer.name().unwrap();
     let committer_email = committer.email().unwrap();
-    let message_id_suffix = format!("{}.git-series.{}", committer.when().seconds(), committer_email);
+    let message_id_suffix = format!(
+        "{}.git-series.{}",
+        committer.when().seconds(),
+        committer_email,
+    );
 
     let cover_entry = stree.get_name("cover");
-    let mut in_reply_to_message_id = m.value_of("in-reply-to").map(|v| {
-        format!("{}{}{}",
-                if v.starts_with('<') { "" } else { "<" },
-                v,
-                if v.ends_with('>') { "" } else { ">" })
-    });
+    let mut in_reply_to_message_id = m.value_of("in-reply-to")
+        .map(|v| format!(
+            "{}{}{}",
+            if v.starts_with('<') { "" } else { "<" },
+            v,
+            if v.ends_with('>') { "" } else { ">" },
+        ));
 
     let version = m.value_of("reroll-count");
     let subject_prefix = if m.is_present("rfc") {
@@ -1477,8 +1650,9 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
         m.value_of("subject-prefix").unwrap_or("PATCH")
     };
     let subject_patch = version.map_or(
-            subject_prefix.to_string(),
-            |n| format!("{}{}v{}", subject_prefix, ensure_space(&subject_prefix), n));
+        subject_prefix.to_string(),
+        |n| format!("{}{}v{}", subject_prefix, ensure_space(&subject_prefix), n),
+    );
     let file_prefix = version.map_or("".to_string(), |n| format!("v{}-", n));
 
     let num_width = commits.len().to_string().len();
@@ -1493,7 +1667,7 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     } else {
         DiffColors::plain()
     };
-    let mut out : Box<dyn IoWrite> = if to_stdout {
+    let mut out: Box<dyn IoWrite> = if to_stdout {
         Box::new(out)
     } else {
         Box::new(std::io::stdout())
@@ -1527,7 +1701,16 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
         in_reply_to_message_id = Some(cover_message_id);
         writeln!(out, "From: {} <{}>", committer_name, committer_email)?;
         writeln!(out, "Date: {}", date_822(committer.when()))?;
-        writeln!(out, "Subject: [{}{}{:0>num_width$}/{}] {}\n", subject_patch, ensure_space(&subject_patch), 0, commits.len(), subject, num_width = num_width)?;
+        writeln!(
+            out,
+            "Subject: [{}{}{:0>num_width$}/{}] {}\n",
+            subject_patch,
+            ensure_space(&subject_patch),
+            0,
+            commits.len(),
+            subject,
+            num_width=num_width,
+        )?;
         if !body.is_empty() {
             writeln!(out, "{}", body)?;
         }
@@ -1552,7 +1735,11 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
         let summary_sanitized = sanitize_summary(&subject);
         let this_message_id = format!("<{}.{}>", commit_id, message_id_suffix);
         let parent = commit.parent(0)?;
-        let diff = repo.diff_tree_to_tree(Some(&parent.tree().unwrap()), Some(&commit.tree().unwrap()), None)?;
+        let diff = repo.diff_tree_to_tree(
+            Some(&parent.tree().unwrap()),
+            Some(&commit.tree().unwrap()),
+            None,
+        )?;
         let stats = diffstat(&diff)?;
 
         if !to_stdout {
@@ -1580,7 +1767,14 @@ fn format(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
                 format!("[{}] ", subject_patch)
             }
         } else {
-            format!("[{}{}{:0>num_width$}/{}] ", subject_patch, ensure_space(&subject_patch), commit_num+1, commits.len(), num_width=num_width)
+            format!(
+                "[{}{}{:0>num_width$}/{}] ",
+                subject_patch,
+                ensure_space(&subject_patch),
+                commit_num + 1,
+                commits.len(),
+                num_width=num_width,
+            )
         };
         writeln!(out, "Subject: {}{}\n", prefix, subject)?;
 
@@ -1674,19 +1868,30 @@ fn log(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
 fn rebase(repo: &Repository, m: &ArgMatches) -> Result<()> {
     match repo.state() {
         git2::RepositoryState::Clean => (),
-        git2::RepositoryState::RebaseMerge if repo.path().join("rebase-merge").join("git-series").exists() => {
-            return Err("git series rebase already in progress.\nUse \"git rebase --continue\" or \"git rebase --abort\".".into());
-        },
-        s => { return Err(format!("{:?} in progress; cannot rebase", s).into()); }
+        git2::RepositoryState::RebaseMerge
+            if repo.path().join("rebase-merge").join("git-series").exists()
+        => {
+            return Err(concat!(
+                "git series rebase already in progress.\n",
+                "Use \"git rebase --continue\" or \"git rebase --abort\".",
+            ).into());
+        }
+        s => return Err(format!("{:?} in progress; cannot rebase", s).into()),
     }
 
     let internals = Internals::read(repo)?;
-    let series = internals.working.get("series")?.ok_or("Could not find entry \"series\" in working index")?;
-    let base = internals.working.get("base")?.ok_or("Cannot rebase series; no base set.\nUse \"git series base\" to set base.")?;
+    let series = internals.working.get("series")?
+        .ok_or("Could not find entry \"series\" in working index")?;
+    let base = internals.working.get("base")?
+        .ok_or("Cannot rebase series; no base set.\nUse \"git series base\" to set base.")?;
     if series.id() == base.id() {
         return Err("No patches to rebase; series and base identical.".into());
     } else if !repo.graph_descendant_of(series.id(), base.id())? {
-        return Err(format!("Cannot rebase: current base {} not an ancestor of series {}", base.id(), series.id()).into());
+        return Err(format!(
+            "Cannot rebase: current base {} not an ancestor of series {}",
+            base.id(),
+            series.id(),
+        ).into());
     }
 
     // Check for unstaged or uncommitted changes before attempting to rebase.
@@ -1708,14 +1913,17 @@ fn rebase(repo: &Repository, m: &ArgMatches) -> Result<()> {
     }
 
     let mut revwalk = repo.revwalk()?;
-    revwalk.set_sorting(git2::Sort::TOPOLOGICAL|git2::Sort::REVERSE);
+    revwalk.set_sorting(git2::Sort::TOPOLOGICAL | git2::Sort::REVERSE);
     revwalk.push(series.id())?;
     revwalk.hide(base.id())?;
     let commits: Vec<Commit> = revwalk.map(|c| {
         let id = c?;
         let mut commit = repo.find_commit(id)?;
         if commit.parent_ids().count() > 1 {
-            return Err(format!("Error: cannot rebase merge commit:\n{}", commit_obj_summarize(&mut commit)?).into());
+            return Err(format!(
+                "Error: cannot rebase merge commit:\n{}",
+                commit_obj_summarize(&mut commit)?,
+            ).into());
         }
         Ok(commit)
     }).collect::<Result<_>>()?;
@@ -1727,7 +1935,7 @@ fn rebase(repo: &Repository, m: &ArgMatches) -> Result<()> {
             let obj = repo.revparse_single(onto)?;
             let commit = obj.peel(ObjectType::Commit)?;
             Some(commit.id())
-        },
+        }
     };
 
     let newbase = onto.unwrap_or(base.id());
@@ -1790,7 +1998,12 @@ fn rebase(repo: &Repository, m: &ArgMatches) -> Result<()> {
     dir.into_path();
 
     checkout_tree(repo, &newbase_obj)?;
-    repo.reference("HEAD", newbase, true, &format!("rebase -i (start): checkout {}", newbase))?;
+    repo.reference(
+        "HEAD",
+        newbase,
+        true,
+        &format!("rebase -i (start): checkout {}", newbase),
+    )?;
 
     let status = Command::new("git").arg("rebase").arg("--continue").status()?;
     if !status.success() {
@@ -1806,10 +2019,12 @@ fn req(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     let shead_commit = shead.resolve()?.peel_to_commit()?;
     let stree = shead_commit.tree()?;
 
-    let series = stree.get_name("series").ok_or("Internal error: series did not contain \"series\"")?;
+    let series = stree.get_name("series")
+        .ok_or("Internal error: series did not contain \"series\"")?;
     let series_id = series.id();
     let mut series_commit = repo.find_commit(series_id)?;
-    let base = stree.get_name("base").ok_or("Cannot request pull; no base set.\nUse \"git series base\" to set base.")?;
+    let base = stree.get_name("base")
+        .ok_or("Cannot request pull; no base set.\nUse \"git series base\" to set base.")?;
     let mut base_commit = repo.find_commit(base.id())?;
 
     let (cover_content, subject, cover_body) = if let Some(entry) = stree.get_name("cover") {
@@ -1827,7 +2042,8 @@ fn req(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     let full_tag_peeled = format!("{}^{{}}", full_tag);
     let full_head = format!("refs/heads/{}", tag);
     let mut remote = repo.remote_anonymous(url)?;
-    remote.connect(git2::Direction::Fetch).map_err(|e| format!("Could not connect to remote repository {}\n{}", url, e))?;
+    remote.connect(git2::Direction::Fetch)
+        .map_err(|e| format!("Could not connect to remote repository {}\n{}", url, e))?;
     let remote_heads = remote.list()?;
 
     /* Find the requested name as either a tag or head */
@@ -1846,10 +2062,16 @@ fn req(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     let (msg, extra_body, remote_pull_name) = match (opt_remote_tag, opt_remote_tag_peeled, opt_remote_head) {
         (Some(remote_tag), Some(remote_tag_peeled), _) => {
             if remote_tag_peeled != series_id {
-                return Err(format!("Remote tag {} does not refer to series {}", tag, series_id).into());
+                return Err(format!(
+                    "Remote tag {} does not refer to series {}",
+                    tag, series_id,
+                ).into());
             }
-            let local_tag = repo.find_tag(remote_tag).map_err(|e|
-                    format!("Could not find remote tag {} ({}) in local repository: {}", tag, remote_tag, e))?;
+            let local_tag = repo.find_tag(remote_tag)
+                .map_err(|e| format!(
+                    "Could not find remote tag {} ({}) in local repository: {}",
+                    tag, remote_tag, e,
+                ))?;
             let mut local_tag_msg = local_tag.message().unwrap().to_string();
             if let Some(sig_index) = local_tag_msg.find("-----BEGIN PGP ") {
                 local_tag_msg.truncate(sig_index);
@@ -1859,19 +2081,25 @@ fn req(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
                 _ => None,
             };
             (Some(local_tag_msg), extra_body, full_tag)
-        },
+        }
         (Some(remote_tag), None, _) => {
             if remote_tag != series_id {
-                return Err(format!("Remote unannotated tag {} does not refer to series {}", tag, series_id).into());
+                return Err(format!(
+                    "Remote unannotated tag {} does not refer to series {}",
+                    tag, series_id,
+                ).into());
             }
             (cover_content, None, full_tag)
         }
         (_, _, Some(remote_head)) => {
             if remote_head != series_id {
-                return Err(format!("Remote branch {} does not refer to series {}", tag, series_id).into());
+                return Err(format!(
+                    "Remote branch {} does not refer to series {}",
+                    tag, series_id,
+                ).into());
             }
             (cover_content, None, full_head)
-        },
+        }
         _ => {
             return Err(format!("Remote does not have either a tag or branch named {}", tag).into())
         }
@@ -1884,19 +2112,30 @@ fn req(out: &mut Output, repo: &Repository, m: &ArgMatches) -> Result<()> {
     };
 
     let mut revwalk = repo.revwalk()?;
-    revwalk.set_sorting(git2::Sort::TOPOLOGICAL|git2::Sort::REVERSE);
+    revwalk.set_sorting(git2::Sort::TOPOLOGICAL | git2::Sort::REVERSE);
     revwalk.push(series_id)?;
     revwalk.hide(base.id())?;
-    let mut commits: Vec<Commit> = revwalk.map(|c| Ok(repo.find_commit(c?)?)).collect::<Result<_>>()?;
+    let mut commits: Vec<Commit> = revwalk
+        .map(|c| Ok(repo.find_commit(c?)?))
+        .collect::<Result<_>>()?;
     if commits.is_empty() {
         return Err("No patches to request pull of; series and base identical.".into());
     }
 
     let author = get_signature(&config, "AUTHOR")?;
     let author_email = author.email().unwrap();
-    let message_id = format!("<pull.{}.{}.git-series.{}>", shead_commit.id(), author.when().seconds(), author_email);
-
-    let diff = repo.diff_tree_to_tree(Some(&base_commit.tree().unwrap()), Some(&series_commit.tree().unwrap()), None)?;
+    let message_id = format!(
+        "<pull.{}.{}.git-series.{}>",
+        shead_commit.id(),
+        author.when().seconds(),
+        author_email
+    );
+
+    let diff = repo.diff_tree_to_tree(
+        Some(&base_commit.tree().unwrap()),
+        Some(&series_commit.tree().unwrap()),
+        None,
+    )?;
     let stats = diffstat(&diff)?;
 
     out.auto_pager(&config, "request-pull", true)?;
@@ -2028,7 +2267,7 @@ fn main() {
             ("start", Some(ref sm)) => start(&repo, &sm),
             ("status", Some(ref sm)) => commit_status(&mut out, &repo, &sm, true),
             ("unadd", Some(ref sm)) => unadd(&repo, &sm),
-            _ => unreachable!()
+            _ => unreachable!(),
         }
     }();