Adds a new command to rename remote branches and update tracking refs. Renaming remote refs is performed atomically using a single push. The push creates the new remote ref and deletes the old if it succeeds. The frontend now invokes remote-rename when needed and shows labels. - Atomic remote rename via push with create/ref and delete - Frontend supports remote branch renames from the branch panel - Compare UI now shows labels for remote refs in results
233 lines
7.8 KiB
Rust
233 lines
7.8 KiB
Rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
|
|
mod badge;
|
|
mod external_tools;
|
|
mod git;
|
|
mod telemetry;
|
|
|
|
use badge::set_sync_badge;
|
|
use external_tools::{
|
|
detect_external_tools, launch_external_diff, launch_external_merge, launch_external_tool,
|
|
};
|
|
use git::{
|
|
SearchCancellationState, add_remote, add_worktree, amend_commit, apply_file_patch,
|
|
cancel_code_search, cancel_file_history, checkout_branch, cherry_pick_abort,
|
|
cherry_pick_commit, cherry_pick_continue, clone_repository, commit, commit_ai_generate,
|
|
commit_ai_load, commit_ai_local_models, commit_ai_review, commit_ai_split, commit_ai_status,
|
|
compare_commits, compare_file_to_head, compare_file_to_parent, create_branch, create_tag,
|
|
cred_delete, cred_load, cred_save, delete_branch, delete_commit_note, delete_remote_branch,
|
|
delete_tag, diff_file_against_working_tree, fetch, fetch_commit_notes, get_commit_note,
|
|
get_file_blame, get_file_patch, get_remote_url, get_status, init_repository,
|
|
last_commit_message, list_branches, list_commits, list_file_history,
|
|
list_interactive_rebase_commits, list_reflog, list_remotes, list_repository_files,
|
|
list_stashes, list_tags, list_worktrees, lock_worktree, merge_abort, merge_branch,
|
|
merge_continue, move_worktree, open_repo_in_explorer, open_repository, open_repository_bundle,
|
|
open_repository_file, prune_worktrees, pull, push, push_commit_notes, push_tag, read_conflict,
|
|
rebase_abort, rebase_branch, rebase_continue, remove_remote, remove_worktree, rename_branch,
|
|
rename_remote_branch, repair_worktree, resolve_conflict, resolve_conflict_side,
|
|
restore_file_from_commit, restore_files, restore_reflog_entry, restore_to_commit,
|
|
revert_commit, run_sequence_editor_if_requested, search_code_introductions,
|
|
set_branch_upstream, set_commit_note, stage_files, start_interactive_rebase, stash_apply,
|
|
stash_drop, stash_pop, stash_push, undo_last_commit, unlock_worktree, unstage_files,
|
|
update_remote,
|
|
};
|
|
use tauri::Manager;
|
|
use telemetry::{emit_frontend_log, emit_frontend_span, set_telemetry_enabled};
|
|
|
|
struct ConsoleLogger;
|
|
|
|
impl log::Log for ConsoleLogger {
|
|
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
|
|
metadata.level() <= log::Level::Info
|
|
}
|
|
|
|
fn log(&self, record: &log::Record<'_>) {
|
|
if self.enabled(record.metadata()) {
|
|
eprintln!(
|
|
"[{}] [{}] {}",
|
|
record.level(),
|
|
record.target(),
|
|
record.args()
|
|
);
|
|
}
|
|
}
|
|
|
|
fn flush(&self) {}
|
|
}
|
|
|
|
static CONSOLE_LOGGER: ConsoleLogger = ConsoleLogger;
|
|
|
|
fn init_console_logging() {
|
|
if log::set_logger(&CONSOLE_LOGGER).is_ok() {
|
|
log::set_max_level(log::LevelFilter::Info);
|
|
log::info!(target: "gitty", "Rust console logging initialized");
|
|
}
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn close_splashscreen(app: tauri::AppHandle) -> Result<(), String> {
|
|
if let Some(window) = app.get_webview_window("splashscreen") {
|
|
let _ = window.hide();
|
|
window
|
|
.destroy()
|
|
.map_err(|error| format!("failed to destroy splashscreen: {error}"))?;
|
|
}
|
|
|
|
if let Some(window) = app.get_webview_window("main") {
|
|
let _ = window.maximize();
|
|
window
|
|
.show()
|
|
.map_err(|error| format!("failed to show main window: {error}"))?;
|
|
let _ = window.set_focus();
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
init_console_logging();
|
|
telemetry::init();
|
|
if let Some(result) = run_sequence_editor_if_requested() {
|
|
if let Err(error) = result {
|
|
eprintln!("{error}");
|
|
std::process::exit(1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
let builder = tauri::Builder::default()
|
|
.plugin(tauri_plugin_single_instance::init(|app, _, _| {
|
|
#[cfg(desktop)]
|
|
let _ = app
|
|
.get_webview_window("main")
|
|
.expect("no main window")
|
|
.set_focus();
|
|
}))
|
|
.plugin(
|
|
tauri_plugin_aptabase::Builder::new("A-SH-1344793789")
|
|
.with_options(tauri_plugin_aptabase::InitOptions {
|
|
host: Some("https://aptabase.cbsk-tech.de".to_string()),
|
|
flush_interval: None,
|
|
})
|
|
.build(),
|
|
)
|
|
.manage(SearchCancellationState::default())
|
|
.manage(commit_ai::CommitAiEngine::new())
|
|
.plugin(tauri_plugin_dialog::init());
|
|
|
|
// Linux installs are expected to come from the system package manager (see the
|
|
// PKGBUILD), which owns updates itself — the self-updater is only wired up for
|
|
// the platforms whose install method this app ships (NSIS/Windows, .app/macOS).
|
|
#[cfg(not(target_os = "linux"))]
|
|
let builder = builder.plugin(tauri_plugin_updater::Builder::new().build());
|
|
|
|
builder
|
|
.invoke_handler(tauri::generate_handler![
|
|
open_repository,
|
|
init_repository,
|
|
clone_repository,
|
|
open_repo_in_explorer,
|
|
open_repository_file,
|
|
detect_external_tools,
|
|
launch_external_tool,
|
|
launch_external_diff,
|
|
launch_external_merge,
|
|
get_status,
|
|
list_branches,
|
|
list_remotes,
|
|
add_remote,
|
|
update_remote,
|
|
remove_remote,
|
|
set_branch_upstream,
|
|
delete_remote_branch,
|
|
list_stashes,
|
|
checkout_branch,
|
|
create_branch,
|
|
rename_branch,
|
|
rename_remote_branch,
|
|
delete_branch,
|
|
list_worktrees,
|
|
add_worktree,
|
|
remove_worktree,
|
|
move_worktree,
|
|
lock_worktree,
|
|
unlock_worktree,
|
|
prune_worktrees,
|
|
repair_worktree,
|
|
list_tags,
|
|
create_tag,
|
|
delete_tag,
|
|
push_tag,
|
|
cherry_pick_commit,
|
|
cherry_pick_continue,
|
|
cherry_pick_abort,
|
|
stage_files,
|
|
unstage_files,
|
|
stash_push,
|
|
stash_apply,
|
|
stash_pop,
|
|
stash_drop,
|
|
restore_files,
|
|
get_file_patch,
|
|
apply_file_patch,
|
|
commit,
|
|
amend_commit,
|
|
undo_last_commit,
|
|
last_commit_message,
|
|
commit_ai_status,
|
|
commit_ai_load,
|
|
commit_ai_local_models,
|
|
commit_ai_generate,
|
|
commit_ai_review,
|
|
commit_ai_split,
|
|
pull,
|
|
push,
|
|
fetch,
|
|
list_commits,
|
|
get_commit_note,
|
|
set_commit_note,
|
|
delete_commit_note,
|
|
fetch_commit_notes,
|
|
push_commit_notes,
|
|
restore_to_commit,
|
|
restore_file_from_commit,
|
|
merge_branch,
|
|
merge_continue,
|
|
merge_abort,
|
|
revert_commit,
|
|
rebase_branch,
|
|
rebase_continue,
|
|
rebase_abort,
|
|
list_interactive_rebase_commits,
|
|
start_interactive_rebase,
|
|
list_reflog,
|
|
restore_reflog_entry,
|
|
list_repository_files,
|
|
open_repository_bundle,
|
|
list_file_history,
|
|
cancel_file_history,
|
|
get_file_blame,
|
|
compare_commits,
|
|
compare_file_to_head,
|
|
compare_file_to_parent,
|
|
diff_file_against_working_tree,
|
|
search_code_introductions,
|
|
cancel_code_search,
|
|
read_conflict,
|
|
resolve_conflict,
|
|
resolve_conflict_side,
|
|
get_remote_url,
|
|
cred_load,
|
|
cred_save,
|
|
cred_delete,
|
|
set_sync_badge,
|
|
close_splashscreen,
|
|
set_telemetry_enabled,
|
|
emit_frontend_log,
|
|
emit_frontend_span
|
|
])
|
|
.run(tauri::generate_context!())
|
|
.expect("error while running tauri application");
|
|
}
|