Skip to content

Commit 083a834

Browse files
authored
Allow merging when migrating from z (#33)
If the user passes the `--merge` flag to the `migrate` subcommand, all duplicate entries will have their ranks and epochs updated: the rank will be the sum of the stored rank and the newly-parsed rank, while the epoch will be the maximum of the stored epoch and the newly-parsed epoch. This allows one to import from the `z` database even after having used `zoxide` for any amount of time. This also permits a user who has already sourced the init script to import their old database without needing to do something like `rm ~/.zo && zoxide migrate ~/.z`.
1 parent f4cd115 commit 083a834

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

src/db.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ impl DB {
7070
Ok(())
7171
}
7272

73-
pub fn migrate<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
74-
if !self.dirs.is_empty() {
73+
pub fn migrate<P: AsRef<Path>>(&mut self, path: P, merge: bool) -> Result<()> {
74+
if !self.dirs.is_empty() && !merge {
7575
bail!(
76-
"To prevent conflicts, you can only migrate from z with an empty \
77-
zoxide database!"
76+
"To prevent conflicts, you can only migrate from z with an empty zoxide database!
77+
If you wish to merge the two, specify the `--merge` flag."
7878
);
7979
}
8080

@@ -87,7 +87,10 @@ impl DB {
8787
let line = if let Ok(line) = read_line {
8888
line
8989
} else {
90-
eprintln!("could not read line {}: {:?}", line_number, read_line);
90+
eprintln!(
91+
"could not read entry at line {}: {:?}",
92+
line_number, read_line
93+
);
9194
continue;
9295
};
9396

@@ -131,6 +134,17 @@ impl DB {
131134
}
132135
};
133136

137+
if merge {
138+
// If the path exists in the database, add the ranks and set the epoch to
139+
// the largest of the parsed epoch and the already present epoch.
140+
if let Some(dir) = self.dirs.iter_mut().find(|dir| dir.path == path_str) {
141+
dir.rank += rank;
142+
dir.last_accessed = Epoch::max(epoch, dir.last_accessed);
143+
144+
continue;
145+
};
146+
}
147+
134148
// FIXME: When we switch to PathBuf for storing directories inside Dir, just
135149
// pass `PathBuf::from(path_str)`
136150
self.dirs.push(Dir {

src/subcommand/migrate.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ use structopt::StructOpt;
77
#[structopt(about = "Migrate from z database")]
88
pub struct Migrate {
99
path: String,
10+
11+
#[structopt(long, help = "Merge entries into existing database")]
12+
merge: bool,
1013
}
1114

1215
impl Migrate {
1316
pub fn run(&self, env: &Env) -> Result<()> {
14-
util::get_db(env)?.migrate(&self.path)
17+
util::get_db(env)?.migrate(&self.path, self.merge)
1518
}
1619
}

0 commit comments

Comments
 (0)