Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support choosing checkout branch method when status is not empty #2494

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 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
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added
* support choosing checkout branch method when status is not empty [[@extrawurst](https://github.com/extrawurst)] ([#2404](https://github.com/extrawurst/gitui/issues/2404))

## [0.27.0] - 2024-01-14

**new: manage remotes**
Expand Down
51 changes: 51 additions & 0 deletions asyncgit/src/sync/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,54 @@ 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 statuses = repo.statuses(None)?;

for status in statuses.iter() {
if status.status().is_wt_modified()
|| status.status().is_wt_new()
{
let oid = repo.head()?.target().unwrap();
let obj = repo.find_object(oid, None)?;

repo.checkout_tree(&obj, None)?;
repo.reset(&obj, git2::ResetType::Hard, None)?;
}
}

Ok(true)
}

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

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

File::create(root.join(file_path))
.unwrap()
.write_all(b"test\nfoo")
.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, is_local) => {
self.checkout_option_popup.open(branch, is_local)?;
}
};

Ok(flags)
Expand Down
47 changes: 31 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,37 @@ 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,
)
.unwrap();

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.local.clone(),
));
}

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

Ok(())
}

Expand Down
Loading