History

migrate hashing API users to fallible versions

Emily committed 1 year ago

Commit fbf6cc81 parent f2b07c032 files · +115 −84Browse files

Unified · Split

32 files
  1. gix-commitgraph/src/file/verify.rs +1 −1
  2. gix-diff/tests/diff/blob/pipeline.rs +14 −14
  3. gix-diff/tests/diff/blob/platform.rs +4 −4
  4. gix-diff/tests/diff/main.rs +3 −3
  5. gix-diff/tests/diff/rewrites/tracker.rs +11 −11
  6. gix-filter/src/ident.rs +1 −1
  7. gix-hash/src/hasher/io.rs +1 −1
  8. gix-index/src/extension/end_of_index_entry/decode.rs +1 −1
  9. gix-index/src/extension/end_of_index_entry/write.rs +1 −1
  10. gix-index/src/file/write.rs +1 −1
  11. gix-merge/tests/merge/blob/mod.rs +3 −3
  12. gix-merge/tests/merge/blob/pipeline.rs +6 −6
  13. gix-merge/tests/merge/blob/platform.rs +5 −5
  14. gix-object/benches/edit_tree.rs +1 −1
  15. gix-object/src/data.rs +1 −1
  16. gix-object/tests/object/main.rs +2 −2
  17. gix-object/tests/object/tree/editor.rs +1 −1
  18. gix-odb/src/memory.rs +1 −1
  19. gix-odb/src/sink.rs +1 −1
  20. gix-odb/src/store_impls/loose/verify.rs +5 −1
  21. gix-odb/src/store_impls/loose/write.rs +5 −1
  22. gix-pack/src/data/input/bytes_to_entries.rs +2 −2
  23. gix-pack/src/data/output/bytes.rs +6 −1
  24. gix-pack/src/index/encode.rs +1 −1
  25. gix-pack/src/index/write/mod.rs +10 −7
  26. gix-pack/src/multi_index/write.rs +1 −1
  27. gix-pack/src/verify.rs +2 −1
  28. gix-status/src/index_as_worktree/traits.rs +4 −2
  29. gix-status/src/index_as_worktree_with_renames/mod.rs +8 −3
  30. gix/src/repository/impls.rs +1 −1
  31. gix/src/repository/object.rs +6 −3
  32. tests/it/src/commands/git_to_sh.rs +5 −1
gix-commitgraph/src/file/verify.rs+1−1
@@ -156,7 +156,7 @@ impl File { · 155 unmodified lines
156 let data_len_without_trailer = self.data.len() - self.hash_len;156 let data_len_without_trailer = self.data.len() - self.hash_len;
157 let mut hasher = gix_hash::hasher(self.object_hash());157 let mut hasher = gix_hash::hasher(self.object_hash());
158 hasher.update(&self.data[..data_len_without_trailer]);158 hasher.update(&self.data[..data_len_without_trailer]);
159 let actual = hasher.finalize();159 let actual = hasher.try_finalize()?;
160 actual.verify(self.checksum())?;160 actual.verify(self.checksum())?;
161 Ok(actual)161 Ok(actual)
162 }162 }
gix-diff/tests/diff/blob/pipeline.rs+14−14
@@ -72,7 +72,7 @@ pub(crate) mod convert_to_diffable { · 71 unmodified lines
72 72
73 let mut db = ObjectDb::default();73 let mut db = ObjectDb::default();
74 let b_content = "b-content";74 let b_content = "b-content";
75 let id = db.insert(b_content);75 let id = db.insert(b_content)?;
76 76
77 let out = filter.convert_to_diffable(77 let out = filter.convert_to_diffable(
78 &id,78 &id,
@@ -129,7 +129,7 @@ pub(crate) mod convert_to_diffable { · 50 unmodified lines
129 assert_eq!(buf.len(), 0, "it should avoid querying that data in the first place");129 assert_eq!(buf.len(), 0, "it should avoid querying that data in the first place");
130 130
131 let mut db = ObjectDb::default();131 let mut db = ObjectDb::default();
132 let id = db.insert(large_content);132 let id = db.insert(large_content)?;
133 let out = filter.convert_to_diffable(133 let out = filter.convert_to_diffable(
134 &id,134 &id,
135 EntryKind::Blob,135 EntryKind::Blob,
@@ -211,7 +211,7 @@ pub(crate) mod convert_to_diffable { · 75 unmodified lines
211 drop(tmp);211 drop(tmp);
212 212
213 let mut db = ObjectDb::default();213 let mut db = ObjectDb::default();
214 let id = db.insert(large_content);214 let id = db.insert(large_content)?;
215 215
216 let out = filter.convert_to_diffable(216 let out = filter.convert_to_diffable(
217 &id,217 &id,
@@ -397,7 +397,7 @@ pub(crate) mod convert_to_diffable { · 179 unmodified lines
397 397
398 let mut db = ObjectDb::default();398 let mut db = ObjectDb::default();
399 let b_content = "b-content\n";399 let b_content = "b-content\n";
400 let id = db.insert(b_content);400 let id = db.insert(b_content)?;
401 401
402 let out = filter.convert_to_diffable(402 let out = filter.convert_to_diffable(
403 &id,403 &id,
@@ -416,7 +416,7 @@ pub(crate) mod convert_to_diffable { · 12 unmodified lines
416 416
417 let mut db = ObjectDb::default();417 let mut db = ObjectDb::default();
418 let b_content = "b\n";418 let b_content = "b\n";
419 let id = db.insert(b_content);419 let id = db.insert(b_content)?;
420 let out = filter.convert_to_diffable(420 let out = filter.convert_to_diffable(
421 &id,421 &id,
422 EntryKind::Blob,422 EntryKind::Blob,
@@ -490,7 +490,7 @@ pub(crate) mod convert_to_diffable { · 67 unmodified lines
490 490
491 let mut db = ObjectDb::default();491 let mut db = ObjectDb::default();
492 let b_content = "b-co\0ntent\n";492 let b_content = "b-co\0ntent\n";
493 let id = db.insert(b_content);493 let id = db.insert(b_content)?;
494 494
495 let out = filter.convert_to_diffable(495 let out = filter.convert_to_diffable(
496 &id,496 &id,
@@ -509,7 +509,7 @@ pub(crate) mod convert_to_diffable { · 12 unmodified lines
509 509
510 let platform = attributes.at_entry("c", None, &gix_object::find::Never)?;510 let platform = attributes.at_entry("c", None, &gix_object::find::Never)?;
511 511
512 let id = db.insert("b");512 let id = db.insert("b")?;
513 let out = filter.convert_to_diffable(513 let out = filter.convert_to_diffable(
514 &id,514 &id,
515 EntryKind::Blob,515 EntryKind::Blob,
@@ -638,7 +638,7 @@ pub(crate) mod convert_to_diffable { · 122 unmodified lines
638 assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));638 assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));
639 assert_eq!(buf.as_bstr(), "a\n", "unconditionally use git according to mode");639 assert_eq!(buf.as_bstr(), "a\n", "unconditionally use git according to mode");
640 640
641 let id = db.insert("a\n");641 let id = db.insert("a\n")?;
642 for mode in worktree_modes {642 for mode in worktree_modes {
643 let out = filter.convert_to_diffable(643 let out = filter.convert_to_diffable(
644 &id,644 &id,
@@ -714,7 +714,7 @@ pub(crate) mod convert_to_diffable { · 69 unmodified lines
714 assert_eq!(buf.len(), 0, "always cleared");714 assert_eq!(buf.len(), 0, "always cleared");
715 715
716 buf.push(1);716 buf.push(1);
717 let id = db.insert("link-target");717 let id = db.insert("link-target")?;
718 let out = filter.convert_to_diffable(718 let out = filter.convert_to_diffable(
719 &id,719 &id,
720 EntryKind::Link,720 EntryKind::Link,
@@ -761,7 +761,7 @@ pub(crate) mod convert_to_diffable { · 40 unmodified lines
761 assert_eq!(buf.len(), 0, "it's always cleared before any potential use");761 assert_eq!(buf.len(), 0, "it's always cleared before any potential use");
762 }762 }
763 763
764 let id = db.insert("b\n");764 let id = db.insert("b\n")?;
765 for mode in all_modes {765 for mode in all_modes {
766 buf.push(1);766 buf.push(1);
767 let out = filter.convert_to_diffable(767 let out = filter.convert_to_diffable(
@@ -814,7 +814,7 @@ pub(crate) mod convert_to_diffable { · 46 unmodified lines
814 );814 );
815 }815 }
816 816
817 let id = db.insert("c\n");817 let id = db.insert("c\n")?;
818 for mode in worktree_modes {818 for mode in worktree_modes {
819 let out = filter.convert_to_diffable(819 let out = filter.convert_to_diffable(
820 &id,820 &id,
@@ -863,7 +863,7 @@ pub(crate) mod convert_to_diffable { · 42 unmodified lines
863 assert_eq!(buf.len(), 0);863 assert_eq!(buf.len(), 0);
864 }864 }
865 865
866 let id = db.insert("unset\n");866 let id = db.insert("unset\n")?;
867 for mode in all_modes {867 for mode in all_modes {
868 let out = filter.convert_to_diffable(868 let out = filter.convert_to_diffable(
869 &id,869 &id,
@@ -890,7 +890,7 @@ pub(crate) mod convert_to_diffable { · 20 unmodified lines
890 }890 }
891 891
892 let platform = attributes.at_entry("d", None, &gix_object::find::Never)?;892 let platform = attributes.at_entry("d", None, &gix_object::find::Never)?;
893 let id = db.insert("d-in-db");893 let id = db.insert("d-in-db")?;
894 for mode in worktree_modes {894 for mode in worktree_modes {
895 let out = filter.convert_to_diffable(895 let out = filter.convert_to_diffable(
896 &null,896 &null,
@@ -959,7 +959,7 @@ pub(crate) mod convert_to_diffable { · 62 unmodified lines
959 "no text filter, so git conversion was applied for worktree source"959 "no text filter, so git conversion was applied for worktree source"
960 );960 );
961 961
962 let id = db.insert("e-in-db");962 let id = db.insert("e-in-db")?;
963 let out = filter.convert_to_diffable(963 let out = filter.convert_to_diffable(
964 &id,964 &id,
965 EntryKind::Blob,965 EntryKind::Blob,
gix-diff/tests/diff/blob/platform.rs+4−4
@@ -30,7 +30,7 @@ fn resources_of_worktree_and_odb_and_check_link() -> crate::Result { · 29 unmodified lines
30 30
31 let mut db = ObjectDb::default();31 let mut db = ObjectDb::default();
32 let a_content = "a-content";32 let a_content = "a-content";
33 let id = db.insert(a_content);33 let id = db.insert(a_content)?;
34 platform.set_resource(34 platform.set_resource(
35 id,35 id,
36 EntryKind::BlobExecutable,36 EntryKind::BlobExecutable,
@@ -194,7 +194,7 @@ fn diff_binary() -> crate::Result { · 157 unmodified lines
194 194
195 let mut db = ObjectDb::default();195 let mut db = ObjectDb::default();
196 let a_content = "b";196 let a_content = "b";
197 let id = db.insert(a_content);197 let id = db.insert(a_content)?;
198 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::NewOrDestination, &db)?;198 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::NewOrDestination, &db)?;
199 199
200 let out = platform.prepare_diff()?;200 let out = platform.prepare_diff()?;
@@ -235,7 +235,7 @@ fn diff_performed_despite_external_command() -> crate::Result { · 34 unmodified lines
235 235
236 let mut db = ObjectDb::default();236 let mut db = ObjectDb::default();
237 let a_content = "b";237 let a_content = "b";
238 let id = db.insert(a_content);238 let id = db.insert(a_content)?;
239 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::NewOrDestination, &db)?;239 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::NewOrDestination, &db)?;
240 240
241 let out = platform.prepare_diff()?;241 let out = platform.prepare_diff()?;
@@ -277,7 +277,7 @@ fn diff_skipped_due_to_external_command_and_enabled_option() -> crate::Result { · 35 unmodified lines
277 277
278 let mut db = ObjectDb::default();278 let mut db = ObjectDb::default();
279 let a_content = "b";279 let a_content = "b";
280 let id = db.insert(a_content);280 let id = db.insert(a_content)?;
281 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::NewOrDestination, &db)?;281 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::NewOrDestination, &db)?;
282 282
283 let out = platform.prepare_diff()?;283 let out = platform.prepare_diff()?;
gix-diff/tests/diff/main.rs+3−3
@@ -51,10 +51,10 @@ mod util { · 50 unmodified lines
51 51
52 impl ObjectDb {52 impl ObjectDb {
53 /// Insert `data` and return its hash. That can be used to find it again.53 /// Insert `data` and return its hash. That can be used to find it again.
54 pub fn insert(&mut self, data: &str) -> gix_hash::ObjectId {54 pub fn insert(&mut self, data: &str) -> Result<gix_hash::ObjectId, Error> {
55 let id = gix_object::compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Blob, data.as_bytes());55 let id = gix_object::try_compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Blob, data.as_bytes())?;
56 self.data_by_id.insert(id, data.into());56 self.data_by_id.insert(id, data.into());
57 id57 Ok(id)
58 }58 }
59 }59 }
60}60}
gix-diff/tests/diff/rewrites/tracker.rs+11−11
@@ -92,7 +92,7 @@ fn copy_by_similarity_reports_limit_if_encountered() -> crate::Result { · 91 unmodified lines
92 (Change::addition(), "a-cpy-2", "a"),92 (Change::addition(), "a-cpy-2", "a"),
93 (Change::modification(), "d", "ab"),93 (Change::modification(), "d", "ab"),
94 ],94 ],
95 );95 )?;
96 96
97 let mut calls = 0;97 let mut calls = 0;
98 let out = util::assert_emit_with_objects(98 let out = util::assert_emit_with_objects(
@@ -145,7 +145,7 @@ fn copy_by_id() -> crate::Result { · 46 unmodified lines
145 (Change::addition(), "a-cpy-2", "a"),145 (Change::addition(), "a-cpy-2", "a"),
146 (Change::modification(), "d", "a"),146 (Change::modification(), "d", "a"),
147 ],147 ],
148 );148 )?;
149 149
150 let mut calls = 0;150 let mut calls = 0;
151 let out = util::assert_emit_with_objects(151 let out = util::assert_emit_with_objects(
@@ -218,7 +218,7 @@ fn copy_by_id_search_in_all_sources() -> crate::Result { · 66 unmodified lines
218 (Change::addition(), "a-cpy-1", "a"),218 (Change::addition(), "a-cpy-1", "a"),
219 (Change::addition(), "a-cpy-2", "a"),219 (Change::addition(), "a-cpy-2", "a"),
220 ],220 ],
221 );221 )?;
222 222
223 let mut calls = 0;223 let mut calls = 0;
224 let content_id = hex_to_id("2e65efe2a145dda7ee51d1741299f848e5bf752e");224 let content_id = hex_to_id("2e65efe2a145dda7ee51d1741299f848e5bf752e");
@@ -299,7 +299,7 @@ fn copy_by_50_percent_similarity() -> crate::Result { · 74 unmodified lines
299 (Change::addition(), "a-cpy-2", "a\nc"),299 (Change::addition(), "a-cpy-2", "a\nc"),
300 (Change::modification(), "d", "a"),300 (Change::modification(), "d", "a"),
301 ],301 ],
302 );302 )?;
303 303
304 let mut calls = 0;304 let mut calls = 0;
305 let out = util::assert_emit_with_objects(305 let out = util::assert_emit_with_objects(
@@ -377,7 +377,7 @@ fn copy_by_id_in_additions_only() -> crate::Result { · 71 unmodified lines
377 (Change::modification(), "a", "a"),377 (Change::modification(), "a", "a"),
378 (Change::modification(), "a-cpy-1", "a"),378 (Change::modification(), "a-cpy-1", "a"),
379 ],379 ],
380 );380 )?;
381 381
382 let mut calls = 0;382 let mut calls = 0;
383 let out = util::assert_emit_with_objects(383 let out = util::assert_emit_with_objects(
@@ -429,7 +429,7 @@ fn rename_by_similarity_reports_limit_if_encountered() -> crate::Result { · 45 unmodified lines
429 (Change::addition(), "b", "firt\nsecond\n"),429 (Change::addition(), "b", "firt\nsecond\n"),
430 (Change::addition(), "c", "second\nunrelated\n"),430 (Change::addition(), "c", "second\nunrelated\n"),
431 ],431 ],
432 );432 )?;
433 433
434 let mut calls = 0;434 let mut calls = 0;
435 let out = util::assert_emit_with_objects(435 let out = util::assert_emit_with_objects(
@@ -475,7 +475,7 @@ fn rename_by_50_percent_similarity() -> crate::Result { · 39 unmodified lines
475 (Change::addition(), "b", "firt\nsecond\n"),475 (Change::addition(), "b", "firt\nsecond\n"),
476 (Change::addition(), "c", "second\nunrelated\n"),476 (Change::addition(), "c", "second\nunrelated\n"),
477 ],477 ],
478 );478 )?;
479 479
480 let mut calls = 0;480 let mut calls = 0;
481 let out = util::assert_emit_with_objects(481 let out = util::assert_emit_with_objects(
@@ -596,7 +596,7 @@ fn directory_renames_by_id_can_fail_gracefully() -> crate::Result { · 114 unmodified lines
596 (Change::deletion(), "a", "first\nsecond\n"),596 (Change::deletion(), "a", "first\nsecond\n"),
597 (Change::addition(), "b", "firt\nsecond\n"),597 (Change::addition(), "b", "firt\nsecond\n"),
598 ],598 ],
599 );599 )?;
600 600
601 let mut calls = 0;601 let mut calls = 0;
602 let out = util::assert_emit_with_objects(602 let out = util::assert_emit_with_objects(
@@ -803,16 +803,16 @@ mod util { · 200 unmodified lines
803 pub fn add_retained_blobs<'a>(803 pub fn add_retained_blobs<'a>(
804 tracker: &mut rewrites::Tracker<Change>,804 tracker: &mut rewrites::Tracker<Change>,
805 blobs: impl IntoIterator<Item = (Change, &'a str, &'a str)>,805 blobs: impl IntoIterator<Item = (Change, &'a str, &'a str)>,
806 ) -> ObjectDb {806 ) -> crate::Result<ObjectDb> {
807 let mut db = ObjectDb::default();807 let mut db = ObjectDb::default();
808 for (mut change, location, data) in blobs {808 for (mut change, location, data) in blobs {
809 change.id = db.insert(data);809 change.id = db.insert(data)?;
810 assert!(810 assert!(
811 tracker.try_push_change(change, location.into()).is_none(),811 tracker.try_push_change(change, location.into()).is_none(),
812 "input changes must be tracked"812 "input changes must be tracked"
813 );813 );
814 }814 }
815 db815 Ok(db)
816 }816 }
817 817
818 pub fn assert_emit(818 pub fn assert_emit(
gix-filter/src/ident.rs+1−1
@@ -68,7 +68,7 @@ pub fn apply(src: &[u8], object_hash: gix_hash::Kind, buf: &mut Vec<u8>) -> Resu · 67 unmodified lines
68 while let Some(pos) = src[ofs..].find(b"$Id$") {68 while let Some(pos) = src[ofs..].find(b"$Id$") {
69 let id = match id {69 let id = match id {
70 None => {70 None => {
71 let new_id = gix_object::compute_hash(object_hash, gix_object::Kind::Blob, src);71 let new_id = gix_object::try_compute_hash(object_hash, gix_object::Kind::Blob, src)?;
72 id = new_id.into();72 id = new_id.into();
73 clear_and_set_capacity(buf, src.len() + HASH_LEN)?; // pre-allocate for one ID73 clear_and_set_capacity(buf, src.len() + HASH_LEN)?; // pre-allocate for one ID
74 new_id74 new_id
gix-hash/src/hasher/io.rs+1−1
@@ -76,7 +76,7 @@ pub fn bytes_with_hasher( · 75 unmodified lines
76 }76 }
77 }77 }
78 78
79 let id = hasher.finalize();79 let id = hasher.try_finalize()?;
80 progress.show_throughput(start);80 progress.show_throughput(start);
81 Ok(id)81 Ok(id)
82}82}
gix-index/src/extension/end_of_index_entry/decode.rs+1−1
@@ -44,7 +44,7 @@ pub fn decode(data: &[u8], object_hash: gix_hash::Kind) -> Result<Option<usize>, · 43 unmodified lines
44 last_chunk = Some(chunk);44 last_chunk = Some(chunk);
45 }45 }
46 46
47 if hasher.finalize().verify(checksum).is_err() {47 if hasher.try_finalize()?.verify(checksum).is_err() {
48 return Ok(None);48 return Ok(None);
49 }49 }
50 // The last-to-this chunk ends where ours starts50 // The last-to-this chunk ends where ours starts
gix-index/src/extension/end_of_index_entry/write.rs+1−1
@@ -23,7 +23,7 @@ pub fn write_to( · 22 unmodified lines
23 hasher.update(&signature);23 hasher.update(&signature);
24 hasher.update(&size.to_be_bytes());24 hasher.update(&size.to_be_bytes());
25 }25 }
26 out.write_all(hasher.finalize().as_slice())?;26 out.write_all(hasher.try_finalize()?.as_slice())?;
27 27
28 Ok(())28 Ok(())
29}29}
gix-index/src/file/write.rs+1−1
@@ -31,7 +31,7 @@ impl File { · 30 unmodified lines
31 let mut hasher = hasher::io::Write::new(&mut out, self.state.object_hash);31 let mut hasher = hasher::io::Write::new(&mut out, self.state.object_hash);
32 let out: &mut dyn std::io::Write = &mut hasher;32 let out: &mut dyn std::io::Write = &mut hasher;
33 let version = self.state.write_to(out, options)?;33 let version = self.state.write_to(out, options)?;
34 (version, hasher.hash.finalize())34 (version, hasher.hash.try_finalize()?)
35 };35 };
36 out.write_all(hash.as_slice())?;36 out.write_all(hash.as_slice())?;
37 Ok((version, hash))37 Ok((version, hash))
gix-merge/tests/merge/blob/mod.rs+3−3
@@ -43,10 +43,10 @@ mod util { · 42 unmodified lines
43 43
44 impl ObjectDb {44 impl ObjectDb {
45 /// Insert `data` and return its hash. That can be used to find it again.45 /// Insert `data` and return its hash. That can be used to find it again.
46 pub fn insert(&mut self, data: &str) -> gix_hash::ObjectId {46 pub fn insert(&mut self, data: &str) -> Result<gix_hash::ObjectId, Error> {
47 let id = gix_object::compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Blob, data.as_bytes());47 let id = gix_object::try_compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Blob, data.as_bytes())?;
48 self.data_by_id.insert(id, data.into());48 self.data_by_id.insert(id, data.into());
49 id49 Ok(id)
50 }50 }
51 }51 }
52}52}
gix-merge/tests/merge/blob/pipeline.rs+6−6
@@ -67,7 +67,7 @@ fn without_transformation() -> crate::Result { · 66 unmodified lines
67 67
68 let mut db = ObjectDb::default();68 let mut db = ObjectDb::default();
69 let b_content = "b-content";69 let b_content = "b-content";
70 let id = db.insert(b_content);70 let id = db.insert(b_content)?;
71 71
72 let out = filter.convert_to_mergeable(72 let out = filter.convert_to_mergeable(
73 &id,73 &id,
@@ -148,7 +148,7 @@ fn binary_below_large_file_threshold() -> crate::Result { · 74 unmodified lines
148 assert_eq!(buf.as_bstr(), binary_content);148 assert_eq!(buf.as_bstr(), binary_content);
149 149
150 let mut db = ObjectDb::default();150 let mut db = ObjectDb::default();
151 let id = db.insert(binary_content);151 let id = db.insert(binary_content)?;
152 let out = filter.convert_to_mergeable(152 let out = filter.convert_to_mergeable(
153 &id,153 &id,
154 EntryKind::Blob,154 EntryKind::Blob,
@@ -203,7 +203,7 @@ fn above_large_file_threshold() -> crate::Result { · 48 unmodified lines
203 203
204 drop(tmp);204 drop(tmp);
205 let mut db = ObjectDb::default();205 let mut db = ObjectDb::default();
206 let id = db.insert(large_content);206 let id = db.insert(large_content)?;
207 207
208 let out = filter.convert_to_mergeable(208 let out = filter.convert_to_mergeable(
209 &id,209 &id,
@@ -352,7 +352,7 @@ fn worktree_filter() -> crate::Result { · 142 unmodified lines
352 "worktree files need to be converted back to what's stored in Git"352 "worktree files need to be converted back to what's stored in Git"
353 );353 );
354 354
355 let id = db.insert(a_content);355 let id = db.insert(a_content)?;
356 let out = filter.convert_to_mergeable(356 let out = filter.convert_to_mergeable(
357 &id,357 &id,
358 EntryKind::Blob,358 EntryKind::Blob,
@@ -385,7 +385,7 @@ fn worktree_filter() -> crate::Result { · 26 unmodified lines
385 drop(tmp);385 drop(tmp);
386 386
387 let b_content = "b-content\n";387 let b_content = "b-content\n";
388 let id = db.insert(b_content);388 let id = db.insert(b_content)?;
389 389
390 let out = filter.convert_to_mergeable(390 let out = filter.convert_to_mergeable(
391 &id,391 &id,
@@ -403,7 +403,7 @@ fn worktree_filter() -> crate::Result { · 11 unmodified lines
403 403
404 let mut db = ObjectDb::default();404 let mut db = ObjectDb::default();
405 let b_content = "b-content\r\n";405 let b_content = "b-content\r\n";
406 let id = db.insert(b_content);406 let id = db.insert(b_content)?;
407 let out = filter.convert_to_mergeable(407 let out = filter.convert_to_mergeable(
408 &id,408 &id,
409 EntryKind::Blob,409 EntryKind::Blob,
gix-merge/tests/merge/blob/platform.rs+5−5
@@ -31,7 +31,7 @@ mod merge { · 30 unmodified lines
31 ("ours", ResourceKind::CurrentOrOurs),31 ("ours", ResourceKind::CurrentOrOurs),
32 ("theirs\0", ResourceKind::OtherOrTheirs),32 ("theirs\0", ResourceKind::OtherOrTheirs),
33 ] {33 ] {
34 let id = db.insert(content);34 let id = db.insert(content)?;
35 platform.set_resource(35 platform.set_resource(
36 id,36 id,
37 EntryKind::Blob,37 EntryKind::Blob,
@@ -81,7 +81,7 @@ mod merge { · 43 unmodified lines
81 ("any\0", ResourceKind::CurrentOrOurs),81 ("any\0", ResourceKind::CurrentOrOurs),
82 ("any\0", ResourceKind::OtherOrTheirs),82 ("any\0", ResourceKind::OtherOrTheirs),
83 ] {83 ] {
84 let id = db.insert(content);84 let id = db.insert(content)?;
85 platform.set_resource(85 platform.set_resource(
86 id,86 id,
87 EntryKind::Blob,87 EntryKind::Blob,
@@ -131,7 +131,7 @@ mod merge { · 43 unmodified lines
131 ("ours", ResourceKind::CurrentOrOurs),131 ("ours", ResourceKind::CurrentOrOurs),
132 ("theirs", ResourceKind::OtherOrTheirs),132 ("theirs", ResourceKind::OtherOrTheirs),
133 ] {133 ] {
134 let id = db.insert(content);134 let id = db.insert(content)?;
135 platform.set_resource(id, EntryKind::Blob, "b".into(), kind, &db)?;135 platform.set_resource(id, EntryKind::Blob, "b".into(), kind, &db)?;
136 }136 }
137 137
@@ -284,7 +284,7 @@ theirs · 146 unmodified lines
284 ("ours", ResourceKind::CurrentOrOurs),284 ("ours", ResourceKind::CurrentOrOurs),
285 ("theirs", ResourceKind::OtherOrTheirs),285 ("theirs", ResourceKind::OtherOrTheirs),
286 ] {286 ] {
287 let id = db.insert(content);287 let id = db.insert(content)?;
288 platform.set_resource(id, EntryKind::Blob, "b".into(), kind, &db)?;288 platform.set_resource(id, EntryKind::Blob, "b".into(), kind, &db)?;
289 }289 }
290 290
@@ -313,7 +313,7 @@ theirs · 22 unmodified lines
313 "we handle word-splitting and definitely pick-up what's written into the %A buffer"313 "we handle word-splitting and definitely pick-up what's written into the %A buffer"
314 );314 );
315 315
316 let id = db.insert("binary\0");316 let id = db.insert("binary\0")?;
317 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::OtherOrTheirs, &db)?;317 platform.set_resource(id, EntryKind::Blob, "b".into(), ResourceKind::OtherOrTheirs, &db)?;
318 let platform_ref = platform.prepare_merge(&db, Default::default())?;318 let platform_ref = platform.prepare_merge(&db, Default::default())?;
319 let res = platform_ref.merge(&mut buf, default_labels(), &Default::default())?;319 let res = platform_ref.merge(&mut buf, default_labels(), &Default::default())?;
gix-object/benches/edit_tree.rs+1−1
@@ -147,7 +147,7 @@ fn new_inmemory_writes() -> ( · 146 unmodified lines
147 move |tree: &Tree| {147 move |tree: &Tree| {
148 buf.clear();148 buf.clear();
149 tree.write_to(&mut buf)?;149 tree.write_to(&mut buf)?;
150 let id = gix_object::compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Tree, &buf);150 let id = gix_object::try_compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Tree, &buf)?;
151 let mut borrowed = store.borrow_mut();151 let mut borrowed = store.borrow_mut();
152 match borrowed.entry(id) {152 match borrowed.entry(id) {
153 Entry::Occupied(_) => {}153 Entry::Occupied(_) => {}
gix-object/src/data.rs+1−1
@@ -66,7 +66,7 @@ pub mod verify { · 65 unmodified lines
66 /// If the hashes do not match, an [`Error`] is returned, containing the actual66 /// If the hashes do not match, an [`Error`] is returned, containing the actual
67 /// hash of `self`.67 /// hash of `self`.
68 pub fn verify_checksum(&self, expected: &gix_hash::oid) -> Result<gix_hash::ObjectId, Error> {68 pub fn verify_checksum(&self, expected: &gix_hash::oid) -> Result<gix_hash::ObjectId, Error> {
69 let actual = crate::compute_hash(expected.kind(), self.kind, self.data);69 let actual = crate::try_compute_hash(expected.kind(), self.kind, self.data)?;
70 actual.verify(expected)?;70 actual.verify(expected)?;
71 Ok(actual)71 Ok(actual)
72 }72 }
gix-object/tests/object/main.rs+2−2
@@ -12,11 +12,11 @@ mod tree; · 11 unmodified lines
12fn compute_hash() {12fn compute_hash() {
13 let hk = gix_hash::Kind::Sha1;13 let hk = gix_hash::Kind::Sha1;
14 assert_eq!(14 assert_eq!(
15 gix_object::compute_hash(hk, gix_object::Kind::Blob, &[]),15 gix_object::try_compute_hash(hk, gix_object::Kind::Blob, &[]).expect("empty hash doesn’t collide"),
16 gix_hash::ObjectId::empty_blob(hk)16 gix_hash::ObjectId::empty_blob(hk)
17 );17 );
18 assert_eq!(18 assert_eq!(
19 gix_object::compute_hash(hk, gix_object::Kind::Tree, &[]),19 gix_object::try_compute_hash(hk, gix_object::Kind::Tree, &[]).expect("empty hash doesn’t collide"),
20 gix_hash::ObjectId::empty_tree(hk)20 gix_hash::ObjectId::empty_tree(hk)
21 );21 );
22}22}
gix-object/tests/object/tree/editor.rs+1−1
@@ -805,7 +805,7 @@ mod utils { · 804 unmodified lines
805 move |tree: &Tree| {805 move |tree: &Tree| {
806 buf.clear();806 buf.clear();
807 tree.write_to(&mut buf)?;807 tree.write_to(&mut buf)?;
808 let id = gix_object::compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Tree, &buf);808 let id = gix_object::try_compute_hash(gix_hash::Kind::Sha1, gix_object::Kind::Tree, &buf)?;
809 store.borrow_mut().insert(id, tree.clone());809 store.borrow_mut().insert(id, tree.clone());
810 let old = num_writes.get();810 let old = num_writes.get();
811 num_writes.set(old + 1);811 num_writes.set(old + 1);
gix-odb/src/memory.rs+1−1
@@ -219,7 +219,7 @@ where · 218 unmodified lines
219 let mut buf = Vec::new();219 let mut buf = Vec::new();
220 from.read_to_end(&mut buf)?;220 from.read_to_end(&mut buf)?;
221 221
222 let id = gix_object::compute_hash(self.object_hash, kind, &buf);222 let id = gix_object::try_compute_hash(self.object_hash, kind, &buf)?;
223 map.borrow_mut().insert(id, (kind, buf));223 map.borrow_mut().insert(id, (kind, buf));
224 Ok(id)224 Ok(id)
225 }225 }
gix-odb/src/sink.rs+1−1
@@ -53,6 +53,6 @@ impl gix_object::Write for Sink { · 52 unmodified lines
53 c.reset();53 c.reset();
54 }54 }
55 55
56 Ok(hasher.finalize())56 Ok(hasher.try_finalize()?)
57 }57 }
58}58}
gix-odb/src/store_impls/loose/verify.rs+5−1
@@ -85,7 +85,11 @@ impl Store { · 84 unmodified lines
85 .map_err(|_| integrity::Error::Retry)?85 .map_err(|_| integrity::Error::Retry)?
86 .ok_or(integrity::Error::Retry)?;86 .ok_or(integrity::Error::Retry)?;
87 sink.write_buf(object.kind, object.data)87 sink.write_buf(object.kind, object.data)
88 .expect("sink never fails")88 .map_err(|err| integrity::Error::ObjectHasher {
89 source: *err.downcast().expect("sink can only fail in hasher"),
90 kind: object.kind,
91 expected: id,
92 })?
89 .verify(&id)93 .verify(&id)
90 .map_err(|err| integrity::Error::ObjectEncodeMismatch {94 .map_err(|err| integrity::Error::ObjectEncodeMismatch {
91 source: err,95 source: err,
gix-odb/src/store_impls/loose/write.rs+5−1
@@ -130,7 +130,11 @@ impl Store { · 129 unmodified lines
130 &self,130 &self,
131 hasher::io::Write { hash, inner: file }: hasher::io::Write<CompressedTempfile>,131 hasher::io::Write { hash, inner: file }: hasher::io::Write<CompressedTempfile>,
132 ) -> Result<gix_hash::ObjectId, Error> {132 ) -> Result<gix_hash::ObjectId, Error> {
133 let id = hash.finalize();133 let id = hash.try_finalize().map_err(|err| Error::Io {
134 source: err.into(),
135 message: "hash tempfile in",
136 path: self.path.to_owned(),
137 })?;
134 let object_path = loose::hash_path(&id, self.path.clone());138 let object_path = loose::hash_path(&id, self.path.clone());
135 let object_dir = object_path139 let object_dir = object_path
136 .parent()140 .parent()
gix-pack/src/data/input/bytes_to_entries.rs+2−2
@@ -180,7 +180,7 @@ where · 179 unmodified lines
180 }180 }
181 181
182 if let Some(hash) = self.hash.take() {182 if let Some(hash) = self.hash.take() {
183 let actual_id = hash.finalize();183 let actual_id = hash.try_finalize().map_err(hasher::io::Error::from)?;
184 if self.mode == input::Mode::Restore {184 if self.mode == input::Mode::Restore {
185 id = actual_id;185 id = actual_id;
186 } else {186 } else {
@@ -190,7 +190,7 @@ where · 3 unmodified lines
190 Some(id)190 Some(id)
191 } else if self.mode == input::Mode::Restore {191 } else if self.mode == input::Mode::Restore {
192 let hash = self.hash.clone().expect("in restore mode a hash is set");192 let hash = self.hash.clone().expect("in restore mode a hash is set");
193 Some(hash.finalize())193 Some(hash.try_finalize().map_err(hasher::io::Error::from)?)
194 } else {194 } else {
195 None195 None
196 })196 })
gix-pack/src/data/output/bytes.rs+6−1
@@ -126,7 +126,12 @@ where · 125 unmodified lines
126 }126 }
127 }127 }
128 None => {128 None => {
129 let digest = self.output.hash.clone().finalize();129 let digest = self
130 .output
131 .hash
132 .clone()
133 .try_finalize()
134 .map_err(hasher::io::Error::from)?;
130 self.output135 self.output
131 .inner136 .inner
132 .write_all(digest.as_slice())137 .write_all(digest.as_slice())
gix-pack/src/index/encode.rs+1−1
@@ -137,7 +137,7 @@ mod function { · 136 unmodified lines
137 137
138 let bytes_written_without_trailer = out.bytes;138 let bytes_written_without_trailer = out.bytes;
139 let out = out.inner.into_inner().map_err(io::Error::from)?;139 let out = out.inner.into_inner().map_err(io::Error::from)?;
140 let index_hash = out.hash.finalize();140 let index_hash = out.hash.try_finalize()?;
141 out.inner.write_all(index_hash.as_slice())?;141 out.inner.write_all(index_hash.as_slice())?;
142 out.inner.flush()?;142 out.inner.flush()?;
143 143
gix-pack/src/index/write/mod.rs+10−7
@@ -193,10 +193,7 @@ impl crate::index::File { · 192 unmodified lines
193 entry,193 entry,
194 decompressed: bytes,194 decompressed: bytes,
195 ..195 ..
196 }| {196 }| { modify_base(data, entry, bytes, version.hash()) },
197 modify_base(data, entry, bytes, version.hash());
198 Ok::<_, Error>(())
199 },
200 traverse::Options {197 traverse::Options {
201 object_progress: Box::new(198 object_progress: Box::new(
202 root_progress.add_child_with_id("Resolving".into(), ProgressId::ResolveObjects.into()),199 root_progress.add_child_with_id("Resolving".into(), ProgressId::ResolveObjects.into()),
@@ -228,7 +225,7 @@ impl crate::index::File { · 25 unmodified lines
228 let header = crate::data::header::encode(pack_version, 0);225 let header = crate::data::header::encode(pack_version, 0);
229 let mut hasher = gix_hash::hasher(object_hash);226 let mut hasher = gix_hash::hasher(object_hash);
230 hasher.update(&header);227 hasher.update(&header);
231 hasher.finalize()228 hasher.try_finalize().map_err(hasher::io::Error::from)?
232 }229 }
233 None => return Err(Error::IteratorInvariantTrailer),230 None => return Err(Error::IteratorInvariantTrailer),
234 };231 };
@@ -254,8 +251,14 @@ impl crate::index::File { · 19 unmodified lines
254 }251 }
255}252}
256 253
257fn modify_base(entry: &mut TreeEntry, pack_entry: &crate::data::Entry, decompressed: &[u8], hash: gix_hash::Kind) {254fn modify_base(
255 entry: &mut TreeEntry,
256 pack_entry: &crate::data::Entry,
257 decompressed: &[u8],
258 hash: gix_hash::Kind,
259) -> Result<(), hasher::Error> {
258 let object_kind = pack_entry.header.as_kind().expect("base object as source of iteration");260 let object_kind = pack_entry.header.as_kind().expect("base object as source of iteration");
259 let id = gix_object::compute_hash(hash, object_kind, decompressed);261 let id = gix_object::try_compute_hash(hash, object_kind, decompressed)?;
260 entry.id = id;262 entry.id = id;
263 Ok(())
261}264}
gix-pack/src/multi_index/write.rs+1−1
@@ -218,7 +218,7 @@ impl multi_index::File { · 217 unmodified lines
218 }218 }
219 219
220 // write trailing checksum220 // write trailing checksum
221 let multi_index_checksum = out.inner.hash.finalize();221 let multi_index_checksum = out.inner.hash.try_finalize().map_err(hasher::io::Error::from)?;
222 out.inner222 out.inner
223 .inner223 .inner
224 .write_all(multi_index_checksum.as_slice())224 .write_all(multi_index_checksum.as_slice())
gix-pack/src/verify.rs+2−1
@@ -54,8 +54,9 @@ pub fn checksum_on_disk_or_mmap( · 53 unmodified lines
54 hasher.update(&data[..data_len_without_trailer]);54 hasher.update(&data[..data_len_without_trailer]);
55 progress.inc_by(data_len_without_trailer);55 progress.inc_by(data_len_without_trailer);
56 progress.show_throughput(start);56 progress.show_throughput(start);
57 hasher.finalize()57 hasher.try_finalize()?
58 }58 }
59 Err(hasher::io::Error::Hasher(err)) => return Err(checksum::Error::Hasher(err)),
59 };60 };
60 61
61 actual.verify(&expected)?;62 actual.verify(&expected)?;
gix-status/src/index_as_worktree/traits.rs+4−2
@@ -143,14 +143,16 @@ impl CompareBlobs for HashEq { · 142 unmodified lines
143 let mut stream = data.stream_worktree_file()?;143 let mut stream = data.stream_worktree_file()?;
144 match stream.as_bytes() {144 match stream.as_bytes() {
145 Some(buffer) => {145 Some(buffer) => {
146 let file_hash = gix_object::compute_hash(entry.id.kind(), gix_object::Kind::Blob, buffer);146 let file_hash = gix_object::try_compute_hash(entry.id.kind(), gix_object::Kind::Blob, buffer)
147 .map_err(hasher::io::Error::from)?;
147 Ok((entry.id != file_hash).then_some(file_hash))148 Ok((entry.id != file_hash).then_some(file_hash))
148 }149 }
149 None => {150 None => {
150 let file_hash = match stream.size() {151 let file_hash = match stream.size() {
151 None => {152 None => {
152 stream.read_to_end(buf).map_err(hasher::io::Error::from)?;153 stream.read_to_end(buf).map_err(hasher::io::Error::from)?;
153 gix_object::compute_hash(entry.id.kind(), gix_object::Kind::Blob, buf)154 gix_object::try_compute_hash(entry.id.kind(), gix_object::Kind::Blob, buf)
155 .map_err(hasher::io::Error::from)?
154 }156 }
155 Some(len) => gix_object::compute_stream_hash(157 Some(len) => gix_object::compute_stream_hash(
156 entry.id.kind(),158 entry.id.kind(),
gix-status/src/index_as_worktree_with_renames/mod.rs+8−3
@@ -536,18 +536,23 @@ pub(super) mod function { · 535 unmodified lines
536 should_interrupt,536 should_interrupt,
537 )537 )
538 .map_err(Error::HashFile)?,538 .map_err(Error::HashFile)?,
539 ToGitOutcome::Buffer(buf) => gix_object::compute_hash(object_hash, gix_object::Kind::Blob, buf),539 ToGitOutcome::Buffer(buf) => {
540 gix_object::try_compute_hash(object_hash, gix_object::Kind::Blob, buf)
541 .map_err(|err| Error::HashFile(err.into()))?
542 }
540 ToGitOutcome::Process(mut stream) => {543 ToGitOutcome::Process(mut stream) => {
541 buf.clear();544 buf.clear();
542 stream.read_to_end(buf).map_err(|err| Error::HashFile(err.into()))?;545 stream.read_to_end(buf).map_err(|err| Error::HashFile(err.into()))?;
543 gix_object::compute_hash(object_hash, gix_object::Kind::Blob, buf)546 gix_object::try_compute_hash(object_hash, gix_object::Kind::Blob, buf)
547 .map_err(|err| Error::HashFile(err.into()))?
544 }548 }
545 }549 }
546 }550 }
547 Kind::Symlink => {551 Kind::Symlink => {
548 let path = worktree_root.join(gix_path::from_bstr(rela_path));552 let path = worktree_root.join(gix_path::from_bstr(rela_path));
549 let target = gix_path::into_bstr(std::fs::read_link(path).map_err(Error::ReadLink)?);553 let target = gix_path::into_bstr(std::fs::read_link(path).map_err(Error::ReadLink)?);
550 gix_object::compute_hash(object_hash, gix_object::Kind::Blob, &target)554 gix_object::try_compute_hash(object_hash, gix_object::Kind::Blob, &target)
555 .map_err(|err| Error::HashFile(err.into()))?
551 }556 }
552 Kind::Directory | Kind::Repository => object_hash.null(),557 Kind::Directory | Kind::Repository => object_hash.null(),
553 })558 })
gix/src/repository/impls.rs+1−1
@@ -106,7 +106,7 @@ impl gix_object::Write for crate::Repository { · 105 unmodified lines
106 }106 }
107 107
108 fn write_buf(&self, object: gix_object::Kind, from: &[u8]) -> Result<gix_hash::ObjectId, gix_object::write::Error> {108 fn write_buf(&self, object: gix_object::Kind, from: &[u8]) -> Result<gix_hash::ObjectId, gix_object::write::Error> {
109 let oid = gix_object::compute_hash(self.object_hash(), object, from);109 let oid = gix_object::try_compute_hash(self.object_hash(), object, from)?;
110 if self.objects.exists(&oid) {110 if self.objects.exists(&oid) {
111 return Ok(oid);111 return Ok(oid);
112 }112 }
gix/src/repository/object.rs+6−3
@@ -172,7 +172,8 @@ impl crate::Repository { · 171 unmodified lines
172 }172 }
173 173
174 fn write_object_inner(&self, buf: &[u8], kind: gix_object::Kind) -> Result<Id<'_>, object::write::Error> {174 fn write_object_inner(&self, buf: &[u8], kind: gix_object::Kind) -> Result<Id<'_>, object::write::Error> {
175 let oid = gix_object::compute_hash(self.object_hash(), kind, buf);175 let oid = gix_object::try_compute_hash(self.object_hash(), kind, buf)
176 .map_err(|err| Box::new(err) as Box<dyn std::error::Error + Send + Sync>)?;
176 if self.objects.exists(&oid) {177 if self.objects.exists(&oid) {
177 return Ok(oid.attach(self));178 return Ok(oid.attach(self));
178 }179 }
@@ -189,7 +190,8 @@ impl crate::Repository { · 10 unmodified lines
189 /// pre-hashing the data, and checking if the object is already present.190 /// pre-hashing the data, and checking if the object is already present.
190 pub fn write_blob(&self, bytes: impl AsRef<[u8]>) -> Result<Id<'_>, object::write::Error> {191 pub fn write_blob(&self, bytes: impl AsRef<[u8]>) -> Result<Id<'_>, object::write::Error> {
191 let bytes = bytes.as_ref();192 let bytes = bytes.as_ref();
192 let oid = gix_object::compute_hash(self.object_hash(), gix_object::Kind::Blob, bytes);193 let oid = gix_object::try_compute_hash(self.object_hash(), gix_object::Kind::Blob, bytes)
194 .map_err(|err| Box::new(err) as Box<dyn std::error::Error + Send + Sync>)?;
193 if self.objects.exists(&oid) {195 if self.objects.exists(&oid) {
194 return Ok(oid.attach(self));196 return Ok(oid.attach(self));
195 }197 }
@@ -214,7 +216,8 @@ impl crate::Repository { · 18 unmodified lines
214 }216 }
215 217
216 fn write_blob_stream_inner(&self, buf: &[u8]) -> Result<Id<'_>, object::write::Error> {218 fn write_blob_stream_inner(&self, buf: &[u8]) -> Result<Id<'_>, object::write::Error> {
217 let oid = gix_object::compute_hash(self.object_hash(), gix_object::Kind::Blob, buf);219 let oid = gix_object::try_compute_hash(self.object_hash(), gix_object::Kind::Blob, buf)
220 .map_err(|err| Box::new(err) as Box<dyn std::error::Error + Send + Sync>)?;
218 if self.objects.exists(&oid) {221 if self.objects.exists(&oid) {
219 return Ok(oid.attach(self));222 return Ok(oid.attach(self));
220 }223 }
tests/it/src/commands/git_to_sh.rs+5−1
@@ -115,7 +115,11 @@ pub(super) mod function { · 114 unmodified lines
115 })?;115 })?;
116 let mapped = crate::commands::copy_royal::remapped(data);116 let mapped = crate::commands::copy_royal::remapped(data);
117 (117 (
118 gix::objs::compute_hash(repo.object_hash(), gix::object::Kind::Blob, mapped.as_bytes()),118 gix::objs::try_compute_hash(
119 repo.object_hash(),
120 gix::object::Kind::Blob,
121 mapped.as_bytes(),
122 )?,
119 Cow::Owned(mapped.into()),123 Cow::Owned(mapped.into()),
120 )124 )
121 }125 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t