mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-23 03:26:36 +03:00
Use gix
for branch normalization
This commit is contained in:
parent
0d1ac25ef4
commit
107eea6743
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2333,7 +2333,6 @@ dependencies = [
|
||||
"git2",
|
||||
"gitbutler-tagged-string",
|
||||
"gix",
|
||||
"regex",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -6,7 +6,6 @@ authors = ["GitButler <gitbutler@gitbutler.com>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
regex = "1.10"
|
||||
anyhow.workspace = true
|
||||
git2.workspace = true
|
||||
gix.workspace = true
|
||||
|
@ -3,27 +3,45 @@ mod refname;
|
||||
use anyhow::bail;
|
||||
use gitbutler_tagged_string::TaggedString;
|
||||
pub use refname::{LocalRefname, Refname, RemoteRefname, VirtualRefname};
|
||||
use regex::Regex;
|
||||
|
||||
// TODO(ST): return `BString`, probably take BString, as branch names don't have to be valid UTF8
|
||||
pub fn normalize_branch_name(name: &str) -> anyhow::Result<String> {
|
||||
// Remove specific symbols
|
||||
let exclude_pattern = Regex::new(r"[|\+^~<>\\:*]").unwrap();
|
||||
let mut result = exclude_pattern.replace_all(name, "-").to_string();
|
||||
|
||||
// Replace spaces with hyphens
|
||||
let space_pattern = Regex::new(r"\s+").unwrap();
|
||||
result = space_pattern.replace_all(&result, "-").to_string();
|
||||
|
||||
// Remove leading and trailing hyphens and slashes and dots
|
||||
let trim_pattern = Regex::new(r"^[-/\.]+|[-/\.]+$").unwrap();
|
||||
result = trim_pattern.replace_all(&result, "").to_string();
|
||||
|
||||
let refname = format!("refs/gitbutler/{result}");
|
||||
if gix::validate::reference::name(refname.as_str().into()).is_err() {
|
||||
bail!("Could not turn {result:?} into a valid reference name")
|
||||
let mut sanitized = gix::validate::reference::name_partial_or_sanitize(name.into());
|
||||
fn is_forbidden_in_trailer_or_leader(b: u8) -> bool {
|
||||
b == b'-' || b == b'.' || b == b'/'
|
||||
}
|
||||
while let Some(last) = sanitized.last() {
|
||||
if is_forbidden_in_trailer_or_leader(*last) {
|
||||
sanitized.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while let Some(first) = sanitized.first() {
|
||||
if is_forbidden_in_trailer_or_leader(*first) {
|
||||
sanitized.remove(0);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
let mut previous_is_hyphen = false;
|
||||
sanitized.retain(|b| {
|
||||
if *b == b'-' {
|
||||
if previous_is_hyphen {
|
||||
return false;
|
||||
}
|
||||
previous_is_hyphen = true;
|
||||
} else {
|
||||
previous_is_hyphen = false;
|
||||
}
|
||||
true
|
||||
});
|
||||
|
||||
if sanitized.is_empty() {
|
||||
bail!("Could not turn {name:?} into a valid reference name")
|
||||
}
|
||||
Ok(sanitized.to_string())
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -5,11 +5,12 @@ mod normalize_branch_name {
|
||||
fn valid_substitutions() {
|
||||
for (input, expected) in [
|
||||
("a", "a"),
|
||||
("a+b", "a-b"),
|
||||
("a+b", "a+b"),
|
||||
("a^b", "a-b"),
|
||||
("a^^^b", "a-b"),
|
||||
("a~b", "a-b"),
|
||||
("a<b", "a-b"),
|
||||
("a>b", "a-b"),
|
||||
("a<b", "a<b"),
|
||||
("a>b", "a>b"),
|
||||
("a\\b", "a-b"),
|
||||
("a:b", "a-b"),
|
||||
("a*b", "a-b"),
|
||||
@ -24,7 +25,11 @@ mod normalize_branch_name {
|
||||
("/-a-/", "a"),
|
||||
(".a.", "a"),
|
||||
] {
|
||||
assert_eq!(normalize_branch_name(input).expect("valid"), expected);
|
||||
assert_eq!(
|
||||
normalize_branch_name(input).expect("valid"),
|
||||
expected,
|
||||
"{input} -> {expected}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,17 +37,15 @@ mod normalize_branch_name {
|
||||
fn clear_error_on_failure() {
|
||||
assert_eq!(
|
||||
normalize_branch_name("-").unwrap_err().to_string(),
|
||||
"Could not turn \"\" into a valid reference name"
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_branch_name("#[test]").unwrap_err().to_string(),
|
||||
"Could not turn \"#[test]\" into a valid reference name"
|
||||
"Could not turn \"-\" into a valid reference name",
|
||||
"show the original value, not the processed one to be familiar to the user"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex_valid() -> anyhow::Result<()> {
|
||||
assert_eq!(normalize_branch_name("feature/branch")?, "feature/branch");
|
||||
assert_eq!(normalize_branch_name("#[test]")?, "#-test]");
|
||||
assert_eq!(normalize_branch_name("foo#branch")?, "foo#branch");
|
||||
assert_eq!(normalize_branch_name("foo!branch")?, "foo!branch");
|
||||
let input = r#"Revert "GitButler Integration Commit"
|
||||
|
Loading…
Reference in New Issue
Block a user