Let the git remote be set from Settings
Attaching a workspace to an existing repository meant leaving for a terminal: gitsync could init, commit and push, and could tell whether an 'origin' existed, but had no way to create one, and nothing in the settings held a remote URL. Sync just logged "no 'origin' remote configured" and committed locally. Settings > Git remote... now shows the workspace repository's origin and lets it be set, repointed or cleared. The URL is read from and written to the repository, never to config.json, because a remote belongs to the checkout — so each workspace shows its own, and the box is refreshed whenever the repository in play changes. This is separate from the Gitea publishing in New project, which is a cookiecutter post-gen hook and only ever applies to generated projects. Also factors out first_output_line, which repo_root and the new origin_url were both open-coding, and origin_args, so the add-vs-set-url decision can be tested without a repository on disk. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GBWj9TphFMCoh7VHaSRnvQ
This commit is contained in:
@@ -137,6 +137,7 @@ impl App {
|
||||
if ws.join(".git").exists() {
|
||||
self.is_repo = true;
|
||||
self.repo_root = Some(ws.to_path_buf());
|
||||
self.remote_input = gitsync::origin_url(ws).unwrap_or_default();
|
||||
return;
|
||||
}
|
||||
match gitsync::repo_root(ws) {
|
||||
@@ -151,10 +152,12 @@ impl App {
|
||||
Some(root) => {
|
||||
self.is_repo = true;
|
||||
self.repo_root = Some(root);
|
||||
self.remote_input = gitsync::origin_url(ws).unwrap_or_default();
|
||||
}
|
||||
None => {
|
||||
self.is_repo = false;
|
||||
self.repo_root = None;
|
||||
self.remote_input.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,6 +169,7 @@ impl App {
|
||||
self.status = format!("Using git repository at {}", root.display());
|
||||
self.is_repo = true;
|
||||
self.repo_root = Some(root);
|
||||
self.remote_input = gitsync::origin_url(self.workspace()).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,6 +664,7 @@ impl App {
|
||||
self.git_log = outcome.log;
|
||||
self.show_log = true;
|
||||
self.is_repo = gitsync::is_repo(&ws);
|
||||
self.remote_input = gitsync::origin_url(&ws).unwrap_or_default();
|
||||
self.repo_root = self.is_repo.then_some(ws);
|
||||
self.status = if self.is_repo {
|
||||
"Initialised git repository".to_string()
|
||||
@@ -1025,6 +1030,111 @@ impl App {
|
||||
}
|
||||
|
||||
/// Settings dialog for the markdown seeded into template-backed new files.
|
||||
/// Open the git-remote dialog, reading the current `origin` fresh so the
|
||||
/// box shows what the repository actually holds.
|
||||
pub(super) fn open_git_remote(&mut self) {
|
||||
self.remote_input = gitsync::origin_url(self.workspace()).unwrap_or_default();
|
||||
self.show_git_remote = true;
|
||||
}
|
||||
|
||||
/// Point the workspace's repository at the typed remote.
|
||||
///
|
||||
/// Nothing about the URL is kept in this app's config: it is written to the
|
||||
/// repository and read straight back, so what the box shows afterwards is
|
||||
/// what git holds, and a different project shows its own.
|
||||
pub(super) fn set_git_remote(&mut self) {
|
||||
let ws = self.workspace().to_path_buf();
|
||||
if !self.is_repo {
|
||||
self.status = "Not a git repository yet \u{2014} use \u{201c}Init git\u{201d} first"
|
||||
.to_string();
|
||||
return;
|
||||
}
|
||||
let outcome = gitsync::set_origin(&ws, &self.remote_input);
|
||||
self.git_log = outcome.log;
|
||||
self.show_log = true;
|
||||
self.remote_input = gitsync::origin_url(&ws).unwrap_or_default();
|
||||
self.status = if !outcome.ok {
|
||||
"Could not set the remote (see log)".to_string()
|
||||
} else if self.remote_input.is_empty() {
|
||||
"Removed the origin remote".to_string()
|
||||
} else {
|
||||
format!("origin is now {}", self.remote_input)
|
||||
};
|
||||
}
|
||||
|
||||
/// The dialog for attaching a workspace to an existing remote repository.
|
||||
///
|
||||
/// Creating the repository on the server is a template hook's job, and only
|
||||
/// happens for projects made through New project. Anything else — a
|
||||
/// workspace that predates the app, or one whose hook did not run — needs
|
||||
/// the remote set by hand, which otherwise meant leaving for a terminal.
|
||||
pub(super) fn git_remote_window(&mut self, ctx: &egui::Context) {
|
||||
let mut open = self.show_git_remote;
|
||||
let mut apply = false;
|
||||
let mut close = false;
|
||||
let is_repo = self.is_repo;
|
||||
let root = self
|
||||
.repo_root
|
||||
.as_ref()
|
||||
.map(|r| r.display().to_string())
|
||||
.unwrap_or_default();
|
||||
egui::Window::new("Git remote")
|
||||
.open(&mut open)
|
||||
.resizable(false)
|
||||
.collapsible(false)
|
||||
.default_width(460.0)
|
||||
.show(ctx, |ui| {
|
||||
if !is_repo {
|
||||
ui.label(
|
||||
egui::RichText::new(
|
||||
"This workspace is not a git repository yet. Use \u{201c}Init \
|
||||
git\u{201d} in the toolbar first, then set the remote here.",
|
||||
)
|
||||
.small()
|
||||
.weak(),
|
||||
);
|
||||
ui.separator();
|
||||
}
|
||||
ui.label(egui::RichText::new(format!("Repository: {root}")).small().weak());
|
||||
ui.add_space(4.0);
|
||||
ui.label("origin:");
|
||||
let r = ui.add(
|
||||
egui::TextEdit::singleline(&mut self.remote_input)
|
||||
.desired_width(f32::INFINITY)
|
||||
.hint_text("ssh://git@host:port/user/repo.git"),
|
||||
);
|
||||
apply |= r.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter));
|
||||
ui.label(
|
||||
egui::RichText::new(
|
||||
"The repository has to exist on the server already \u{2014} this \
|
||||
attaches to it, it does not create it. Until origin is set, \
|
||||
\u{201c}\u{27f3} Sync (git)\u{201d} commits locally and says so in \
|
||||
the log. Clear the box and press Set to detach.",
|
||||
)
|
||||
.small()
|
||||
.weak(),
|
||||
);
|
||||
ui.add_space(4.0);
|
||||
ui.label(
|
||||
egui::RichText::new(
|
||||
"Stored in the repository, not in this app's settings, so each \
|
||||
project keeps its own.",
|
||||
)
|
||||
.small()
|
||||
.weak(),
|
||||
);
|
||||
ui.separator();
|
||||
ui.horizontal(|ui| {
|
||||
apply |= ui.add_enabled(is_repo, egui::Button::new("Set origin")).clicked();
|
||||
close |= ui.button("Close").clicked();
|
||||
});
|
||||
});
|
||||
if apply {
|
||||
self.set_git_remote();
|
||||
}
|
||||
self.show_git_remote = open && !close;
|
||||
}
|
||||
|
||||
/// Carry out what a file row's right-click menu picked.
|
||||
///
|
||||
/// Right-clicking acts on the row you clicked, so that row becomes the
|
||||
|
||||
Reference in New Issue
Block a user