Compare commits
5 Commits
0f45708e81
...
unittests
| Author | SHA1 | Date | |
|---|---|---|---|
| d73314cefb | |||
| 239e587cbc | |||
| 742c8587ce | |||
|
|
fb45087477 | ||
|
|
a3dc2df37d |
4
Justfile
4
Justfile
@@ -40,8 +40,8 @@ build-static:
|
|||||||
|
|
||||||
test: test-unit test-integration test-e2e
|
test: test-unit test-integration test-e2e
|
||||||
|
|
||||||
test-unit:
|
test-unit +tests="":
|
||||||
cargo test --lib --bins
|
cargo test --lib --bins -- --show-output {{tests}}
|
||||||
|
|
||||||
test-integration:
|
test-integration:
|
||||||
cargo test --test "*"
|
cargo test --test "*"
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ pub mod gitlab;
|
|||||||
pub use github::Github;
|
pub use github::Github;
|
||||||
pub use gitlab::Gitlab;
|
pub use gitlab::Gitlab;
|
||||||
|
|
||||||
use super::repo;
|
|
||||||
use super::auth;
|
use super::auth;
|
||||||
|
use super::repo;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -166,7 +166,11 @@ pub trait Provider {
|
|||||||
.header("accept", accept_header.unwrap_or("application/json"))
|
.header("accept", accept_header.unwrap_or("application/json"))
|
||||||
.header(
|
.header(
|
||||||
"authorization",
|
"authorization",
|
||||||
format!("{} {}", Self::auth_header_key(), &self.secret_token().access()),
|
format!(
|
||||||
|
"{} {}",
|
||||||
|
Self::auth_header_key(),
|
||||||
|
&self.secret_token().access()
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.body(())
|
.body(())
|
||||||
.map_err(|error| error.to_string())?;
|
.map_err(|error| error.to_string())?;
|
||||||
|
|||||||
@@ -1184,7 +1184,7 @@ impl RepoHandle {
|
|||||||
&& !branch_name.ends_with(&format!("{}{}", super::BRANCH_NAMESPACE_SEPARATOR, name))
|
&& !branch_name.ends_with(&format!("{}{}", super::BRANCH_NAMESPACE_SEPARATOR, name))
|
||||||
{
|
{
|
||||||
return Err(WorktreeRemoveFailureReason::Error(format!(
|
return Err(WorktreeRemoveFailureReason::Error(format!(
|
||||||
"Branch {} is checked out in worktree, this does not look correct",
|
"Branch \"{}\" is checked out in worktree, this does not look correct",
|
||||||
&branch_name
|
&branch_name
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|||||||
133
src/worktree.rs
133
src/worktree.rs
@@ -1,9 +1,112 @@
|
|||||||
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";
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
use tempdir::TempDir;
|
||||||
|
|
||||||
|
fn init_empty_repo() -> PathBuf {
|
||||||
|
let directory = TempDir::new("grm-worktree").unwrap();
|
||||||
|
Command::new("git")
|
||||||
|
.args(["init", "."])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("touch")
|
||||||
|
.args(["test"])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("git")
|
||||||
|
.args(["add", "test"])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("git")
|
||||||
|
.args(["commit", "-m", "Initial commit"])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("bash")
|
||||||
|
.args(["-c", "git ls-files | xargs rm -rf"])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("mv")
|
||||||
|
.args([".git", GIT_MAIN_WORKTREE_DIRECTORY])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("git")
|
||||||
|
.args([
|
||||||
|
"--git-dir",
|
||||||
|
GIT_MAIN_WORKTREE_DIRECTORY,
|
||||||
|
"config",
|
||||||
|
"core.bare",
|
||||||
|
"true",
|
||||||
|
])
|
||||||
|
.current_dir(directory.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
directory.into_path()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_new_worktree() {
|
||||||
|
let repo_path = init_empty_repo();
|
||||||
|
|
||||||
|
let out = add_worktree(&repo_path, "test", None, None, true);
|
||||||
|
assert!(out.is_ok());
|
||||||
|
let repo = git2::Repository::open(repo_path.join("test")).unwrap();
|
||||||
|
assert_eq!(repo.head().unwrap().shorthand().unwrap(), "test");
|
||||||
|
assert!(repo
|
||||||
|
.find_branch("test", git2::BranchType::Local)
|
||||||
|
.unwrap()
|
||||||
|
.upstream()
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_new_worktree_with_remote_track() {
|
||||||
|
let repo_path = init_empty_repo();
|
||||||
|
|
||||||
|
let out = add_worktree(&repo_path, "test", None, Some(("origin", "test")), true);
|
||||||
|
assert!(out.is_ok());
|
||||||
|
let repo = git2::Repository::open(repo_path.join("test")).unwrap();
|
||||||
|
assert_eq!(repo.head().unwrap().shorthand().unwrap(), "test");
|
||||||
|
assert_eq!(
|
||||||
|
repo.find_branch("test", git2::BranchType::Local)
|
||||||
|
.unwrap()
|
||||||
|
.upstream()
|
||||||
|
.unwrap()
|
||||||
|
.name()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
"test"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,15 +134,38 @@ pub fn add_worktree(
|
|||||||
|
|
||||||
let mut remote_branch_exists = false;
|
let mut remote_branch_exists = false;
|
||||||
|
|
||||||
|
let mut target_branch = match repo.find_local_branch(name) {
|
||||||
|
Ok(branchref) => {
|
||||||
|
if !no_track {
|
||||||
|
if let Some((remote_name, remote_branch_name)) = track {
|
||||||
|
let remote_branch = repo.find_remote_branch(remote_name, remote_branch_name);
|
||||||
|
if let Ok(remote_branch) = remote_branch {
|
||||||
|
remote_branch_exists = true;
|
||||||
|
if let Ok(local_upstream_branch) = branchref.upstream() {
|
||||||
|
if remote_branch.name()? != local_upstream_branch.name()? {
|
||||||
|
print_warning(&format!(
|
||||||
|
"You specified a tracking branch ({}) for an existing branch ({}), but \
|
||||||
|
it differs from the current upstream ({}). Will keep current upstream"
|
||||||
|
, format!("{}/{}", remote_name, remote_branch_name), branchref.name()?, local_upstream_branch.name()?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
branchref
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
let default_checkout = || repo.default_branch()?.to_commit();
|
let default_checkout = || repo.default_branch()?.to_commit();
|
||||||
|
|
||||||
let checkout_commit;
|
let checkout_commit;
|
||||||
|
|
||||||
if no_track {
|
if no_track {
|
||||||
checkout_commit = default_checkout()?;
|
checkout_commit = default_checkout()?;
|
||||||
} else {
|
} else {
|
||||||
match track {
|
match track {
|
||||||
Some((remote_name, remote_branch_name)) => {
|
Some((remote_name, remote_branch_name)) => {
|
||||||
let remote_branch = repo.find_remote_branch(remote_name, remote_branch_name);
|
let remote_branch =
|
||||||
|
repo.find_remote_branch(remote_name, remote_branch_name);
|
||||||
match remote_branch {
|
match remote_branch {
|
||||||
Ok(branch) => {
|
Ok(branch) => {
|
||||||
remote_branch_exists = true;
|
remote_branch_exists = true;
|
||||||
@@ -77,9 +203,8 @@ pub fn add_worktree(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
||||||
|
|||||||
Reference in New Issue
Block a user