diff --git a/atuin-client/src/history/store.rs b/atuin-client/src/history/store.rs index ab88182a..73166de1 100644 --- a/atuin-client/src/history/store.rs +++ b/atuin-client/src/history/store.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use eyre::{bail, eyre, Result}; use rmp::decode::Bytes; @@ -230,6 +232,20 @@ impl HistoryStore { Ok(()) } + + /// Get a list of history IDs that exist in the store + /// Note: This currently involves loading all history into memory. This is not going to be a + /// large amount in absolute terms, but do not all it in a hot loop. + pub async fn history_ids(&self) -> Result> { + let history = self.history().await?; + + let ret = HashSet::from_iter(history.iter().map(|h| match h { + HistoryRecord::Create(h) => h.id.clone(), + HistoryRecord::Delete(id) => id.clone(), + })); + + Ok(ret) + } } #[cfg(test)] diff --git a/atuin/src/command/client/history.rs b/atuin/src/command/client/history.rs index 7d4689f9..7a12b699 100644 --- a/atuin/src/command/client/history.rs +++ b/atuin/src/command/client/history.rs @@ -374,11 +374,20 @@ impl Cmd { ) -> Result<()> { println!("Importing all history.db data into records.db"); + println!("Fetching history from old database"); let history = db.list(&[], &context, None, false, true).await?; + println!("Fetching history already in store"); + let store_ids = store.history_ids().await?; + for i in history { println!("loaded {}", i.id); + if store_ids.contains(&i.id) { + println!("skipping {} - already exists", i.id); + continue; + } + if i.deleted_at.is_some() { store.push(i.clone()).await?; store.delete(i.id).await?;