Merge efc009ee65
into 0e575b2809
This commit is contained in:
commit
1f6ba60412
12 changed files with 425 additions and 2 deletions
|
@ -760,7 +760,11 @@
|
||||||
// Choices: always, auto, never, system
|
// Choices: always, auto, never, system
|
||||||
// Default: inherits editor scrollbar settings
|
// Default: inherits editor scrollbar settings
|
||||||
// "show": null
|
// "show": null
|
||||||
}
|
},
|
||||||
|
//// Whether to show a list of previous commits in the git panel.
|
||||||
|
///
|
||||||
|
/// Default: false
|
||||||
|
"commit_history": false
|
||||||
},
|
},
|
||||||
"message_editor": {
|
"message_editor": {
|
||||||
// Whether to automatically replace emoji shortcodes with emoji characters.
|
// Whether to automatically replace emoji shortcodes with emoji characters.
|
||||||
|
|
|
@ -464,6 +464,7 @@ impl Server {
|
||||||
.add_request_handler(forward_mutating_project_request::<proto::GitInit>)
|
.add_request_handler(forward_mutating_project_request::<proto::GitInit>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::GetRemotes>)
|
.add_request_handler(forward_read_only_project_request::<proto::GetRemotes>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::GitShow>)
|
.add_request_handler(forward_read_only_project_request::<proto::GitShow>)
|
||||||
|
.add_request_handler(forward_read_only_project_request::<proto::GitLog>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::LoadCommitDiff>)
|
.add_request_handler(forward_read_only_project_request::<proto::LoadCommitDiff>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::GitReset>)
|
.add_request_handler(forward_read_only_project_request::<proto::GitReset>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::GitCheckoutFiles>)
|
.add_request_handler(forward_read_only_project_request::<proto::GitCheckoutFiles>)
|
||||||
|
|
|
@ -156,6 +156,15 @@ impl GitRepository for FakeGitRepository {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn log(&self, _skip: u64, _max_count: u64) -> BoxFuture<'_, Result<Vec<CommitDetails>>> {
|
||||||
|
async {
|
||||||
|
Ok(vec![CommitDetails {
|
||||||
|
..Default::default()
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
fn reset(
|
fn reset(
|
||||||
&self,
|
&self,
|
||||||
_commit: String,
|
_commit: String,
|
||||||
|
|
|
@ -359,6 +359,10 @@ pub trait GitRepository: Send + Sync {
|
||||||
|
|
||||||
fn show(&self, commit: String) -> BoxFuture<'_, Result<CommitDetails>>;
|
fn show(&self, commit: String) -> BoxFuture<'_, Result<CommitDetails>>;
|
||||||
|
|
||||||
|
/// Returns the git commit log returning at most `max_count` commits from
|
||||||
|
/// the current branch, skipping `skip` results
|
||||||
|
fn log(&self, skip: u64, max_count: u64) -> BoxFuture<'_, Result<Vec<CommitDetails>>>;
|
||||||
|
|
||||||
fn load_commit(&self, commit: String, cx: AsyncApp) -> BoxFuture<'_, Result<CommitDiff>>;
|
fn load_commit(&self, commit: String, cx: AsyncApp) -> BoxFuture<'_, Result<CommitDiff>>;
|
||||||
fn blame(&self, path: RepoPath, content: Rope) -> BoxFuture<'_, Result<crate::blame::Blame>>;
|
fn blame(&self, path: RepoPath, content: Rope) -> BoxFuture<'_, Result<crate::blame::Blame>>;
|
||||||
|
|
||||||
|
@ -614,6 +618,57 @@ impl GitRepository for RealGitRepository {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn log(&self, skip: u64, max_size: u64) -> BoxFuture<'_, Result<Vec<CommitDetails>>> {
|
||||||
|
let working_directory = self.working_directory();
|
||||||
|
self.executor
|
||||||
|
.spawn(async move {
|
||||||
|
let working_directory = working_directory?;
|
||||||
|
let output = new_std_command("git")
|
||||||
|
.current_dir(&working_directory)
|
||||||
|
.args([
|
||||||
|
"--no-pager",
|
||||||
|
"--no-optional-locks",
|
||||||
|
"log",
|
||||||
|
"--skip",
|
||||||
|
&skip.to_string(),
|
||||||
|
"--max-count",
|
||||||
|
&max_size.to_string(),
|
||||||
|
"--format=%H%x00%B%x00%at%x00%ae%x00%an%x00",
|
||||||
|
])
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
let output = std::str::from_utf8(&output.stdout)?
|
||||||
|
.trim()
|
||||||
|
.trim_end_matches('\0');
|
||||||
|
let parts: Vec<&str> = output.split('\0').map(|value| value.trim()).collect();
|
||||||
|
|
||||||
|
if parts.len() % 5 != 0 {
|
||||||
|
bail!("unexpected git log output length: {}", parts.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut commits = Vec::with_capacity(parts.len() / 5);
|
||||||
|
|
||||||
|
for chunk in parts.chunks(5) {
|
||||||
|
let sha = chunk[0].to_string().into();
|
||||||
|
let message = chunk[1].to_string().into();
|
||||||
|
let commit_timestamp = chunk[2].parse()?;
|
||||||
|
let author_email = chunk[3].to_string().into();
|
||||||
|
let author_name = chunk[4].to_string().into();
|
||||||
|
|
||||||
|
commits.push(CommitDetails {
|
||||||
|
sha,
|
||||||
|
message,
|
||||||
|
commit_timestamp,
|
||||||
|
author_email,
|
||||||
|
author_name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(commits)
|
||||||
|
})
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
fn load_commit(&self, commit: String, cx: AsyncApp) -> BoxFuture<'_, Result<CommitDiff>> {
|
fn load_commit(&self, commit: String, cx: AsyncApp) -> BoxFuture<'_, Result<CommitDiff>> {
|
||||||
let Some(working_directory) = self.repository.lock().workdir().map(ToOwned::to_owned)
|
let Some(working_directory) = self.repository.lock().workdir().map(ToOwned::to_owned)
|
||||||
else {
|
else {
|
||||||
|
|
285
crates/git_ui/src/git_commit_list.rs
Normal file
285
crates/git_ui/src/git_commit_list.rs
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
use crate::commit_view::CommitView;
|
||||||
|
use git::{blame::ParsedCommitMessage, repository::CommitSummary};
|
||||||
|
use gpui::{
|
||||||
|
App, Entity, ListScrollEvent, ListState, MouseButton, ParentElement, Render, Stateful, Task,
|
||||||
|
WeakEntity, list, prelude::*,
|
||||||
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use project::{
|
||||||
|
Project,
|
||||||
|
git_store::{GitStoreEvent, Repository},
|
||||||
|
};
|
||||||
|
use time::OffsetDateTime;
|
||||||
|
use ui::{ListItem, Scrollbar, ScrollbarState, prelude::*};
|
||||||
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
const COMMITS_PER_PAGE: u64 = 20;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct CommitDetails {
|
||||||
|
pub sha: SharedString,
|
||||||
|
pub author_name: SharedString,
|
||||||
|
pub author_email: SharedString,
|
||||||
|
pub commit_time: OffsetDateTime,
|
||||||
|
pub message: Option<ParsedCommitMessage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GitCommitList {
|
||||||
|
pub(crate) active_repository: Option<Entity<Repository>>,
|
||||||
|
pub(crate) project: Entity<Project>,
|
||||||
|
pub(crate) workspace: WeakEntity<Workspace>,
|
||||||
|
|
||||||
|
commits: Vec<CommitDetails>,
|
||||||
|
commits_loading: bool,
|
||||||
|
|
||||||
|
commits_list: ListState,
|
||||||
|
scrollbar_state: ScrollbarState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GitCommitList {
|
||||||
|
pub fn new(workspace: &mut Workspace, window: &mut Window, cx: &mut App) -> Entity<Self> {
|
||||||
|
let project = workspace.project().clone();
|
||||||
|
let git_store = project.read(cx).git_store().clone();
|
||||||
|
let active_repository = project.read(cx).active_repository(cx);
|
||||||
|
let workspace = workspace.weak_handle();
|
||||||
|
|
||||||
|
cx.new(|cx| {
|
||||||
|
cx.subscribe_in(
|
||||||
|
&git_store,
|
||||||
|
window,
|
||||||
|
move |this: &mut GitCommitList, _git_store, event, window, cx| match event {
|
||||||
|
GitStoreEvent::ActiveRepositoryChanged(_) => {
|
||||||
|
this.active_repository = this.project.read(cx).active_repository(cx);
|
||||||
|
this.reload_history(window, cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload the git history on repository changes to the current repo
|
||||||
|
GitStoreEvent::RepositoryUpdated(_, _, true) => this.reload_history(window, cx),
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
let commits_list = ListState::new(0, gpui::ListAlignment::Top, px(1000.));
|
||||||
|
commits_list.set_scroll_handler(cx.listener(
|
||||||
|
|this: &mut Self, event: &ListScrollEvent, window, cx| {
|
||||||
|
if this.commits.len() > 5
|
||||||
|
&& event.visible_range.end >= this.commits.len() - 5
|
||||||
|
&& this.has_next_page()
|
||||||
|
{
|
||||||
|
this.load_next_history_page(window, cx);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
let scrollbar_state =
|
||||||
|
ScrollbarState::new(commits_list.clone()).parent_entity(&cx.entity());
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
active_repository,
|
||||||
|
project,
|
||||||
|
workspace,
|
||||||
|
commits: Vec::new(),
|
||||||
|
commits_loading: false,
|
||||||
|
commits_list,
|
||||||
|
scrollbar_state,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.load_next_history_page(window, cx);
|
||||||
|
|
||||||
|
this
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reload_history(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
self.commits.clear();
|
||||||
|
self.commits_loading = false;
|
||||||
|
self.commits_list.reset(0);
|
||||||
|
|
||||||
|
self.load_next_history_page(window, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We probabbly have a next page if the length of all pages matches the per page amount
|
||||||
|
fn has_next_page(&self) -> bool {
|
||||||
|
self.commits.len() % (COMMITS_PER_PAGE as usize) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_next_history_page(&self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
// Skip if already loading a page
|
||||||
|
if self.commits_loading {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let skip = self.commits.len() as u64;
|
||||||
|
|
||||||
|
cx.spawn_in(window, async move |this, cx| {
|
||||||
|
let details = this.update(cx, |list: &mut GitCommitList, cx| {
|
||||||
|
list.commits_loading = true;
|
||||||
|
list.load_commit_history(cx, skip, COMMITS_PER_PAGE)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let details = details.await?;
|
||||||
|
|
||||||
|
let commits: Vec<CommitDetails> = details
|
||||||
|
.into_iter()
|
||||||
|
.map(|commit| {
|
||||||
|
anyhow::Ok(CommitDetails {
|
||||||
|
sha: commit.sha.clone(),
|
||||||
|
author_name: commit.author_name.clone(),
|
||||||
|
author_email: commit.author_email.clone(),
|
||||||
|
commit_time: OffsetDateTime::from_unix_timestamp(commit.commit_timestamp)?,
|
||||||
|
message: Some(ParsedCommitMessage {
|
||||||
|
message: commit.message,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.try_collect()?;
|
||||||
|
|
||||||
|
this.update(cx, |this: &mut GitCommitList, cx| {
|
||||||
|
let count = commits.len();
|
||||||
|
let current_count = this.commits_list.item_count();
|
||||||
|
|
||||||
|
this.commits_loading = false;
|
||||||
|
this.commits.extend(commits);
|
||||||
|
this.commits_list
|
||||||
|
.splice(current_count..current_count, count);
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_commit_history(
|
||||||
|
&self,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
skip: u64,
|
||||||
|
max_count: u64,
|
||||||
|
) -> Task<anyhow::Result<Vec<git::repository::CommitDetails>>> {
|
||||||
|
let Some(repo) = self.active_repository.clone() else {
|
||||||
|
return Task::ready(Err(anyhow::anyhow!("no active repo")));
|
||||||
|
};
|
||||||
|
repo.update(cx, |repo, cx| {
|
||||||
|
let git_log = repo.log(skip, max_count);
|
||||||
|
cx.spawn(async move |_, _| git_log.await?)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_element(
|
||||||
|
&self,
|
||||||
|
item_id: ElementId,
|
||||||
|
commit: &CommitDetails,
|
||||||
|
_window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) -> impl IntoElement {
|
||||||
|
let commit_summary = CommitSummary {
|
||||||
|
sha: commit.sha.clone(),
|
||||||
|
subject: commit
|
||||||
|
.message
|
||||||
|
.as_ref()
|
||||||
|
.map_or(Default::default(), |message| {
|
||||||
|
message
|
||||||
|
.message
|
||||||
|
.split('\n')
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.trim_end()
|
||||||
|
.to_string()
|
||||||
|
.into()
|
||||||
|
}),
|
||||||
|
commit_timestamp: commit.commit_time.unix_timestamp(),
|
||||||
|
has_parent: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
ListItem::new(item_id)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.items_center()
|
||||||
|
.h_8()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(Color::Default.color(cx))
|
||||||
|
.child(commit_summary.subject.clone()),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.items_center()
|
||||||
|
.h_8()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(Color::Hidden.color(cx))
|
||||||
|
.child(commit.author_name.clone())
|
||||||
|
.ml_1(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_click({
|
||||||
|
let workspace = self.workspace.clone();
|
||||||
|
let repo = self.active_repository.as_ref().map(|repo| repo.downgrade());
|
||||||
|
move |_, window, cx| {
|
||||||
|
let repo = match repo.clone() {
|
||||||
|
Some(repo) => repo,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
CommitView::open(commit_summary.clone(), repo, workspace.clone(), window, cx);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Stateful<Div> {
|
||||||
|
div()
|
||||||
|
.occlude()
|
||||||
|
.id("git-history-scrollbar")
|
||||||
|
.on_mouse_move(cx.listener(|_, _, _, cx| {
|
||||||
|
cx.notify();
|
||||||
|
cx.stop_propagation()
|
||||||
|
}))
|
||||||
|
.on_hover(|_, _, cx| {
|
||||||
|
cx.stop_propagation();
|
||||||
|
})
|
||||||
|
.on_any_mouse_down(|_, _, cx| {
|
||||||
|
cx.stop_propagation();
|
||||||
|
})
|
||||||
|
.on_mouse_up(
|
||||||
|
MouseButton::Left,
|
||||||
|
cx.listener(|_, _, _, cx| {
|
||||||
|
cx.stop_propagation();
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
|
||||||
|
cx.notify();
|
||||||
|
}))
|
||||||
|
.h_full()
|
||||||
|
.absolute()
|
||||||
|
.right_1()
|
||||||
|
.top_1()
|
||||||
|
.bottom_0()
|
||||||
|
.w(px(12.))
|
||||||
|
.cursor_default()
|
||||||
|
.children(Scrollbar::vertical(self.scrollbar_state.clone()).map(|s| s.auto_hide(cx)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for GitCommitList {
|
||||||
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
v_flex()
|
||||||
|
.border_t_1()
|
||||||
|
.border_color(cx.theme().colors().border.opacity(0.8))
|
||||||
|
.flex_shrink()
|
||||||
|
.h_48()
|
||||||
|
.w_full()
|
||||||
|
.child(
|
||||||
|
list(
|
||||||
|
self.commits_list.clone(),
|
||||||
|
cx.processor(move |list, index, window, cx| {
|
||||||
|
let item: &CommitDetails = &list.commits[index];
|
||||||
|
|
||||||
|
list.render_element(ElementId::Name(item.sha.clone()), item, window, cx)
|
||||||
|
.into_any_element()
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.size_full(),
|
||||||
|
)
|
||||||
|
.child(self.render_vertical_scrollbar(cx))
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ use crate::askpass_modal::AskPassModal;
|
||||||
use crate::commit_modal::CommitModal;
|
use crate::commit_modal::CommitModal;
|
||||||
use crate::commit_tooltip::CommitTooltip;
|
use crate::commit_tooltip::CommitTooltip;
|
||||||
use crate::commit_view::CommitView;
|
use crate::commit_view::CommitView;
|
||||||
|
use crate::git_commit_list::GitCommitList;
|
||||||
use crate::git_panel_settings::StatusStyle;
|
use crate::git_panel_settings::StatusStyle;
|
||||||
use crate::project_diff::{self, Diff, ProjectDiff};
|
use crate::project_diff::{self, Diff, ProjectDiff};
|
||||||
use crate::remote_output::{self, RemoteAction, SuccessMessage};
|
use crate::remote_output::{self, RemoteAction, SuccessMessage};
|
||||||
|
@ -370,6 +371,7 @@ pub struct GitPanel {
|
||||||
local_committer_task: Option<Task<()>>,
|
local_committer_task: Option<Task<()>>,
|
||||||
bulk_staging: Option<BulkStaging>,
|
bulk_staging: Option<BulkStaging>,
|
||||||
_settings_subscription: Subscription,
|
_settings_subscription: Subscription,
|
||||||
|
history: Entity<GitCommitList>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -520,6 +522,8 @@ impl GitPanel {
|
||||||
)
|
)
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
|
let history = GitCommitList::new(workspace, window, cx);
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
active_repository,
|
active_repository,
|
||||||
commit_editor,
|
commit_editor,
|
||||||
|
@ -559,6 +563,7 @@ impl GitPanel {
|
||||||
vertical_scrollbar,
|
vertical_scrollbar,
|
||||||
bulk_staging: None,
|
bulk_staging: None,
|
||||||
_settings_subscription,
|
_settings_subscription,
|
||||||
|
history,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.schedule_update(false, window, cx);
|
this.schedule_update(false, window, cx);
|
||||||
|
@ -4556,6 +4561,9 @@ impl Render for GitPanel {
|
||||||
.when(!self.amend_pending, |this| {
|
.when(!self.amend_pending, |this| {
|
||||||
this.children(self.render_previous_commit(cx))
|
this.children(self.render_previous_commit(cx))
|
||||||
})
|
})
|
||||||
|
.when(GitPanelSettings::get_global(cx).commit_history, |this| {
|
||||||
|
this.child(self.history.clone())
|
||||||
|
})
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
)
|
)
|
||||||
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
||||||
|
|
|
@ -75,6 +75,11 @@ pub struct GitPanelSettingsContent {
|
||||||
///
|
///
|
||||||
/// Default: false
|
/// Default: false
|
||||||
pub collapse_untracked_diff: Option<bool>,
|
pub collapse_untracked_diff: Option<bool>,
|
||||||
|
|
||||||
|
//// Whether to show a list of previous commits in the git panel.
|
||||||
|
///
|
||||||
|
/// Default: false
|
||||||
|
pub commit_history: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
@ -87,6 +92,7 @@ pub struct GitPanelSettings {
|
||||||
pub fallback_branch_name: String,
|
pub fallback_branch_name: String,
|
||||||
pub sort_by_path: bool,
|
pub sort_by_path: bool,
|
||||||
pub collapse_untracked_diff: bool,
|
pub collapse_untracked_diff: bool,
|
||||||
|
pub commit_history: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings for GitPanelSettings {
|
impl Settings for GitPanelSettings {
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub mod commit_tooltip;
|
||||||
mod commit_view;
|
mod commit_view;
|
||||||
mod conflict_view;
|
mod conflict_view;
|
||||||
pub mod file_diff_view;
|
pub mod file_diff_view;
|
||||||
|
pub mod git_commit_list;
|
||||||
pub mod git_panel;
|
pub mod git_panel;
|
||||||
mod git_panel_settings;
|
mod git_panel_settings;
|
||||||
pub mod onboarding;
|
pub mod onboarding;
|
||||||
|
|
|
@ -3469,6 +3469,41 @@ impl Repository {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn log(
|
||||||
|
&mut self,
|
||||||
|
skip: u64,
|
||||||
|
max_count: u64,
|
||||||
|
) -> oneshot::Receiver<Result<Vec<CommitDetails>>> {
|
||||||
|
let id = self.id;
|
||||||
|
self.send_job(None, move |git_repo, _cx| async move {
|
||||||
|
match git_repo {
|
||||||
|
RepositoryState::Local { backend, .. } => backend.log(skip, max_count).await,
|
||||||
|
RepositoryState::Remote { project_id, client } => {
|
||||||
|
let resp = client
|
||||||
|
.request(proto::GitLog {
|
||||||
|
project_id: project_id.0,
|
||||||
|
repository_id: id.to_proto(),
|
||||||
|
skip,
|
||||||
|
max_count,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(resp
|
||||||
|
.commits
|
||||||
|
.into_iter()
|
||||||
|
.map(|commit| CommitDetails {
|
||||||
|
sha: commit.sha.into(),
|
||||||
|
message: commit.message.into(),
|
||||||
|
commit_timestamp: commit.commit_timestamp,
|
||||||
|
author_email: commit.author_email.into(),
|
||||||
|
author_name: commit.author_name.into(),
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load_commit_diff(&mut self, commit: String) -> oneshot::Receiver<Result<CommitDiff>> {
|
pub fn load_commit_diff(&mut self, commit: String) -> oneshot::Receiver<Result<CommitDiff>> {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
self.send_job(None, move |git_repo, cx| async move {
|
self.send_job(None, move |git_repo, cx| async move {
|
||||||
|
|
|
@ -230,6 +230,18 @@ message GitShow {
|
||||||
string commit = 4;
|
string commit = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GitLog {
|
||||||
|
uint64 project_id = 1;
|
||||||
|
reserved 2;
|
||||||
|
uint64 repository_id = 3;
|
||||||
|
uint64 skip = 4;
|
||||||
|
uint64 max_count = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GitLogResponse {
|
||||||
|
repeated GitCommitDetails commits = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message GitCommitDetails {
|
message GitCommitDetails {
|
||||||
string sha = 1;
|
string sha = 1;
|
||||||
string message = 2;
|
string message = 2;
|
||||||
|
|
|
@ -396,7 +396,10 @@ message Envelope {
|
||||||
GitCloneResponse git_clone_response = 364;
|
GitCloneResponse git_clone_response = 364;
|
||||||
|
|
||||||
LspQuery lsp_query = 365;
|
LspQuery lsp_query = 365;
|
||||||
LspQueryResponse lsp_query_response = 366; // current max
|
LspQueryResponse lsp_query_response = 366;
|
||||||
|
|
||||||
|
GitLog git_log = 367;
|
||||||
|
GitLogResponse git_log_response = 368; // current max
|
||||||
}
|
}
|
||||||
|
|
||||||
reserved 87 to 88;
|
reserved 87 to 88;
|
||||||
|
|
|
@ -284,6 +284,8 @@ messages!(
|
||||||
(GitReset, Background),
|
(GitReset, Background),
|
||||||
(GitCheckoutFiles, Background),
|
(GitCheckoutFiles, Background),
|
||||||
(GitShow, Background),
|
(GitShow, Background),
|
||||||
|
(GitLog, Background),
|
||||||
|
(GitLogResponse, Background),
|
||||||
(GitCommitDetails, Background),
|
(GitCommitDetails, Background),
|
||||||
(SetIndexText, Background),
|
(SetIndexText, Background),
|
||||||
(Push, Background),
|
(Push, Background),
|
||||||
|
@ -462,6 +464,7 @@ request_messages!(
|
||||||
(InstallExtension, Ack),
|
(InstallExtension, Ack),
|
||||||
(RegisterBufferWithLanguageServers, Ack),
|
(RegisterBufferWithLanguageServers, Ack),
|
||||||
(GitShow, GitCommitDetails),
|
(GitShow, GitCommitDetails),
|
||||||
|
(GitLog, GitLogResponse),
|
||||||
(GitReset, Ack),
|
(GitReset, Ack),
|
||||||
(GitCheckoutFiles, Ack),
|
(GitCheckoutFiles, Ack),
|
||||||
(SetIndexText, Ack),
|
(SetIndexText, Ack),
|
||||||
|
@ -609,6 +612,7 @@ entity_messages!(
|
||||||
CancelLanguageServerWork,
|
CancelLanguageServerWork,
|
||||||
RegisterBufferWithLanguageServers,
|
RegisterBufferWithLanguageServers,
|
||||||
GitShow,
|
GitShow,
|
||||||
|
GitLog,
|
||||||
GitReset,
|
GitReset,
|
||||||
GitCheckoutFiles,
|
GitCheckoutFiles,
|
||||||
SetIndexText,
|
SetIndexText,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue