Repository: gitui-org/gitui (language: rust)

Issue:
Allow reset to branch in branches view
**Is your feature request related to a problem? Please describe.**
As part of my workflow (squashing commits locally before merging), I need to leave gitui to run a command like `git reset --soft master`. While possible to do in the commits/log view, it is not always easy to find the desired branch as the target for resetting. 

**Describe the solution you'd like**
I would suggest that it be possible to reset directly from the branches view. Not sure what hotkey is best since `Shift+R` is already taken in that view (and so is 'r'), but that would make it consistent with the log view. Hitting the hotkey to reset should bring up the same menu as was added for #1500 and function the same way, just targeting the select branch instead of a specific commit.

**Describe alternatives you've considered**
Maybe this could be mitigated by making it easier to find branches in the log view (I couldn't find a way to in the `find` dialogue). But that seems less direct than adding a way in the branch view itself.

**Additional context**
Thanks for the awesome tool!



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d439524a1..bf1de5be09 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,10 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## Unreleased
 
 ### Added
-* provide nightly builds (see [NIGHTLIES.md](./NIGHTLIES.md)) ([#2083](https://github.com/extrawurst/gitui/issues/2083))
 * sign commits using openpgp [[@hendrikmaus](https://github.com/hendrikmaus)] ([#97](https://github.com/extrawurst/gitui/issues/97))
-* support `core.commitChar` filtering [[@concelare](https://github.com/concelare)] ([#2136](https://github.com/extrawurst/gitui/issues/2136))
+* provide nightly builds (see [NIGHTLIES.md](./NIGHTLIES.md)) ([#2083](https://github.com/extrawurst/gitui/issues/2083))
 * more version info in `gitui -V` and `help popup` (including git hash)
+* support `core.commitChar` filtering [[@concelare](https://github.com/concelare)] ([#2136](https://github.com/extrawurst/gitui/issues/2136))
+* allow reset in branch popup ([#2170](https://github.com/extrawurst/gitui/issues/2170))
 
 ### Changed
 * Make info and error message popups scrollable [[@MichaelAug](https://github.com/MichaelAug)] ([#1138](https://github.com/extrawurst/gitui/issues/1138))
diff --git a/src/app.rs b/src/app.rs
index f2b4a4a9bb..e35da87051 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -482,13 +482,13 @@ impl App {
 			pull_popup,
 			fetch_popup,
 			tag_commit_popup,
+			reset_popup,
 			create_branch_popup,
 			rename_branch_popup,
 			select_branch_popup,
 			revision_files_popup,
 			submodule_popup,
 			tags_popup,
-			reset_popup,
 			options_popup,
 			help_popup,
 			revlog,
diff --git a/src/keys/key_list.rs b/src/keys/key_list.rs
index 71e6756db4..a542ef938a 100644
--- a/src/keys/key_list.rs
+++ b/src/keys/key_list.rs
@@ -99,6 +99,7 @@ pub struct KeysList {
 	pub delete_branch: GituiKeyEvent,
 	pub merge_branch: GituiKeyEvent,
 	pub rebase_branch: GituiKeyEvent,
+	pub reset_branch: GituiKeyEvent,
 	pub compare_commits: GituiKeyEvent,
 	pub tags: GituiKeyEvent,
 	pub delete_tag: GituiKeyEvent,
@@ -190,6 +191,7 @@ impl Default for KeysList {
 			delete_branch: GituiKeyEvent::new(KeyCode::Char('D'),  KeyModifiers::SHIFT),
 			merge_branch: GituiKeyEvent::new(KeyCode::Char('m'),  KeyModifiers::empty()),
 			rebase_branch: GituiKeyEvent::new(KeyCode::Char('R'),  KeyModifiers::SHIFT),
+			reset_branch: GituiKeyEvent::new(KeyCode::Char('s'),  KeyModifiers::empty()),
 			compare_commits: GituiKeyEvent::new(KeyCode::Char('C'),  KeyModifiers::SHIFT),
 			tags: GituiKeyEvent::new(KeyCode::Char('T'),  KeyModifiers::SHIFT),
 			delete_tag: GituiKeyEvent::new(KeyCode::Char('D'),  KeyModifiers::SHIFT),
diff --git a/src/popups/branchlist.rs b/src/popups/branchlist.rs
index f7c9b94dd5..599b3bea23 100644
--- a/src/popups/branchlist.rs
+++ b/src/popups/branchlist.rs
@@ -211,6 +211,12 @@ impl Component for BranchListPopup {
 				true,
 				true,
 			));
+
+			out.push(CommandInfo::new(
+				strings::commands::reset_branch(&self.key_config),
+				self.valid_selection(),
+				true,
+			));
 		}
 		visibility_blocking(self)
 	}
@@ -277,7 +283,7 @@ impl Component for BranchListPopup {
 			) && self.valid_selection()
 			{
 				self.hide();
-				if let Some(commit_id) = self.get_selected() {
+				if let Some(commit_id) = self.get_selected_commit() {
 					self.queue.push(InternalEvent::OpenPopup(
 						StackablePopupOpen::CompareCommits(
 							InspectCommitOpen::new(commit_id),
@@ -288,6 +294,13 @@ impl Component for BranchListPopup {
 				&& self.has_remotes
 			{
 				self.queue.push(InternalEvent::FetchRemotes);
+			} else if key_match(e, self.key_config.keys.reset_branch)
+			{
+				if let Some(commit_id) = self.get_selected_commit() {
+					self.queue.push(InternalEvent::OpenResetPopup(
+						commit_id,
+					));
+				}
 			} else if key_match(
 				e,
 				self.key_config.keys.cmd_bar_toggle,
@@ -466,7 +479,7 @@ impl BranchListPopup {
 	}
 
 	fn inspect_head_of_branch(&mut self) {
-		if let Some(commit_id) = self.get_selected() {
+		if let Some(commit_id) = self.get_selected_commit() {
 			self.hide();
 			self.queue.push(InternalEvent::OpenPopup(
 				StackablePopupOpen::InspectCommit(
@@ -509,7 +522,8 @@ impl BranchListPopup {
 			.count() > 0
 	}
 
-	fn get_selected(&self) -> Option<CommitId> {
+	// top commit of selected branch
+	fn get_selected_commit(&self) -> Option<CommitId> {
 		self.branches
 			.get(usize::from(self.selection))
 			.map(|b| b.top_commit)
diff --git a/src/strings.rs b/src/strings.rs
index 67eb79ba7a..70ca9e3e8f 100644
--- a/src/strings.rs
+++ b/src/strings.rs
@@ -1403,17 +1403,29 @@ pub mod commands {
 	pub fn reset_commit(key_config: &SharedKeyConfig) -> CommandText {
 		CommandText::new(
 			format!(
-				"Confirm  [{}]",
+				"Confirm [{}]",
 				key_config.get_hint(key_config.keys.enter),
 			),
 			"confirm reset",
 			CMD_GROUP_LOG,
 		)
 	}
+
+	pub fn reset_branch(key_config: &SharedKeyConfig) -> CommandText {
+		CommandText::new(
+			format!(
+				"Reset [{}]",
+				key_config.get_hint(key_config.keys.reset_branch),
+			),
+			"confirm reset",
+			CMD_GROUP_BRANCHES,
+		)
+	}
+
 	pub fn reset_type(key_config: &SharedKeyConfig) -> CommandText {
 		CommandText::new(
 			format!(
-				"Change Type  [{}{}]",
+				"Change Type [{}{}]",
 				key_config.get_hint(key_config.keys.move_up),
 				key_config.get_hint(key_config.keys.move_down)
 			),


Test patch: