Skip to content

Commit 6baa843

Browse files
author
Stephan Dilly
committed
allow aborting merge
1 parent e662863 commit 6baa843

File tree

6 files changed

+89
-38
lines changed

6 files changed

+89
-38
lines changed

Diff for: asyncgit/src/sync/branch/merge_commit.rs

-31
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,6 @@ use crate::{
88
use git2::MergeOptions;
99
use scopetime::scope_time;
1010

11-
///
12-
pub fn merge_branch(repo_path: &str, branch: &str) -> Result<()> {
13-
scope_time!("merge_branch");
14-
15-
let repo = utils::repo(repo_path)?;
16-
17-
let branch = repo.find_branch(branch, BranchType::Local)?;
18-
19-
let id = branch.into_reference().peel_to_commit()?;
20-
21-
let annotated = repo.find_annotated_commit(id.id())?;
22-
23-
let (analysis, _) = repo.merge_analysis(&[&annotated])?;
24-
25-
//TODO: support merge on unborn
26-
if analysis.is_unborn() {
27-
return Err(Error::Generic("head is unborn".into()));
28-
}
29-
30-
let mut opt = MergeOptions::default();
31-
// opt.fail_on_conflict(true);
32-
33-
repo.merge(&[&annotated], Some(&mut opt), None)?;
34-
35-
// if repo.index()?.has_conflicts() {
36-
// return Err(Error::Generic("creates conflicts".into()));
37-
// }
38-
39-
Ok(())
40-
}
41-
4211
/// merge upstream using a merge commit without conflicts. fails if not possible without conflicts
4312
pub fn merge_upstream_commit(
4413
repo_path: &str,

Diff for: asyncgit/src/sync/merge.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use crate::{
2+
error::{Error, Result},
3+
sync::utils,
4+
};
5+
use git2::{BranchType, MergeOptions};
6+
use scopetime::scope_time;
7+
8+
///
9+
pub fn abort_merge(repo_path: &str) -> Result<()> {
10+
scope_time!("cleanup_state");
11+
12+
let repo = utils::repo(repo_path)?;
13+
14+
repo.cleanup_state()?;
15+
16+
Ok(())
17+
}
18+
19+
///
20+
pub fn merge_branch(repo_path: &str, branch: &str) -> Result<()> {
21+
scope_time!("merge_branch");
22+
23+
let repo = utils::repo(repo_path)?;
24+
25+
let branch = repo.find_branch(branch, BranchType::Local)?;
26+
27+
let id = branch.into_reference().peel_to_commit()?;
28+
29+
let annotated = repo.find_annotated_commit(id.id())?;
30+
31+
let (analysis, _) = repo.merge_analysis(&[&annotated])?;
32+
33+
//TODO: support merge on unborn
34+
if analysis.is_unborn() {
35+
return Err(Error::Generic("head is unborn".into()));
36+
}
37+
38+
let mut opt = MergeOptions::default();
39+
40+
repo.merge(&[&annotated], Some(&mut opt), None)?;
41+
42+
Ok(())
43+
}

Diff for: asyncgit/src/sync/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mod hooks;
1515
mod hunks;
1616
mod ignore;
1717
mod logwalker;
18+
mod merge;
1819
mod patches;
1920
pub mod remotes;
2021
mod reset;
@@ -29,8 +30,7 @@ pub use blame::{blame_file, BlameHunk, FileBlame};
2930
pub use branch::{
3031
branch_compare_upstream, checkout_branch, config_is_pull_rebase,
3132
create_branch, delete_branch, get_branch_remote,
32-
get_branches_info, merge_commit::merge_branch,
33-
merge_commit::merge_upstream_commit,
33+
get_branches_info, merge_commit::merge_upstream_commit,
3434
merge_ff::branch_merge_upstream_fastforward,
3535
merge_rebase::merge_upstream_rebase, rename::rename_branch,
3636
BranchCompare, BranchInfo,
@@ -50,6 +50,7 @@ pub use hooks::{
5050
pub use hunks::{reset_hunk, stage_hunk, unstage_hunk};
5151
pub use ignore::add_to_ignore;
5252
pub use logwalker::LogWalker;
53+
pub use merge::{abort_merge, merge_branch};
5354
pub use remotes::{
5455
get_default_remote, get_remotes, push::AsyncProgress,
5556
tags::PushTagsProgress,

Diff for: src/keys.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub struct KeyConfig {
7272
pub push: KeyEvent,
7373
pub force_push: KeyEvent,
7474
pub pull: KeyEvent,
75+
pub abort_merge: KeyEvent,
7576
}
7677

7778
#[rustfmt::skip]
@@ -122,14 +123,15 @@ impl Default for KeyConfig {
122123
log_tag_commit: KeyEvent { code: KeyCode::Char('t'), modifiers: KeyModifiers::empty()},
123124
commit_amend: KeyEvent { code: KeyCode::Char('a'), modifiers: KeyModifiers::CONTROL},
124125
copy: KeyEvent { code: KeyCode::Char('y'), modifiers: KeyModifiers::empty()},
125-
create_branch: KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::NONE},
126-
rename_branch: KeyEvent { code: KeyCode::Char('r'), modifiers: KeyModifiers::NONE},
127-
select_branch: KeyEvent { code: KeyCode::Char('b'), modifiers: KeyModifiers::NONE},
126+
create_branch: KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::empty()},
127+
rename_branch: KeyEvent { code: KeyCode::Char('r'), modifiers: KeyModifiers::empty()},
128+
select_branch: KeyEvent { code: KeyCode::Char('b'), modifiers: KeyModifiers::empty()},
128129
delete_branch: KeyEvent{code: KeyCode::Char('D'), modifiers: KeyModifiers::SHIFT},
129-
merge_branch: KeyEvent{code: KeyCode::Char('m'), modifiers: KeyModifiers::NONE},
130+
merge_branch: KeyEvent{code: KeyCode::Char('m'), modifiers: KeyModifiers::empty()},
130131
push: KeyEvent { code: KeyCode::Char('p'), modifiers: KeyModifiers::empty()},
131132
force_push: KeyEvent { code: KeyCode::Char('P'), modifiers: KeyModifiers::SHIFT},
132133
pull: KeyEvent { code: KeyCode::Char('f'), modifiers: KeyModifiers::empty()},
134+
abort_merge: KeyEvent { code: KeyCode::Char('M'), modifiers: KeyModifiers::SHIFT},
133135
}
134136
}
135137
}

Diff for: src/strings.rs

+10
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,16 @@ pub mod commands {
520520
CMD_GROUP_GENERAL,
521521
)
522522
}
523+
pub fn abort_merge(key_config: &SharedKeyConfig) -> CommandText {
524+
CommandText::new(
525+
format!(
526+
"Abort merge [{}]",
527+
key_config.get_hint(key_config.abort_merge),
528+
),
529+
"abort ongoing merge",
530+
CMD_GROUP_GENERAL,
531+
)
532+
}
523533
pub fn select_staging(
524534
key_config: &SharedKeyConfig,
525535
) -> CommandText {

Diff for: src/tabs/status.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
},
99
keys::SharedKeyConfig,
1010
queue::{Action, InternalEvent, Queue, ResetItem},
11-
strings,
11+
strings, try_or_popup,
1212
ui::style::SharedTheme,
1313
};
1414
use anyhow::Result;
@@ -465,6 +465,16 @@ impl Status {
465465
.as_ref()
466466
.map_or(true, |state| state.ahead > 0)
467467
}
468+
469+
fn can_abort_merge() -> bool {
470+
sync::repo_state(CWD).unwrap_or(RepoState::Clean)
471+
== RepoState::Merge
472+
}
473+
474+
fn abort_merge(&self) -> Result<()> {
475+
sync::abort_merge(CWD)?;
476+
Ok(())
477+
}
468478
}
469479

470480
impl Component for Status {
@@ -507,6 +517,12 @@ impl Component for Status {
507517
true,
508518
!focus_on_diff,
509519
));
520+
521+
out.push(CommandInfo::new(
522+
strings::commands::abort_merge(&self.key_config),
523+
true,
524+
Self::can_abort_merge() || force_all,
525+
));
510526
}
511527

512528
{
@@ -653,6 +669,16 @@ impl Component for Status {
653669
&& !self.is_focus_on_diff()
654670
{
655671
self.pull();
672+
Ok(EventState::Consumed)
673+
} else if k == self.key_config.abort_merge
674+
&& Self::can_abort_merge()
675+
{
676+
try_or_popup!(
677+
self,
678+
"abort merge error:",
679+
self.abort_merge()
680+
);
681+
656682
Ok(EventState::Consumed)
657683
} else {
658684
Ok(EventState::NotConsumed)

0 commit comments

Comments
 (0)