diff --git a/src-tauri/src/dedup.rs b/src-tauri/src/dedup.rs new file mode 100644 index 000000000..503b6f3b7 --- /dev/null +++ b/src-tauri/src/dedup.rs @@ -0,0 +1,43 @@ +use std::collections::HashSet; + +// dedup makes sure that _new_ is not in _existing_ by adding a number to it. +// the number is increased until the name is unique. +pub fn dedup(existing: &[&str], new: &str) -> String { + let used_numbers = existing + .iter() + .filter(|x| x.starts_with(new)) + .filter_map(|x| { + x.strip_prefix(new) + .map(|x| x.trim_start()) + .map(|x| x.parse::().unwrap_or(-1)) + }) + .collect::>(); + if used_numbers.is_empty() || !used_numbers.contains(&-1) { + new.to_string() + } else { + // pick first unused number + let mut number = 1; + while used_numbers.contains(&number) { + number += 1; + } + format!("{} {}", new, number) + } +} + +#[test] +fn test_dedup() { + vec![ + (vec!["foo", "foo 2"], "foo", "foo 1"), + (vec!["foo", "foo 1", "foo 2"], "foo", "foo 3"), + (vec!["foo", "foo 1", "foo 2"], "foo 1", "foo 1 1"), + (vec!["foo", "foo 1", "foo 2"], "foo 2", "foo 2 1"), + (vec!["foo", "foo 1", "foo 2"], "foo 3", "foo 3"), + (vec!["foo 2"], "foo", "foo"), + (vec!["foo", "foo 1", "foo 2", "foo 4"], "foo", "foo 3"), + ] + .iter() + .enumerate() + .for_each(|(i, (existing, new, expected))| { + assert_eq!(dedup(existing, new), expected.to_string(), "test {}", i + 1); + }); +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 84b717f7a..ce1e116c8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -4,6 +4,7 @@ extern crate scopeguard; pub mod app; pub mod bookmarks; pub mod database; +pub mod dedup; pub mod deltas; pub mod events; pub mod files; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 90a2b1d90..b5a673d15 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,6 +1,7 @@ #[macro_use(defer)] extern crate scopeguard; +mod dedup; mod app; mod assets; mod bookmarks; diff --git a/src-tauri/src/virtual_branches/mod.rs b/src-tauri/src/virtual_branches/mod.rs index 32f88d769..274537143 100644 --- a/src-tauri/src/virtual_branches/mod.rs +++ b/src-tauri/src/virtual_branches/mod.rs @@ -21,6 +21,7 @@ pub use iterator::BranchIterator as Iterator; use uuid::Uuid; use crate::{ + dedup::dedup, gb_repository, project_repository::{self, conflicts, diff}, reader, sessions, @@ -1137,7 +1138,15 @@ pub fn create_virtual_branch( .name .as_ref() .map(|name| name.to_string()) - .unwrap_or_else(|| format!("Virtual branch {}", all_virtual_branches.len() + 1)); + .unwrap_or_else(|| { + dedup( + &all_virtual_branches + .iter() + .map(|b| b.name.as_str()) + .collect::>(), + "Virtual branch", + ) + }); let mut branch = Branch { id: Uuid::new_v4().to_string(),