branchless/core/rewrite/
mod.rs

1//! Tools for editing the commit graph.
2
3mod evolve;
4mod execute;
5mod plan;
6pub mod rewrite_hooks;
7
8use std::sync::Mutex;
9
10pub use evolve::{find_abandoned_children, find_rewrite_target};
11pub use execute::{
12    execute_rebase_plan, move_branches, ExecuteRebasePlanOptions, ExecuteRebasePlanResult,
13    FailedMergeInfo, MergeConflictRemediation,
14};
15pub use plan::{
16    BuildRebasePlanError, BuildRebasePlanOptions, OidOrLabel, RebaseCommand, RebasePlan,
17    RebasePlanBuilder, RebasePlanPermissions,
18};
19use tracing::instrument;
20
21use crate::core::task::{Resource, ResourcePool};
22use crate::git::Repo;
23
24/// A thread-safe [`Repo`] resource pool.
25#[derive(Debug)]
26pub struct RepoResource {
27    repo: Mutex<Repo>,
28}
29
30impl RepoResource {
31    /// Make a copy of the provided [`Repo`] and use that to populate the
32    /// [`ResourcePool`].
33    #[instrument]
34    pub fn new_pool(repo: &Repo) -> eyre::Result<ResourcePool<Self>> {
35        let repo = Mutex::new(repo.try_clone()?);
36        let resource = Self { repo };
37        Ok(ResourcePool::new(resource))
38    }
39}
40
41impl Resource for RepoResource {
42    type Output = Repo;
43
44    type Error = eyre::Error;
45
46    fn try_create(&self) -> Result<Self::Output, Self::Error> {
47        let repo = self
48            .repo
49            .lock()
50            .map_err(|_| eyre::eyre!("Poisoned mutex for RepoResource"))?;
51        let repo = repo.try_clone()?;
52        Ok(repo)
53    }
54}
55
56/// Type synonym for [`ResourcePool<RepoResource>`].
57pub type RepoPool = ResourcePool<RepoResource>;
58
59/// Testing helpers.
60pub mod testing {
61    use std::collections::HashSet;
62    use std::path::PathBuf;
63
64    use chashmap::CHashMap;
65
66    use crate::core::dag::Dag;
67    use crate::core::rewrite::{BuildRebasePlanOptions, RebasePlanPermissions};
68    use crate::git::NonZeroOid;
69
70    use super::RebasePlanBuilder;
71
72    /// Create a `RebasePlanPermissions` that can rewrite any commit, for testing.
73    pub fn omnipotent_rebase_plan_permissions(
74        dag: &Dag,
75        build_options: BuildRebasePlanOptions,
76    ) -> eyre::Result<RebasePlanPermissions> {
77        Ok(RebasePlanPermissions {
78            build_options,
79            allowed_commits: dag.query_all()?,
80        })
81    }
82
83    /// Get the internal touched paths cache for a `RebasePlanBuilder`.
84    pub fn get_builder_touched_paths_cache<'a>(
85        builder: &'a RebasePlanBuilder,
86    ) -> &'a CHashMap<NonZeroOid, HashSet<PathBuf>> {
87        &builder.touched_paths_cache
88    }
89}