gix/repository/
impls.rs

1use std::ops::DerefMut;
2
3use gix_hash::ObjectId;
4use gix_object::Exists;
5
6impl Clone for crate::Repository {
7    fn clone(&self) -> Self {
8        let mut new = crate::Repository::from_refs_and_objects(
9            self.refs.clone(),
10            self.objects.clone(),
11            self.work_tree.clone(),
12            self.common_dir.clone(),
13            self.config.clone(),
14            self.options.clone(),
15            #[cfg(feature = "index")]
16            self.index.clone(),
17            self.shallow_commits.clone(),
18            #[cfg(feature = "attributes")]
19            self.modules.clone(),
20        );
21
22        if self.bufs.is_none() {
23            new.bufs.take();
24        }
25
26        new
27    }
28}
29
30impl std::fmt::Debug for crate::Repository {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        f.debug_struct("Repository")
33            .field("kind", &self.kind())
34            .field("git_dir", &self.git_dir())
35            .field("workdir", &self.workdir())
36            .finish()
37    }
38}
39
40impl PartialEq<crate::Repository> for crate::Repository {
41    fn eq(&self, other: &crate::Repository) -> bool {
42        self.git_dir().canonicalize().ok() == other.git_dir().canonicalize().ok()
43            && self.work_tree.as_deref().and_then(|wt| wt.canonicalize().ok())
44                == other.work_tree.as_deref().and_then(|wt| wt.canonicalize().ok())
45    }
46}
47
48impl From<&crate::ThreadSafeRepository> for crate::Repository {
49    fn from(repo: &crate::ThreadSafeRepository) -> Self {
50        crate::Repository::from_refs_and_objects(
51            repo.refs.clone(),
52            gix_odb::memory::Proxy::from(gix_odb::Cache::from(repo.objects.to_handle())).with_write_passthrough(),
53            repo.work_tree.clone(),
54            repo.common_dir.clone(),
55            repo.config.clone(),
56            repo.linked_worktree_options.clone(),
57            #[cfg(feature = "index")]
58            repo.index.clone(),
59            repo.shallow_commits.clone(),
60            #[cfg(feature = "attributes")]
61            repo.modules.clone(),
62        )
63    }
64}
65
66impl From<crate::ThreadSafeRepository> for crate::Repository {
67    fn from(repo: crate::ThreadSafeRepository) -> Self {
68        crate::Repository::from_refs_and_objects(
69            repo.refs,
70            gix_odb::memory::Proxy::from(gix_odb::Cache::from(repo.objects.to_handle())).with_write_passthrough(),
71            repo.work_tree,
72            repo.common_dir,
73            repo.config,
74            repo.linked_worktree_options,
75            #[cfg(feature = "index")]
76            repo.index,
77            repo.shallow_commits,
78            #[cfg(feature = "attributes")]
79            repo.modules.clone(),
80        )
81    }
82}
83
84impl From<crate::Repository> for crate::ThreadSafeRepository {
85    fn from(r: crate::Repository) -> Self {
86        crate::ThreadSafeRepository {
87            refs: r.refs,
88            objects: r.objects.into_inner().store(),
89            work_tree: r.work_tree,
90            common_dir: r.common_dir,
91            config: r.config,
92            linked_worktree_options: r.options,
93            #[cfg(feature = "index")]
94            index: r.index,
95            #[cfg(feature = "attributes")]
96            modules: r.modules,
97            shallow_commits: r.shallow_commits,
98        }
99    }
100}
101
102impl gix_object::Write for crate::Repository {
103    fn write(&self, object: &dyn gix_object::WriteTo) -> Result<gix_hash::ObjectId, gix_object::write::Error> {
104        let mut buf = self.empty_reusable_buffer();
105        object.write_to(buf.deref_mut())?;
106        self.write_buf(object.kind(), &buf)
107    }
108
109    fn write_buf(&self, object: gix_object::Kind, from: &[u8]) -> Result<gix_hash::ObjectId, gix_object::write::Error> {
110        let oid = gix_object::compute_hash(self.object_hash(), object, from)?;
111        if self.objects.exists(&oid) {
112            return Ok(oid);
113        }
114        self.objects.write_buf(object, from)
115    }
116
117    fn write_stream(
118        &self,
119        kind: gix_object::Kind,
120        size: u64,
121        from: &mut dyn std::io::Read,
122    ) -> Result<gix_hash::ObjectId, gix_object::write::Error> {
123        let mut buf = self.empty_reusable_buffer();
124        let bytes = std::io::copy(from, buf.deref_mut())?;
125        if size != bytes {
126            return Err(format!("Found {bytes} bytes in stream, but had {size} bytes declared").into());
127        }
128        self.write_buf(kind, &buf)
129    }
130}
131
132impl gix_object::FindHeader for crate::Repository {
133    fn try_header(&self, id: &gix_hash::oid) -> Result<Option<gix_object::Header>, gix_object::find::Error> {
134        if id == ObjectId::empty_tree(self.object_hash()) {
135            return Ok(Some(gix_object::Header {
136                kind: gix_object::Kind::Tree,
137                size: 0,
138            }));
139        }
140        self.objects.try_header(id)
141    }
142}
143
144impl gix_object::Find for crate::Repository {
145    fn try_find<'a>(
146        &self,
147        id: &gix_hash::oid,
148        buffer: &'a mut Vec<u8>,
149    ) -> Result<Option<gix_object::Data<'a>>, gix_object::find::Error> {
150        if id == ObjectId::empty_tree(self.object_hash()) {
151            buffer.clear();
152            return Ok(Some(gix_object::Data {
153                kind: gix_object::Kind::Tree,
154                data: &[],
155            }));
156        }
157        self.objects.try_find(id, buffer)
158    }
159}
160
161impl gix_object::Exists for crate::Repository {
162    fn exists(&self, id: &gix_hash::oid) -> bool {
163        if id == ObjectId::empty_tree(self.object_hash()) {
164            return true;
165        }
166        self.objects.exists(id)
167    }
168}