Skip to content
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
8624ec5
chore: add .editorconfig file
Fatpandac Jan 20, 2025
aaa1bfa
feat: add discard_status function
Fatpandac Jan 20, 2025
160f9f8
feat: support choosing checkout branch method
Fatpandac Jan 20, 2025
4c17a4b
chore: fmt
Fatpandac Jan 20, 2025
96a41ca
fix: use stash pop to replace stash apply
Fatpandac Jan 20, 2025
82c9a75
Merge branch 'master' into feat/checkout_method
Fatpandac Jan 21, 2025
9cc2632
chore: update changelog
Fatpandac Jan 21, 2025
b33c170
chore: remove .editorconfig
Fatpandac Jan 22, 2025
4d222f3
chore: update changelog
Fatpandac Jan 22, 2025
30cad4d
fix: merge import
Fatpandac Jan 22, 2025
bc3656f
fix: move type_to_string func to strings.rs and rename
Fatpandac Jan 22, 2025
c44cd5a
test: add test for discard_status
Fatpandac Jan 22, 2025
6cda6c2
Merge branch 'master' into feat/checkout_method
Fatpandac Jan 22, 2025
e33fdd1
chore: update changelog
Fatpandac Jan 22, 2025
be3b643
Merge branch 'master' into feat/checkout_method
Fatpandac Jan 29, 2025
08fe2bd
Merge branch 'master' into feat/checkout_method
Fatpandac Feb 1, 2025
856ace5
fix: change to another way to implement discarding status
Fatpandac Feb 2, 2025
6cdca09
fix: changed to use default stash message
Fatpandac Feb 2, 2025
5af887c
Merge branch 'master' into feat/checkout_method
Fatpandac Feb 7, 2025
af4f03c
Merge branch 'master' into feat/checkout_method
Fatpandac Feb 8, 2025
18635ba
Merge branch 'master' into feat/checkout_method
Fatpandac Feb 19, 2025
2f95c99
Merge branch 'master' into feat/checkout_method
Fatpandac Feb 20, 2025
ef72456
Merge branch 'master' into feat/checkout_method
Fatpandac Feb 26, 2025
3ffcec7
Merge branch 'master' into feat/checkout_method
Fatpandac Mar 27, 2025
c023441
Merge branch 'master' into feat/checkout_method
Fatpandac Apr 22, 2025
8b0bc26
Merge branch 'master' into feat/checkout_method
Fatpandac Sep 29, 2025
b5d9ce2
fix(test): correct logic causing test discard to fail
Fatpandac Sep 29, 2025
a682e79
fix: fixed by clippy
Fatpandac Sep 29, 2025
af2b6b9
fix: fixed by clippy
Fatpandac Sep 29, 2025
56f87bd
Merge branch 'master' into feat/checkout_method
extrawurst Oct 28, 2025
959f336
fix new deby
extrawurst Oct 28, 2025
fd5ff21
Merge branch 'master' into feat/checkout_method
extrawurst Oct 28, 2025
1ee38a2
Merge branch 'master' into feat/checkout_method
Fatpandac Oct 29, 2025
7c4bb1c
refactor: use BranchInfo instead of local in CheckoutOptionPopup
Fatpandac Nov 1, 2025
6bdece1
Merge branch 'master' into feat/checkout_method
Fatpandac Nov 1, 2025
4932690
refactor: move checkout_option_to_string into CheckoutOptions::to_str…
Fatpandac Nov 1, 2025
8816f3d
refactor: move CheckoutOptions change logic into next/previous methods
Fatpandac Nov 1, 2025
0a3706d
chore: fix by clippy
Fatpandac Nov 1, 2025
61f0019
chore: format
Fatpandac Nov 1, 2025
07cf88b
fix: remove CheckoutOptions::KeepLocalChanges
Fatpandac Nov 1, 2025
0db55e9
chore: format
Fatpandac Nov 2, 2025
6779391
fix: using the branch returned by let Some(branch)
Fatpandac Nov 3, 2025
9b12be2
fix: change CheckoutOptions enum
Fatpandac Nov 3, 2025
2280f8d
Merge branch 'master' into feat/checkout_method
Fatpandac Nov 12, 2025
13bdaa0
chore: format
Fatpandac Nov 12, 2025
8eeb90c
Merge branch 'master' into feat/checkout_method
Fatpandac Nov 28, 2025
cac6c5f
Merge branch 'master' into feat/checkout_method
extrawurst Nov 28, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* increase MSRV from 1.81 to 1.82 [[@cruessler](https://github.com/cruessler)]

### Added
* support choosing checkout branch method when status is not empty [[@fatpandac](https://github.com/fatpandac)] ([#2404](https://github.com/extrawurst/gitui/issues/2404))
* Support pre-push hook [[@xlai89](https://github.com/xlai89)] ([#1933](https://github.com/extrawurst/gitui/issues/1933))
* Message tab supports pageUp and pageDown [[@xlai89](https://github.com/xlai89)] ([#2623](https://github.com/extrawurst/gitui/issues/2623))
* Files and status tab support pageUp and pageDown [[@fatpandac](https://github.com/fatpandac)] ([#1951](https://github.com/extrawurst/gitui/issues/1951))
Expand Down
5 changes: 5 additions & 0 deletions asyncgit/src/sync/branch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ impl BranchInfo {

None
}

/// returns whether branch is local
pub const fn is_local(&self) -> bool {
matches!(self.details, BranchDetails::Local(_))
}
}

///
Expand Down
46 changes: 46 additions & 0 deletions asyncgit/src/sync/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,49 @@ pub fn get_status(

Ok(res)
}

/// discard all changes in the working directory
pub fn discard_status(repo_path: &RepoPath) -> Result<bool> {
let repo = repo(repo_path)?;
let commit = repo.head()?.peel_to_commit()?;

repo.reset(commit.as_object(), git2::ResetType::Hard, None)?;

Ok(true)
}

#[cfg(test)]
mod tests {
use super::*;
use crate::sync::{commit, stage_add_file, tests::repo_init};
use std::{fs::File, io::Write, path::Path};

#[test]
fn test_discard_status() {
let file_path = Path::new("README.md");
let (_td, repo) = repo_init().unwrap();
let root = repo.path().parent().unwrap();
let repo_path: &RepoPath =
&root.as_os_str().to_str().unwrap().into();

let mut file = File::create(root.join(file_path)).unwrap();

// initial commit
stage_add_file(repo_path, file_path).unwrap();
commit(repo_path, "commit msg").unwrap();

writeln!(file, "Test for discard_status").unwrap();

let statuses =
get_status(repo_path, StatusType::WorkingDir, None)
.unwrap();
assert_eq!(statuses.len(), 1);

discard_status(repo_path).unwrap();

let statuses =
get_status(repo_path, StatusType::WorkingDir, None)
.unwrap();
assert_eq!(statuses.len(), 0);
}
}
27 changes: 17 additions & 10 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ use crate::{
options::{Options, SharedOptions},
popup_stack::PopupStack,
popups::{
AppOption, BlameFilePopup, BranchListPopup, CommitPopup,
CompareCommitsPopup, ConfirmPopup, CreateBranchPopup,
CreateRemotePopup, ExternalEditorPopup, FetchPopup,
FileRevlogPopup, FuzzyFindPopup, HelpPopup,
InspectCommitPopup, LogSearchPopupPopup, MsgPopup,
OptionsPopup, PullPopup, PushPopup, PushTagsPopup,
RemoteListPopup, RenameBranchPopup, RenameRemotePopup,
ResetPopup, RevisionFilesPopup, StashMsgPopup,
SubmodulesListPopup, TagCommitPopup, TagListPopup,
UpdateRemoteUrlPopup,
AppOption, BlameFilePopup, BranchListPopup,
CheckoutOptionPopup, CommitPopup, CompareCommitsPopup,
ConfirmPopup, CreateBranchPopup, CreateRemotePopup,
ExternalEditorPopup, FetchPopup, FileRevlogPopup,
FuzzyFindPopup, HelpPopup, InspectCommitPopup,
LogSearchPopupPopup, MsgPopup, OptionsPopup, PullPopup,
PushPopup, PushTagsPopup, RemoteListPopup, RenameBranchPopup,
RenameRemotePopup, ResetPopup, RevisionFilesPopup,
StashMsgPopup, SubmodulesListPopup, TagCommitPopup,
TagListPopup, UpdateRemoteUrlPopup,
},
queue::{
Action, AppTabs, InternalEvent, NeedsUpdate, Queue,
Expand Down Expand Up @@ -98,6 +98,7 @@ pub struct App {
submodule_popup: SubmodulesListPopup,
tags_popup: TagListPopup,
reset_popup: ResetPopup,
checkout_option_popup: CheckoutOptionPopup,
cmdbar: RefCell<CommandBar>,
tab: usize,
revlog: Revlog,
Expand Down Expand Up @@ -218,6 +219,7 @@ impl App {
stashing_tab: Stashing::new(&env),
stashlist_tab: StashList::new(&env),
files_tab: FilesTab::new(&env),
checkout_option_popup: CheckoutOptionPopup::new(&env),
tab: 0,
queue: env.queue,
theme: env.theme,
Expand Down Expand Up @@ -493,6 +495,7 @@ impl App {
fetch_popup,
tag_commit_popup,
reset_popup,
checkout_option_popup,
create_branch_popup,
create_remote_popup,
rename_remote_popup,
Expand Down Expand Up @@ -533,6 +536,7 @@ impl App {
submodule_popup,
tags_popup,
reset_popup,
checkout_option_popup,
create_branch_popup,
rename_branch_popup,
revision_files_popup,
Expand Down Expand Up @@ -905,6 +909,9 @@ impl App {
InternalEvent::CommitSearch(options) => {
self.revlog.search(options);
}
InternalEvent::CheckoutOption(branch) => {
self.checkout_option_popup.open(branch)?;
}
}

Ok(flags)
Expand Down
46 changes: 30 additions & 16 deletions src/popups/branchlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ use asyncgit::{
checkout_remote_branch, BranchDetails, LocalBranch,
RemoteBranch,
},
checkout_branch, get_branches_info, BranchInfo, BranchType,
CommitId, RepoPathRef, RepoState,
checkout_branch, get_branches_info,
status::StatusType,
BranchInfo, BranchType, CommitId, RepoPathRef, RepoState,
},
AsyncGitNotification,
};
Expand Down Expand Up @@ -582,23 +583,36 @@ impl BranchListPopup {
anyhow::bail!("no valid branch selected");
}

if self.local {
checkout_branch(
&self.repo.borrow(),
&self.branches[self.selection as usize].name,
)?;
self.hide();
let status = sync::status::get_status(
&self.repo.borrow(),
StatusType::WorkingDir,
None,
)
.expect("Could not get status");

let selected_branch = &self.branches[self.selection as usize];
if status.is_empty() {
if self.local {
checkout_branch(
&self.repo.borrow(),
&selected_branch.name,
)?;
self.hide();
} else {
checkout_remote_branch(
&self.repo.borrow(),
selected_branch,
)?;
self.local = true;
self.update_branches()?;
}
self.queue.push(InternalEvent::Update(NeedsUpdate::ALL));
} else {
checkout_remote_branch(
&self.repo.borrow(),
&self.branches[self.selection as usize],
)?;
self.local = true;
self.update_branches()?;
self.queue.push(InternalEvent::CheckoutOption(
selected_branch.clone(),
));
}

self.queue.push(InternalEvent::Update(NeedsUpdate::ALL));

Ok(())
}

Expand Down
Loading
Loading