Add git init button (#26522)

Because why not

Release Notes:

- N/A
This commit is contained in:
Mikayla Maki 2025-03-12 00:25:19 -07:00 committed by GitHub
parent 050f5f6723
commit 036c123488
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 429 additions and 83 deletions

View file

@ -1767,6 +1767,88 @@ impl GitPanel {
.detach_and_log_err(cx);
}
pub(crate) fn git_init(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let worktrees = self
.project
.read(cx)
.visible_worktrees(cx)
.collect::<Vec<_>>();
let worktree = if worktrees.len() == 1 {
Task::ready(Some(worktrees.first().unwrap().clone()))
} else if worktrees.len() == 0 {
let result = window.prompt(
PromptLevel::Warning,
"Unable to initialize a git repository",
Some("Open a directory first"),
&["Ok"],
cx,
);
cx.background_executor()
.spawn(async move {
result.await.ok();
})
.detach();
return;
} else {
let worktree_directories = worktrees
.iter()
.map(|worktree| worktree.read(cx).abs_path())
.map(|worktree_abs_path| {
if let Ok(path) = worktree_abs_path.strip_prefix(util::paths::home_dir()) {
Path::new("~")
.join(path)
.to_string_lossy()
.to_string()
.into()
} else {
worktree_abs_path.to_string_lossy().to_string().into()
}
})
.collect_vec();
let prompt = picker_prompt::prompt(
"Where would you like to initialize this git repository?",
worktree_directories,
self.workspace.clone(),
window,
cx,
);
cx.spawn(|_, _| async move { prompt.await.map(|ix| worktrees[ix].clone()) })
};
cx.spawn_in(window, |this, mut cx| async move {
let worktree = match worktree.await {
Some(worktree) => worktree,
None => {
return;
}
};
let Ok(result) = this.update(&mut cx, |this, cx| {
let fallback_branch_name = GitPanelSettings::get_global(cx)
.fallback_branch_name
.clone();
this.project.read(cx).git_init(
worktree.read(cx).abs_path(),
fallback_branch_name,
cx,
)
}) else {
return;
};
let result = result.await;
this.update_in(&mut cx, |this, _, cx| match result {
Ok(()) => {}
Err(e) => this.show_error_toast("init", e, cx),
})
.ok();
})
.detach();
}
pub(crate) fn pull(&mut self, window: &mut Window, cx: &mut Context<Self>) {
if !self.can_push_and_pull(cx) {
return;
@ -1971,7 +2053,7 @@ impl GitPanel {
cx,
)
})?
.await?;
.await;
Ok(selection.map(|selection| Remote {
name: current_remotes[selection].clone(),
@ -2677,7 +2759,13 @@ impl GitPanel {
})
}
fn render_panel_header(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
fn render_panel_header(
&self,
window: &mut Window,
cx: &mut Context<Self>,
) -> Option<impl IntoElement> {
self.active_repository.as_ref()?;
let text;
let action;
let tooltip;
@ -2697,39 +2785,42 @@ impl GitPanel {
_ => format!("{} Changes", self.entry_count),
};
self.panel_header_container(window, cx)
.px_2()
.child(
panel_button(change_string)
.color(Color::Muted)
.tooltip(Tooltip::for_action_title_in(
"Open diff",
&Diff,
&self.focus_handle,
))
.on_click(|_, _, cx| {
cx.defer(|cx| {
cx.dispatch_action(&Diff);
})
}),
)
.child(div().flex_grow()) // spacer
.child(self.render_overflow_menu("overflow_menu"))
.child(
panel_filled_button(text)
.tooltip(Tooltip::for_action_title_in(
tooltip,
action.as_ref(),
&self.focus_handle,
))
.disabled(self.entry_count == 0)
.on_click(move |_, _, cx| {
let action = action.boxed_clone();
cx.defer(move |cx| {
cx.dispatch_action(action.as_ref());
})
}),
)
Some(
self.panel_header_container(window, cx)
.px_2()
.child(
panel_button(change_string)
.color(Color::Muted)
.tooltip(Tooltip::for_action_title_in(
"Open diff",
&Diff,
&self.focus_handle,
))
.on_click(|_, _, cx| {
cx.defer(|cx| {
cx.dispatch_action(&Diff);
})
}),
)
.child(div().flex_grow()) // spacer
.child(self.render_overflow_menu("overflow_menu"))
.child(div().w_2()) // another spacer
.child(
panel_filled_button(text)
.tooltip(Tooltip::for_action_title_in(
tooltip,
action.as_ref(),
&self.focus_handle,
))
.disabled(self.entry_count == 0)
.on_click(move |_, _, cx| {
let action = action.boxed_clone();
cx.defer(move |cx| {
cx.dispatch_action(action.as_ref());
})
}),
),
)
}
pub fn render_footer(
@ -2949,12 +3040,29 @@ impl GitPanel {
.items_center()
.child(
v_flex()
.gap_3()
.child(if self.active_repository.is_some() {
"No changes to commit"
} else {
"No Git repositories"
})
.gap_2()
.child(h_flex().w_full().justify_around().child(
if self.active_repository.is_some() {
"No changes to commit"
} else {
"No Git repositories"
},
))
.children(self.active_repository.is_none().then(|| {
h_flex().w_full().justify_around().child(
panel_filled_button("Initialize Repository")
.tooltip(Tooltip::for_action_title_in(
"git init",
&git::Init,
&self.focus_handle,
))
.on_click(move |_, _, cx| {
cx.defer(move |cx| {
cx.dispatch_action(&git::Init);
})
}),
)
}))
.text_ui_sm(cx)
.mx_auto()
.text_color(Color::Placeholder.color(cx)),
@ -3674,7 +3782,7 @@ impl Render for GitPanel {
.child(
v_flex()
.size_full()
.child(self.render_panel_header(window, cx))
.children(self.render_panel_header(window, cx))
.map(|this| {
if has_entries {
this.child(self.render_entries(has_write_access, window, cx))