Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a292dfe
Revamped VCS trait
Jordonbc Jan 15, 2026
b60bcd4
Improved
Jordonbc Jan 15, 2026
ec3035e
Update openvcs.git.ovcsp
Jordonbc Jan 15, 2026
3b22e6d
Made backend call async
Jordonbc Jan 15, 2026
83688a0
Update client
Jordonbc Jan 22, 2026
a1709eb
Merge branch 'Dev' into Improved-Git
Jordonbc Feb 7, 2026
6f0abab
Update Cargo.lock
Jordonbc Feb 7, 2026
a3b7613
client: add untracked text diff fallback path
Jordonbc Feb 7, 2026
4bc7074
Improve development workflow
Jordonbc Feb 7, 2026
8626771
backend: update git plugin submodule for wasm dist path
Jordonbc Feb 7, 2026
6530a9f
backend: reuse workspace target for plugin dist
Jordonbc Feb 7, 2026
6d86bcc
backend: remove plugin target symlink workaround
Jordonbc Feb 7, 2026
c0a2ac9
Fix issues
Jordonbc Feb 7, 2026
003008e
Update Git
Jordonbc Feb 7, 2026
84b379c
Update .gitignore
Jordonbc Feb 7, 2026
198a3f1
Update Cargo.lock
Jordonbc Feb 7, 2026
4fa1936
frontend: reduce UI lag in diff and menus
Jordonbc Feb 7, 2026
5f0887a
Revert "frontend: reduce UI lag in diff and menus"
Jordonbc Feb 7, 2026
17762a7
Fix some performance issues with scrollbars
Jordonbc Feb 7, 2026
5e90a87
Improve scrollbar performance
Jordonbc Feb 7, 2026
d19f79b
Improved performance
Jordonbc Feb 7, 2026
70c9a16
Improve
Jordonbc Feb 7, 2026
c9917c5
Update scrollbars.ts
Jordonbc Feb 7, 2026
4f60fb4
Scroll bar issues
Jordonbc Feb 7, 2026
c8803cb
Update OfficialThemes
Jordonbc Feb 7, 2026
df20839
Update components.css
Jordonbc Feb 7, 2026
f56fc28
Update OfficialThemes
Jordonbc Feb 7, 2026
5264d03
Update scrollbars.ts
Jordonbc Feb 7, 2026
91b7faf
Implement new side bar for easier switching
Jordonbc Feb 7, 2026
43fd9c4
Improved drawer
Jordonbc Feb 7, 2026
d142a5b
Add more animations
Jordonbc Feb 7, 2026
4876c9c
frontend: add global animations performance toggle
Jordonbc Feb 7, 2026
bc46389
frontend: render git submodule status entries
Jordonbc Feb 7, 2026
d4fc697
backend: update git plugin submodule modal behavior
Jordonbc Feb 7, 2026
3d9170b
backend: update git plugin open-submodule behavior
Jordonbc Feb 7, 2026
fb50129
frontend: close all dialogs when repository changes
Jordonbc Feb 7, 2026
de7074d
backend: update git plugin modal loading feedback
Jordonbc Feb 7, 2026
3a67825
backend: update git plugin modal sizing
Jordonbc Feb 7, 2026
d8ec6ef
backend: update plugin dialog dimensions
Jordonbc Feb 7, 2026
6f5b601
backend: update plugin loading-only sizing change
Jordonbc Feb 7, 2026
18f0c50
backend: update plugin loading indicator sizing
Jordonbc Feb 7, 2026
f06e486
backend: update plugin centered loader layout
Jordonbc Feb 7, 2026
171e27d
backend: update submodule remove confirmation flow
Jordonbc Feb 7, 2026
a1ee7df
backend: update submodule remove confirmation dialog
Jordonbc Feb 7, 2026
3a2f9e1
backend: update add-submodule dialog flow
Jordonbc Feb 7, 2026
8afe697
backend: update Git plugin spacing tweak
Jordonbc Feb 7, 2026
56a4432
backend: update submodule modal overlap fix
Jordonbc Feb 7, 2026
011fc83
frontend: fix missing fetch popover symbol
Jordonbc Feb 7, 2026
b90ff45
Update Git
Jordonbc Feb 7, 2026
d15a412
Merge branch 'Dev' into Improved-Git
Jordonbc Feb 7, 2026
ae5830b
ci: checkout submodules in GitHub workflows
Jordonbc Feb 7, 2026
b56a6ee
backend: validate VCS backend workspace root
Jordonbc Feb 7, 2026
81a3b28
Merge branch 'Dev' into Improved-Git
Jordonbc Feb 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
submodules: recursive

- name: Initialize CodeQL
uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
submodules: recursive
# Dev CI doesn't need LFS assets; skipping saves bandwidth and disk.
lfs: false

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
with:
ref: ${{ env.TARGET_REF }}
fetch-depth: 0 # we need history and tags
submodules: recursive
lfs: false

- name: Fetch tags
Expand Down Expand Up @@ -99,6 +100,7 @@ jobs:
with:
ref: ${{ env.TARGET_REF }}
fetch-depth: 0
submodules: recursive
lfs: true

- name: Compute metadata (date, short SHA, compare, changelog)
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
with:
lfs: true
fetch-depth: 0
submodules: recursive

- name: Compute version tag
id: version
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ dist-ssr
/target
/Backend/icons/android
/Backend/icons/ios
/Core
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "Backend/built-in-plugins/Git"]
path = Backend/built-in-plugins/Git
url = git@github.com:Open-VCS/OpenVCS-Plugin-Git.git
[submodule "Backend/built-in-plugins/OfficialThemes"]
path = Backend/built-in-plugins/OfficialThemes
url = git@github.com:Open-VCS/OpenVCS-Plugin-Themes.git
15 changes: 15 additions & 0 deletions Backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ fn sanitize_semver_ident(s: &str) -> String {
}
}

fn ensure_generated_builtins_resource_dir(manifest_dir: &std::path::Path) {
// Keep `bundle.resources` valid for plain `cargo build` runs even before
// plugin bundles are generated.
let generated = manifest_dir.join("../target/openvcs/built-in-plugins");
if let Err(err) = fs::create_dir_all(&generated) {
panic!(
"failed to create generated built-in plugins resource dir {}: {}",
generated.display(),
err
);
}
}

fn main() {
// Base config path (in the Backend crate)
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
Expand Down Expand Up @@ -229,6 +242,8 @@ fn main() {
println!("cargo:rustc-env=OPENVCS_VERSION={}", version);
println!("cargo:rustc-env=OPENVCS_BUILD={}", build_id);

ensure_generated_builtins_resource_dir(&manifest_dir);

// Proceed with tauri build steps
tauri_build::build();
}
1 change: 1 addition & 0 deletions Backend/built-in-plugins/Git
Submodule Git added at 7da5eb
1 change: 1 addition & 0 deletions Backend/built-in-plugins/OfficialThemes
Submodule OfficialThemes added at 91a9fa
3 changes: 0 additions & 3 deletions Backend/built-in-plugins/openvcs.git.ovcsp

This file was deleted.

3 changes: 0 additions & 3 deletions Backend/built-in-plugins/openvcs.official-themes.ovcsp

This file was deleted.

48 changes: 19 additions & 29 deletions Backend/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use log::warn;
use openvcs_core::{backend_id, BackendId};
use openvcs_core::BackendId;
use std::sync::Arc;
use tauri::path::BaseDirectory;
use tauri::WindowEvent;
Expand All @@ -23,27 +23,21 @@ mod utilities;
mod validate;
mod workarounds;

pub const GIT_SYSTEM_ID: BackendId = backend_id!("git-system");

fn preferred_git_backend_id(cfg: &settings::AppConfig) -> Option<BackendId> {
let configured = cfg.git.backend.trim();
if !configured.is_empty() {
return Some(BackendId::from(configured.to_string()));
}

// No configured backend: pick a git backend from enabled plugins (if any exist).
let mut git_ids: Vec<String> = Vec::new();
if let Ok(plugin_bes) = crate::plugin_vcs_backends::list_plugin_vcs_backends() {
for p in plugin_bes {
let id = p.backend_id.as_ref();
if id.starts_with("git-") {
git_ids.push(id.to_string());
}
fn preferred_vcs_backend_id(_cfg: &settings::AppConfig) -> Option<BackendId> {
let desired = _cfg.general.default_backend.trim().to_string();
if !desired.is_empty() {
let desired = BackendId::from(desired);
if crate::plugin_vcs_backends::has_plugin_vcs_backend(&desired) {
return Some(desired);
}
}
git_ids.sort();
git_ids.dedup();
git_ids.into_iter().next().map(BackendId::from)

crate::plugin_vcs_backends::list_plugin_vcs_backends()
.ok()
.and_then(|mut backends| {
backends.sort_by(|a, b| a.backend_id.as_ref().cmp(b.backend_id.as_ref()));
backends.into_iter().next().map(|b| b.backend_id)
})
}

/// Attempt to reopen the most recent repository at startup if the
Expand All @@ -60,8 +54,8 @@ fn try_reopen_last_repo<R: tauri::Runtime>(app_handle: &tauri::AppHandle<R>) {

let recents = state.recents();
if let Some(path) = recents.into_iter().find(|p| p.exists()) {
let Some(backend) = preferred_git_backend_id(&app_config) else {
log::warn!("startup reopen: no git backend available");
let Some(backend) = preferred_vcs_backend_id(&app_config) else {
log::warn!("startup reopen: no VCS backend available");
return;
};

Expand Down Expand Up @@ -175,6 +169,8 @@ fn build_invoke_handler<R: tauri::Runtime>(
tauri_commands::add_repo,
tauri_commands::list_vcs_backends_cmd,
tauri_commands::set_vcs_backend_cmd,
tauri_commands::reopen_current_repo_cmd,
tauri_commands::call_vcs_backend_method,
tauri_commands::validate_git_url,
tauri_commands::validate_add_path,
tauri_commands::validate_clone_input,
Expand Down Expand Up @@ -224,15 +220,9 @@ fn build_invoke_handler<R: tauri::Runtime>(
tauri_commands::git_push,
tauri_commands::git_undo_since_push,
tauri_commands::git_undo_to_commit,
tauri_commands::git_lfs_fetch_all,
tauri_commands::git_lfs_pull,
tauri_commands::git_lfs_prune,
tauri_commands::git_lfs_track_paths,
tauri_commands::git_lfs_untrack_paths,
tauri_commands::git_lfs_is_tracked,
tauri_commands::git_lfs_tracked_paths,
tauri_commands::git_add_to_gitignore_paths,
tauri_commands::open_repo_file,
tauri_commands::read_repo_file_text,
tauri_commands::list_themes,
tauri_commands::load_theme,
tauri_commands::list_plugins,
Expand Down
4 changes: 4 additions & 0 deletions Backend/src/plugin_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ pub fn built_in_plugin_dirs() -> Vec<PathBuf> {
// in a `resources` subdirectory or directly alongside the exe.
candidates.push(dir.join("resources").join(BUILT_IN_PLUGINS_DIR_NAME));
candidates.push(dir.join(BUILT_IN_PLUGINS_DIR_NAME));
// Dev builds can generate built-in bundles under `target/openvcs/`.
if let Some(target_dir) = dir.parent() {
candidates.push(target_dir.join("openvcs").join(BUILT_IN_PLUGINS_DIR_NAME));
}
#[cfg(target_os = "macos")]
if let Some(parent) = dir.parent() {
candidates.push(parent.join("Resources").join(BUILT_IN_PLUGINS_DIR_NAME));
Expand Down
11 changes: 10 additions & 1 deletion Backend/src/plugin_runtime/vcs_proxy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::plugin_bundles::ApprovalState;
use crate::plugin_runtime::stdio_rpc::{RpcConfig, RpcError, SpawnConfig, StdioRpcProcess};
use crate::settings::AppConfig;
use openvcs_core::models::{
Capabilities, ConflictDetails, ConflictSide, FetchOptions, LogQuery, StashItem, StatusPayload,
StatusSummary, VcsEvent,
Expand All @@ -26,6 +27,11 @@ impl PluginVcsProxy {
repo_path: &Path,
) -> Result<Arc<dyn Vcs>, VcsError> {
let workdir = repo_path.to_path_buf();
let cfg = AppConfig::load_or_default();
let cfg = serde_json::to_value(cfg).map_err(|e| VcsError::Backend {
backend: backend_id.clone(),
msg: format!("serialize config: {e}"),
})?;
let spawn = SpawnConfig {
plugin_id,
component_label: format!("vcs-backend-{}", backend_id.as_ref()),
Expand All @@ -42,7 +48,10 @@ impl PluginVcsProxy {
rpc,
};
p.rpc
.call("open", json!({ "path": path_to_utf8(repo_path)? }))
.call(
"open",
json!({ "path": path_to_utf8(repo_path)?, "config": cfg }),
)
.map_err(map_rpc_err)?;
Ok(Arc::new(p))
}
Expand Down
23 changes: 13 additions & 10 deletions Backend/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::{fs, io};

fn default_true() -> bool {
true
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppConfig {
pub schema_version: u32,
Expand Down Expand Up @@ -61,7 +65,7 @@ pub struct General {
#[serde(default)]
pub language: Language,
#[serde(default)]
pub default_backend: DefaultBackend,
pub default_backend: String,
#[serde(default)]
pub update_channel: UpdateChannel,
#[serde(default)]
Expand All @@ -79,7 +83,7 @@ impl Default for General {
theme: Theme::System,
theme_pack: default_theme_pack(),
language: Language::System,
default_backend: DefaultBackend::Git,
default_backend: "git".into(),
update_channel: UpdateChannel::Stable,
reopen_last_repos: true,
checks_on_launch: true,
Expand Down Expand Up @@ -233,12 +237,15 @@ pub struct Performance {
pub progressive_render: bool,
#[serde(default)]
pub gpu_accel: bool,
#[serde(default = "default_true")]
pub animations: bool,
}
impl Default for Performance {
fn default() -> Self {
Self {
progressive_render: true,
gpu_accel: true,
animations: true,
}
}
}
Expand Down Expand Up @@ -398,14 +405,6 @@ pub enum GitSshBinary {
Custom,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
#[derive(Default)]
pub enum DefaultBackend {
#[default]
Git,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
#[derive(Default)]
Expand Down Expand Up @@ -609,6 +608,10 @@ impl AppConfig {
if self.general.theme_pack.trim().is_empty() {
self.general.theme_pack = default_theme_pack();
}
self.general.default_backend = self.general.default_backend.trim().to_string();
if self.general.default_backend.is_empty() {
self.general.default_backend = "git".into();
}

// Git
self.git.backend = self.git.backend.trim().to_string();
Expand Down
32 changes: 21 additions & 11 deletions Backend/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,31 @@ pub const MAX_RECENTS: usize = 10;
fn apply_git_ssh_env(cfg: &AppConfig) {
// Prefer config-driven runtime env so the VCS backend (in another crate) can read it.
// Keep env var names stable for packaging and troubleshooting.
std::env::set_var(
"OPENVCS_SSH_MODE",
match cfg.git.ssh_binary {
crate::settings::GitSshBinary::Auto => "auto",
crate::settings::GitSshBinary::Host => "host",
crate::settings::GitSshBinary::Bundled => "bundled",
crate::settings::GitSshBinary::Custom => "custom",
},
);
unsafe {
// Safety: OpenVCS sets these env vars during startup/config updates and treats them as
// process-wide configuration for child processes (e.g. `git`).
std::env::set_var(
"OPENVCS_SSH_MODE",
match cfg.git.ssh_binary {
crate::settings::GitSshBinary::Auto => "auto",
crate::settings::GitSshBinary::Host => "host",
crate::settings::GitSshBinary::Bundled => "bundled",
crate::settings::GitSshBinary::Custom => "custom",
},
);
}
if cfg.git.ssh_binary == crate::settings::GitSshBinary::Custom
&& !cfg.git.ssh_path.trim().is_empty()
{
std::env::set_var("OPENVCS_SSH", cfg.git.ssh_path.trim());
unsafe {
// Safety: see comment above.
std::env::set_var("OPENVCS_SSH", cfg.git.ssh_path.trim());
}
} else {
std::env::remove_var("OPENVCS_SSH");
unsafe {
// Safety: see comment above.
std::env::remove_var("OPENVCS_SSH");
}
}
}

Expand Down
Loading
Loading