ok/jj
1
0
Fork 0
forked from mirrors/jj

git: on import_refs(), exclude uninteresting dirs such as refs/jj/keep

For loose refs, uninteresting directories can be just skipped. For packed refs,
gix will have to do binary search for each prefix to find the starting point.
Still it's better overall if the repository contains tons of refs/jj/keep refs.

With my linux repo containing ~5k loose jj refs, this saves ~40ms:

    % hyperfine --warmup 3 --runs 10 \
        "/tmp/jj-gix --ignore-working-copy git import -R ~/mirrors/linux" \
        "/tmp/jj-gix-iter --ignore-working-copy git import -R ~/mirrors/linux"
    Benchmark 1: /tmp/jj-gix --ignore-working-copy git import -R ~/mirrors/linux
      Time (mean ± σ):     151.6 ms ±  11.4 ms    [User: 38.8 ms, System: 111.6 ms]
      Range (min … max):   129.8 ms … 159.5 ms    10 runs
    Benchmark 2: /tmp/jj-gix-iter --ignore-working-copy git import -R ~/mirrors/linux
      Time (mean ± σ):     109.9 ms ±  11.6 ms    [User: 27.5 ms, System: 82.4 ms]
      Range (min … max):    89.4 ms … 117.8 ms    10 runs
This commit is contained in:
Yuya Nishihara 2023-11-13 21:27:37 +09:00
parent 044716ee40
commit 39b065f7ab

View file

@ -424,10 +424,19 @@ fn diff_refs_to_import(
)
.filter(|(ref_name, _)| git_ref_filter(ref_name))
.collect();
let mut changed_git_refs = Vec::new();
let mut changed_remote_refs = BTreeMap::new();
let git_references = git_repo.references().map_err(GitImportError::from_git)?;
for git_ref in git_references.all().map_err(GitImportError::from_git)? {
let chain_git_refs_iters = || -> Result<_, gix::reference::iter::init::Error> {
// Exclude uninteresting directories such as refs/jj/keep.
Ok(itertools::chain!(
git_references.local_branches()?,
git_references.remote_branches()?,
git_references.tags()?,
))
};
for git_ref in chain_git_refs_iters().map_err(GitImportError::from_git)? {
let git_ref = git_ref.map_err(GitImportError::from_git)?;
let Ok(full_name) = str::from_utf8(git_ref.name().as_bstr()) else {
// Skip non-utf8 refs.