Set git config properly for worktrees on init/clone

Close #1
This commit is contained in:
2021-11-26 16:52:12 +01:00
parent 83973f8a1a
commit b967b6dca3
2 changed files with 56 additions and 33 deletions

View File

@@ -13,14 +13,15 @@ use output::*;
use comfy_table::{Cell, Table}; use comfy_table::{Cell, Table};
use repo::{ use repo::{
clone_repo, detect_remote_type, get_repo_status, init_repo, open_repo, Remote, clone_repo, detect_remote_type, get_repo_status, init_repo, open_repo, repo_make_bare,
RemoteTrackingStatus, Repo, RepoErrorKind, repo_set_config_push, Remote, RemoteTrackingStatus, Repo, RepoErrorKind,
}; };
const GIT_MAIN_WORKTREE_DIRECTORY: &str = ".git-main-working-tree"; const GIT_MAIN_WORKTREE_DIRECTORY: &str = ".git-main-working-tree";
const BRANCH_NAMESPACE_SEPARATOR: &str = "/"; const BRANCH_NAMESPACE_SEPARATOR: &str = "/";
const GIT_CONFIG_BARE_KEY: &str = "core.bare"; const GIT_CONFIG_BARE_KEY: &str = "core.bare";
const GIT_CONFIG_PUSH_DEFAULT: &str = "push.default";
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@@ -1155,23 +1156,17 @@ pub fn run() {
process::exit(1); process::exit(1);
}); });
let mut config = worktree_repo.config().unwrap_or_else(|error| { repo_make_bare(&worktree_repo, true).unwrap_or_else(|error| {
print_error(&format!( print_error(&format!("Error: {}", error));
"Opening getting repository configuration: {}",
error
));
process::exit(1); process::exit(1);
}); });
config repo_set_config_push(&worktree_repo, "upstream").unwrap_or_else(|error| {
.set_bool(GIT_CONFIG_BARE_KEY, true) print_error(&format!("Error: {}", error));
.unwrap_or_else(|error| { process::exit(1);
print_error(&format!( });
"Error setting {}: {}",
GIT_CONFIG_BARE_KEY, error print_success("Conversion done");
));
process::exit(1);
});
} }
cmd::WorktreeAction::Clean(_args) => { cmd::WorktreeAction::Clean(_args) => {
let repo = get_repo(&dir); let repo = get_repo(&dir);

View File

@@ -199,16 +199,43 @@ pub fn open_repo(path: &Path, is_worktree: bool) -> Result<Repository, RepoError
} }
pub fn init_repo(path: &Path, is_worktree: bool) -> Result<Repository, Box<dyn std::error::Error>> { pub fn init_repo(path: &Path, is_worktree: bool) -> Result<Repository, Box<dyn std::error::Error>> {
match is_worktree { let repo = match is_worktree {
false => match Repository::init(path) { false => Repository::init(path)?,
Ok(r) => Ok(r), true => Repository::init_bare(path.join(super::GIT_MAIN_WORKTREE_DIRECTORY))?,
Err(e) => Err(Box::new(e)), };
},
true => match Repository::init_bare(path.join(super::GIT_MAIN_WORKTREE_DIRECTORY)) { if is_worktree {
Ok(r) => Ok(r), repo_set_config_push(&repo, "upstream")?;
Err(e) => Err(Box::new(e)),
},
} }
Ok(repo)
}
pub fn get_repo_config(repo: &git2::Repository) -> Result<git2::Config, String> {
repo.config()
.map_err(|error| format!("Failed getting repository configuration: {}", error))
}
pub fn repo_make_bare(repo: &git2::Repository, value: bool) -> Result<(), String> {
let mut config = get_repo_config(repo)?;
config
.set_bool(super::GIT_CONFIG_BARE_KEY, value)
.map_err(|error| format!("Could not set {}: {}", super::GIT_CONFIG_BARE_KEY, error))
}
pub fn repo_set_config_push(repo: &git2::Repository, value: &str) -> Result<(), String> {
let mut config = get_repo_config(repo)?;
config
.set_str(super::GIT_CONFIG_PUSH_DEFAULT, value)
.map_err(|error| {
format!(
"Could not set {}: {}",
super::GIT_CONFIG_PUSH_DEFAULT,
error
)
})
} }
pub fn clone_repo( pub fn clone_repo(
@@ -230,10 +257,7 @@ pub fn clone_repo(
RemoteType::Https => { RemoteType::Https => {
let mut builder = git2::build::RepoBuilder::new(); let mut builder = git2::build::RepoBuilder::new();
builder.bare(is_worktree); builder.bare(is_worktree);
match builder.clone(&remote.url, &clone_target) { builder.clone(&remote.url, &clone_target)?;
Ok(_) => Ok(()),
Err(e) => Err(Box::new(e)),
}
} }
RemoteType::Ssh => { RemoteType::Ssh => {
let mut callbacks = RemoteCallbacks::new(); let mut callbacks = RemoteCallbacks::new();
@@ -248,12 +272,16 @@ pub fn clone_repo(
builder.bare(is_worktree); builder.bare(is_worktree);
builder.fetch_options(fo); builder.fetch_options(fo);
match builder.clone(&remote.url, &clone_target) { builder.clone(&remote.url, &clone_target)?;
Ok(_) => Ok(()),
Err(e) => Err(Box::new(e)),
}
} }
} }
if is_worktree {
let repo = open_repo(&clone_target, false)?;
repo_set_config_push(&repo, "upstream")?;
}
Ok(())
} }
pub fn get_repo_status(repo: &git2::Repository, is_worktree: bool) -> RepoStatus { pub fn get_repo_status(repo: &git2::Repository, is_worktree: bool) -> RepoStatus {