1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// SPDX-License-Identifier: Apache-2.0
//! Git projection command definitions.
use std::path::PathBuf;
use clap::Subcommand;
/// Source for a git import: either a local filesystem path or a URL that
/// sley can fetch from.
///
/// We discriminate by inspecting the input string: anything containing
/// `://` (https/ssh/git/file URLs) or starting with `git@` (ssh shorthand)
/// is treated as a URL; everything else is a local path. This keeps the
/// rules predictable — `/tmp/foo` always means a path, and a stray
/// `git@host:path` shorthand never gets misread as a relative path.
#[derive(Debug, Clone)]
pub enum GitSource {
Path(PathBuf),
Url(String),
}
impl GitSource {
pub fn parse(s: &str) -> Result<Self, String> {
if s.contains("://") || s.starts_with("git@") {
Ok(GitSource::Url(s.to_string()))
} else {
Ok(GitSource::Path(PathBuf::from(s)))
}
}
pub fn display(&self) -> String {
match self {
GitSource::Path(p) => p.display().to_string(),
GitSource::Url(u) => u.clone(),
}
}
}
pub(crate) fn parse_git_source(s: &str) -> Result<GitSource, String> {
GitSource::parse(s)
}
#[derive(Subcommand, Clone)]
pub enum ImportCommands {
/// Import Git commits to Heddle.
///
/// Walks local branches and tags by default. To import remote-tracking
/// refs (`refs/remotes/*`), name them explicitly with `--ref`.
Git {
/// Local path or git URL to import from.
#[arg(short, long, value_parser = parse_git_source)]
path: Option<GitSource>,
/// Ref names to import (repeatable). Scopes the import to the
/// listed branches, tags, or remote-tracking refs; omit to
/// import all branches and tags.
#[arg(long = "ref", value_name = "REF")]
refs: Vec<String>,
/// Accept git tree entries Heddle cannot represent losslessly.
#[arg(long)]
lossy: bool,
},
}
#[derive(Subcommand, Clone)]
pub enum ExportCommands {
/// Export Heddle states to Git.
///
/// Writes a complete bare Git repository at `--destination` containing
/// every reachable Heddle state as a Git commit, with branches and tags
/// mirroring Heddle's threads and markers.
Git {
/// Destination path for the exported Git repository. Must be writable;
/// will be initialized as a bare repo if it does not already exist.
#[arg(short, long)]
destination: Option<std::path::PathBuf>,
},
}
#[derive(Subcommand, Clone, Debug)]
pub enum SyncCommands {
/// Bidirectional sync with Git (export + import).
Git {
/// Local path or git URL to sync with.
#[arg(short, long, value_parser = parse_git_source)]
path: Option<GitSource>,
},
}