Skip to content

Commit

Permalink
rewrite: optimize for rebase onto metadata-only change
Browse files Browse the repository at this point in the history
When you run e.g. `jj describe <some old commit>` or `jj squash -r
<some old commit>`, the descendants' tree objects will not change, so
we can avoid calculating them. This speeds up rebasing of 126 commits
in the git.git repo from ~9.8 s to ~3.6 s.
  • Loading branch information
martinvonz committed Dec 8, 2021
1 parent 7b72451 commit f084a05
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
6 changes: 5 additions & 1 deletion lib/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::hash::{Hash, Hasher};
use std::sync::Arc;

use crate::backend;
use crate::backend::{ChangeId, CommitId, Signature};
use crate::backend::{ChangeId, CommitId, Signature, TreeId};
use crate::repo_path::RepoPath;
use crate::store::Store;
use crate::tree::Tree;
Expand Down Expand Up @@ -112,6 +112,10 @@ impl Commit {
.unwrap()
}

pub fn tree_id(&self) -> &TreeId {
&self.data.root_tree
}

pub fn change_id(&self) -> &ChangeId {
&self.data.change_id
}
Expand Down
22 changes: 18 additions & 4 deletions lib/src/rewrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,24 @@ pub fn rebase_commit(
new_parents: &[Commit],
) -> Commit {
let store = mut_repo.store();
let old_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), &old_commit.parents());
let new_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), new_parents);
// TODO: pass in labels for the merge parts
let new_tree_id = merge_trees(&new_base_tree, &old_base_tree, &old_commit.tree()).unwrap();
let old_parents = old_commit.parents();
let old_parent_trees = old_parents
.iter()
.map(|parent| parent.store_commit().root_tree.clone())
.collect_vec();
let new_parent_trees = new_parents
.iter()
.map(|parent| parent.store_commit().root_tree.clone())
.collect_vec();
let new_tree_id = if new_parent_trees == old_parent_trees {
// Optimization
old_commit.tree_id().clone()
} else {
let old_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), &old_parents);
let new_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), new_parents);
// TODO: pass in labels for the merge parts
merge_trees(&new_base_tree, &old_base_tree, &old_commit.tree()).unwrap()
};
let new_parent_ids = new_parents
.iter()
.map(|commit| commit.id().clone())
Expand Down

0 comments on commit f084a05

Please sign in to comment.