Skip to content

Commit

Permalink
resolve default branch on repo creation, allow to override (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
kilork authored May 10, 2024
1 parent 02ffb2a commit ee276af
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 333 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ repository = "https://github.com/kilork/hg-git-fast-import"
rust-version = "1.78"
version = "1.3.8"

[lib]
doctest = false

[features]
jemalloc = ["jemallocator"]

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ FLAGS:
OPTIONS:
-a, --authors <authors> Authors remapping in toml format
-c, --config <config> Repository configuration in toml format
--default-branch <default-branch> Default branch to use
--git-active-branches <git-active-branches> Git maximum number of branches to maintain active at once
--limit-high <limit-high> Limit high revision to import
--log <log>
Expand Down Expand Up @@ -231,6 +232,7 @@ path_prefix = 'prefix1'
tag_prefix = 'prefix2-'
branch_prefix = 'prefix3-'
prefix_default_branch = true
default_branch = 'main'
# Same as authors section in single mode, but for this child repository.
[repositories.config.authors]
Expand Down
4 changes: 3 additions & 1 deletion examples/multi.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Path to target git repository.
# Path to target master git repository.
path_git = "000_git"
# Default branch in master repo. Optional.
default_branch = "main"

# This is subsection with list of repositories to be aggregated into single repo.
# Each subsection start like this (see toml format for arrays).
Expand Down
2 changes: 2 additions & 0 deletions examples/single.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ branch_prefix = 'prefix3-'
# This behavior can be changed by specifying this as true.
# Optional.
prefix_default_branch = false
# Default branch in repo. Optional.
default_branch = "main"

# Mapping between authors in Mercurial and authors in Git.
# Required mainly because of Git asks for particular format "Somename <email@address>".
Expand Down
3 changes: 3 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub enum Cli {
/// Limit high revision to import.
#[structopt(name = "limit-high", long)]
limit_high: Option<usize>,
/// Default branch to use.
#[structopt(name = "default-branch", long)]
default_branch: Option<String>,
#[structopt(flatten)]
common: Common,
},
Expand Down
17 changes: 17 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ pub struct RepositoryConfig {
pub tag_prefix: Option<String>,
#[serde(default)]
pub prefix_default_branch: bool,
pub default_branch: Option<String>,
}

impl RepositoryConfig {
pub fn default_branch(&self) -> Option<&str> {
self.default_branch.as_deref()
}
}

impl Default for RepositoryConfig {
Expand All @@ -32,6 +39,7 @@ impl Default for RepositoryConfig {
branch_prefix: None,
tag_prefix: None,
prefix_default_branch: false,
default_branch: None,
}
}
}
Expand All @@ -50,6 +58,13 @@ pub struct PathRepositoryConfig {
pub struct MultiConfig {
pub path_git: PathBuf,
pub repositories: Vec<PathRepositoryConfig>,
default_branch: Option<String>,
}

impl MultiConfig {
pub fn default_branch(&self) -> Option<&str> {
self.default_branch.as_deref()
}
}

#[derive(Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -100,6 +115,7 @@ mod tests {
.into_iter()
.collect()
),
default_branch: Some("main".into()),
..Default::default()
}
)
Expand All @@ -114,6 +130,7 @@ mod tests {
result,
super::MultiConfig {
path_git: "000_git".into(),
default_branch: Some("main".into()),
repositories: vec![
super::PathRepositoryConfig {
path_hg: "001_hg".into(),
Expand Down
38 changes: 32 additions & 6 deletions src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use std::io::prelude::*;
use std::process::{Child, Command, ExitStatus, Stdio};
use tracing::{debug, error, info};

pub const DEFAULT_BRANCH: &str = "master";

pub struct StdoutTargetRepository<'a> {
stdoutlock: std::io::StdoutLock<'a>,
}
Expand All @@ -27,8 +29,9 @@ impl<'a> TargetRepository for StdoutTargetRepository<'a> {
fn start_import(
&mut self,
_git_active_branches: Option<usize>,
) -> Result<(&mut dyn Write, Option<RepositorySavedState>), TargetRepositoryError> {
Ok((&mut self.stdoutlock, None))
_default_branch: Option<&str>,
) -> Result<(&mut dyn Write, Option<RepositorySavedState>, String), TargetRepositoryError> {
Ok((&mut self.stdoutlock, None, DEFAULT_BRANCH.to_string()))
}
fn finish(&mut self) -> Result<(), TargetRepositoryError> {
Ok(())
Expand Down Expand Up @@ -66,13 +69,16 @@ impl<'a> GitTargetRepository<'a> {
saved_state
}

pub fn create_repo(&self) -> Result<(), TargetRepositoryError> {
pub fn create_repo(&self, default_branch: &str) -> Result<(), TargetRepositoryError> {
let path = &self.path;
info!("Creating new dir");
fs::create_dir_all(path)?;

info!("Init Git repo");
let status = Command::new("git").arg("init").current_dir(path).status()?;
let status = Command::new("git")
.args(["init", "-b", default_branch])
.current_dir(path)
.status()?;
if !status.success() {
error!("Cannot init Git repo");
return Err(TargetRepositoryError::CannotInitRepo(status));
Expand All @@ -87,6 +93,19 @@ impl<'a> GitTargetRepository<'a> {
Ok(())
}

pub fn git_config_default_branch(&self) -> Result<String, TargetRepositoryError> {
let output = Command::new("git")
.args(["config", "--global", "init.defaultBranch"])
.output()?;
let output_str = String::from_utf8_lossy(&output.stdout);
let default_branch = output_str.trim();
Ok(if !default_branch.is_empty() {
default_branch.into()
} else {
DEFAULT_BRANCH.into()
})
}

pub fn git_cmd(&self, args: &[&str]) -> Command {
let mut git_cmd = Command::new("git");
git_cmd.current_dir(&self.path).args(args);
Expand Down Expand Up @@ -134,7 +153,8 @@ impl<'a> TargetRepository for GitTargetRepository<'a> {
fn start_import(
&mut self,
git_active_branches: Option<usize>,
) -> Result<(&mut dyn Write, Option<RepositorySavedState>), TargetRepositoryError> {
default_branch: Option<&str>,
) -> Result<(&mut dyn Write, Option<RepositorySavedState>, String), TargetRepositoryError> {
let path = &self.path;
let saved_state;
info!("Checking Git repo: {}", path.to_str().unwrap());
Expand All @@ -145,6 +165,11 @@ impl<'a> TargetRepository for GitTargetRepository<'a> {
std::fs::remove_dir_all(path)?;
}

let default_branch = if let Some(default_branch) = default_branch {
default_branch.to_string()
} else {
self.git_config_default_branch()?
};
if path.exists() {
if path.is_dir() {
info!("Path exists, checking for saved state");
Expand All @@ -166,7 +191,7 @@ impl<'a> TargetRepository for GitTargetRepository<'a> {
return Err(TargetRepositoryError::IsNotDir);
}
} else {
self.create_repo()?;
self.create_repo(&default_branch)?;
saved_state = None;
}

Expand All @@ -188,6 +213,7 @@ impl<'a> TargetRepository for GitTargetRepository<'a> {
.map(|x| x.stdin.as_mut().unwrap())
.unwrap(),
saved_state,
default_branch,
))
}

Expand Down
Loading

0 comments on commit ee276af

Please sign in to comment.