feat(git): sync with a remote — fetch, pull and push
Add remote sync to the Git panel: set/edit an origin URL, then fetch, pull (fast-forward) and push, with live ahead/behind counts against the remote-tracking branch. Backend: - git_ops: remote_status (git2 ahead/behind + upstream), set_remote, and fetch/pull/push that shell out to the system git CLI so they reuse the user's existing credentials (SSH agent, keychain / credential helpers) instead of reimplementing libgit2 credential callbacks. Pull is --ff-only to avoid leaving a conflicted tree from the GUI; push uses --set-upstream. - New commands git_remote_status/set_remote/fetch/pull/push, registered. - Test: push to a bare local remote, then assert upstream + ahead/behind. Frontend: - RemoteStatus type, api wrappers, store state (remote, syncing) with refreshRemote wired into refreshGit; pull reloads diagrams + open buffer. - GitPanel remote section: URL, ahead/behind badges, Fetch/Pull/Push, and a set-remote dialog. cargo test (7 passing incl. roundtrip), svelte-check and build all green.
This commit is contained in:
@@ -6,7 +6,7 @@ use tauri::State;
|
||||
use crate::db::{self, ProjectRecord};
|
||||
use crate::diagram::{self, DiagramInfo};
|
||||
use crate::error::{AppError, Result};
|
||||
use crate::git_ops::{self, BranchInfo, CommitInfo, FileStatus};
|
||||
use crate::git_ops::{self, BranchInfo, CommitInfo, FileStatus, RemoteStatus};
|
||||
use crate::project::{self, ProjectConfig};
|
||||
use crate::state::AppState;
|
||||
|
||||
@@ -176,6 +176,37 @@ pub fn git_checkout_branch(path: String, name: String) -> Result<()> {
|
||||
git_ops::checkout_branch(Path::new(&path), &name)
|
||||
}
|
||||
|
||||
// ---- Remote sync ----------------------------------------------------------
|
||||
|
||||
#[tauri::command]
|
||||
pub fn git_remote_status(path: String) -> Result<RemoteStatus> {
|
||||
git_ops::remote_status(Path::new(&path))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn git_set_remote(path: String, url: String) -> Result<()> {
|
||||
let url = url.trim();
|
||||
if url.is_empty() {
|
||||
return Err(AppError::other("remote URL cannot be empty"));
|
||||
}
|
||||
git_ops::set_remote(Path::new(&path), url)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn git_fetch(path: String) -> Result<String> {
|
||||
git_ops::fetch(Path::new(&path))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn git_pull(path: String) -> Result<String> {
|
||||
git_ops::pull(Path::new(&path))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn git_push(path: String) -> Result<String> {
|
||||
git_ops::push(Path::new(&path))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Export helpers & settings
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user