Allow nested worktree directories
This commit is contained in:
@@ -79,6 +79,36 @@ def test_worktree_add_simple():
|
|||||||
assert repo.active_branch.tracking_branch() is None
|
assert repo.active_branch.tracking_branch() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_worktree_add_into_subdirectory():
|
||||||
|
with TempGitRepositoryWorktree() as base_dir:
|
||||||
|
cmd = grm(["wt", "add", "dir/test"], cwd=base_dir)
|
||||||
|
assert cmd.returncode == 0
|
||||||
|
|
||||||
|
files = os.listdir(base_dir)
|
||||||
|
assert len(files) == 2
|
||||||
|
assert set(files) == {".git-main-working-tree", "dir"}
|
||||||
|
|
||||||
|
files = os.listdir(os.path.join(base_dir, "dir"))
|
||||||
|
assert set(files) == {"test"}
|
||||||
|
|
||||||
|
repo = git.Repo(os.path.join(base_dir, "dir", "test"))
|
||||||
|
assert not repo.bare
|
||||||
|
assert not repo.is_dirty()
|
||||||
|
assert repo.active_branch.tracking_branch() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_worktree_add_into_invalid_subdirectory():
|
||||||
|
with TempGitRepositoryWorktree() as base_dir:
|
||||||
|
cmd = grm(["wt", "add", "/dir/test"], cwd=base_dir)
|
||||||
|
assert cmd.returncode == 1
|
||||||
|
assert "dir" not in os.listdir(base_dir)
|
||||||
|
assert "dir" not in os.listdir("/")
|
||||||
|
|
||||||
|
cmd = grm(["wt", "add", "dir/"], cwd=base_dir)
|
||||||
|
assert cmd.returncode == 1
|
||||||
|
assert "dir" not in os.listdir(base_dir)
|
||||||
|
|
||||||
|
|
||||||
def test_worktree_add_with_tracking():
|
def test_worktree_add_with_tracking():
|
||||||
for remote_branch_already_exists in (True, False):
|
for remote_branch_already_exists in (True, False):
|
||||||
for has_config in (True, False):
|
for has_config in (True, False):
|
||||||
|
|||||||
@@ -157,7 +157,22 @@ fn main() {
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match grm::add_worktree(&cwd, &action_args.name, track, action_args.no_track) {
|
let mut name: &str = &action_args.name;
|
||||||
|
let subdirectory;
|
||||||
|
let split = name.split_once('/');
|
||||||
|
match split {
|
||||||
|
None => subdirectory = None,
|
||||||
|
Some(split) => {
|
||||||
|
if split.0.is_empty() || split.1.is_empty() {
|
||||||
|
print_error("Worktree name cannot start or end with a slash");
|
||||||
|
process::exit(1);
|
||||||
|
} else {
|
||||||
|
(subdirectory, name) = (Some(Path::new(split.0)), split.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match grm::add_worktree(&cwd, name, subdirectory, track, action_args.no_track) {
|
||||||
Ok(_) => print_success(&format!("Worktree {} created", &action_args.name)),
|
Ok(_) => print_success(&format!("Worktree {} created", &action_args.name)),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
print_error(&format!("Error creating worktree: {}", error));
|
print_error(&format!("Error creating worktree: {}", error));
|
||||||
|
|||||||
13
src/lib.rs
13
src/lib.rs
@@ -461,6 +461,7 @@ pub fn find_in_tree(path: &Path) -> Result<(Tree, Vec<String>), String> {
|
|||||||
pub fn add_worktree(
|
pub fn add_worktree(
|
||||||
directory: &Path,
|
directory: &Path,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
subdirectory: Option<&Path>,
|
||||||
track: Option<(&str, &str)>,
|
track: Option<(&str, &str)>,
|
||||||
no_track: bool,
|
no_track: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@@ -473,7 +474,12 @@ pub fn add_worktree(
|
|||||||
|
|
||||||
let config = repo::read_worktree_root_config(directory)?;
|
let config = repo::read_worktree_root_config(directory)?;
|
||||||
|
|
||||||
if repo.find_worktree(name).is_ok() {
|
let path = match subdirectory {
|
||||||
|
Some(dir) => dir.join(name),
|
||||||
|
None => Path::new(name).to_path_buf(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if repo.find_worktree(&path).is_ok() {
|
||||||
return Err(format!("Worktree {} already exists", &name));
|
return Err(format!("Worktree {} already exists", &name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +611,10 @@ pub fn add_worktree(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.new_worktree(name, &directory.join(&name), &target_branch)?;
|
if let Some(subdirectory) = subdirectory {
|
||||||
|
std::fs::create_dir_all(subdirectory).map_err(|error| error.to_string())?;
|
||||||
|
}
|
||||||
|
repo.new_worktree(name, &path, &target_branch)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,8 +362,10 @@ impl Repo {
|
|||||||
self.0.config().map_err(convert_libgit2_error)
|
self.0.config().map_err(convert_libgit2_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_worktree(&self, name: &str) -> Result<(), String> {
|
pub fn find_worktree(&self, path: &Path) -> Result<(), String> {
|
||||||
self.0.find_worktree(name).map_err(convert_libgit2_error)?;
|
self.0
|
||||||
|
.find_worktree(path.to_str().expect("Worktree path is not valid utf-8"))
|
||||||
|
.map_err(convert_libgit2_error)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user