Update handling of branches on worktree setup

This commit is contained in:
Hannes Körber
2022-06-13 17:46:50 +02:00
committed by Hannes Körber
parent a3dc2df37d
commit fb45087477

View File

@@ -1,9 +1,23 @@
use std::path::Path; use std::path::Path;
use super::output::*;
use super::repo; use super::repo;
pub const GIT_MAIN_WORKTREE_DIRECTORY: &str = ".git-main-working-tree"; pub const GIT_MAIN_WORKTREE_DIRECTORY: &str = ".git-main-working-tree";
// The logic about the base branch and the tracking branch is as follows:
//
// * If a branch with the same name does not exist and no track is given, use the default
// branch
//
// * If a branch with the same name exists and no track is given, use that
//
// * If a branch with the same name does not exist and track is given, use the
// local branch that tracks that branch
//
// * If a branch with the same name exists and track is given, use the locally
// existing branch. If the locally existing branch is not the local branch to
// the remote tracking branch, issue a warning
pub fn add_worktree( pub fn add_worktree(
directory: &Path, directory: &Path,
name: &str, name: &str,
@@ -31,55 +45,77 @@ pub fn add_worktree(
let mut remote_branch_exists = false; let mut remote_branch_exists = false;
let default_checkout = || repo.default_branch()?.to_commit(); let mut target_branch = match repo.find_local_branch(name) {
Ok(branchref) => {
let checkout_commit; if !no_track {
if no_track { if let Some((remote_name, remote_branch_name)) = track {
checkout_commit = default_checkout()?; let remote_branch = repo.find_remote_branch(remote_name, remote_branch_name);
} else { if let Ok(remote_branch) = remote_branch {
match track {
Some((remote_name, remote_branch_name)) => {
let remote_branch = repo.find_remote_branch(remote_name, remote_branch_name);
match remote_branch {
Ok(branch) => {
remote_branch_exists = true; remote_branch_exists = true;
checkout_commit = branch.to_commit()?; if let Ok(local_upstream_branch) = branchref.upstream() {
} if remote_branch.name()? != local_upstream_branch.name()? {
Err(_) => { print_warning(&format!(
remote_branch_exists = false; "You specified a tracking branch ({}) for an existing branch ({}), but \
checkout_commit = default_checkout()?; it differs from the current upstream ({}). Will keep current upstream"
, format!("{}/{}", remote_name, remote_branch_name), branchref.name()?, local_upstream_branch.name()?))
}
}
} }
} }
} }
None => match &config { branchref
None => checkout_commit = default_checkout()?, }
Some(config) => match &config.track { Err(_) => {
None => checkout_commit = default_checkout()?, let default_checkout = || repo.default_branch()?.to_commit();
Some(track_config) => {
if track_config.default { let checkout_commit;
let remote_branch =
repo.find_remote_branch(&track_config.default_remote, name); if no_track {
match remote_branch { checkout_commit = default_checkout()?;
Ok(branch) => { } else {
remote_branch_exists = true; match track {
checkout_commit = branch.to_commit()?; Some((remote_name, remote_branch_name)) => {
} let remote_branch =
Err(_) => { repo.find_remote_branch(remote_name, remote_branch_name);
match remote_branch {
Ok(branch) => {
remote_branch_exists = true;
checkout_commit = branch.to_commit()?;
}
Err(_) => {
remote_branch_exists = false;
checkout_commit = default_checkout()?;
}
}
}
None => match &config {
None => checkout_commit = default_checkout()?,
Some(config) => match &config.track {
None => checkout_commit = default_checkout()?,
Some(track_config) => {
if track_config.default {
let remote_branch =
repo.find_remote_branch(&track_config.default_remote, name);
match remote_branch {
Ok(branch) => {
remote_branch_exists = true;
checkout_commit = branch.to_commit()?;
}
Err(_) => {
checkout_commit = default_checkout()?;
}
}
} else {
checkout_commit = default_checkout()?; checkout_commit = default_checkout()?;
} }
} }
} else { },
checkout_commit = default_checkout()?; },
} };
} }
},
},
};
}
let mut target_branch = match repo.find_local_branch(name) { repo.create_branch(name, &checkout_commit)?
Ok(branchref) => branchref, }
Err(_) => repo.create_branch(name, &checkout_commit)?,
}; };
fn push( fn push(