Skip to main content

gitkraft_gui/features/commits/
commands.rs

1//! Async command helpers for commit operations.
2//!
3//! Each function spawns blocking work on a background thread via the
4//! `git_task!` macro, performs the git operation, and maps the result into a
5//! [`Message`].
6
7use std::path::PathBuf;
8
9use iced::Task;
10
11use crate::message::Message;
12
13/// Load just the file list (paths + statuses) for a commit — no line parsing.
14pub fn load_commit_file_list(path: PathBuf, oid: String) -> Task<Message> {
15    git_task!(
16        Message::CommitFileListLoaded,
17        (|| {
18            let repo = open_repo!(&path);
19            gitkraft_core::features::diff::get_commit_file_list(&repo, &oid)
20                .map_err(|e| e.to_string())
21        })()
22    )
23}
24
25/// Load the full diff for a single file in a commit.
26pub fn load_single_file_diff(path: PathBuf, oid: String, file_path: String) -> Task<Message> {
27    git_task!(
28        Message::SingleFileDiffLoaded,
29        (|| {
30            let repo = open_repo!(&path);
31            gitkraft_core::features::diff::get_single_file_diff(&repo, &oid, &file_path)
32                .map_err(|e| e.to_string())
33        })()
34    )
35}
36
37/// Create a new commit with the currently staged changes.
38/// Search commits by query string (searches message, author, SHA).
39pub fn search_commits(path: PathBuf, query: String) -> Task<Message> {
40    git_task!(
41        Message::SearchResultsLoaded,
42        (|| {
43            let repo = open_repo!(&path);
44            gitkraft_core::features::log::search_commits(&repo, &query, 100)
45                .map_err(|e| e.to_string())
46        })()
47    )
48}
49
50/// Load the file list of changes between a commit and the current working tree.
51pub fn search_diff_file_list(path: PathBuf, oid: String) -> Task<Message> {
52    git_task!(
53        Message::SearchDiffFilesLoaded,
54        (|| {
55            let repo = open_repo!(&path);
56            gitkraft_core::features::diff::file_list_commit_vs_workdir(&repo, &oid)
57                .map_err(|e| e.to_string())
58        })()
59    )
60}
61
62/// Diff a single file from a specific commit against the current working tree (for search overlay).
63pub fn search_diff_file(path: PathBuf, oid: String, file_path: String) -> Task<Message> {
64    git_task!(
65        Message::SearchFileDiffLoaded,
66        (|| {
67            let repo = open_repo!(&path);
68            gitkraft_core::features::diff::diff_file_commit_vs_workdir(&repo, &oid, &file_path)
69                .map_err(|e| e.to_string())
70        })()
71    )
72}
73
74/// Diff multiple files from a specific commit against the current working tree.
75pub fn search_diff_multi_files(
76    path: PathBuf,
77    oid: String,
78    file_paths: Vec<String>,
79) -> Task<Message> {
80    git_task!(
81        Message::SearchMultiDiffLoaded,
82        (|| {
83            let repo = open_repo!(&path);
84            let mut diffs = Vec::with_capacity(file_paths.len());
85            for fp in &file_paths {
86                match gitkraft_core::features::diff::diff_file_commit_vs_workdir(&repo, &oid, fp) {
87                    Ok(diff) => diffs.push(diff),
88                    Err(e) => {
89                        return Err(format!("{fp}: {e}"));
90                    }
91                }
92            }
93            Ok(diffs)
94        })()
95    )
96}
97
98/// Diff a file from a specific commit against the current working tree.
99pub fn diff_file_with_working_tree(path: PathBuf, oid: String, file_path: String) -> Task<Message> {
100    git_task!(
101        Message::DiffWithWorkingTreeLoaded,
102        (|| {
103            let repo = open_repo!(&path);
104            gitkraft_core::features::diff::diff_file_commit_vs_workdir(&repo, &oid, &file_path)
105                .map_err(|e| e.to_string())
106        })()
107    )
108}
109
110pub fn create_commit(path: PathBuf, message: String) -> Task<Message> {
111    git_task!(
112        Message::CommitCreated,
113        (|| {
114            let repo = open_repo!(&path);
115            gitkraft_core::features::commits::create_commit(&repo, &message)
116                .map(|_| ())
117                .map_err(|e| e.to_string())
118        })()
119    )
120}