Skip to content

Commit a3430c8

Browse files
committed
BUTCLI: add commit marking
1 parent 0021f34 commit a3430c8

File tree

6 files changed

+85
-6
lines changed

6 files changed

+85
-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.98"
1414
itertools.workspace = true
1515
serde.workspace = true
1616
regex = "1.11.1"
17+
gix = { workspace = true }
1718
chrono = { version = "0.4.41", features = [] }
1819
serde_regex = "1.1.0"
1920
serde_json = "1.0.142"

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
@@ -92,6 +92,13 @@ pub(crate) fn commit_graph(repo_path: &Path, _json: bool) -> anyhow::Result<()>
9292
}
9393
}
9494
for commit in branch.commits.iter() {
95+
let marked =
96+
crate::mark::commit_marked(ctx, commit.id.to_string()).unwrap_or_default();
97+
let mark = if marked {
98+
Some("◀ Marked ▶".red().bold())
99+
} else {
100+
None
101+
};
95102
let state_str = match commit.state {
96103
but_workspace::ui::CommitState::LocalOnly => "{local}".normal(),
97104
but_workspace::ui::CommitState::LocalAndRemote(_) => "{pushed}".cyan(),
@@ -107,14 +114,15 @@ pub(crate) fn commit_graph(repo_path: &Path, _json: bool) -> anyhow::Result<()>
107114
.format("%Y-%m-%d %H:%M:%S")
108115
.to_string();
109116
println!(
110-
"{}● {}{} {} {} {} {}",
117+
"{}● {}{} {} {} {} {} {}",
111118
"│ ".repeat(nesting),
112119
&commit.id.to_string()[..2].blue().underline(),
113120
&commit.id.to_string()[2..7].blue(),
114121
state_str,
115122
conflicted_str,
116123
commit.author.name,
117-
time_string.dimmed()
124+
time_string.dimmed(),
125+
mark.clone().unwrap_or_default()
118126
);
119127
println!(
120128
"{}│ {}",

crates/but/src/mark/mod.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,34 @@ pub(crate) fn handle(
2525
}
2626
match target_result[0].clone() {
2727
crate::id::CliId::Branch { name } => mark_branch(ctx, name, delete),
28-
crate::id::CliId::Commit { oid } => mark_commit(oid, delete),
28+
crate::id::CliId::Commit { oid } => mark_commit(ctx, oid, delete),
2929
_ => bail!("Nope"),
3030
}
3131
}
3232

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

3758
fn mark_branch(ctx: &mut CommandContext, branch_name: String, delete: bool) -> anyhow::Result<()> {
@@ -69,3 +90,10 @@ pub(crate) fn stack_marked(ctx: &mut CommandContext, stack_id: StackId) -> anyho
6990
.any(|r| r.target_stack_id() == Some(stack_id.to_string()));
7091
Ok(rules)
7192
}
93+
94+
pub(crate) fn commit_marked(ctx: &mut CommandContext, commit_id: String) -> anyhow::Result<bool> {
95+
let rules = but_rules::list_rules(ctx)?
96+
.iter()
97+
.any(|r| r.target_commit_id() == Some(commit_id.clone()));
98+
Ok(rules)
99+
}

0 commit comments

Comments
 (0)