mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-13 08:13:00 +02:00
Git Improvements (#382)
This commit is contained in:
+68
-14
@@ -4,6 +4,7 @@ import { createFastMutation } from '@yaakapp/app/hooks/useFastMutation';
|
||||
import { queryClient } from '@yaakapp/app/lib/queryClient';
|
||||
import { useMemo } from 'react';
|
||||
import { BranchDeleteResult, CloneResult, GitCommit, GitRemote, GitStatusSummary, PullResult, PushResult } from './bindings/gen_git';
|
||||
import { showToast } from '@yaakapp/app/lib/toast';
|
||||
|
||||
export * from './bindings/gen_git';
|
||||
export * from './bindings/gen_models';
|
||||
@@ -13,11 +14,20 @@ export interface GitCredentials {
|
||||
password: string;
|
||||
}
|
||||
|
||||
export type DivergedStrategy = 'force_reset' | 'merge' | 'cancel';
|
||||
|
||||
export type UncommittedChangesStrategy = 'reset' | 'cancel';
|
||||
|
||||
export interface GitCallbacks {
|
||||
addRemote: () => Promise<GitRemote | null>;
|
||||
promptCredentials: (
|
||||
result: Extract<PushResult, { type: 'needs_credentials' }>,
|
||||
) => Promise<GitCredentials | null>;
|
||||
promptDiverged: (
|
||||
result: Extract<PullResult, { type: 'diverged' }>,
|
||||
) => Promise<DivergedStrategy>;
|
||||
promptUncommittedChanges: () => Promise<UncommittedChangesStrategy>;
|
||||
forceSync: () => Promise<void>;
|
||||
}
|
||||
|
||||
const onSuccess = () => queryClient.invalidateQueries({ queryKey: ['git'] });
|
||||
@@ -69,6 +79,15 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
||||
return invoke<PushResult>('cmd_git_push', { dir });
|
||||
};
|
||||
|
||||
const handleError = (err: unknown) => {
|
||||
showToast({
|
||||
id: `${err}`,
|
||||
message: `${err}`,
|
||||
color: 'danger',
|
||||
timeout: 5000,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: createFastMutation<void, string, void>({
|
||||
mutationKey: ['git', 'init'],
|
||||
@@ -133,10 +152,9 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
||||
},
|
||||
onSuccess,
|
||||
}),
|
||||
fetchAll: createFastMutation<string, string, void>({
|
||||
mutationKey: ['git', 'checkout', dir],
|
||||
fetchAll: createFastMutation<void, string, void>({
|
||||
mutationKey: ['git', 'fetch_all', dir],
|
||||
mutationFn: () => invoke('cmd_git_fetch_all', { dir }),
|
||||
onSuccess,
|
||||
}),
|
||||
push: createFastMutation<PushResult, string, void>({
|
||||
mutationKey: ['git', 'push', dir],
|
||||
@@ -147,20 +165,51 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
||||
mutationKey: ['git', 'pull', dir],
|
||||
async mutationFn() {
|
||||
const result = await invoke<PullResult>('cmd_git_pull', { dir });
|
||||
if (result.type !== 'needs_credentials') return result;
|
||||
|
||||
// Needs credentials, prompt for them
|
||||
const creds = await callbacks.promptCredentials(result);
|
||||
if (creds == null) throw new Error('Canceled');
|
||||
if (result.type === 'needs_credentials') {
|
||||
const creds = await callbacks.promptCredentials(result);
|
||||
if (creds == null) throw new Error('Canceled');
|
||||
|
||||
await invoke('cmd_git_add_credential', {
|
||||
remoteUrl: result.url,
|
||||
username: creds.username,
|
||||
password: creds.password,
|
||||
});
|
||||
await invoke('cmd_git_add_credential', {
|
||||
remoteUrl: result.url,
|
||||
username: creds.username,
|
||||
password: creds.password,
|
||||
});
|
||||
|
||||
// Pull again
|
||||
return invoke<PullResult>('cmd_git_pull', { dir });
|
||||
// Pull again after credentials
|
||||
return invoke<PullResult>('cmd_git_pull', { dir });
|
||||
}
|
||||
|
||||
if (result.type === 'uncommitted_changes') {
|
||||
callbacks.promptUncommittedChanges().then(async (strategy) => {
|
||||
if (strategy === 'cancel') return;
|
||||
|
||||
await invoke('cmd_git_reset_changes', { dir });
|
||||
return invoke<PullResult>('cmd_git_pull', { dir });
|
||||
}).then(async () => { onSuccess(); await callbacks.forceSync(); }, handleError);
|
||||
}
|
||||
|
||||
if (result.type === 'diverged') {
|
||||
callbacks.promptDiverged(result).then((strategy) => {
|
||||
if (strategy === 'cancel') return;
|
||||
|
||||
if (strategy === 'force_reset') {
|
||||
return invoke<PullResult>('cmd_git_pull_force_reset', {
|
||||
dir,
|
||||
remote: result.remote,
|
||||
branch: result.branch,
|
||||
});
|
||||
}
|
||||
|
||||
return invoke<PullResult>('cmd_git_pull_merge', {
|
||||
dir,
|
||||
remote: result.remote,
|
||||
branch: result.branch,
|
||||
});
|
||||
}).then(async () => { onSuccess(); await callbacks.forceSync(); }, handleError);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
onSuccess,
|
||||
}),
|
||||
@@ -169,6 +218,11 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
||||
mutationFn: (args) => invoke('cmd_git_unstage', { dir, ...args }),
|
||||
onSuccess,
|
||||
}),
|
||||
resetChanges: createFastMutation<void, string, void>({
|
||||
mutationKey: ['git', 'reset-changes', dir],
|
||||
mutationFn: () => invoke('cmd_git_reset_changes', { dir }),
|
||||
onSuccess,
|
||||
}),
|
||||
} as const;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user