Delete branch (#332)

This commit is contained in:
Richard Menzies 2020-10-11 13:30:44 +01:00 committed by GitHub
parent 1f55c18945
commit b6c932d0af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 154 additions and 6 deletions

View File

@ -66,6 +66,7 @@
copy: ( code: Char('y'), modifiers: ( bits: 0,),),
create_branch: ( code: Char('c'), modifiers: ( bits: 0,),),
select_branch: ( code: Char('b'), modifiers: ( bits: 0,),),
delete_branch: ( code: Char('D'), modifiers: ( bits: 1,),),
push: ( code: Char('p'), modifiers: ( bits: 0,),),
fetch: ( code: Char('f'), modifiers: ( bits: 0,),),
)

View File

@ -112,6 +112,24 @@ pub fn checkout_branch(
}
}
/// The user must not be on the branch for the branch to be deleted
pub fn delete_branch(
repo_path: &str,
branch_ref: &str,
) -> Result<()> {
scope_time!("delete_branch");
let repo = utils::repo(repo_path)?;
let branch_as_ref = repo.find_reference(branch_ref)?;
let mut branch = git2::Branch::wrap(branch_as_ref);
if !branch.is_head() {
branch.delete()?;
} else {
return Err(Error::Generic("You cannot be on the branch you want to delete, switch branch, then delete this branch".to_string()));
}
Ok(())
}
/// creates a new branch pointing to current HEAD commit and updating HEAD to new branch
pub fn create_branch(repo_path: &str, name: &str) -> Result<()> {
scope_time!("create_branch");
@ -254,3 +272,49 @@ mod tests_checkout {
assert!(checkout_branch(repo_path, "refs/heads/test").is_ok());
}
}
#[cfg(test)]
mod test_delete_branch {
use super::*;
use crate::sync::tests::repo_init;
#[test]
fn test_delete_branch() {
let (_td, repo) = repo_init().unwrap();
let root = repo.path().parent().unwrap();
let repo_path = root.as_os_str().to_str().unwrap();
create_branch(repo_path, "branch1").unwrap();
create_branch(repo_path, "branch2").unwrap();
checkout_branch(repo_path, "refs/heads/branch1").unwrap();
assert_eq!(
repo.branches(None)
.unwrap()
.nth(1)
.unwrap()
.unwrap()
.0
.name()
.unwrap()
.unwrap(),
"branch2"
);
delete_branch(repo_path, "refs/heads/branch2").unwrap();
assert_eq!(
repo.branches(None)
.unwrap()
.nth(1)
.unwrap()
.unwrap()
.0
.name()
.unwrap()
.unwrap(),
"master"
);
}
}

View File

@ -19,8 +19,8 @@ pub mod utils;
pub(crate) use branch::get_branch_name;
pub use branch::{
checkout_branch, create_branch, get_branches_to_display,
BranchForDisplay,
checkout_branch, create_branch, delete_branch,
get_branches_to_display, BranchForDisplay,
};
pub use commit::{amend, commit, tag};
pub use commit_details::{

View File

@ -473,6 +473,20 @@ impl App {
sync::reset_hunk(CWD, path, hash)?;
flags.insert(NeedsUpdate::ALL);
}
Action::DeleteBranch(branch_ref) => {
if let Err(e) =
sync::delete_branch(CWD, &branch_ref)
{
self.queue.borrow_mut().push_back(
InternalEvent::ShowErrorMsg(
e.to_string(),
),
)
} else {
flags.insert(NeedsUpdate::ALL);
self.select_branch_popup.hide();
}
}
},
InternalEvent::ConfirmAction(action) => {
self.reset.open(action)?;
@ -593,15 +607,15 @@ impl App {
self.commit.draw(f, size)?;
self.stashmsg_popup.draw(f, size)?;
self.reset.draw(f, size)?;
self.help.draw(f, size)?;
self.inspect_commit_popup.draw(f, size)?;
self.msg.draw(f, size)?;
self.external_editor_popup.draw(f, size)?;
self.tag_commit_popup.draw(f, size)?;
self.select_branch_popup.draw(f, size)?;
self.create_branch_popup.draw(f, size)?;
self.push_popup.draw(f, size)?;
self.reset.draw(f, size)?;
self.msg.draw(f, size)?;
Ok(())
}

View File

@ -151,6 +151,15 @@ impl ResetComponent {
strings::confirm_title_reset(&self.key_config),
strings::confirm_msg_resethunk(&self.key_config),
),
Action::DeleteBranch(branch_ref) => (
strings::confirm_title_delete_branch(
&self.key_config,
),
strings::confirm_msg_delete_branch(
&self.key_config,
branch_ref.to_string(),
),
),
};
}

View File

@ -4,7 +4,7 @@ use super::{
};
use crate::{
keys::SharedKeyConfig,
queue::{InternalEvent, NeedsUpdate, Queue},
queue::{Action, InternalEvent, NeedsUpdate, Queue},
strings, ui,
};
use asyncgit::{
@ -45,7 +45,7 @@ impl DrawableComponent for SelectBranchComponent {
// Render a scrolllist of branches inside a box
if self.visible {
const SIZE: (u16, u16) = (50, 45);
const SIZE: (u16, u16) = (50, 20);
let scroll_threshold = SIZE.1 / 3;
let scroll =
self.selection.saturating_sub(scroll_threshold);
@ -113,6 +113,14 @@ impl Component for SelectBranchComponent {
true,
true,
));
out.push(CommandInfo::new(
strings::commands::delete_branch_popup(
&self.key_config,
),
!self.selection_is_cur_branch(),
true,
));
}
visibility_blocking(self)
}
@ -142,6 +150,19 @@ impl Component for SelectBranchComponent {
.borrow_mut()
.push_back(InternalEvent::CreateBranch);
self.hide();
} else if e == self.key_config.delete_branch
&& !self.selection_is_cur_branch()
{
self.queue.borrow_mut().push_back(
InternalEvent::ConfirmAction(
Action::DeleteBranch(
self.branch_names
[self.selection as usize]
.reference
.clone(),
),
),
);
}
}
@ -200,6 +221,18 @@ impl SelectBranchComponent {
Ok(())
}
///
pub fn selection_is_cur_branch(&self) -> bool {
self.branch_names
.iter()
.enumerate()
.filter(|(index, b)| {
b.is_head && *index == self.selection as usize
})
.count()
> 0
}
///
fn move_selection(&mut self, inc: bool) {
let mut new_selection = self.selection;

View File

@ -61,6 +61,7 @@ pub struct KeyConfig {
pub copy: KeyEvent,
pub create_branch: KeyEvent,
pub select_branch: KeyEvent,
pub delete_branch: KeyEvent,
pub push: KeyEvent,
pub fetch: KeyEvent,
}
@ -113,6 +114,7 @@ impl Default for KeyConfig {
copy: KeyEvent { code: KeyCode::Char('y'), modifiers: KeyModifiers::empty()},
create_branch: KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::NONE},
select_branch: KeyEvent { code: KeyCode::Char('b'), modifiers: KeyModifiers::NONE},
delete_branch: KeyEvent{code: KeyCode::Char('D'), modifiers: KeyModifiers::SHIFT},
push: KeyEvent { code: KeyCode::Char('p'), modifiers: KeyModifiers::empty()},
fetch: KeyEvent { code: KeyCode::Char('f'), modifiers: KeyModifiers::empty()},
}

View File

@ -28,6 +28,8 @@ pub enum Action {
Reset(ResetItem),
ResetHunk(String, u64),
StashDrop(CommitId),
///
DeleteBranch(String),
}
///

View File

@ -90,6 +90,17 @@ pub fn confirm_msg_resethunk(
) -> String {
"confirm reset hunk?".to_string()
}
pub fn confirm_title_delete_branch(
_key_config: &SharedKeyConfig,
) -> String {
"Delete Branch".to_string()
}
pub fn confirm_msg_delete_branch(
_key_config: &SharedKeyConfig,
branch_ref: String,
) -> String {
branch_ref + "\nconfirm delete branch?"
}
pub fn log_title(_key_config: &SharedKeyConfig) -> String {
"Commit".to_string()
}
@ -604,6 +615,18 @@ pub mod commands {
CMD_GROUP_GENERAL,
)
}
pub fn delete_branch_popup(
key_config: &SharedKeyConfig,
) -> CommandText {
CommandText::new(
format!(
"Delete [{}]",
get_hint(key_config.delete_branch),
),
"delete a branch",
CMD_GROUP_GENERAL,
)
}
pub fn open_branch_select_popup(
key_config: &SharedKeyConfig,
) -> CommandText {