@@ -329,6 +329,7 @@ impl Upstream {
pub struct CommitOptions {
pub amend: bool,
pub signoff: bool,
+ pub allow_empty: bool,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
@@ -715,7 +716,7 @@ pub trait GitRepository: Send + Sync {
fn create_worktree(
&self,
- branch_name: String,
+ branch_name: Option<String>,
path: PathBuf,
from_commit: Option<String>,
) -> BoxFuture<'_, Result<()>>;
@@ -916,6 +917,12 @@ pub trait GitRepository: Send + Sync {
fn commit_data_reader(&self) -> Result<CommitDataReader>;
+ fn update_ref(&self, ref_name: String, commit: String) -> BoxFuture<'_, Result<()>>;
+
+ fn delete_ref(&self, ref_name: String) -> BoxFuture<'_, Result<()>>;
+
+ fn stage_all_including_untracked(&self) -> BoxFuture<'_, Result<()>>;
+
fn set_trusted(&self, trusted: bool);
fn is_trusted(&self) -> bool;
}
@@ -1660,19 +1667,20 @@ impl GitRepository for RealGitRepository {
fn create_worktree(
&self,
- branch_name: String,
+ branch_name: Option<String>,
path: PathBuf,
from_commit: Option<String>,
) -> BoxFuture<'_, Result<()>> {
let git_binary = self.git_binary();
- let mut args = vec![
- OsString::from("worktree"),
- OsString::from("add"),
- OsString::from("-b"),
- OsString::from(branch_name.as_str()),
- OsString::from("--"),
- OsString::from(path.as_os_str()),
- ];
+ let mut args = vec![OsString::from("worktree"), OsString::from("add")];
+ if let Some(branch_name) = &branch_name {
+ args.push(OsString::from("-b"));
+ args.push(OsString::from(branch_name.as_str()));
+ } else {
+ args.push(OsString::from("--detach"));
+ }
+ args.push(OsString::from("--"));
+ args.push(OsString::from(path.as_os_str()));
if let Some(from_commit) = from_commit {
args.push(OsString::from(from_commit));
} else {
@@ -2165,6 +2173,10 @@ impl GitRepository for RealGitRepository {
cmd.arg("--signoff");
}
+ if options.allow_empty {
+ cmd.arg("--allow-empty");
+ }
+
if let Some((name, email)) = name_and_email {
cmd.arg("--author").arg(&format!("{name} <{email}>"));
}
@@ -2176,6 +2188,50 @@ impl GitRepository for RealGitRepository {
.boxed()
}
+ fn update_ref(&self, ref_name: String, commit: String) -> BoxFuture<'_, Result<()>> {
+ let git_binary = self.git_binary();
+ self.executor
+ .spawn(async move {
+ let args: Vec<OsString> = vec![
+ "--no-optional-locks".into(),
+ "update-ref".into(),
+ ref_name.into(),
+ commit.into(),
+ ];
+ git_binary?.run(&args).await?;
+ Ok(())
+ })
+ .boxed()
+ }
+
+ fn delete_ref(&self, ref_name: String) -> BoxFuture<'_, Result<()>> {
+ let git_binary = self.git_binary();
+ self.executor
+ .spawn(async move {
+ let args: Vec<OsString> = vec![
+ "--no-optional-locks".into(),
+ "update-ref".into(),
+ "-d".into(),
+ ref_name.into(),
+ ];
+ git_binary?.run(&args).await?;
+ Ok(())
+ })
+ .boxed()
+ }
+
+ fn stage_all_including_untracked(&self) -> BoxFuture<'_, Result<()>> {
+ let git_binary = self.git_binary();
+ self.executor
+ .spawn(async move {
+ let args: Vec<OsString> =
+ vec!["--no-optional-locks".into(), "add".into(), "-A".into()];
+ git_binary?.run(&args).await?;
+ Ok(())
+ })
+ .boxed()
+ }
+
fn push(
&self,
branch_name: String,
@@ -4009,7 +4065,7 @@ mod tests {
// Create a new worktree
repo.create_worktree(
- "test-branch".to_string(),
+ Some("test-branch".to_string()),
worktree_path.clone(),
Some("HEAD".to_string()),
)
@@ -4068,7 +4124,7 @@ mod tests {
// Create a worktree
let worktree_path = worktrees_dir.join("worktree-to-remove");
repo.create_worktree(
- "to-remove".to_string(),
+ Some("to-remove".to_string()),
worktree_path.clone(),
Some("HEAD".to_string()),
)
@@ -4092,7 +4148,7 @@ mod tests {
// Create a worktree
let worktree_path = worktrees_dir.join("dirty-wt");
repo.create_worktree(
- "dirty-wt".to_string(),
+ Some("dirty-wt".to_string()),
worktree_path.clone(),
Some("HEAD".to_string()),
)
@@ -4162,7 +4218,7 @@ mod tests {
// Create a worktree
let old_path = worktrees_dir.join("old-worktree-name");
repo.create_worktree(
- "old-name".to_string(),
+ Some("old-name".to_string()),
old_path.clone(),
Some("HEAD".to_string()),
)