Skip to content

Commit 76905bb

Browse files
committed
feat(git): show hook progress for push and checkout operations
Stream hook output for pushes, tag changes, branch switches, and checkout branch creation. Allow pre-push failures to retry without hooks and show post-checkout failures as warnings after the checkout completes.
1 parent c43da15 commit 76905bb

15 files changed

Lines changed: 1031 additions & 178 deletions

File tree

src-tauri/src/commands/branches.rs

Lines changed: 85 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::AppState;
22
use crate::git::types::{
3-
AddRemoteRequest, BranchInfo, BranchRequest, CreateBranchRequest, CreateTagRequest,
4-
DeleteBranchRequest, DeleteRemoteBranchRequest, DeleteRemoteTagRequest, DeleteTagRequest,
5-
OperationResult, PruneRemoteRequest, PushTagRequest, RemoteInfo, RemoveRemoteRequest,
6-
RenameBranchRequest, RenameRemoteRequest, RepoRequest, SetBranchUpstreamRequest,
7-
SetRemoteUrlRequest, TagInfo,
3+
AddRemoteRequest, BranchInfo, BranchRequest, CommitProgressEvent, CreateBranchRequest,
4+
CreateTagRequest, DeleteBranchRequest, DeleteRemoteBranchRequest, DeleteRemoteTagRequest,
5+
DeleteTagRequest, GitHookAttemptResult, OperationResult, PruneRemoteRequest, PushTagRequest,
6+
RemoteInfo, RemoveRemoteRequest, RenameBranchRequest, RenameRemoteRequest, RepoRequest,
7+
SetBranchUpstreamRequest, SetRemoteUrlRequest, TagInfo,
88
};
9+
use std::sync::Arc;
910
use tauri::Manager;
1011

1112
#[tauri::command]
@@ -22,14 +23,22 @@ pub async fn get_branches(
2223
}
2324

2425
#[tauri::command]
25-
pub fn switch_branch(
26+
pub async fn switch_branch(
2627
request: BranchRequest,
27-
state: tauri::State<'_, AppState>,
28-
) -> Result<OperationResult, String> {
29-
state
30-
.git_service
31-
.switch_branch(request)
32-
.map_err(|error| error.to_string())
28+
on_progress: tauri::ipc::Channel<CommitProgressEvent>,
29+
app: tauri::AppHandle,
30+
) -> Result<GitHookAttemptResult<OperationResult>, String> {
31+
tauri::async_runtime::spawn_blocking(move || {
32+
app.state::<AppState>()
33+
.git_service
34+
.switch_branch_with_progress(
35+
request,
36+
Arc::new(move |event| drop(on_progress.send(event))),
37+
)
38+
})
39+
.await
40+
.map_err(|error| error.to_string())?
41+
.map_err(|error| error.to_string())
3342
}
3443

3544
#[tauri::command]
@@ -44,14 +53,22 @@ pub fn set_branch_upstream(
4453
}
4554

4655
#[tauri::command]
47-
pub fn create_branch(
56+
pub async fn create_branch(
4857
request: CreateBranchRequest,
49-
state: tauri::State<'_, AppState>,
50-
) -> Result<OperationResult, String> {
51-
state
52-
.git_service
53-
.create_branch(request)
54-
.map_err(|error| error.to_string())
58+
on_progress: tauri::ipc::Channel<CommitProgressEvent>,
59+
app: tauri::AppHandle,
60+
) -> Result<GitHookAttemptResult<OperationResult>, String> {
61+
tauri::async_runtime::spawn_blocking(move || {
62+
app.state::<AppState>()
63+
.git_service
64+
.create_branch_with_progress(
65+
request,
66+
Arc::new(move |event| drop(on_progress.send(event))),
67+
)
68+
})
69+
.await
70+
.map_err(|error| error.to_string())?
71+
.map_err(|error| error.to_string())
5572
}
5673

5774
#[tauri::command]
@@ -109,36 +126,64 @@ pub fn create_tag(
109126
}
110127

111128
#[tauri::command]
112-
pub fn push_tag(
129+
pub async fn push_tag(
113130
request: PushTagRequest,
114-
state: tauri::State<'_, AppState>,
115-
) -> Result<OperationResult, String> {
116-
state
117-
.git_service
118-
.push_tag(request)
119-
.map_err(|e| e.to_string())
131+
skip_hooks: bool,
132+
on_progress: tauri::ipc::Channel<CommitProgressEvent>,
133+
app: tauri::AppHandle,
134+
) -> Result<GitHookAttemptResult<OperationResult>, String> {
135+
tauri::async_runtime::spawn_blocking(move || {
136+
app.state::<AppState>().git_service.push_tag_with_progress(
137+
request,
138+
skip_hooks,
139+
Arc::new(move |event| drop(on_progress.send(event))),
140+
)
141+
})
142+
.await
143+
.map_err(|error| error.to_string())?
144+
.map_err(|error| error.to_string())
120145
}
121146

122147
#[tauri::command]
123-
pub fn delete_remote_tag(
148+
pub async fn delete_remote_tag(
124149
request: DeleteRemoteTagRequest,
125-
state: tauri::State<'_, AppState>,
126-
) -> Result<OperationResult, String> {
127-
state
128-
.git_service
129-
.delete_remote_tag(request)
130-
.map_err(|error| error.to_string())
150+
skip_hooks: bool,
151+
on_progress: tauri::ipc::Channel<CommitProgressEvent>,
152+
app: tauri::AppHandle,
153+
) -> Result<GitHookAttemptResult<OperationResult>, String> {
154+
tauri::async_runtime::spawn_blocking(move || {
155+
app.state::<AppState>()
156+
.git_service
157+
.delete_remote_tag_with_progress(
158+
request,
159+
skip_hooks,
160+
Arc::new(move |event| drop(on_progress.send(event))),
161+
)
162+
})
163+
.await
164+
.map_err(|error| error.to_string())?
165+
.map_err(|error| error.to_string())
131166
}
132167

133168
#[tauri::command]
134-
pub fn delete_remote_branch(
169+
pub async fn delete_remote_branch(
135170
request: DeleteRemoteBranchRequest,
136-
state: tauri::State<'_, AppState>,
137-
) -> Result<OperationResult, String> {
138-
state
139-
.git_service
140-
.delete_remote_branch(request)
141-
.map_err(|error| error.to_string())
171+
skip_hooks: bool,
172+
on_progress: tauri::ipc::Channel<CommitProgressEvent>,
173+
app: tauri::AppHandle,
174+
) -> Result<GitHookAttemptResult<OperationResult>, String> {
175+
tauri::async_runtime::spawn_blocking(move || {
176+
app.state::<AppState>()
177+
.git_service
178+
.delete_remote_branch_with_progress(
179+
request,
180+
skip_hooks,
181+
Arc::new(move |event| drop(on_progress.send(event))),
182+
)
183+
})
184+
.await
185+
.map_err(|error| error.to_string())?
186+
.map_err(|error| error.to_string())
142187
}
143188

144189
#[tauri::command]

src-tauri/src/commands/repo.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use crate::git::types::{
22
CloneRequest, CommitAttemptResult, CommitDetails, CommitDetailsRequest, CommitFileItem,
33
CommitFilesRequest, CommitMarkers, CommitMessageRecovery, CommitProgressEvent, CommitRequest,
44
DiffRequest, ExportCommitPatchRequest, ExportPatchRequest, ExternalDiffRequest, FetchRequest,
5-
FileDiff, FileRequest, GitIdentity, HunkStageRequest, IdentityRequest, ImportPatchRequest,
6-
LocalCopyDestinationMode, LocalCopyError, LocalCopyMode, LocalCopyProgress,
5+
FileDiff, FileRequest, GitHookAttemptResult, GitIdentity, HunkStageRequest, IdentityRequest,
6+
ImportPatchRequest, LocalCopyDestinationMode, LocalCopyError, LocalCopyMode, LocalCopyProgress,
77
LocalCopyProgressPhase, LocalCopyRequest, LocalCopyResult, LocalCopyWarning, NumstatRequest,
88
NumstatResult, OperationResult, PullAnalysis, PullStrategyRequest, PushRequest, PushResult,
99
RepoRequest, RepoStatus, SetIdentityRequest, SshAllowedSignerStatus, StageFilesRequest,
@@ -2850,10 +2850,18 @@ pub fn add_ssh_signing_key_to_allowed_signers(
28502850
#[tauri::command]
28512851
pub async fn push_changes(
28522852
request: PushRequest,
2853+
skip_hooks: bool,
2854+
on_progress: tauri::ipc::Channel<CommitProgressEvent>,
28532855
app: tauri::AppHandle,
2854-
) -> Result<PushResult, String> {
2856+
) -> Result<GitHookAttemptResult<PushResult>, String> {
28552857
tauri::async_runtime::spawn_blocking(move || {
2856-
app.state::<AppState>().git_service.push_changes(request)
2858+
app.state::<AppState>()
2859+
.git_service
2860+
.push_changes_with_progress(
2861+
request,
2862+
skip_hooks,
2863+
Arc::new(move |event| drop(on_progress.send(event))),
2864+
)
28572865
})
28582866
.await
28592867
.map_err(|e| e.to_string())?

0 commit comments

Comments
 (0)