Compare commits
1 Commits
performanc
...
commit-whi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc9c3456e7 |
@@ -12,7 +12,7 @@ use gpui::{AppContext as _, AsyncApp, BackgroundExecutor, SharedString, Task};
|
|||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rope::Rope;
|
use rope::Rope;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use smol::io::{AsyncBufReadExt, AsyncReadExt, BufReader};
|
use smol::io::{AsyncBufReadExt, AsyncReadExt, BufReader};
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::process::{ExitStatus, Stdio};
|
use std::process::{ExitStatus, Stdio};
|
||||||
@@ -137,10 +137,18 @@ impl Upstream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
pub enum CommitMessageCleanup {
|
||||||
|
#[default]
|
||||||
|
Strip,
|
||||||
|
Whitespace,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct CommitOptions {
|
pub struct CommitOptions {
|
||||||
pub amend: bool,
|
pub amend: bool,
|
||||||
pub signoff: bool,
|
pub signoff: bool,
|
||||||
|
pub cleanup: CommitMessageCleanup,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||||
@@ -1637,12 +1645,16 @@ impl GitRepository for RealGitRepository {
|
|||||||
let git_binary_path = self.any_git_binary_path.clone();
|
let git_binary_path = self.any_git_binary_path.clone();
|
||||||
let executor = self.executor.clone();
|
let executor = self.executor.clone();
|
||||||
async move {
|
async move {
|
||||||
|
let cleanup_kind = match options.cleanup {
|
||||||
|
CommitMessageCleanup::Strip => "--cleanup=strip",
|
||||||
|
CommitMessageCleanup::Whitespace => "--cleanup=whitespace",
|
||||||
|
};
|
||||||
let mut cmd = new_smol_command(git_binary_path);
|
let mut cmd = new_smol_command(git_binary_path);
|
||||||
cmd.current_dir(&working_directory?)
|
cmd.current_dir(&working_directory?)
|
||||||
.envs(env.iter())
|
.envs(env.iter())
|
||||||
.args(["commit", "--quiet", "-m"])
|
.args(["commit", "--quiet", "-m"])
|
||||||
.arg(&message.to_string())
|
.arg(&message.to_string())
|
||||||
.arg("--cleanup=strip")
|
.arg(cleanup_kind)
|
||||||
.stdout(smol::process::Stdio::piped())
|
.stdout(smol::process::Stdio::piped())
|
||||||
.stderr(smol::process::Stdio::piped());
|
.stderr(smol::process::Stdio::piped());
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::branch_picker::{self, BranchList};
|
use crate::branch_picker::{self, BranchList};
|
||||||
use crate::git_panel::{GitPanel, commit_message_editor};
|
use crate::git_panel::{GitPanel, commit_message_editor};
|
||||||
use git::repository::CommitOptions;
|
|
||||||
use git::{Amend, Commit, GenerateCommitMessage, Signoff};
|
use git::{Amend, Commit, GenerateCommitMessage, Signoff};
|
||||||
use panel::{panel_button, panel_editor_style};
|
use panel::{panel_button, panel_editor_style};
|
||||||
use project::DisableAiSettings;
|
use project::DisableAiSettings;
|
||||||
@@ -439,10 +438,8 @@ impl CommitModal {
|
|||||||
telemetry::event!("Git Committed", source = "Git Modal");
|
telemetry::event!("Git Committed", source = "Git Modal");
|
||||||
this.git_panel.update(cx, |git_panel, cx| {
|
this.git_panel.update(cx, |git_panel, cx| {
|
||||||
git_panel.commit_changes(
|
git_panel.commit_changes(
|
||||||
CommitOptions {
|
is_amend_pending,
|
||||||
amend: is_amend_pending,
|
is_signoff_enabled,
|
||||||
signoff: is_signoff_enabled,
|
|
||||||
},
|
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
@@ -498,14 +495,7 @@ impl CommitModal {
|
|||||||
}
|
}
|
||||||
telemetry::event!("Git Committed", source = "Git Modal");
|
telemetry::event!("Git Committed", source = "Git Modal");
|
||||||
self.git_panel.update(cx, |git_panel, cx| {
|
self.git_panel.update(cx, |git_panel, cx| {
|
||||||
git_panel.commit_changes(
|
git_panel.commit_changes(false, git_panel.signoff_enabled(), window, cx)
|
||||||
CommitOptions {
|
|
||||||
amend: false,
|
|
||||||
signoff: git_panel.signoff_enabled(),
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
}
|
}
|
||||||
@@ -530,14 +520,7 @@ impl CommitModal {
|
|||||||
telemetry::event!("Git Amended", source = "Git Modal");
|
telemetry::event!("Git Amended", source = "Git Modal");
|
||||||
self.git_panel.update(cx, |git_panel, cx| {
|
self.git_panel.update(cx, |git_panel, cx| {
|
||||||
git_panel.set_amend_pending(false, cx);
|
git_panel.set_amend_pending(false, cx);
|
||||||
git_panel.commit_changes(
|
git_panel.commit_changes(true, git_panel.signoff_enabled(), window, cx);
|
||||||
CommitOptions {
|
|
||||||
amend: true,
|
|
||||||
signoff: git_panel.signoff_enabled(),
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1538,14 +1538,7 @@ impl GitPanel {
|
|||||||
.contains_focused(window, cx)
|
.contains_focused(window, cx)
|
||||||
{
|
{
|
||||||
telemetry::event!("Git Committed", source = "Git Panel");
|
telemetry::event!("Git Committed", source = "Git Panel");
|
||||||
self.commit_changes(
|
self.commit_changes(false, self.signoff_enabled, window, cx)
|
||||||
CommitOptions {
|
|
||||||
amend: false,
|
|
||||||
signoff: self.signoff_enabled,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
cx.propagate();
|
cx.propagate();
|
||||||
}
|
}
|
||||||
@@ -1563,14 +1556,7 @@ impl GitPanel {
|
|||||||
self.load_last_commit_message_if_empty(cx);
|
self.load_last_commit_message_if_empty(cx);
|
||||||
} else {
|
} else {
|
||||||
telemetry::event!("Git Amended", source = "Git Panel");
|
telemetry::event!("Git Amended", source = "Git Panel");
|
||||||
self.commit_changes(
|
self.commit_changes(true, self.signoff_enabled, window, cx);
|
||||||
CommitOptions {
|
|
||||||
amend: true,
|
|
||||||
signoff: self.signoff_enabled,
|
|
||||||
},
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1657,7 +1643,8 @@ impl GitPanel {
|
|||||||
|
|
||||||
pub(crate) fn commit_changes(
|
pub(crate) fn commit_changes(
|
||||||
&mut self,
|
&mut self,
|
||||||
options: CommitOptions,
|
amend: bool,
|
||||||
|
signoff: bool,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
@@ -1696,7 +1683,7 @@ impl GitPanel {
|
|||||||
let task = if self.has_staged_changes() {
|
let task = if self.has_staged_changes() {
|
||||||
// Repository serializes all git operations, so we can just send a commit immediately
|
// Repository serializes all git operations, so we can just send a commit immediately
|
||||||
let commit_task = active_repository.update(cx, |repo, cx| {
|
let commit_task = active_repository.update(cx, |repo, cx| {
|
||||||
repo.commit(message.into(), None, options, askpass, cx)
|
repo.commit(message.into(), None, amend, signoff, askpass, cx)
|
||||||
});
|
});
|
||||||
cx.background_spawn(async move { commit_task.await? })
|
cx.background_spawn(async move { commit_task.await? })
|
||||||
} else {
|
} else {
|
||||||
@@ -1708,7 +1695,7 @@ impl GitPanel {
|
|||||||
.map(|status_entry| status_entry.repo_path.clone())
|
.map(|status_entry| status_entry.repo_path.clone())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if changed_files.is_empty() && !options.amend {
|
if changed_files.is_empty() && !amend {
|
||||||
error_spawn("No changes to commit", window, cx);
|
error_spawn("No changes to commit", window, cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1718,7 +1705,7 @@ impl GitPanel {
|
|||||||
cx.spawn(async move |_, cx| {
|
cx.spawn(async move |_, cx| {
|
||||||
stage_task.await?;
|
stage_task.await?;
|
||||||
let commit_task = active_repository.update(cx, |repo, cx| {
|
let commit_task = active_repository.update(cx, |repo, cx| {
|
||||||
repo.commit(message.into(), None, options, askpass, cx)
|
repo.commit(message.into(), None, amend, signoff, askpass, cx)
|
||||||
})?;
|
})?;
|
||||||
commit_task.await?
|
commit_task.await?
|
||||||
})
|
})
|
||||||
@@ -1740,7 +1727,7 @@ impl GitPanel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.pending_commit = Some(task);
|
self.pending_commit = Some(task);
|
||||||
if options.amend {
|
if amend {
|
||||||
self.set_amend_pending(false, cx);
|
self.set_amend_pending(false, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3646,11 +3633,7 @@ impl GitPanel {
|
|||||||
telemetry::event!("Git Committed", source = "Git Panel");
|
telemetry::event!("Git Committed", source = "Git Panel");
|
||||||
git_panel
|
git_panel
|
||||||
.update(cx, |git_panel, cx| {
|
.update(cx, |git_panel, cx| {
|
||||||
git_panel.commit_changes(
|
git_panel.commit_changes(amend, signoff, window, cx);
|
||||||
CommitOptions { amend, signoff },
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ pub mod pending_op;
|
|||||||
use crate::{
|
use crate::{
|
||||||
ProjectEnvironment, ProjectItem, ProjectPath,
|
ProjectEnvironment, ProjectItem, ProjectPath,
|
||||||
buffer_store::{BufferStore, BufferStoreEvent},
|
buffer_store::{BufferStore, BufferStoreEvent},
|
||||||
|
project_settings::{GitSettings, ProjectSettings},
|
||||||
worktree_store::{WorktreeStore, WorktreeStoreEvent},
|
worktree_store::{WorktreeStore, WorktreeStoreEvent},
|
||||||
};
|
};
|
||||||
use anyhow::{Context as _, Result, anyhow, bail};
|
use anyhow::{Context as _, Result, anyhow, bail};
|
||||||
@@ -55,7 +56,7 @@ use rpc::{
|
|||||||
proto::{self, git_reset, split_repository_update},
|
proto::{self, git_reset, split_repository_update},
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use settings::WorktreeId;
|
use settings::{Settings as _, WorktreeId};
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::{BTreeSet, HashSet, VecDeque},
|
collections::{BTreeSet, HashSet, VecDeque},
|
||||||
@@ -2009,10 +2010,8 @@ impl GitStore {
|
|||||||
repository_handle.commit(
|
repository_handle.commit(
|
||||||
message,
|
message,
|
||||||
name.zip(email),
|
name.zip(email),
|
||||||
CommitOptions {
|
options.amend,
|
||||||
amend: options.amend,
|
options.signoff,
|
||||||
signoff: options.signoff,
|
|
||||||
},
|
|
||||||
askpass,
|
askpass,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
@@ -4266,21 +4265,41 @@ impl Repository {
|
|||||||
&mut self,
|
&mut self,
|
||||||
message: SharedString,
|
message: SharedString,
|
||||||
name_and_email: Option<(SharedString, SharedString)>,
|
name_and_email: Option<(SharedString, SharedString)>,
|
||||||
options: CommitOptions,
|
amend: bool,
|
||||||
|
signoff: bool,
|
||||||
askpass: AskPassDelegate,
|
askpass: AskPassDelegate,
|
||||||
_cx: &mut App,
|
cx: &mut App,
|
||||||
) -> oneshot::Receiver<Result<()>> {
|
) -> oneshot::Receiver<Result<()>> {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let askpass_delegates = self.askpass_delegates.clone();
|
let askpass_delegates = self.askpass_delegates.clone();
|
||||||
let askpass_id = util::post_inc(&mut self.latest_askpass_id);
|
let askpass_id = util::post_inc(&mut self.latest_askpass_id);
|
||||||
|
let project_path =
|
||||||
self.send_job(Some("git commit".into()), move |git_repo, _cx| async move {
|
self.repo_path_to_project_path(&RepoPath::from_rel_path(RelPath::empty()), cx);
|
||||||
|
self.send_job(Some("git commit".into()), move |git_repo, cx| async move {
|
||||||
match git_repo {
|
match git_repo {
|
||||||
RepositoryState::Local {
|
RepositoryState::Local {
|
||||||
backend,
|
backend,
|
||||||
environment,
|
environment,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let cleanup = cx.update(|cx| {
|
||||||
|
ProjectSettings::get(
|
||||||
|
project_path
|
||||||
|
.as_ref()
|
||||||
|
.map(|project_path| settings::SettingsLocation {
|
||||||
|
worktree_id: project_path.worktree_id,
|
||||||
|
path: &project_path.path,
|
||||||
|
}),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.git
|
||||||
|
.commit_cleanup
|
||||||
|
})?;
|
||||||
|
let options = CommitOptions {
|
||||||
|
amend,
|
||||||
|
signoff,
|
||||||
|
cleanup,
|
||||||
|
};
|
||||||
backend
|
backend
|
||||||
.commit(message, name_and_email, options, askpass, environment)
|
.commit(message, name_and_email, options, askpass, environment)
|
||||||
.await
|
.await
|
||||||
@@ -4299,10 +4318,7 @@ impl Repository {
|
|||||||
message: String::from(message),
|
message: String::from(message),
|
||||||
name: name.map(String::from),
|
name: name.map(String::from),
|
||||||
email: email.map(String::from),
|
email: email.map(String::from),
|
||||||
options: Some(proto::commit::CommitOptions {
|
options: Some(proto::commit::CommitOptions { amend, signoff }),
|
||||||
amend: options.amend,
|
|
||||||
signoff: options.signoff,
|
|
||||||
}),
|
|
||||||
askpass_id,
|
askpass_id,
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use context_server::ContextServerCommand;
|
|||||||
use dap::adapters::DebugAdapterName;
|
use dap::adapters::DebugAdapterName;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::StreamExt as _;
|
use futures::StreamExt as _;
|
||||||
|
use git::repository::CommitMessageCleanup;
|
||||||
use gpui::{AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Subscription, Task};
|
use gpui::{AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Subscription, Task};
|
||||||
use lsp::LanguageServerName;
|
use lsp::LanguageServerName;
|
||||||
use paths::{
|
use paths::{
|
||||||
@@ -352,6 +353,10 @@ pub struct GitSettings {
|
|||||||
///
|
///
|
||||||
/// Default: file_name_first
|
/// Default: file_name_first
|
||||||
pub path_style: GitPathStyle,
|
pub path_style: GitPathStyle,
|
||||||
|
/// How commit cleanup is handled in the commit message.
|
||||||
|
///
|
||||||
|
/// Default: strip
|
||||||
|
pub commit_cleanup: CommitMessageCleanup,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||||
@@ -522,6 +527,10 @@ impl Settings for ProjectSettings {
|
|||||||
},
|
},
|
||||||
hunk_style: git.hunk_style.unwrap(),
|
hunk_style: git.hunk_style.unwrap(),
|
||||||
path_style: git.path_style.unwrap().into(),
|
path_style: git.path_style.unwrap().into(),
|
||||||
|
commit_cleanup: match git.commit_cleanup.unwrap_or_default() {
|
||||||
|
settings::CommitMessageCleanup::Strip => CommitMessageCleanup::Strip,
|
||||||
|
settings::CommitMessageCleanup::Whitespace => CommitMessageCleanup::Whitespace,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
context_servers: project
|
context_servers: project
|
||||||
|
|||||||
@@ -315,6 +315,10 @@ pub struct GitSettings {
|
|||||||
///
|
///
|
||||||
/// Default: file_name_first
|
/// Default: file_name_first
|
||||||
pub path_style: Option<GitPathStyle>,
|
pub path_style: Option<GitPathStyle>,
|
||||||
|
/// How to cleanup a git commit message.
|
||||||
|
///
|
||||||
|
/// Default: strip
|
||||||
|
pub commit_cleanup: Option<CommitMessageCleanup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
@@ -432,6 +436,26 @@ pub enum GitPathStyle {
|
|||||||
FilePathFirst,
|
FilePathFirst,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Copy,
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Default,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
JsonSchema,
|
||||||
|
MergeFrom,
|
||||||
|
strum::VariantArray,
|
||||||
|
strum::VariantNames,
|
||||||
|
)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum CommitMessageCleanup {
|
||||||
|
#[default]
|
||||||
|
Strip,
|
||||||
|
Whitespace,
|
||||||
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||||
pub struct DiagnosticsSettingsContent {
|
pub struct DiagnosticsSettingsContent {
|
||||||
|
|||||||
Reference in New Issue
Block a user