History

Use `git-chunk` crate for all chunk-related operations (#279)

Sebastian Thiel committed 4 years ago

Commit 0cd7f3b1 parent e14096e1 file · +47 −70Browse files

Showing the changes to git-commitgraph/src (1 of 1 file). Show all

Unified · Split

git-commitgraph/src/file/init.rs+47−70
@@ -44,6 +44,8 @@ pub enum Error { · 43 unmodified lines
44 },44 },
45 #[error("Missing required chunk {:?}", .0.as_bstr())]45 #[error("Missing required chunk {:?}", .0.as_bstr())]
46 MissingChunk(ChunkId),46 MissingChunk(ChunkId),
47 #[error(transparent)]
48 MissingChunk2(#[from] git_chunk::file::index::offset_by_kind::Error),
47 #[error("{0}")]49 #[error("{0}")]
48 Trailer(String),50 Trailer(String),
49 #[error("Commit-graph file uses unsupported hash version: {0}")]51 #[error("Commit-graph file uses unsupported hash version: {0}")]
@@ -116,41 +118,30 @@ impl TryFrom<&Path> for File { · 66 unmodified lines
116 118
117 let chunks = git_chunk::file::Index::from_bytes(&data, ofs, chunk_count as u32)?;119 let chunks = git_chunk::file::Index::from_bytes(&data, ofs, chunk_count as u32)?;
118 120
119 let mut base_graphs_list_offset: Option<usize> = None;121 let base_graphs_list_offset = match chunks.usize_offset_by_id(BASE_GRAPHS_LIST_CHUNK_ID).ok() {
120 let mut commit_data_offset: Option<usize> = None;122 Some(chunk_range) => {
121 let mut commit_data_count = 0u32;123 let chunk_size = chunk_range.len();
122 let mut fan_offset: Option<usize> = None;124 if chunk_size % SHA1_SIZE != 0 {
123 let mut oid_lookup_offset: Option<usize> = None;125 return Err(Error::InvalidChunkSize {
124 let mut oid_lookup_count = 0u32;126 id: BASE_GRAPHS_LIST_CHUNK_ID,
125 127 msg: format!("chunk size {} is not a multiple of {}", chunk_size, SHA1_SIZE),
126 if let Some(chunk_range) = chunks128 });
127 .offset_by_id(BASE_GRAPHS_LIST_CHUNK_ID)129 }
128 .ok()130 let chunk_base_graph_count: u32 = (chunk_size / SHA1_SIZE)
129 .and_then(git_chunk::range::into_usize)131 .try_into()
130 {132 .expect("base graph count to fit in 32-bits");
131 let chunk_size = chunk_range.len();133 if chunk_base_graph_count != u32::from(base_graph_count) {
132 if chunk_size % SHA1_SIZE != 0 {134 return Err(Error::BaseGraphMismatch {
133 return Err(Error::InvalidChunkSize {135 from_chunk: chunk_base_graph_count,
134 id: BASE_GRAPHS_LIST_CHUNK_ID,136 from_header: base_graph_count,
135 msg: format!("chunk size {} is not a multiple of {}", chunk_size, SHA1_SIZE),137 });
136 });138 }
137 }139 Some(chunk_range.start)
138 let chunk_base_graph_count: u32 = (chunk_size / SHA1_SIZE)
139 .try_into()
140 .expect("base graph count to fit in 32-bits");
141 if chunk_base_graph_count != u32::from(base_graph_count) {
142 return Err(Error::BaseGraphMismatch {
143 from_chunk: chunk_base_graph_count,
144 from_header: base_graph_count,
145 });
146 }140 }
147 base_graphs_list_offset = Some(chunk_range.start);141 None => None,
148 }142 };
149 if let Some(chunk_range) = chunks143 let (commit_data_offset, commit_data_count) = {
150 .offset_by_id(COMMIT_DATA_CHUNK_ID)144 let chunk_range = chunks.usize_offset_by_id(COMMIT_DATA_CHUNK_ID)?;
151 .ok()
152 .and_then(git_chunk::range::into_usize)
153 {
154 let chunk_size = chunk_range.len();145 let chunk_size = chunk_range.len();
155 146
156 if chunk_size % COMMIT_DATA_ENTRY_SIZE != 0 {147 if chunk_size % COMMIT_DATA_ENTRY_SIZE != 0 {
@@ -162,22 +153,21 @@ impl TryFrom<&Path> for File { · 5 unmodified lines
162 ),153 ),
163 });154 });
164 }155 }
165 commit_data_offset = Some(chunk_range.start);156 (
166 commit_data_count = (chunk_size / COMMIT_DATA_ENTRY_SIZE)157 chunk_range.start,
167 .try_into()158 (chunk_size / COMMIT_DATA_ENTRY_SIZE)
168 .expect("number of commits in CDAT chunk to fit in 32 bits");159 .try_into()
169 }160 .expect("number of commits in CDAT chunk to fit in 32 bits"),
161 )
162 };
170 163
171 let extra_edges_list_range = chunks164 let extra_edges_list_range = chunks
172 .offset_by_id(EXTENDED_EDGES_LIST_CHUNK_ID)165 .offset_by_id(EXTENDED_EDGES_LIST_CHUNK_ID)
173 .ok()166 .ok()
174 .and_then(git_chunk::range::into_usize);167 .and_then(git_chunk::range::into_usize);
175 168
176 if let Some(chunk_range) = chunks169 let fan_offset = {
177 .offset_by_id(OID_FAN_CHUNK_ID)170 let chunk_range = chunks.usize_offset_by_id(OID_FAN_CHUNK_ID)?;
178 .ok()
179 .and_then(git_chunk::range::into_usize)
180 {
181 let chunk_size = chunk_range.len();171 let chunk_size = chunk_range.len();
182 172
183 let expected_size = 4 * FAN_LEN;173 let expected_size = 4 * FAN_LEN;
@@ -187,39 +177,29 @@ impl TryFrom<&Path> for File { · 3 unmodified lines
187 msg: format!("expected chunk length {}, got {}", expected_size, chunk_size),177 msg: format!("expected chunk length {}, got {}", expected_size, chunk_size),
188 });178 });
189 }179 }
190 fan_offset = Some(chunk_range.start);180 chunk_range.start
191 }181 };
192 182
193 if let Some(chunk_range) = chunks183 let (oid_lookup_offset, oid_lookup_count) = {
194 .offset_by_id(OID_LOOKUP_CHUNK_ID)184 let chunk_range = chunks.usize_offset_by_id(OID_LOOKUP_CHUNK_ID)?;
195 .ok()
196 .and_then(git_chunk::range::into_usize)
197 {
198 let chunk_size = chunk_range.len();185 let chunk_size = chunk_range.len();
199 186
200 if chunk_size % OID_LOOKUP_ENTRY_SIZE != 0 {187 if chunk_size % OID_LOOKUP_ENTRY_SIZE != 0 {
201 return Err(Error::InvalidChunkSize {188 return Err(Error::InvalidChunkSize {
202 id: OID_FAN_CHUNK_ID,189 id: OID_LOOKUP_CHUNK_ID,
203 msg: format!(190 msg: format!(
204 "chunk size {} is not a multiple of {}",191 "chunk size {} is not a multiple of {}",
205 chunk_size, OID_LOOKUP_ENTRY_SIZE192 chunk_size, OID_LOOKUP_ENTRY_SIZE
206 ),193 ),
207 });194 });
208 }195 }
209 oid_lookup_offset = Some(chunk_range.start);196 (
210 oid_lookup_count = (chunk_size / OID_LOOKUP_ENTRY_SIZE)197 chunk_range.start,
211 .try_into()198 (chunk_size / OID_LOOKUP_ENTRY_SIZE)
212 .expect("number of commits in OIDL chunk to fit in 32 bits");199 .try_into()
213 // TODO(ST): Figure out how to handle this. Don't know what to do with the commented code.200 .expect("number of commits in OIDL chunk to fit in 32 bits"),
214 // git allows extra garbage in the extra edges list chunk?201 )
215 // if oid_lookup_count > 0 {202 };
216 // let last_edge = &data[next_chunk_offset - 4..next_chunk_offset];
217 // let last_edge = BigEndian::read_u32(last_edge);
218 // if let ExtraEdge::Internal(_) = ExtraEdge::from_raw(last_edge) {
219 // return Err(Error::ExtraEdgesListOverflow);
220 // }
221 // }
222 }
223 203
224 let trailer = &data[chunks.highest_offset() as usize..];204 let trailer = &data[chunks.highest_offset() as usize..];
225 if trailer.len() != TRAILER_LEN {205 if trailer.len() != TRAILER_LEN {
@@ -230,10 +210,7 @@ impl TryFrom<&Path> for File { · 4 unmodified lines
230 )));210 )));
231 }211 }
232 212
233 let fan_offset = fan_offset.ok_or(Error::MissingChunk(OID_FAN_CHUNK_ID))?;213 if base_graph_count > 0 && base_graphs_list_offset.is_none() {
234 let oid_lookup_offset = oid_lookup_offset.ok_or(Error::MissingChunk(OID_LOOKUP_CHUNK_ID))?;
235 let commit_data_offset = commit_data_offset.ok_or(Error::MissingChunk(COMMIT_DATA_CHUNK_ID))?;
236 if base_graph_count > 0 && base_graphs_list_offset == None {
237 return Err(Error::MissingChunk(BASE_GRAPHS_LIST_CHUNK_ID));214 return Err(Error::MissingChunk(BASE_GRAPHS_LIST_CHUNK_ID));
238 }215 }
239 216