Skip to content

Commit 48701ee

Browse files
krlvischacon
authored andcommitted
BUTCLI: add commit marking
1 parent e424406 commit 48701ee

File tree

6 files changed

+90
-6
lines changed

6 files changed

+90
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/but-rules/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ anyhow = "1.0.99"
1414
itertools.workspace = true
1515
serde.workspace = true
1616
regex = "1.11.2"
17+
gix = { workspace = true }
1718
chrono = { version = "0.4.41", features = [] }
1819
serde_regex = "1.1.0"
1920
serde_json = "1.0.143"

crates/but-rules/src/handler.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use but_graph::VirtualBranchesTomlMetadata;
22
use but_hunk_assignment::{HunkAssignment, assign, assignments_to_requests};
33
use but_hunk_dependency::ui::HunkDependencies;
4-
use but_workspace::{StackId, StacksFilter, ui::StackEntry};
4+
use but_workspace::{DiffSpec, StackId, StacksFilter, commit_engine, ui::StackEntry};
55
use gitbutler_command_context::CommandContext;
66
use itertools::Itertools;
77
use std::str::FromStr;
@@ -26,6 +26,9 @@ pub fn process_workspace_rules(
2626
matches!(
2727
&r.action,
2828
super::Action::Explicit(super::Operation::Assign { .. })
29+
) || matches!(
30+
&r.action,
31+
super::Action::Explicit(super::Operation::Amend { .. })
2932
)
3033
})
3134
.collect_vec();
@@ -60,6 +63,10 @@ pub fn process_workspace_rules(
6063
handle_assign(ctx, assignments, dependencies.as_ref()).unwrap_or_default();
6164
}
6265
}
66+
super::Action::Explicit(super::Operation::Amend { commit_id }) => {
67+
let assignments = matching(assignments, rule.filters.clone());
68+
handle_amend(ctx, assignments, commit_id).unwrap_or_default();
69+
}
6370
_ => continue,
6471
};
6572
}
@@ -137,6 +144,32 @@ fn handle_assign(
137144
}
138145
}
139146

147+
fn handle_amend(
148+
ctx: &mut CommandContext,
149+
assignments: Vec<HunkAssignment>,
150+
commit_id: String,
151+
) -> anyhow::Result<()> {
152+
let changes: Vec<DiffSpec> = assignments.into_iter().map(|a| a.into()).collect();
153+
let project = ctx.project();
154+
let mut guard = project.exclusive_worktree_access();
155+
let repo = but_core::open_repo_for_merging(project.worktree_path())?;
156+
commit_engine::create_commit_and_update_refs_with_project(
157+
&repo,
158+
project,
159+
None,
160+
commit_engine::Destination::AmendCommit {
161+
commit_id: gix::ObjectId::from_str(&commit_id)?,
162+
// TODO: Expose this in the UI for 'edit message' functionality.
163+
new_message: None,
164+
},
165+
None,
166+
changes,
167+
ctx.app_settings().context_lines,
168+
guard.write_permission(),
169+
)?;
170+
Ok(())
171+
}
172+
140173
fn matching(wt_assignments: &[HunkAssignment], filters: Vec<Filter>) -> Vec<HunkAssignment> {
141174
if filters.is_empty() {
142175
return wt_assignments.to_vec();

crates/but-rules/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ impl WorkspaceRule {
4646
}
4747
}
4848

49+
pub fn target_commit_id(&self) -> Option<String> {
50+
if let Action::Explicit(Operation::Amend { commit_id }) = &self.action {
51+
Some(commit_id.clone())
52+
} else {
53+
None
54+
}
55+
}
56+
4957
pub fn id(&self) -> String {
5058
self.id.clone()
5159
}

crates/but/src/log/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ pub(crate) fn commit_graph(repo_path: &Path, json: bool, short: bool) -> anyhow:
100100
}
101101
}
102102
for commit in branch.commits.iter() {
103+
let marked =
104+
crate::mark::commit_marked(ctx, commit.id.to_string()).unwrap_or_default();
105+
let mark = if marked {
106+
Some("◀ Marked ▶".red().bold())
107+
} else {
108+
None
109+
};
103110
let state_str = match commit.state {
104111
but_workspace::ui::CommitState::LocalOnly => "{local}".normal(),
105112
but_workspace::ui::CommitState::LocalAndRemote(_) => "{pushed}".cyan(),
@@ -115,14 +122,15 @@ pub(crate) fn commit_graph(repo_path: &Path, json: bool, short: bool) -> anyhow:
115122
.format("%Y-%m-%d %H:%M:%S")
116123
.to_string();
117124
println!(
118-
"{}● {}{} {} {} {} {}",
125+
"{}● {}{} {} {} {} {} {}",
119126
"│ ".repeat(nesting),
120127
&commit.id.to_string()[..2].blue().underline(),
121128
&commit.id.to_string()[2..7].blue(),
122129
state_str,
123130
conflicted_str,
124131
commit.author.name,
125-
time_string.dimmed()
132+
time_string.dimmed(),
133+
mark.clone().unwrap_or_default()
126134
);
127135
println!(
128136
"{}│ {}",

crates/but/src/mark/mod.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,41 @@ pub(crate) fn handle(
2323
target_result
2424
));
2525
}
26+
// Hack - delete all other rules
27+
for rule in but_rules::list_rules(ctx)? {
28+
but_rules::delete_rule(ctx, &rule.id())?;
29+
}
2630
match target_result[0].clone() {
2731
crate::id::CliId::Branch { name } => mark_branch(ctx, name, delete),
28-
crate::id::CliId::Commit { oid } => mark_commit(oid, delete),
32+
crate::id::CliId::Commit { oid } => mark_commit(ctx, oid, delete),
2933
_ => bail!("Nope"),
3034
}
3135
}
3236

33-
fn mark_commit(_oid: gix::ObjectId, _delete: bool) -> anyhow::Result<()> {
34-
bail!("Not implemented yet");
37+
fn mark_commit(ctx: &mut CommandContext, oid: gix::ObjectId, delete: bool) -> anyhow::Result<()> {
38+
if delete {
39+
let rules = but_rules::list_rules(ctx)?;
40+
for rule in rules {
41+
if rule.target_commit_id() == Some(oid.to_string()) {
42+
but_rules::delete_rule(ctx, &rule.id())?;
43+
}
44+
}
45+
println!("Mark was removed");
46+
return Ok(());
47+
}
48+
let action = but_rules::Action::Explicit(Operation::Amend {
49+
commit_id: oid.to_string(),
50+
});
51+
let req = but_rules::CreateRuleRequest {
52+
trigger: but_rules::Trigger::FileSytemChange,
53+
filters: vec![but_rules::Filter::PathMatchesRegex(regex::Regex::new(
54+
".*",
55+
)?)],
56+
action,
57+
};
58+
but_rules::create_rule(ctx, req)?;
59+
println!("Changes will be amended into commit → {}", &oid.to_string());
60+
Ok(())
3561
}
3662

3763
fn mark_branch(ctx: &mut CommandContext, branch_name: String, delete: bool) -> anyhow::Result<()> {
@@ -69,3 +95,10 @@ pub(crate) fn stack_marked(ctx: &mut CommandContext, stack_id: StackId) -> anyho
6995
.any(|r| r.target_stack_id() == Some(stack_id.to_string()));
7096
Ok(rules)
7197
}
98+
99+
pub(crate) fn commit_marked(ctx: &mut CommandContext, commit_id: String) -> anyhow::Result<bool> {
100+
let rules = but_rules::list_rules(ctx)?
101+
.iter()
102+
.any(|r| r.target_commit_id() == Some(commit_id.clone()));
103+
Ok(rules)
104+
}

0 commit comments

Comments
 (0)