style: 格式化代码并优化导入顺序
This commit is contained in:
301
src/git/mod.rs
301
src/git/mod.rs
@@ -1,49 +1,49 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use git2::{Repository, Signature, StatusOptions, Config, Oid, ObjectType};
|
||||
use std::path::{Path, PathBuf, Component};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use git2::{Config, ObjectType, Oid, Repository, Signature, StatusOptions};
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
pub mod changelog;
|
||||
pub mod commit;
|
||||
pub mod tag;
|
||||
|
||||
|
||||
fn normalize_path_for_git2(path: &Path) -> PathBuf {
|
||||
let mut normalized = path.to_path_buf();
|
||||
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let path_str = path.to_string_lossy();
|
||||
if path_str.starts_with(r"\\?\")
|
||||
&& let Some(stripped) = path_str.strip_prefix(r"\\?\") {
|
||||
normalized = PathBuf::from(stripped);
|
||||
}
|
||||
&& let Some(stripped) = path_str.strip_prefix(r"\\?\")
|
||||
{
|
||||
normalized = PathBuf::from(stripped);
|
||||
}
|
||||
if path_str.starts_with(r"\\?\UNC\")
|
||||
&& let Some(stripped) = path_str.strip_prefix(r"\\?\UNC\") {
|
||||
normalized = PathBuf::from(format!(r"\\{}", stripped));
|
||||
}
|
||||
&& let Some(stripped) = path_str.strip_prefix(r"\\?\UNC\")
|
||||
{
|
||||
normalized = PathBuf::from(format!(r"\\{}", stripped));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
normalized
|
||||
}
|
||||
|
||||
fn get_absolute_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
|
||||
|
||||
if path.is_absolute() {
|
||||
return Ok(normalize_path_for_git2(path));
|
||||
}
|
||||
|
||||
let current_dir = std::env::current_dir()
|
||||
.with_context(|| "Failed to get current directory")?;
|
||||
|
||||
|
||||
let current_dir = std::env::current_dir().with_context(|| "Failed to get current directory")?;
|
||||
|
||||
let absolute = current_dir.join(path);
|
||||
Ok(normalize_path_for_git2(&absolute))
|
||||
}
|
||||
|
||||
fn resolve_path_without_canonicalize(path: &Path) -> PathBuf {
|
||||
let mut components = Vec::new();
|
||||
|
||||
|
||||
for component in path.components() {
|
||||
match component {
|
||||
Component::ParentDir => {
|
||||
@@ -57,25 +57,25 @@ fn resolve_path_without_canonicalize(path: &Path) -> PathBuf {
|
||||
_ => components.push(component),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let mut result = PathBuf::new();
|
||||
for component in components {
|
||||
result.push(component.as_os_str());
|
||||
}
|
||||
|
||||
|
||||
normalize_path_for_git2(&result)
|
||||
}
|
||||
|
||||
fn try_open_repo_with_git2(path: &Path) -> Result<Repository> {
|
||||
let normalized = normalize_path_for_git2(path);
|
||||
|
||||
|
||||
let discover_opts = git2::RepositoryOpenFlags::empty();
|
||||
let ceiling_dirs: [&str; 0] = [];
|
||||
|
||||
|
||||
let repo = Repository::open_ext(&normalized, discover_opts, ceiling_dirs)
|
||||
.or_else(|_| Repository::discover(&normalized))
|
||||
.or_else(|_| Repository::open(&normalized));
|
||||
|
||||
|
||||
repo.map_err(|e| anyhow::anyhow!("git2 failed: {}", e))
|
||||
}
|
||||
|
||||
@@ -85,34 +85,34 @@ fn try_open_repo_with_git_cli(path: &Path) -> Result<Repository> {
|
||||
.current_dir(path)
|
||||
.output()
|
||||
.context("Failed to execute git command")?;
|
||||
|
||||
|
||||
if !output.status.success() {
|
||||
bail!("git CLI failed to find repository");
|
||||
}
|
||||
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let git_root = stdout.trim();
|
||||
|
||||
|
||||
if git_root.is_empty() {
|
||||
bail!("git CLI returned empty path");
|
||||
}
|
||||
|
||||
|
||||
let git_root_path = PathBuf::from(git_root);
|
||||
let normalized = normalize_path_for_git2(&git_root_path);
|
||||
|
||||
|
||||
Repository::open(&normalized)
|
||||
.with_context(|| format!("Failed to open repo from git CLI path: {:?}", normalized))
|
||||
}
|
||||
|
||||
fn diagnose_repo_issue(path: &Path) -> String {
|
||||
let mut issues = Vec::new();
|
||||
|
||||
|
||||
if !path.exists() {
|
||||
issues.push(format!("Path does not exist: {:?}", path));
|
||||
} else if !path.is_dir() {
|
||||
issues.push(format!("Path is not a directory: {:?}", path));
|
||||
}
|
||||
|
||||
|
||||
let git_dir = path.join(".git");
|
||||
if git_dir.exists() {
|
||||
if git_dir.is_dir() {
|
||||
@@ -128,7 +128,7 @@ fn diagnose_repo_issue(path: &Path) -> String {
|
||||
}
|
||||
} else {
|
||||
issues.push("No .git found in current directory".to_string());
|
||||
|
||||
|
||||
let mut current = path;
|
||||
let mut depth = 0;
|
||||
while let Some(parent) = current.parent() {
|
||||
@@ -144,7 +144,7 @@ fn diagnose_repo_issue(path: &Path) -> String {
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let path_str = path.to_string_lossy();
|
||||
@@ -155,11 +155,11 @@ fn diagnose_repo_issue(path: &Path) -> String {
|
||||
issues.push("WARNING: Path has mixed path separators".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if let Ok(current_dir) = std::env::current_dir() {
|
||||
issues.push(format!("Current working directory: {:?}", current_dir));
|
||||
}
|
||||
|
||||
|
||||
issues.join("\n ")
|
||||
}
|
||||
|
||||
@@ -172,17 +172,15 @@ pub struct GitRepo {
|
||||
impl GitRepo {
|
||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
let path = path.as_ref();
|
||||
|
||||
|
||||
let absolute_path = get_absolute_path(path)?;
|
||||
let resolved_path = resolve_path_without_canonicalize(&absolute_path);
|
||||
|
||||
let repo = try_open_repo_with_git2(&resolved_path)
|
||||
.or_else(|git2_err| {
|
||||
try_open_repo_with_git_cli(&resolved_path)
|
||||
.map_err(|cli_err| {
|
||||
let diagnosis = diagnose_repo_issue(&resolved_path);
|
||||
anyhow::anyhow!(
|
||||
"Failed to open git repository:\n\
|
||||
|
||||
let repo = try_open_repo_with_git2(&resolved_path).or_else(|git2_err| {
|
||||
try_open_repo_with_git_cli(&resolved_path).map_err(|cli_err| {
|
||||
let diagnosis = diagnose_repo_issue(&resolved_path);
|
||||
anyhow::anyhow!(
|
||||
"Failed to open git repository:\n\
|
||||
\n\
|
||||
=== git2 Error ===\n {}\n\
|
||||
\n\
|
||||
@@ -195,17 +193,20 @@ impl GitRepo {
|
||||
2. Run: git status (to verify git works)\n\
|
||||
3. Run: git config --global --add safe.directory \"*\"\n\
|
||||
4. Check file permissions",
|
||||
git2_err, cli_err, diagnosis
|
||||
)
|
||||
})
|
||||
})?;
|
||||
|
||||
let repo_path = repo.workdir()
|
||||
git2_err,
|
||||
cli_err,
|
||||
diagnosis
|
||||
)
|
||||
})
|
||||
})?;
|
||||
|
||||
let repo_path = repo
|
||||
.workdir()
|
||||
.map(|p| p.to_path_buf())
|
||||
.unwrap_or_else(|| resolved_path.clone());
|
||||
|
||||
|
||||
let config = repo.config().ok();
|
||||
|
||||
|
||||
Ok(Self {
|
||||
repo,
|
||||
path: normalize_path_for_git2(&repo_path),
|
||||
@@ -246,7 +247,11 @@ impl GitRepo {
|
||||
pub fn get_user_name(&self) -> Result<String> {
|
||||
self.get_config("user.name")?
|
||||
.or_else(|| std::env::var("GIT_AUTHOR_NAME").ok())
|
||||
.ok_or_else(|| anyhow::anyhow!("User name not configured. Set it with: git config user.name \"Your Name\""))
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"User name not configured. Set it with: git config user.name \"Your Name\""
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the configured user email
|
||||
@@ -258,7 +263,8 @@ impl GitRepo {
|
||||
|
||||
/// Get the configured GPG signing key
|
||||
pub fn get_signing_key(&self) -> Result<Option<String>> {
|
||||
Ok(self.get_config("user.signingkey")?
|
||||
Ok(self
|
||||
.get_config("user.signingkey")?
|
||||
.or_else(|| std::env::var("GIT_SIGNING_KEY").ok()))
|
||||
}
|
||||
|
||||
@@ -285,13 +291,9 @@ impl GitRepo {
|
||||
if let Some(program) = self.get_config("gpg.program")? {
|
||||
return Ok(program);
|
||||
}
|
||||
|
||||
let default_gpg = if cfg!(windows) {
|
||||
"gpg.exe"
|
||||
} else {
|
||||
"gpg"
|
||||
};
|
||||
|
||||
|
||||
let default_gpg = if cfg!(windows) { "gpg.exe" } else { "gpg" };
|
||||
|
||||
Ok(default_gpg.to_string())
|
||||
}
|
||||
|
||||
@@ -299,10 +301,13 @@ impl GitRepo {
|
||||
pub fn create_signature(&self) -> Result<Signature<'_>> {
|
||||
let name = self.get_user_name()?;
|
||||
let email = self.get_user_email()?;
|
||||
let time = git2::Time::new(std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as i64, 0);
|
||||
let time = git2::Time::new(
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as i64,
|
||||
0,
|
||||
);
|
||||
Signature::new(&name, &email, &time).map_err(Into::into)
|
||||
}
|
||||
|
||||
@@ -346,7 +351,7 @@ impl GitRepo {
|
||||
/// then lock files like Cargo.lock
|
||||
pub fn get_staged_diff_sorted(&self) -> Result<String> {
|
||||
let diff = self.get_staged_diff()?;
|
||||
|
||||
|
||||
if diff.is_empty() {
|
||||
return Ok(diff);
|
||||
}
|
||||
@@ -382,9 +387,7 @@ impl GitRepo {
|
||||
});
|
||||
|
||||
// Combine sorted diffs
|
||||
let sorted_diff: String = file_diffs.into_iter()
|
||||
.map(|(_, diff)| diff)
|
||||
.collect();
|
||||
let sorted_diff: String = file_diffs.into_iter().map(|(_, diff)| diff).collect();
|
||||
|
||||
Ok(sorted_diff)
|
||||
}
|
||||
@@ -412,20 +415,31 @@ fn extract_file_from_diff_line(line: &str) -> String {
|
||||
fn file_importance_score(filename: &str) -> i32 {
|
||||
// Priority list for important file types
|
||||
let important_extensions = [
|
||||
".rs", ".py", ".js", ".ts", ".tsx", ".jsx", ".go", ".java", ".cpp", ".c", ".rust",
|
||||
".vue", ".svelte", ".html", ".css", ".scss", ".sass", ".less",
|
||||
".rs", ".py", ".js", ".ts", ".tsx", ".jsx", ".go", ".java", ".cpp", ".c", ".rust", ".vue",
|
||||
".svelte", ".html", ".css", ".scss", ".sass", ".less",
|
||||
];
|
||||
|
||||
|
||||
// Config files that are important but less than source code
|
||||
let config_files = [
|
||||
"Cargo.toml", "package.json", "go.mod", "go.sum", "pom.xml",
|
||||
"Makefile", "CMakeLists.txt", "build.gradle", "gradle.properties",
|
||||
"Cargo.toml",
|
||||
"package.json",
|
||||
"go.mod",
|
||||
"go.sum",
|
||||
"pom.xml",
|
||||
"Makefile",
|
||||
"CMakeLists.txt",
|
||||
"build.gradle",
|
||||
"gradle.properties",
|
||||
];
|
||||
|
||||
|
||||
// Lock files - lowest priority
|
||||
let lock_files = [
|
||||
"Cargo.lock", "package-lock.json", "yarn.lock", "pnpm-lock.yaml",
|
||||
"Gemfile.lock", "composer.lock",
|
||||
"Cargo.lock",
|
||||
"package-lock.json",
|
||||
"yarn.lock",
|
||||
"pnpm-lock.yaml",
|
||||
"Gemfile.lock",
|
||||
"composer.lock",
|
||||
];
|
||||
|
||||
// Check lock files first (lowest priority)
|
||||
@@ -498,18 +512,22 @@ impl GitRepo {
|
||||
|
||||
/// Get list of staged files
|
||||
pub fn get_staged_files(&self) -> Result<Vec<String>> {
|
||||
let statuses = self.repo.statuses(Some(
|
||||
StatusOptions::new()
|
||||
.include_untracked(false),
|
||||
))?;
|
||||
let statuses = self
|
||||
.repo
|
||||
.statuses(Some(StatusOptions::new().include_untracked(false)))?;
|
||||
|
||||
let mut files = vec![];
|
||||
for entry in statuses.iter() {
|
||||
let status = entry.status();
|
||||
if (status.is_index_new() || status.is_index_modified() || status.is_index_deleted() || status.is_index_renamed() || status.is_index_typechange())
|
||||
&& let Some(path) = entry.path() {
|
||||
files.push(path.to_string());
|
||||
}
|
||||
if (status.is_index_new()
|
||||
|| status.is_index_modified()
|
||||
|| status.is_index_deleted()
|
||||
|| status.is_index_renamed()
|
||||
|| status.is_index_typechange())
|
||||
&& let Some(path) = entry.path()
|
||||
{
|
||||
files.push(path.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(files)
|
||||
@@ -629,20 +647,21 @@ impl GitRepo {
|
||||
if !output.status.success() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
|
||||
|
||||
let error_msg = if stderr.is_empty() {
|
||||
if stdout.is_empty() {
|
||||
"GPG signing failed. Please check:\n\
|
||||
1. GPG signing key is configured (git config --get user.signingkey)\n\
|
||||
2. GPG agent is running\n\
|
||||
3. You can sign commits manually (try: git commit -S -m 'test')".to_string()
|
||||
3. You can sign commits manually (try: git commit -S -m 'test')"
|
||||
.to_string()
|
||||
} else {
|
||||
stdout.to_string()
|
||||
}
|
||||
} else {
|
||||
stderr.to_string()
|
||||
};
|
||||
|
||||
|
||||
bail!("Failed to create signed commit: {}", error_msg);
|
||||
}
|
||||
|
||||
@@ -655,7 +674,8 @@ impl GitRepo {
|
||||
let head = self.repo.head()?;
|
||||
|
||||
if head.is_branch() {
|
||||
let name = head.shorthand()
|
||||
let name = head
|
||||
.shorthand()
|
||||
.ok_or_else(|| anyhow::anyhow!("Invalid branch name"))?;
|
||||
Ok(name.to_string())
|
||||
} else {
|
||||
@@ -666,7 +686,8 @@ impl GitRepo {
|
||||
/// Get current commit hash (short)
|
||||
pub fn current_commit_short(&self) -> Result<String> {
|
||||
let head = self.repo.head()?;
|
||||
let oid = head.target()
|
||||
let oid = head
|
||||
.target()
|
||||
.ok_or_else(|| anyhow::anyhow!("No target for HEAD"))?;
|
||||
Ok(oid.to_string()[..8].to_string())
|
||||
}
|
||||
@@ -674,7 +695,8 @@ impl GitRepo {
|
||||
/// Get current commit hash (full)
|
||||
pub fn current_commit(&self) -> Result<String> {
|
||||
let head = self.repo.head()?;
|
||||
let oid = head.target()
|
||||
let oid = head
|
||||
.target()
|
||||
.ok_or_else(|| anyhow::anyhow!("No target for HEAD"))?;
|
||||
Ok(oid.to_string())
|
||||
}
|
||||
@@ -773,13 +795,7 @@ impl GitRepo {
|
||||
if sign {
|
||||
self.create_signed_tag_with_git2(name, msg, &sig, target.id())?;
|
||||
} else {
|
||||
self.repo.tag(
|
||||
name,
|
||||
target.as_object(),
|
||||
&sig,
|
||||
msg,
|
||||
false,
|
||||
)?;
|
||||
self.repo.tag(name, target.as_object(), &sig, msg, false)?;
|
||||
}
|
||||
} else {
|
||||
self.repo.tag(
|
||||
@@ -795,7 +811,13 @@ impl GitRepo {
|
||||
}
|
||||
|
||||
/// Create signed tag using git CLI
|
||||
fn create_signed_tag_with_git2(&self, name: &str, message: &str, _signature: &Signature, _target_id: Oid) -> Result<()> {
|
||||
fn create_signed_tag_with_git2(
|
||||
&self,
|
||||
name: &str,
|
||||
message: &str,
|
||||
_signature: &Signature,
|
||||
_target_id: Oid,
|
||||
) -> Result<()> {
|
||||
let output = std::process::Command::new("git")
|
||||
.args(["tag", "-s", name, "-m", message])
|
||||
.current_dir(&self.path)
|
||||
@@ -810,7 +832,12 @@ impl GitRepo {
|
||||
}
|
||||
|
||||
/// Create GPG signature for arbitrary content
|
||||
fn create_gpg_signature_for_content(&self, _content: &str, _gpg_program: &str, _signing_key: &str) -> Result<String> {
|
||||
fn create_gpg_signature_for_content(
|
||||
&self,
|
||||
_content: &str,
|
||||
_gpg_program: &str,
|
||||
_signing_key: &str,
|
||||
) -> Result<String> {
|
||||
Ok(String::new())
|
||||
}
|
||||
|
||||
@@ -838,7 +865,8 @@ impl GitRepo {
|
||||
/// Get remote URL
|
||||
pub fn get_remote_url(&self, remote: &str) -> Result<String> {
|
||||
let remote_obj = self.repo.find_remote(remote)?;
|
||||
let url = remote_obj.url()
|
||||
let url = remote_obj
|
||||
.url()
|
||||
.ok_or_else(|| anyhow::anyhow!("Remote has no URL"))?;
|
||||
Ok(url.to_string())
|
||||
}
|
||||
@@ -889,9 +917,10 @@ impl GitRepo {
|
||||
}
|
||||
|
||||
// Conflicted files (both columns are U or DD, AA, etc.)
|
||||
if (index_status == 'U' || worktree_status == 'U') ||
|
||||
(index_status == 'A' && worktree_status == 'A') ||
|
||||
(index_status == 'D' && worktree_status == 'D') {
|
||||
if (index_status == 'U' || worktree_status == 'U')
|
||||
|| (index_status == 'A' && worktree_status == 'A')
|
||||
|| (index_status == 'D' && worktree_status == 'D')
|
||||
{
|
||||
conflicted += 1;
|
||||
}
|
||||
}
|
||||
@@ -982,49 +1011,51 @@ impl StatusSummary {
|
||||
|
||||
pub fn find_repo<P: AsRef<Path>>(start_path: P) -> Result<GitRepo> {
|
||||
let start_path = start_path.as_ref();
|
||||
|
||||
|
||||
let absolute_start = get_absolute_path(start_path)?;
|
||||
let resolved_start = resolve_path_without_canonicalize(&absolute_start);
|
||||
|
||||
|
||||
if let Ok(repo) = GitRepo::open(&resolved_start) {
|
||||
return Ok(repo);
|
||||
}
|
||||
|
||||
|
||||
let mut current = resolved_start.as_path();
|
||||
let mut attempted_paths = vec![current.to_string_lossy().to_string()];
|
||||
|
||||
|
||||
let max_depth = 50;
|
||||
let mut depth = 0;
|
||||
|
||||
|
||||
while let Some(parent) = current.parent() {
|
||||
depth += 1;
|
||||
if depth > max_depth {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
attempted_paths.push(parent.to_string_lossy().to_string());
|
||||
|
||||
|
||||
if let Ok(repo) = GitRepo::open(parent) {
|
||||
return Ok(repo);
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
|
||||
|
||||
if let Ok(output) = std::process::Command::new("git")
|
||||
.args(["rev-parse", "--show-toplevel"])
|
||||
.current_dir(&resolved_start)
|
||||
.output()
|
||||
&& output.status.success() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let git_root = stdout.trim();
|
||||
if !git_root.is_empty()
|
||||
&& let Ok(repo) = GitRepo::open(git_root) {
|
||||
return Ok(repo);
|
||||
}
|
||||
&& output.status.success()
|
||||
{
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let git_root = stdout.trim();
|
||||
if !git_root.is_empty()
|
||||
&& let Ok(repo) = GitRepo::open(git_root)
|
||||
{
|
||||
return Ok(repo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let diagnosis = diagnose_repo_issue(&resolved_start);
|
||||
|
||||
|
||||
bail!(
|
||||
"No git repository found.\n\
|
||||
\n\
|
||||
@@ -1238,7 +1269,10 @@ impl MergedUserConfig {
|
||||
}
|
||||
|
||||
pub fn has_local_overrides(&self) -> bool {
|
||||
self.name.is_local() || self.email.is_local() || self.signing_key.is_local() || self.ssh_command.is_local()
|
||||
self.name.is_local()
|
||||
|| self.email.is_local()
|
||||
|| self.signing_key.is_local()
|
||||
|| self.ssh_command.is_local()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1265,23 +1299,38 @@ impl UserConfig {
|
||||
diffs.push(ConfigDiff {
|
||||
key: "user.name".to_string(),
|
||||
left: self.name.clone().unwrap_or_else(|| "<not set>".to_string()),
|
||||
right: other.name.clone().unwrap_or_else(|| "<not set>".to_string()),
|
||||
right: other
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
if self.email != other.email {
|
||||
diffs.push(ConfigDiff {
|
||||
key: "user.email".to_string(),
|
||||
left: self.email.clone().unwrap_or_else(|| "<not set>".to_string()),
|
||||
right: other.email.clone().unwrap_or_else(|| "<not set>".to_string()),
|
||||
left: self
|
||||
.email
|
||||
.clone()
|
||||
.unwrap_or_else(|| "<not set>".to_string()),
|
||||
right: other
|
||||
.email
|
||||
.clone()
|
||||
.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
if self.signing_key != other.signing_key {
|
||||
diffs.push(ConfigDiff {
|
||||
key: "user.signingkey".to_string(),
|
||||
left: self.signing_key.clone().unwrap_or_else(|| "<not set>".to_string()),
|
||||
right: other.signing_key.clone().unwrap_or_else(|| "<not set>".to_string()),
|
||||
left: self
|
||||
.signing_key
|
||||
.clone()
|
||||
.unwrap_or_else(|| "<not set>".to_string()),
|
||||
right: other
|
||||
.signing_key
|
||||
.clone()
|
||||
.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user