Commit 25b6f61d authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'rustfmt-20180904'

885c7387 MergeCommand: use debug_struct
a50cdc6b rust: avoid unnecessary Vec collecting
62f8658f rustfmt: add a space after a comment marker
b4898058 rustfmt: markup a TODO item with an issue number
458474b6 rustfmt: reformat function call arguments
b68441b1 rustfmt: reformat `where` clauses
e5d3e65b rustfmt: move operators to the front
9ae0df0a rustfmt: sort imports
...
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !62
parents 11acb0ac 885c7387
Pipeline #115556 passed with stage
in 0 seconds
// Copyright {\d+} Kitware, Inc.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum_trailing_comma = true
fn_args_density = "Compressed"
fn_args_layout = "Visual"
match_block_trailing_comma = true
match_wildcard_trailing_comma = true
reorder_imported_names = true
struct_lit_multiline_style = "ForceMulti"
struct_lit_trailing_comma = "Always"
struct_trailing_comma = "Always"
where_trailing_comma = true
force_multiline_blocks = true
report_todo = "Unnumbered"
report_fixme = "Unnumbered"
struct_lit_single_line = false
trailing_comma = "Always"
license_template_path = ".license.template"
......@@ -14,8 +14,8 @@ use std::fmt::{self, Display};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
/// The Git object id of a commit.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CommitId(String);
impl CommitId {
......@@ -36,8 +36,8 @@ impl Display for CommitId {
}
}
#[derive(Debug, Clone)]
/// A context for performing git commands.
#[derive(Debug, Clone)]
pub struct GitContext {
/// The path to the `.git` directory.
gitdir: PathBuf,
......@@ -45,8 +45,8 @@ pub struct GitContext {
config: Option<PathBuf>,
}
#[derive(Debug, PartialEq, Eq)]
/// An identity for creating git commits.
#[derive(Debug, PartialEq, Eq)]
pub struct Identity {
/// The name.
pub name: String,
......@@ -57,8 +57,9 @@ pub struct Identity {
impl Identity {
/// Create a new identity.
pub fn new<N, E>(name: N, email: E) -> Self
where N: ToString,
E: ToString,
where
N: ToString,
E: ToString,
{
Self {
name: name.to_string(),
......@@ -79,8 +80,8 @@ impl Display for Identity {
}
}
#[derive(Debug)]
/// Status of a merge check.
#[derive(Debug)]
pub enum MergeStatus {
/// The branches do not contain common history.
NoCommonHistory,
......@@ -92,20 +93,23 @@ pub enum MergeStatus {
impl Display for MergeStatus {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"{}",
match *self {
MergeStatus::NoCommonHistory => "no common history",
MergeStatus::AlreadyMerged => "already merged",
MergeStatus::Mergeable(_) => "mergeable",
})
write!(
f,
"{}",
match *self {
MergeStatus::NoCommonHistory => "no common history",
MergeStatus::AlreadyMerged => "already merged",
MergeStatus::Mergeable(_) => "mergeable",
},
)
}
}
impl GitContext {
/// Create a new context for the given directory.
pub fn new<P>(gitdir: P) -> Self
where P: AsRef<Path>,
where
P: AsRef<Path>,
{
Self {
gitdir: gitdir.as_ref().to_path_buf(),
......@@ -115,8 +119,9 @@ impl GitContext {
/// Create a new context for the given directory with git configuration.
pub fn new_with_config<P, C>(gitdir: P, config: C) -> Self
where P: AsRef<Path>,
C: AsRef<Path>,
where
P: AsRef<Path>,
C: AsRef<Path>,
{
Self {
gitdir: gitdir.as_ref().to_path_buf(),
......@@ -143,21 +148,24 @@ impl GitContext {
///
/// The remote is interpreted by Git, so it can be a remote or a specific URL.
pub fn fetch<R, I, N>(&self, remote: R, refnames: I) -> Result<()>
where R: AsRef<str>,
I: IntoIterator<Item = N>,
N: AsRef<OsStr>,
where
R: AsRef<str>,
I: IntoIterator<Item = N>,
N: AsRef<OsStr>,
{
let fetch = self.git()
let fetch = self
.git()
.arg("fetch")
.arg(remote.as_ref())
.args(&refnames.into_iter()
.collect::<Vec<_>>())
.args(refnames.into_iter())
.output()
.chain_err(|| "failed to construct fetch command")?;
if !fetch.status.success() {
bail!(ErrorKind::Git(format!("fetch from {} failed: {}",
remote.as_ref(),
String::from_utf8_lossy(&fetch.stderr))));
bail!(ErrorKind::Git(format!(
"fetch from {} failed: {}",
remote.as_ref(),
String::from_utf8_lossy(&fetch.stderr)
)));
}
Ok(())
......@@ -165,23 +173,29 @@ impl GitContext {
/// Fetch a commit from the given remote into a specific local refname.
pub fn fetch_into<R, N, T>(&self, remote: R, refname: N, target: T) -> Result<()>
where R: AsRef<str>,
N: AsRef<str>,
T: AsRef<str>,
where
R: AsRef<str>,
N: AsRef<str>,
T: AsRef<str>,
{
self.fetch(remote,
&[&format!("{}:{}", refname.as_ref(), target.as_ref())])
self.fetch(
remote,
&[&format!("{}:{}", refname.as_ref(), target.as_ref())],
)
}
/// Fetch a commit from the given remote into a specific local refname, allowing rewinds.
pub fn force_fetch_into<R, N, T>(&self, remote: R, refname: N, target: T) -> Result<()>
where R: AsRef<str>,
N: AsRef<str>,
T: AsRef<str>,
where
R: AsRef<str>,
N: AsRef<str>,
T: AsRef<str>,
{
self.fetch_into(remote.as_ref(),
format!("+{}", refname.as_ref()),
target.as_ref())
self.fetch_into(
remote.as_ref(),
format!("+{}", refname.as_ref()),
target.as_ref(),
)
}
/// Create a tree where further work on the given revision can occur.
......@@ -196,14 +210,16 @@ impl GitContext {
/// The reserved reference is created as `refs/{name}/heads/{id}` where `id` is a unique
/// integer (which is also returned).
pub fn reserve_ref<N>(&self, name: N, commit: &CommitId) -> Result<(String, usize)>
where N: AsRef<str>,
where
N: AsRef<str>,
{
let ref_prefix = format!("refs/{}/heads", name.as_ref());
debug!(target: "git", "reserving ref under {}", ref_prefix);
loop {
let for_each_ref = self.git()
let for_each_ref = self
.git()
.arg("for-each-ref")
.arg("--format=%(refname)")
.arg("--")
......@@ -211,9 +227,11 @@ impl GitContext {
.output()
.chain_err(|| "failed to construct for-each-ref command")?;
if !for_each_ref.status.success() {
bail!(ErrorKind::Git(format!("listing all {} refs: {}",
ref_prefix,
String::from_utf8_lossy(&for_each_ref.stderr))));
bail!(ErrorKind::Git(format!(
"listing all {} refs: {}",
ref_prefix,
String::from_utf8_lossy(&for_each_ref.stderr)
)));
}
let refs = String::from_utf8_lossy(&for_each_ref.stdout);
......@@ -222,7 +240,8 @@ impl GitContext {
debug!(target: "git", "trying to reserve ref {}", new_ref);
let lock_ref = self.git()
let lock_ref = self
.git()
.arg("update-ref")
.arg(&new_ref)
.arg(commit.as_str())
......@@ -258,7 +277,8 @@ impl GitContext {
/// It is assumed that the `bases` refs are aligned with the `heads` references and not used
/// for other purposes.
pub fn reserve_refs<N>(&self, name: N, commit: &CommitId) -> Result<(String, String)>
where N: AsRef<str>,
where
N: AsRef<str>,
{
let (new_ref, id) = self.reserve_ref(name.as_ref(), commit)?;
let new_base = format!("refs/{}/bases/{}", name.as_ref(), id);
......@@ -281,7 +301,8 @@ impl GitContext {
return Ok(MergeStatus::NoCommonHistory);
}
let bases = String::from_utf8_lossy(&merge_base.stdout);
let bases = bases.split_whitespace()
let bases = bases
.split_whitespace()
.map(CommitId::new)
.collect::<Vec<_>>();
......
......@@ -43,8 +43,8 @@ mod prepare;
pub use error::Error;
pub use error::ErrorKind;
pub use error::ResultExt;
pub use error::Result;
pub use error::ResultExt;
pub use git::CommitId;
pub use git::GitContext;
......@@ -52,9 +52,9 @@ pub use git::Identity;
pub use git::MergeStatus;
pub use prepare::Conflict;
pub use prepare::GitWorkArea;
pub use prepare::MergeCommand;
pub use prepare::MergeResult;
pub use prepare::GitWorkArea;
pub use prepare::SubmoduleConfig;
#[cfg(test)]
......
......@@ -24,8 +24,8 @@ use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
#[derive(Debug)]
/// Representation of merge conflict possibilities.
#[derive(Debug)]
pub enum Conflict {
/// A regular blob has conflicted.
Path(PathBuf),
......@@ -45,10 +45,10 @@ impl Conflict {
/// The path to the blob that for the conflict.
pub fn path(&self) -> &Path {
match *self {
Conflict::Path(ref p) |
Conflict::SubmoduleNotMerged(ref p) |
Conflict::SubmoduleNotPresent(ref p) |
Conflict::SubmoduleWithFix(ref p, _) => p,
Conflict::Path(ref p)
| Conflict::SubmoduleNotMerged(ref p)
| Conflict::SubmoduleNotPresent(ref p)
| Conflict::SubmoduleWithFix(ref p, _) => p,
}
}
}
......@@ -88,8 +88,7 @@ impl<'a> MergeCommand<'a> {
/// Set the authorship date of the merge.
pub fn author_date(&mut self, when: DateTime<Utc>) -> &mut Self {
self.command
.env("GIT_AUTHOR_DATE", when.to_rfc2822());
self.command.env("GIT_AUTHOR_DATE", when.to_rfc2822());
self
}
......@@ -97,7 +96,8 @@ impl<'a> MergeCommand<'a> {
///
/// Returns the ID of the merge commit itself.
pub fn commit<M>(self, message: M) -> Result<CommitId>
where M: AsRef<str>,
where
M: AsRef<str>,
{
self.commit_impl(message.as_ref())
}
......@@ -107,24 +107,31 @@ impl<'a> MergeCommand<'a> {
/// This spawns the commit command, feeds the message in over its standard input, runs it and
/// returns the new commit object's ID.
fn commit_impl(mut self, message: &str) -> Result<CommitId> {
let mut commit_tree = self.command
let mut commit_tree = self
.command
.spawn()
.chain_err(|| "failed to construct commit-tree command")?;
{
let commit_tree_stdin =
commit_tree.stdin.as_mut().expect("expected commit-tree to have a stdin");
commit_tree_stdin.write_all(message.as_bytes())
let commit_tree_stdin = commit_tree
.stdin
.as_mut()
.expect("expected commit-tree to have a stdin");
commit_tree_stdin
.write_all(message.as_bytes())
.chain_err(|| {
ErrorKind::Git("failed to write the commit message to commit-tree".to_string())
})?;
}
let commit_tree = commit_tree.wait_with_output()
let commit_tree = commit_tree
.wait_with_output()
.chain_err(|| "failed to execute commit-tree command")?;
if !commit_tree.status.success() {
bail!(ErrorKind::Git(format!("failed to commit the merged tree: {}",
String::from_utf8_lossy(&commit_tree.stderr))));
bail!(ErrorKind::Git(format!(
"failed to commit the merged tree: {}",
String::from_utf8_lossy(&commit_tree.stderr)
)));
}
let merge_commit = String::from_utf8_lossy(&commit_tree.stdout);
......@@ -134,12 +141,12 @@ impl<'a> MergeCommand<'a> {
impl<'a> Debug for MergeCommand<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "MergeCommand")
f.debug_struct("MergeCommand").finish()
}
}
#[derive(Debug)]
/// The result of an attempted merge.
#[derive(Debug)]
pub enum MergeResult<'a> {
/// A merge conflict occurred.
Conflict(Vec<Conflict>),
......@@ -160,9 +167,9 @@ struct PreparingGitWorkArea {
dir: TempDir,
}
#[derive(Debug)]
/// A representation of an empty workarea where actions which require a work tree and an index may
/// be preformed.
#[derive(Debug)]
pub struct GitWorkArea {
/// The context to work with.
context: GitContext,
......@@ -187,18 +194,22 @@ trait WorkareaGitContext {
/// Checkout a set of paths into a workarea.
fn checkout<I, P>(ctx: &WorkareaGitContext, paths: I) -> Result<()>
where I: IntoIterator<Item = P>,
P: AsRef<OsStr>,
where
I: IntoIterator<Item = P>,
P: AsRef<OsStr>,
{
let ls_files = ctx.cmd()
let ls_files = ctx
.cmd()
.arg("ls-files")
.arg("--")
.args(paths.into_iter())
.output()
.chain_err(|| "failed to construct ls-files command")?;
if !ls_files.status.success() {
bail!(ErrorKind::Git(format!("listing paths in the index: {}",
String::from_utf8_lossy(&ls_files.stderr))));
bail!(ErrorKind::Git(format!(
"listing paths in the index: {}",
String::from_utf8_lossy(&ls_files.stderr)
)));
}
checkout_files(ctx, &ls_files.stdout)
......@@ -206,7 +217,8 @@ fn checkout<I, P>(ctx: &WorkareaGitContext, paths: I) -> Result<()>
/// Checkout a set of files (in `git ls-files` format) into a workarea.
fn checkout_files(ctx: &WorkareaGitContext, files: &[u8]) -> Result<()> {
let mut checkout_index = ctx.cmd()
let mut checkout_index = ctx
.cmd()
.arg("checkout-index")
.arg("-f")
.arg("-q")
......@@ -216,25 +228,32 @@ fn checkout_files(ctx: &WorkareaGitContext, files: &[u8]) -> Result<()> {
.stderr(Stdio::piped())
.spawn()
.chain_err(|| "failed to construct checkout-index command")?;
checkout_index.stdin
checkout_index
.stdin
.as_mut()
.expect("expected checkout-index to have a stdin")
.write_all(files)
.chain_err(|| ErrorKind::Git("writing to checkout-index".to_string()))?;
let res = checkout_index.wait().expect("expected checkout-index to execute successfully");
let res = checkout_index
.wait()
.expect("expected checkout-index to execute successfully");
if !res.success() {
let mut stderr = Vec::new();
checkout_index.stderr
checkout_index
.stderr
.as_mut()
.expect("expected checkout-index to have a stderr")
.read_to_end(&mut stderr)
.chain_err(|| "failed to read from checkout-index")?;
bail!(ErrorKind::Git(format!("running checkout-index: {}",
String::from_utf8_lossy(&stderr))));
bail!(ErrorKind::Git(format!(
"running checkout-index: {}",
String::from_utf8_lossy(&stderr),
)));
}
// Update the index for the files we put into the context
let mut update_index = ctx.cmd()
let mut update_index = ctx
.cmd()
.arg("update-index")
.arg("--stdin")
.stdin(Stdio::piped())
......@@ -242,21 +261,27 @@ fn checkout_files(ctx: &WorkareaGitContext, files: &[u8]) -> Result<()> {
.stderr(Stdio::piped())
.spawn()
.chain_err(|| "failed to construct update-index command")?;
update_index.stdin
update_index
.stdin
.as_mut()
.expect("expected update-index to have a stdin")
.write_all(files)
.chain_err(|| ErrorKind::Git("writing to update-index".to_string()))?;
let res = update_index.wait().expect("expected update-index to execute successfully");
let res = update_index
.wait()
.expect("expected update-index to execute successfully");
if !res.success() {
let mut stderr = Vec::new();
update_index.stderr
update_index
.stderr
.as_mut()
.expect("expected update-index to have a stderr")
.read_to_end(&mut stderr)
.chain_err(|| "failed to read from update-index")?;
bail!(ErrorKind::Git(format!("running update-index: {}",
String::from_utf8_lossy(&stderr))));
bail!(ErrorKind::Git(format!(
"running update-index: {}",
String::from_utf8_lossy(&stderr),
)));
}
Ok(())
......@@ -266,7 +291,8 @@ fn checkout_files(ctx: &WorkareaGitContext, files: &[u8]) -> Result<()> {
///
/// Used to simplify printing a filename.
fn file_name(path: &Path) -> Cow<str> {
path.file_name().map_or_else(|| Cow::Borrowed("<unknown>"), OsStr::to_string_lossy)
path.file_name()
.map_or_else(|| Cow::Borrowed("<unknown>"), OsStr::to_string_lossy)
}
impl PreparingGitWorkArea {
......@@ -308,9 +334,11 @@ impl PreparingGitWorkArea {
.output()
.chain_err(|| "failed to construct read-tree command")?;
if !res.status.success() {
bail!(ErrorKind::Git(format!("reading the tree from {}: {}",
rev,
String::from_utf8_lossy(&res.stderr))));
bail!(ErrorKind::Git(format!(
"reading the tree from {}: {}",
rev,
String::from_utf8_lossy(&res.stderr)
)));
}
// Make the index believe the working tree is fine.
......@@ -345,7 +373,8 @@ impl PreparingGitWorkArea {
return Ok(SubmoduleConfig::new());
}
let config = self.git()
let config = self
.git()
.arg("config")
.arg("-f")
.arg(module_path)
......@@ -353,33 +382,45 @@ impl PreparingGitWorkArea {
.output()
.chain_err(|| "failed to construct config command for submodules")?;
if !config.status.success() {
bail!(ErrorKind::Git(format!("reading the submodule configuration: {}",
String::from_utf8_lossy(&config.stderr))));
bail!(ErrorKind::Git(format!(
"reading the submodule configuration: {}",
String::from_utf8_lossy(&config.stderr)
)));
}
let config = String::from_utf8_lossy(&config.stdout);
let mut submodule_config = SubmoduleConfig::new();
let captures = config.lines()
let captures = config
.lines()
.filter_map(|l| SUBMODULE_CONFIG_RE.captures(l));
for capture in captures {
submodule_config.entry(capture.name("name")
.expect("the submodule regex should have a 'name' group")
.as_str()
.to_string())
submodule_config
.entry(
capture
.name("name")
.expect("the submodule regex should have a 'name' group")
.as_str()
.to_string(),
)
.or_insert_with(HashMap::new)
.insert(capture.name("key")
.expect("the submodule regex should have a 'key' group")
.as_str()
.to_string(),
capture.name("value")
.expect("the submodule regex should have a 'value' group")
.as_str()
.to_string());
.insert(
capture
.name("key")
.expect("the submodule regex should have a 'key' group")
.as_str()
.to_string(),
capture
.name("value")
.expect("the submodule regex should have a 'value' group")
.as_str()
.to_string(),
);
}
let gitmoduledir = self.context.gitdir().join("modules");
Ok(submodule_config.into_iter()
Ok(submodule_config
.into_iter()
.filter(|&(ref name, _)| gitmoduledir.join(name).exists())
.collect())
}
......@@ -461,8 +502,10 @@ impl GitWorkArea {
};
let gitfiledir = self.work_tree().join(path);
fs::create_dir_all(&gitfiledir).chain_err(|| {
format!("failed to create the {} submodule directory for the workarea",
name)
format!(
"failed to create the {} submodule directory for the workarea",
name,
)
})?;
let mut gitfile = File::create(gitfiledir.join(".git"))
......@@ -486,7 +529,8 @@ impl GitWorkArea {
/// Figure out if there's a possible resolution for the submodule.
fn submodule_conflict<P>(&self, path: P, ours: &CommitId, theirs: &CommitId) -> Result<Conflict>
where P: AsRef<Path>,
where
P: AsRef<Path>,
{
let path = path.as_ref().to_path_buf();
......@@ -495,20 +539,19 @@ impl GitWorkArea {
file_name(self.dir.path()),
path.display());
let branch_info = self.submodule_config
let branch_info = self
.submodule_config
.iter()
.find(|&(_, config)| {
config.get("path")
.map_or(false,
|submod_path| submod_path.as_str() == path.to_string_lossy())
config.get("path").map_or(false, |submod_path| {
submod_path.as_str() == path.to_string_lossy()
})
})
.map(|(name, config)| {
(name, config.get("branch").map_or("master", String::as_str))
});
.map(|(name, config)| (name, config.get("branch").map_or("master", String::as_str)));
let (name, branch) = if let Some((name, branch_name)) = branch_info {
if branch_name == "." {
// TODO: Pass the branch name we are working on down to here.
// TODO(#6): Pass the branch name we are working on down to here.
debug!(target: "git.workarea",
"the `.` branch specifier for submodules is not supported for conflict \
resolution");
......@@ -545,7 +588,8 @@ impl GitWorkArea {
let refs = String::from_utf8_lossy(&refs.stdout);
for hash in refs.lines() {
let ours_ancestor = submodule_ctx.git()
let ours_ancestor = submodule_ctx
.git()
.arg("merge-base")
.arg("--is-ancestor")
.arg(ours.as_str())
......@@ -554,7 +598,8 @@ impl GitWorkArea {
.chain_err(|| {
"failed to construct merge-base command for submodule conflict resolution"
})?;
let theirs_ancestor = submodule_ctx.git()
let theirs_ancestor = submodule_ctx
.git()
.arg("merge-base")
.arg("--is-ancestor")
.arg(theirs.as_str())
......@@ -574,14 +619,17 @@ impl GitWorkArea {
/// Extract conflict information from the repository.
fn conflict_information(&self) -> Result<Vec<Conflict>> {
let ls_files = self.git()
let ls_files = self
.git()
.arg("ls-files")
.arg("-u")
.output()
.chain_err(|| "failed to construct ls-files command for conflict resolution")?;
if !ls_files.status.success() {
bail!(ErrorKind::Git(format!("listing unmerged files: {}",
String::from_utf8_lossy(&ls_files.stderr))));
bail!(ErrorKind::Git(format!(
"listing unmerged files: {}",
String::from_utf8_lossy(&ls_files.stderr)
)));
}
let conflicts = String::from_utf8_lossy(&ls_files.stdout);
......@@ -591,12 +639,13 @@ impl GitWorkArea {
let mut ours = CommitId::new(String::new());
for conflict in conflicts.lines() {
let info = conflict.split_whitespace()
.collect::<Vec<_>>();
let info = conflict.split_whitespace().collect::<Vec<_>>();
assert!(info.len() == 4,
"expected 4 entries for a conflict, received {}",
info.len());
assert!(
info.len() == 4,
"expected 4 entries for a conflict, received {}",
info.len(),
);
let permissions = info[0];
let hash = info[1];
......@@ -607,7 +656,7 @@ impl GitWorkArea {
if stage == "1" {
// Nothing to do; we don't need to know the hash of the submodule at the
// mergebase of the two branches.
//old = hash.to_owned();
// old = hash.to_owned();
} else if stage == "2" {
ours = CommitId::new(hash);
} else if stage == "3" {
......@@ -629,8 +678,9 @@ impl GitWorkArea {
///
/// All paths supported by Git's globbing and searching mechanisms are supported.
pub fn checkout<I, P>(&mut self, paths: I) -> Result<()>
where I: IntoIterator<Item = P>,
P: AsRef<OsStr>,
where
I: IntoIterator<Item = P>,
P: AsRef<OsStr>,
{
checkout(self, paths)
}
......@@ -640,13 +690,16 @@ impl GitWorkArea {
/// The merge is performed, but only as a tree object. In order to create the actual commit
/// object, a successful merge returns a command which should be executed to create the commit
/// object. That commit object should then be stored in a reference using `git update-ref`.
pub fn setup_merge<'a>(&'a self, bases: &[CommitId], base: &CommitId, topic: &CommitId)
-> Result<MergeResult<'a>> {
let merge_recursive = self.git()
pub fn setup_merge<'a>(
&'a self,
bases: &[CommitId],
base: &CommitId,
topic: &CommitId,
) -> Result<MergeResult<'a>> {
let merge_recursive = self
.git()
.arg("merge-recursive")
.args(&bases.iter()
.map(CommitId::as_str)
.collect::<Vec<_>>())
.args(bases.iter().map(CommitId::as_str))
.arg("--")
.arg(base.as_str())
.arg(topic.as_str())
......@@ -664,35 +717,45 @@ impl GitWorkArea {
/// The merge is performed, but only as a tree object. In order to create the actual commit
/// object, a successful merge returns a command which should be executed to create the commit
/// object. That commit object should then be stored in a reference using `git update-ref`.
pub fn setup_update_merge<'a>(&'a self, base: &CommitId, topic: &CommitId)
-> Result<MergeResult<'a>> {
pub fn setup_update_merge<'a>(
&'a self,
base: &CommitId,
topic: &CommitId,