History

Merge pull request #1854 from GitoxideLabs/montly-report

montly report

Sebastian Thiel committed 1 year ago

Commit 16a248b2 parents 2efce72 d28ff1b136 files · +309 −270Browse files

Unified · Split

136 files
  1. Cargo.toml +1 −0
  2. deny.toml +1 −1
  3. etc/reports/25-02.md +32 −0
  4. gitoxide-core/src/hours/mod.rs +1 −1
  5. gitoxide-core/src/index/information.rs +4 −4
  6. gitoxide-core/src/lib.rs +1 −1
  7. gitoxide-core/src/pack/explode.rs +1 −1
  8. gitoxide-core/src/pack/index.rs +1 −1
  9. gitoxide-core/src/pack/receive.rs +1 −1
  10. gitoxide-core/src/pack/verify.rs +2 −2
  11. gitoxide-core/src/query/engine/update.rs +1 −1
  12. gitoxide-core/src/repository/clean.rs +1 −1
  13. gitoxide-core/src/repository/clone.rs +1 −1
  14. gitoxide-core/src/repository/config.rs +1 −1
  15. gitoxide-core/src/repository/diff.rs +1 −1
  16. gitoxide-core/src/repository/fetch.rs +1 −1
  17. gitoxide-core/src/repository/index/entries.rs +1 −1
  18. gitoxide-core/src/repository/remote.rs +1 −1
  19. gitoxide-core/src/repository/submodule.rs +1 −1
  20. gix-attributes/src/search/outcome.rs +1 −6
  21. gix-blame/src/file/function.rs +1 −1
  22. gix-commitgraph/src/file/init.rs +1 −1
  23. gix-config-value/src/path.rs +2 −2
  24. gix-config/src/file/includes/mod.rs +1 −1
  25. gix-config/src/file/init/from_paths.rs +1 −1
  26. gix-config/src/file/section/body.rs +1 −1
  27. gix-config/src/parse/events.rs +1 −1
  28. gix-credentials/tests/program/from_custom_definition.rs +1 −1
  29. gix-date/src/parse.rs +1 −1
  30. gix-diff/src/blob/pipeline.rs +20 −22
  31. gix-diff/src/blob/platform.rs +1 −1
  32. gix-diff/src/rewrites/tracker.rs +5 −5
  33. gix-diff/src/tree/function.rs +5 −5
  34. gix-diff/tests/diff/rewrites/tracker.rs +2 −2
  35. gix-discover/src/repository.rs +5 −1
  36. gix-discover/tests/discover/upwards/mod.rs +2 −2
  37. gix-features/src/io.rs +2 −2
  38. gix-features/src/parallel/eager_iter.rs +4 −4
  39. gix-features/src/parallel/mod.rs +3 −3
  40. gix-filter/src/driver/process/server.rs +1 −1
  41. gix-filter/src/pipeline/convert.rs +1 −1
  42. gix-fs/src/dir/create.rs +2 −2
  43. gix-glob/src/parse.rs +1 −1
  44. gix-glob/src/wildmatch.rs +5 −5
  45. gix-glob/tests/pattern/matching.rs +1 −1
  46. gix-hash/src/prefix.rs +1 −1
  47. gix-index/src/access/mod.rs +2 −2
  48. gix-index/src/entry/flags.rs +1 −1
  49. gix-index/src/entry/mode.rs +1 −1
  50. gix-index/src/write.rs +1 −1
  51. gix-macros/src/momo.rs +1 −1
  52. gix-mailmap/src/snapshot/mod.rs +1 −1
  53. gix-merge/src/blob/pipeline.rs +1 −1
  54. gix-merge/src/blob/platform/set_resource.rs +1 −1
  55. gix-merge/src/tree/function.rs +13 −13
  56. gix-merge/src/tree/mod.rs +2 −2
  57. gix-merge/tests/merge/blob/builtin_driver.rs +1 −1
  58. gix-merge/tests/merge/tree/mod.rs +1 −1
  59. gix-object/benches/edit_tree.rs +1 −1
  60. gix-object/src/tree/editor.rs +1 −1
  61. gix-odb/src/alternate/mod.rs +1 −1
  62. gix-odb/src/store_impls/dynamic/load_index.rs +1 −1
  63. gix-odb/src/store_impls/dynamic/types.rs +1 −1
  64. gix-odb/src/store_impls/loose/iter.rs +1 −1
  65. gix-pack/src/bundle/write/mod.rs +2 −2
  66. gix-pack/src/cache/delta/from_offsets.rs +2 −2
  67. gix-pack/src/cache/delta/traverse/resolve.rs +2 −2
  68. gix-pack/src/data/file/decode/entry.rs +1 −1
  69. gix-pack/src/data/file/decode/header.rs +1 −1
  70. gix-pack/src/data/input/entry.rs +1 −1
  71. gix-pack/src/data/output/bytes.rs +2 −2
  72. gix-pack/src/data/output/count/objects/tree.rs +1 −1
  73. gix-pack/src/data/output/entry/mod.rs +2 −2
  74. gix-pack/src/index/traverse/with_index.rs +1 −1
  75. gix-pack/src/index/verify.rs +1 −1
  76. gix-pack/src/index/write/mod.rs +3 −3
  77. gix-packetline-blocking/src/read/sidebands/blocking_io.rs +3 −3
  78. gix-packetline/src/read/sidebands/blocking_io.rs +3 −3
  79. gix-path/src/lib.rs +2 −2
  80. gix-pathspec/src/parse.rs +1 −1
  81. gix-pathspec/tests/parse/invalid.rs +1 −1
  82. gix-protocol/src/fetch/response/blocking_io.rs +1 −1
  83. gix-protocol/src/fetch/response/mod.rs +1 −1
  84. gix-protocol/src/handshake/refs/shared.rs +1 −1
  85. gix-protocol/src/remote_progress.rs +1 −1
  86. gix-ref/src/store/file/find.rs +8 −4
  87. gix-ref/src/store/file/log/iter.rs +1 −1
  88. gix-ref/src/store/file/loose/reflog.rs +1 −1
  89. gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs +1 −1
  90. gix-ref/src/store/file/raw_ext.rs +1 −1
  91. gix-ref/src/store/file/transaction/commit.rs +1 −1
  92. gix-ref/src/store/file/transaction/prepare.rs +2 −2
  93. gix-ref/src/transaction/ext.rs +1 −1
  94. gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs +1 −1
  95. gix-refspec/src/match_group/util.rs +1 −1
  96. gix-refspec/tests/refspec/matching.rs +1 −1
  97. gix-revision/src/spec/parse/delegate.rs +1 −1
  98. gix-revision/src/spec/parse/function.rs +5 −5
  99. gix-revwalk/src/graph/mod.rs +3 −3
  100. gix-submodule/src/is_active_platform.rs +1 −1
  101. gix-transport/src/client/blocking_io/http/curl/remote.rs +2 −2
  102. gix-transport/src/client/blocking_io/http/traits.rs +1 −1
  103. gix-transport/src/client/blocking_io/ssh/program_kind.rs +1 −1
  104. gix-transport/src/client/non_io_types.rs +1 −1
  105. gix-transport/tests/client/blocking_io/http/mod.rs +2 −2
  106. gix-traverse/src/commit/simple.rs +2 −2
  107. gix-traverse/src/commit/topo/iter.rs +2 −2
  108. gix-traverse/src/tree/breadthfirst.rs +4 −4
  109. gix-url/src/lib.rs +1 −1
  110. gix-worktree-state/tests/state/checkout.rs +2 −2
  111. gix-worktree/src/stack/state/mod.rs +1 −1
  112. gix/src/clone/fetch/util.rs +2 −2
  113. gix/src/config/cache/incubate.rs +2 −2
  114. gix/src/config/snapshot/_impls.rs +1 −1
  115. gix/src/config/snapshot/credential_helpers.rs +5 −3
  116. gix/src/create.rs +1 −1
  117. gix/src/object/blob.rs +1 −1
  118. gix/src/remote/build.rs +5 −3
  119. gix/src/remote/connection/fetch/update_refs/mod.rs +2 −2
  120. gix/src/remote/connection/ref_map.rs +1 −1
  121. gix/src/remote/init.rs +10 −6
  122. gix/src/remote/url/rewrite.rs +1 −1
  123. gix/src/repository/config/branch.rs +4 −7
  124. gix/src/repository/init.rs +1 −1
  125. gix/src/revision/spec/parse/delegate/mod.rs +18 −20
  126. gix/src/revision/spec/parse/delegate/revision.rs +1 −1
  127. gix/src/revision/walk.rs +2 −2
  128. gix/src/status/iter/mod.rs +1 −1
  129. gix/tests/gix/object/tree/diff.rs +3 −4
  130. gix/tests/gix/repository/excludes.rs +1 −1
  131. src/shared.rs +1 −1
  132. tests/it/src/commands/check_mode.rs +2 −2
  133. tests/snapshots/panic-behaviour/expected-failure +1 −0
  134. tests/snapshots/panic-behaviour/expected-failure-in-thread +1 −0
  135. tests/snapshots/panic-behaviour/expected-failure-in-thread-with-progress +2 −1
  136. tests/tools/src/main.rs +1 −1
Cargo.toml+1−0
@@ -325,6 +325,7 @@ bin-dir = "gitoxide-max-pure-v{ version }-{ target }/{ bin }{ binary-ext }" · 324 unmodified lines
325pedantic = { level = "warn", priority = -1 }325pedantic = { level = "warn", priority = -1 }
326#326#
327# Reviewed and allowed lints327# Reviewed and allowed lints
328needless_continue = "allow"
328enum_glob_use = "allow" # x97329enum_glob_use = "allow" # x97
329missing_errors_doc = "allow" # x1792330missing_errors_doc = "allow" # x1792
330missing_panics_doc = "allow" # x447331missing_panics_doc = "allow" # x447
deny.toml+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
8# More documentation for the advisories section can be found here:8# More documentation for the advisories section can be found here:
9# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html9# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
10[advisories]10[advisories]
11ignore = []11ignore = ['RUSTSEC-2025-0007']
12 12
13 13
14 14
etc/reports/25-02.md+32−0
@@ -0,0 +1,32 @@
1Like the previous month was the first in 2025 with plenty of news to share, this month is a first as well: I seem to have nothing to write about.
2
3Sure, there were a couple of smaller API improvements, but nothing that would inspire me.
4So what did I do all this time? Probably this is the moment where there really is no other way but to talk about GitButler, something I avoided last month just because it doesn't seem to belong into the `gitoxide` newsletter.
5
6## GitButler
7
8[GitButler](https://gitbutler.com) is what I have been working on intensely for the last two months effectively, in a push to help it to unfold its true potential. Thus far it was mostly powered by `git2`, with `gitoxide` sprinkled in there, but the next iteration will be the inverse with `git2` only being used where `gitoxide` is lacking a feature. That way, along with massive architectural changes, it will be able to cope with large repositories and be more compatible with various Git features, too.
9
10I cannot wait to see all this work to finally come to fruition, and of course, to also see myself being pulled to a user interface that truly elevates my workflow and the workflow of other devs just like me who thus far preferred to stay on the command-line.
11
12## Community
13
14### Faster `gix blame`
15
16Christoph Rüßler kept working and managed to greatly improve the `gix blame` performance while increasing its conformance to Git at the same time. This means that now, depending on the sample, `gix blame` *can* be a bit faster than Git, but it typically is still up to 30% slower when commitgraph caches are used. Overall though, the performance is nothing to sneeze at, and it competes quite well except for in pathological cases.
17Admittedly, I am quite blown away by the performance and have a feeling that last time I checked, I didn't use the latest version of the `gix` binary.
18It's worth noting that rename-tracking still isn't support, but I also see no reason why it shouldn't be eventually, a feature that would make `gix blame` so much more useful in practice.
19
20### `gix blame` with experimental cache
21
22A pretty [slim PR](https://github.com/GitoxideLabs/gitoxide/pull/1852) shows how to use a special cache to greatly speedup blames, from ~300ms down to just ~4ms, a massive 75x speedup that would be very useful for editors and IDEs, or forges, I am sure!
23Of course, one first has to build such cache, and probably do so per file, but I am sure there are plenty of use-cases for it when it's driven by dev tooling.
24
25### Gix in Cargo
26
27With `gix status` now available I am planning to integrate it as soon as possible! That didn't happen yet, but… it will, the stack to work off before I can start this is pretty high though so it's unlikely to happen anytime soon.
28
29Cheers
30Sebastian
31
32PS: The latest timesheets can be found [here (2025)](https://github.com/Byron/byron/blob/main/timesheets/2025.csv).
gitoxide-core/src/hours/mod.rs+1−1
@@ -180,7 +180,7 @@ where · 179 unmodified lines
180 break;180 break;
181 }181 }
182 Err(err) => return Err(err.into()),182 Err(err) => return Err(err.into()),
183 };183 }
184 }184 }
185 if let Some(tx) = tx_tree_id {185 if let Some(tx) = tx_tree_id {
186 tx.send(chunk).ok();186 tx.send(chunk).ok();
gitoxide-core/src/index/information.rs+4−4
@@ -92,16 +92,16 @@ mod serde_only { · 91 unmodified lines
92 });92 });
93 if f.link().is_some() {93 if f.link().is_some() {
94 names.push("link");94 names.push("link");
95 };95 }
96 if f.resolve_undo().is_some() {96 if f.resolve_undo().is_some() {
97 names.push("resolve-undo (REUC)");97 names.push("resolve-undo (REUC)");
98 };98 }
99 if f.untracked().is_some() {99 if f.untracked().is_some() {
100 names.push("untracked (UNTR)");100 names.push("untracked (UNTR)");
101 };101 }
102 if f.fs_monitor().is_some() {102 if f.fs_monitor().is_some() {
103 names.push("fs-monitor (FSMN)");103 names.push("fs-monitor (FSMN)");
104 };104 }
105 if f.had_offset_table() {105 if f.had_offset_table() {
106 names.push("offset-table (IEOT)");106 names.push("offset-table (IEOT)");
107 }107 }
gitoxide-core/src/lib.rs+1−1
@@ -86,7 +86,7 @@ pub use discover::discover; · 85 unmodified lines
86pub fn env(mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {86pub fn env(mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
87 if format != OutputFormat::Human {87 if format != OutputFormat::Human {
88 bail!("JSON output isn't supported");88 bail!("JSON output isn't supported");
89 };89 }
90 90
91 let width = 15;91 let width = 15;
92 writeln!(92 writeln!(
gitoxide-core/src/pack/explode.rs+1−1
@@ -161,7 +161,7 @@ pub fn pack_or_pack_index( · 160 unmodified lines
161 )161 )
162 })?;162 })?;
163 163
164 if !object_path.as_ref().map_or(true, |p| p.as_ref().is_dir()) {164 if !object_path.as_ref().is_none_or(|p| p.as_ref().is_dir()) {
165 return Err(anyhow!(165 return Err(anyhow!(
166 "The object directory at '{}' is inaccessible",166 "The object directory at '{}' is inaccessible",
167 object_path167 object_path
gitoxide-core/src/pack/index.rs+1−1
@@ -114,7 +114,7 @@ pub fn from_pack( · 113 unmodified lines
114 OutputFormat::Human => drop(human_output(out, res)),114 OutputFormat::Human => drop(human_output(out, res)),
115 #[cfg(feature = "serde")]115 #[cfg(feature = "serde")]
116 OutputFormat::Json => serde_json::to_writer_pretty(out, &res)?,116 OutputFormat::Json => serde_json::to_writer_pretty(out, &res)?,
117 };117 }
118 Ok(())118 Ok(())
119}119}
120 120
gitoxide-core/src/pack/receive.rs+1−1
@@ -306,6 +306,6 @@ fn receive_pack_blocking( · 305 unmodified lines
306 OutputFormat::Json => {306 OutputFormat::Json => {
307 serde_json::to_writer_pretty(&mut out, &JsonOutcome::from_outcome_and_refs(outcome, refs))?;307 serde_json::to_writer_pretty(&mut out, &JsonOutcome::from_outcome_and_refs(outcome, refs))?;
308 }308 }
309 };309 }
310 Ok(())310 Ok(())
311}311}
gitoxide-core/src/pack/verify.rs+2−2
@@ -177,7 +177,7 @@ where · 176 unmodified lines
177 #[cfg(feature = "serde")]177 #[cfg(feature = "serde")]
178 Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, &multi_index.index_names().iter().zip(res.pack_traverse_statistics).collect::<Vec<_>>())?,178 Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, &multi_index.index_names().iter().zip(res.pack_traverse_statistics).collect::<Vec<_>>())?,
179 _ => {}179 _ => {}
180 };180 }
181 return Ok(())181 return Ok(())
182 },182 },
183 _ => return Err(anyhow!(183 _ => return Err(anyhow!(
@@ -195,7 +195,7 @@ where · 11 unmodified lines
195 #[cfg(feature = "serde")]195 #[cfg(feature = "serde")]
196 Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, stats)?,196 Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, stats)?,
197 _ => {}197 _ => {}
198 };198 }
199 }199 }
200 Ok(())200 Ok(())
201}201}
gitoxide-core/src/query/engine/update.rs+1−1
@@ -447,7 +447,7 @@ pub fn update( · 446 unmodified lines
447 break;447 break;
448 }448 }
449 Err(err) => return Err(err.into()),449 Err(err) => return Err(err.into()),
450 };450 }
451 }451 }
452 db.send_last_chunk();452 db.send_last_chunk();
453 let saw_new_commits = !commits.is_empty();453 let saw_new_commits = !commits.is_empty();
gitoxide-core/src/repository/clean.rs+1−1
@@ -213,7 +213,7 @@ pub(crate) mod function { · 212 unmodified lines
213 continue;213 continue;
214 }214 }
215 }215 }
216 };216 }
217 217
218 let is_ignored = matches!(entry.status, gix::dir::entry::Status::Ignored(_));218 let is_ignored = matches!(entry.status, gix::dir::entry::Status::Ignored(_));
219 let entry_path = gix::path::from_bstr(entry.rela_path);219 let entry_path = gix::path::from_bstr(entry.rela_path);
gitoxide-core/src/repository/clone.rs+1−1
@@ -114,7 +114,7 @@ pub(crate) mod function { · 113 unmodified lines
114 &mut err,114 &mut err,
115 )?;115 )?;
116 }116 }
117 };117 }
118 118
119 if let Some(gix::worktree::state::checkout::Outcome { collisions, errors, .. }) = outcome {119 if let Some(gix::worktree::state::checkout::Outcome { collisions, errors, .. }) = outcome {
120 if !(collisions.is_empty() && errors.is_empty()) {120 if !(collisions.is_empty() && errors.is_empty()) {
gitoxide-core/src/repository/config.rs+1−1
@@ -84,7 +84,7 @@ impl Filter { · 83 unmodified lines
84 }84 }
85 (None, _) => {}85 (None, _) => {}
86 (Some(_), None) => return false,86 (Some(_), None) => return false,
87 };87 }
88 true88 true
89 }89 }
90}90}
gitoxide-core/src/repository/diff.rs+1−1
@@ -99,7 +99,7 @@ fn write_changes( · 98 unmodified lines
99 writeln!(out, " {:o} -> {:o}", source_entry_mode.0, entry_mode.0)?;99 writeln!(out, " {:o} -> {:o}", source_entry_mode.0, entry_mode.0)?;
100 }100 }
101 }101 }
102 };102 }
103 }103 }
104 104
105 Ok(())105 Ok(())
gitoxide-core/src/repository/fetch.rs+1−1
@@ -264,7 +264,7 @@ pub(crate) mod function { · 263 unmodified lines
264 gix::remote::fetch::refmap::Source::Ref(r) => {264 gix::remote::fetch::refmap::Source::Ref(r) => {
265 crate::repository::remote::refs::print_ref(&mut out, r)?;265 crate::repository::remote::refs::print_ref(&mut out, r)?;
266 }266 }
267 };267 }
268 let mode_and_type = update.type_change.map_or_else(268 let mode_and_type = update.type_change.map_or_else(
269 || format!("{}", update.mode),269 || format!("{}", update.mode),
270 |type_change| {270 |type_change| {
gitoxide-core/src/repository/index/entries.rs+1−1
@@ -184,7 +184,7 @@ pub(crate) mod function { · 183 unmodified lines
184 .unwrap_or_default()184 .unwrap_or_default()
185 },185 },
186 )186 )
187 .map_or(true, |m| m.is_excluded());187 .is_none_or(|m| m.is_excluded());
188 188
189 let entry_is_submodule = entry.mode.is_submodule();189 let entry_is_submodule = entry.mode.is_submodule();
190 if entry_is_excluded && (!entry_is_submodule || !recurse_submodules) {190 if entry_is_excluded && (!entry_is_submodule || !recurse_submodules) {
gitoxide-core/src/repository/remote.rs+1−1
@@ -105,7 +105,7 @@ mod refs_impl { · 104 unmodified lines
105 out,105 out,
106 &map.remote_refs.into_iter().map(JsonRef::from).collect::<Vec<_>>(),106 &map.remote_refs.into_iter().map(JsonRef::from).collect::<Vec<_>>(),
107 )?,107 )?,
108 };108 }
109 Ok(())109 Ok(())
110 }110 }
111 }111 }
gitoxide-core/src/repository/submodule.rs+1−1
@@ -28,7 +28,7 @@ fn print_sm(sm: Submodule<'_>, dirty_suffix: Option<&str>, out: &mut impl std::i · 27 unmodified lines
28 let mut sm_repo = sm.open()?;28 let mut sm_repo = sm.open()?;
29 if let Some(repo) = sm_repo.as_mut() {29 if let Some(repo) = sm_repo.as_mut() {
30 repo.object_cache_size_if_unset(4 * 1024 * 1024);30 repo.object_cache_size_if_unset(4 * 1024 * 1024);
31 };31 }
32 writeln!(32 writeln!(
33 out,33 out,
34 " {is_active} {path} {config} head:{head_id} index:{index_id} ({worktree}) [{url}]",34 " {is_active} {path} {config} head:{head_id} index:{index_id} ({worktree}) [{url}]",
gix-attributes/src/search/outcome.rs+1−6
@@ -237,12 +237,7 @@ impl Outcome { · 236 unmodified lines
237 }237 }
238 238
239 fn reduce_and_check_if_done(&mut self, attr: AttributeId) -> bool {239 fn reduce_and_check_if_done(&mut self, attr: AttributeId) -> bool {
240 if self.selected.is_empty()240 if self.selected.is_empty() || self.selected.iter().any(|(_name, id)| *id == Some(attr)) {
241 || self
242 .selected
243 .iter()
244 .any(|(_name, id)| id.map_or(false, |id| id == attr))
245 {
246 *self.remaining.as_mut().expect("initialized") -= 1;241 *self.remaining.as_mut().expect("initialized") -= 1;
247 }242 }
248 self.is_done()243 self.is_done()
gix-blame/src/file/function.rs+1−1
@@ -684,7 +684,7 @@ fn collect_parents( · 683 unmodified lines
684 parent_ids.push((id, parent_commit_time));684 parent_ids.push((id, parent_commit_time));
685 }685 }
686 }686 }
687 };687 }
688 Ok(parent_ids)688 Ok(parent_ids)
689}689}
690 690
gix-commitgraph/src/file/init.rs+1−1
@@ -85,7 +85,7 @@ impl File { · 84 unmodified lines
85 x => {85 x => {
86 return Err(Error::UnsupportedVersion(x));86 return Err(Error::UnsupportedVersion(x));
87 }87 }
88 };88 }
89 ofs += 1;89 ofs += 1;
90 90
91 let object_hash = gix_hash::Kind::try_from(data[ofs]).map_err(Error::UnsupportedHashVersion)?;91 let object_hash = gix_hash::Kind::try_from(data[ofs]).map_err(Error::UnsupportedHashVersion)?;
gix-config-value/src/path.rs+2−2
@@ -122,8 +122,8 @@ impl<'a> Path<'a> { · 121 unmodified lines
122 /// the `home_for_user` function to be provided.122 /// the `home_for_user` function to be provided.
123 /// The interpolation uses `getpwnam` sys call and is therefore not available on windows.123 /// The interpolation uses `getpwnam` sys call and is therefore not available on windows.
124 /// - `%(prefix)/` is expanded to the location where `gitoxide` is installed.124 /// - `%(prefix)/` is expanded to the location where `gitoxide` is installed.
125 /// This location is not known at compile time and therefore need to be125 /// This location is not known at compile time and therefore need to be
126 /// optionally provided by the caller through `git_install_dir`.126 /// optionally provided by the caller through `git_install_dir`.
127 ///127 ///
128 /// Any other, non-empty path value is returned unchanged and error is returned in case of an empty path value or if required input128 /// Any other, non-empty path value is returned unchanged and error is returned in case of an empty path value or if required input
129 /// wasn't provided.129 /// wasn't provided.
gix-config/src/file/includes/mod.rs+1−1
@@ -32,7 +32,7 @@ impl File<'static> { · 31 unmodified lines
32 /// which later overwrite portions of the included file, which seems unusual as these would be related to `includes`.32 /// which later overwrite portions of the included file, which seems unusual as these would be related to `includes`.
33 /// We can fix this by 'splitting' the include section if needed so the included sections are put into the right place.33 /// We can fix this by 'splitting' the include section if needed so the included sections are put into the right place.
34 /// - `hasconfig:remote.*.url` will not prevent itself to include files with `[remote "name"]\nurl = x` values, but it also34 /// - `hasconfig:remote.*.url` will not prevent itself to include files with `[remote "name"]\nurl = x` values, but it also
35 /// won't match them, i.e. one cannot include something that will cause the condition to match or to always be true.35 /// won't match them, i.e. one cannot include something that will cause the condition to match or to always be true.
36 pub fn resolve_includes(&mut self, options: init::Options<'_>) -> Result<(), Error> {36 pub fn resolve_includes(&mut self, options: init::Options<'_>) -> Result<(), Error> {
37 if options.includes.max_depth == 0 {37 if options.includes.max_depth == 0 {
38 return Ok(());38 return Ok(());
gix-config/src/file/init/from_paths.rs+1−1
@@ -116,7 +116,7 @@ impl File<'static> { · 115 unmodified lines
116 return Err(Error::Io { source: err, path });116 return Err(Error::Io { source: err, path });
117 }117 }
118 }118 }
119 };119 }
120 meta.path = Some(path);120 meta.path = Some(path);
121 121
122 let config = Self::from_bytes_owned(buf, meta, options)?;122 let config = Self::from_bytes_owned(buf, meta, options)?;
gix-config/src/file/section/body.rs+1−1
@@ -151,7 +151,7 @@ impl Body<'_> { · 150 unmodified lines
151 value_range.end = i;151 value_range.end = i;
152 } else {152 } else {
153 value_range.start = i;153 value_range.start = i;
154 };154 }
155 }155 }
156 _ => (),156 _ => (),
157 }157 }
gix-config/src/parse/events.rs+1−1
@@ -305,7 +305,7 @@ fn from_bytes<'a, 'b>( · 304 unmodified lines
305 events: std::mem::take(&mut events),305 events: std::mem::take(&mut events),
306 });306 });
307 }307 }
308 };308 }
309 header = match convert(Event::SectionHeader(next_header)) {309 header = match convert(Event::SectionHeader(next_header)) {
310 Event::SectionHeader(h) => h,310 Event::SectionHeader(h) => h,
311 _ => unreachable!("BUG: convert must not change the event type, just the lifetime"),311 _ => unreachable!("BUG: convert must not change the event type, just the lifetime"),
gix-credentials/tests/program/from_custom_definition.rs+1−1
@@ -12,7 +12,7 @@ const SH: &str = "/bin/sh"; · 11 unmodified lines
12fn empty() {12fn empty() {
13 let prog = Program::from_custom_definition("");13 let prog = Program::from_custom_definition("");
14 let git = *GIT;14 let git = *GIT;
15 assert!(matches!(&prog.kind, Kind::ExternalName { name_and_args } if name_and_args == ""));15 assert!(matches!(&prog.kind, Kind::ExternalName { name_and_args } if name_and_args.is_empty()));
16 assert_eq!(16 assert_eq!(
17 format!("{:?}", prog.to_command(&helper::Action::Store("egal".into()))),17 format!("{:?}", prog.to_command(&helper::Action::Store("egal".into()))),
18 format!(r#""{git}" "credential-" "store""#),18 format!(r#""{git}" "credential-" "store""#),
gix-date/src/parse.rs+1−1
@@ -77,7 +77,7 @@ pub(crate) mod function { · 76 unmodified lines
77 let mut offset_in_seconds = hours * 3600 + minutes * 60;77 let mut offset_in_seconds = hours * 3600 + minutes * 60;
78 if sign == Sign::Minus {78 if sign == Sign::Minus {
79 offset_in_seconds *= -1;79 offset_in_seconds *= -1;
80 };80 }
81 let time = Time {81 let time = Time {
82 seconds,82 seconds,
83 offset: offset_in_seconds,83 offset: offset_in_seconds,
gix-diff/src/blob/pipeline.rs+20−22
@@ -395,7 +395,7 @@ impl Pipeline { · 394 unmodified lines
395 && header.size > self.options.large_file_threshold_bytes395 && header.size > self.options.large_file_threshold_bytes
396 {396 {
397 is_binary = Some(true);397 is_binary = Some(true);
398 };398 }
399 let data = if is_binary == Some(true) {399 let data = if is_binary == Some(true) {
400 Data::Binary { size: header.size }400 Data::Binary { size: header.size }
401 } else {401 } else {
@@ -461,27 +461,25 @@ impl Pipeline { · 59 unmodified lines
461 out.clear();461 out.clear();
462 run_cmd(rela_path, cmd, out)?;462 run_cmd(rela_path, cmd, out)?;
463 }463 }
464 None => {464 None => match res {
465 match res {465 ToWorktreeOutcome::Unchanged(_) => {}
466 ToWorktreeOutcome::Unchanged(_) => {}466 ToWorktreeOutcome::Buffer(src) => {
467 ToWorktreeOutcome::Buffer(src) => {467 out.clear();
468 out.clear();468 out.try_reserve(src.len())?;
469 out.try_reserve(src.len())?;469 out.extend_from_slice(src);
470 out.extend_from_slice(src);470 }
471 }471 ToWorktreeOutcome::Process(MaybeDelayed::Immediate(mut stream)) => {
472 ToWorktreeOutcome::Process(MaybeDelayed::Immediate(mut stream)) => {472 std::io::copy(&mut stream, out).map_err(|err| {
473 std::io::copy(&mut stream, out).map_err(|err| {473 convert_to_diffable::Error::StreamCopy {
474 convert_to_diffable::Error::StreamCopy {474 rela_path: rela_path.to_owned(),
475 rela_path: rela_path.to_owned(),475 source: err,
476 source: err,476 }
477 }477 })?;
478 })?;478 }
479 }479 ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {
480 ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {480 unreachable!("we prohibit this")
481 unreachable!("we prohibit this")481 }
482 }482 },
483 };
484 }
485 }483 }
486 }484 }
487 485
gix-diff/src/blob/platform.rs+1−1
@@ -362,7 +362,7 @@ impl Platform { · 361 unmodified lines
362 /// * `mode` is the kind of object (only blobs and links are allowed)362 /// * `mode` is the kind of object (only blobs and links are allowed)
363 /// * `rela_path` is the relative path as seen from the (work)tree root.363 /// * `rela_path` is the relative path as seen from the (work)tree root.
364 /// * `kind` identifies the side of the diff this resource will be used for.364 /// * `kind` identifies the side of the diff this resource will be used for.
365 /// A diff needs both `OldOrSource` *and* `NewOrDestination`.365 /// A diff needs both `OldOrSource` *and* `NewOrDestination`.
366 /// * `objects` provides access to the object database in case the resource can't be read from a worktree.366 /// * `objects` provides access to the object database in case the resource can't be read from a worktree.
367 ///367 ///
368 /// Note that it's assumed that either `id + mode (` or `rela_path` can serve as unique identifier for the resource,368 /// Note that it's assumed that either `id + mode (` or `rela_path` can serve as unique identifier for the resource,
gix-diff/src/rewrites/tracker.rs+5−5
@@ -166,9 +166,9 @@ impl<T: Change> Tracker<T> { · 165 unmodified lines
166 /// We may refuse the push if that information isn't needed for what we have to track.166 /// We may refuse the push if that information isn't needed for what we have to track.
167 pub fn try_push_change(&mut self, change: T, location: &BStr) -> Option<T> {167 pub fn try_push_change(&mut self, change: T, location: &BStr) -> Option<T> {
168 let change_kind = change.kind();168 let change_kind = change.kind();
169 if let (None, ChangeKind::Modification { .. }) = (self.rewrites.copies, change_kind) {169 if let (None, ChangeKind::Modification) = (self.rewrites.copies, change_kind) {
170 return Some(change);170 return Some(change);
171 };171 }
172 172
173 let entry_kind = change.entry_mode().kind();173 let entry_kind = change.entry_mode().kind();
174 if entry_kind == EntryKind::Commit {174 if entry_kind == EntryKind::Commit {
@@ -179,7 +179,7 @@ impl<T: Change> Tracker<T> { · 4 unmodified lines
179 .filter(|_| matches!(change_kind, ChangeKind::Addition | ChangeKind::Deletion));179 .filter(|_| matches!(change_kind, ChangeKind::Addition | ChangeKind::Deletion));
180 if let (None, EntryKind::Tree) = (relation, entry_kind) {180 if let (None, EntryKind::Tree) = (relation, entry_kind) {
181 return Some(change);181 return Some(change);
182 };182 }
183 183
184 let start = self.path_backing.len();184 let start = self.path_backing.len();
185 self.path_backing.extend_from_slice(location);185 self.path_backing.extend_from_slice(location);
@@ -514,7 +514,7 @@ impl<T: Change> Tracker<T> { · 328 unmodified lines
514 dst_items.push((item.change.id().to_owned(), item));514 dst_items.push((item.change.id().to_owned(), item));
515 }515 }
516 _ => continue,516 _ => continue,
517 };517 }
518 }518 }
519 519
520 for ((src_id, src_item), (dst_id, dst_item)) in src_items.into_iter().zip(dst_items) {520 for ((src_id, src_item), (dst_id, dst_item)) in src_items.into_iter().zip(dst_items) {
@@ -758,7 +758,7 @@ fn find_match<'a, T: Change>( · 237 unmodified lines
758 Operation::SourceOrDestinationIsBinary => {758 Operation::SourceOrDestinationIsBinary => {
759 // TODO: figure out if git does more here759 // TODO: figure out if git does more here
760 }760 }
761 };761 }
762 }762 }
763 }763 }
764 Ok(None)764 Ok(None)
gix-diff/src/tree/function.rs+5−5
@@ -70,7 +70,7 @@ where · 69 unmodified lines
70 }70 }
71 Some((None, None, _)) => unreachable!("BUG: it makes no sense to fill the stack with empties"),71 Some((None, None, _)) => unreachable!("BUG: it makes no sense to fill the stack with empties"),
72 None => return Ok(()),72 None => return Ok(()),
73 };73 }
74 pop_path = false;74 pop_path = false;
75 }75 }
76 (Some(lhs), Some(rhs)) => {76 (Some(lhs), Some(rhs)) => {
@@ -328,7 +328,7 @@ fn handle_lhs_and_rhs_with_equal_filenames( · 251 unmodified lines
328 .cancelled()328 .cancelled()
329 {329 {
330 return Err(Error::Cancelled);330 return Err(Error::Cancelled);
331 };331 }
332 332
333 let relation = relation_to_propagate.or_else(|| {333 let relation = relation_to_propagate.or_else(|| {
334 *change_id += 1;334 *change_id += 1;
@@ -343,7 +343,7 @@ fn handle_lhs_and_rhs_with_equal_filenames( · 8 unmodified lines
343 .cancelled()343 .cancelled()
344 {344 {
345 return Err(Error::Cancelled);345 return Err(Error::Cancelled);
346 };346 }
347 queue.push_back((None, Some(rhs.oid.to_owned()), to_child(relation)));347 queue.push_back((None, Some(rhs.oid.to_owned()), to_child(relation)));
348 }348 }
349 (true, _) => {349 (true, _) => {
@@ -371,7 +371,7 @@ fn handle_lhs_and_rhs_with_equal_filenames( · 21 unmodified lines
371 .cancelled()371 .cancelled()
372 {372 {
373 return Err(Error::Cancelled);373 return Err(Error::Cancelled);
374 };374 }
375 queue.push_back((Some(lhs.oid.to_owned()), None, to_child(relation)));375 queue.push_back((Some(lhs.oid.to_owned()), None, to_child(relation)));
376 }376 }
377 (false, false) => {377 (false, false) => {
@@ -390,7 +390,7 @@ fn handle_lhs_and_rhs_with_equal_filenames( · 12 unmodified lines
390 return Err(Error::Cancelled);390 return Err(Error::Cancelled);
391 }391 }
392 }392 }
393 };393 }
394 Ok(())394 Ok(())
395}395}
396 396
gix-diff/tests/diff/rewrites/tracker.rs+2−2
@@ -441,7 +441,7 @@ fn rename_by_similarity_reports_limit_if_encountered() -> crate::Result { · 440 unmodified lines
441 1 => assert_eq!(dst.location, "b"),441 1 => assert_eq!(dst.location, "b"),
442 2 => assert_eq!(dst.location, "c"),442 2 => assert_eq!(dst.location, "c"),
443 _ => panic!("too many elements emitted"),443 _ => panic!("too many elements emitted"),
444 };444 }
445 calls += 1;445 calls += 1;
446 Action::Continue446 Action::Continue
447 },447 },
@@ -511,7 +511,7 @@ fn rename_by_50_percent_similarity() -> crate::Result { · 63 unmodified lines
511 assert_eq!(dst.location, "c");511 assert_eq!(dst.location, "c");
512 }512 }
513 _ => panic!("too many elements emitted"),513 _ => panic!("too many elements emitted"),
514 };514 }
515 calls += 1;515 calls += 1;
516 Action::Continue516 Action::Continue
517 },517 },
gix-discover/src/repository.rs+5−1
@@ -76,7 +76,11 @@ mod path { · 75 unmodified lines
76 None => {76 None => {
77 let mut dir = normalize_on_trailing_dot_dot(dir)?;77 let mut dir = normalize_on_trailing_dot_dot(dir)?;
78 dir.pop(); // ".git" suffix78 dir.pop(); // ".git" suffix
79 let work_dir = dir.as_os_str().is_empty().then(|| PathBuf::from(".")).unwrap_or(dir);79 let work_dir = if dir.as_os_str().is_empty() {
80 PathBuf::from(".")
81 } else {
82 dir
83 };
80 Path::WorkTree(work_dir)84 Path::WorkTree(work_dir)
81 }85 }
82 },86 },
gix-discover/tests/discover/upwards/mod.rs+2−2
@@ -319,7 +319,7 @@ fn do_not_shorten_absolute_paths() -> crate::Result { · 318 unmodified lines
319 assert!(work_dir.is_absolute());319 assert!(work_dir.is_absolute());
320 }320 }
321 _ => panic!("expected worktree path"),321 _ => panic!("expected worktree path"),
322 };322 }
323 323
324 Ok(())324 Ok(())
325}325}
@@ -345,7 +345,7 @@ mod dot_git_only { · 19 unmodified lines
345 assert_eq!(work_dir, expected.as_ref());345 assert_eq!(work_dir, expected.as_ref());
346 }346 }
347 _ => panic!("expected worktree path"),347 _ => panic!("expected worktree path"),
348 };348 }
349 }349 }
350 350
351 #[test]351 #[test]
gix-features/src/io.rs+2−2
@@ -30,7 +30,7 @@ pub mod pipe { · 29 unmodified lines
30 Ok(Err(err)) => return Err(err),30 Ok(Err(err)) => return Err(err),
31 Err(_) => {}31 Err(_) => {}
32 }32 }
33 };33 }
34 Ok(&self.buf)34 Ok(&self.buf)
35 }35 }
36 36
@@ -77,7 +77,7 @@ pub mod pipe { · 40 unmodified lines
77 /// Returns the _([`write`][Writer], [`read`][Reader])_ ends of a pipe for transferring bytes, analogous to a unix pipe.77 /// Returns the _([`write`][Writer], [`read`][Reader])_ ends of a pipe for transferring bytes, analogous to a unix pipe.
78 ///78 ///
79 /// * `in_flight_writes` defines the amount of chunks of bytes to keep in memory until the `write` end will block when writing.79 /// * `in_flight_writes` defines the amount of chunks of bytes to keep in memory until the `write` end will block when writing.
80 /// If `0`, the `write` end will always block until the `read` end consumes the transferred bytes.80 /// If `0`, the `write` end will always block until the `read` end consumes the transferred bytes.
81 pub fn unidirectional(in_flight_writes: usize) -> (Writer, Reader) {81 pub fn unidirectional(in_flight_writes: usize) -> (Writer, Reader) {
82 let (tx, rx) = std::sync::mpsc::sync_channel(in_flight_writes);82 let (tx, rx) = std::sync::mpsc::sync_channel(in_flight_writes);
83 (83 (
gix-features/src/parallel/eager_iter.rs+4−4
@@ -17,11 +17,11 @@ where · 16 unmodified lines
17 /// with a given `chunk_size` allowing a maximum `chunks_in_flight`.17 /// with a given `chunk_size` allowing a maximum `chunks_in_flight`.
18 ///18 ///
19 /// * `chunk_size` describes how many items returned by `iter` will be a single item of this `EagerIter`.19 /// * `chunk_size` describes how many items returned by `iter` will be a single item of this `EagerIter`.
20 /// This helps to reduce the overhead imposed by transferring many small items.20 /// This helps to reduce the overhead imposed by transferring many small items.
21 /// If this number is 1, each item will become a single chunk. 0 is invalid.21 /// If this number is 1, each item will become a single chunk. 0 is invalid.
22 /// * `chunks_in_flight` describes how many chunks can be kept in memory in case the consumer of the `EagerIter`s items22 /// * `chunks_in_flight` describes how many chunks can be kept in memory in case the consumer of the `EagerIter`s items
23 /// isn't consuming them fast enough. Setting this number to 0 effectively turns off any caching, but blocks `EagerIter`23 /// isn't consuming them fast enough. Setting this number to 0 effectively turns off any caching, but blocks `EagerIter`
24 /// if its items aren't consumed fast enough.24 /// if its items aren't consumed fast enough.
25 pub fn new(iter: I, chunk_size: usize, chunks_in_flight: usize) -> Self {25 pub fn new(iter: I, chunk_size: usize, chunks_in_flight: usize) -> Self {
26 let (sender, receiver) = std::sync::mpsc::sync_channel(chunks_in_flight);26 let (sender, receiver) = std::sync::mpsc::sync_channel(chunks_in_flight);
27 let size_hint = iter.size_hint();27 let size_hint = iter.size_hint();
gix-features/src/parallel/mod.rs+3−3
@@ -66,11 +66,11 @@ pub fn optimize_chunk_size_and_thread_limit( · 65 unmodified lines
66///66///
67/// * `desired_chunk_size` is the amount of items per chunk you think should be used.67/// * `desired_chunk_size` is the amount of items per chunk you think should be used.
68/// * `num_items` is the total amount of items in the iteration, if `Some`.68/// * `num_items` is the total amount of items in the iteration, if `Some`.
69/// Otherwise this knowledge will not affect the output of this function.69/// Otherwise this knowledge will not affect the output of this function.
70/// * `thread_limit` is the amount of threads to use at most, if `Some`.70/// * `thread_limit` is the amount of threads to use at most, if `Some`.
71/// Otherwise this knowledge will not affect the output of this function.71/// Otherwise this knowledge will not affect the output of this function.
72/// * `available_threads` is the total amount of threads available, if `Some`.72/// * `available_threads` is the total amount of threads available, if `Some`.
73/// Otherwise the actual amount of available threads is determined by querying the system.73/// Otherwise the actual amount of available threads is determined by querying the system.
74///74///
75/// `Note` that this implementation is available only if the `parallel` feature toggle is set.75/// `Note` that this implementation is available only if the `parallel` feature toggle is set.
76#[cfg(feature = "parallel")]76#[cfg(feature = "parallel")]
gix-filter/src/driver/process/server.rs+1−1
@@ -126,7 +126,7 @@ impl Server { · 125 unmodified lines
126 }126 }
127 }127 }
128 None => continue,128 None => continue,
129 };129 }
130 }130 }
131 131
132 for cap in &capabilities {132 for cap in &capabilities {
gix-filter/src/pipeline/convert.rs+1−1
@@ -202,7 +202,7 @@ impl Pipeline { · 201 unmodified lines
202 let (src, dest) = bufs.src_and_dest();202 let (src, dest) = bufs.src_and_dest();
203 if eol::convert_to_worktree(src, digest, dest, self.options.eol_config)? {203 if eol::convert_to_worktree(src, digest, dest, self.options.eol_config)? {
204 bufs.swap();204 bufs.swap();
205 };205 }
206 206
207 if let Some(encoding) = encoding {207 if let Some(encoding) = encoding {
208 let (src, dest) = bufs.src_and_dest();208 let (src, dest) = bufs.src_and_dest();
gix-fs/src/dir/create.rs+2−2
@@ -165,7 +165,7 @@ impl<'a> Iterator for Iter<'a> { · 164 unmodified lines
165 }165 }
166 if self.retries.on_create_directory_failure < 1 {166 if self.retries.on_create_directory_failure < 1 {
167 return self.permanent_failure(dir, NotFound);167 return self.permanent_failure(dir, NotFound);
168 };168 }
169 self.cursors.push(dir);169 self.cursors.push(dir);
170 self.cursors.push(match dir.parent() {170 self.cursors.push(match dir.parent() {
171 None => return self.permanent_failure(dir, InvalidInput),171 None => return self.permanent_failure(dir, InvalidInput),
@@ -177,7 +177,7 @@ impl<'a> Iterator for Iter<'a> { · 5 unmodified lines
177 self.retries.on_interrupt -= 1;177 self.retries.on_interrupt -= 1;
178 if self.retries.on_interrupt <= 1 {178 if self.retries.on_interrupt <= 1 {
179 return self.permanent_failure(dir, Interrupted);179 return self.permanent_failure(dir, Interrupted);
180 };180 }
181 self.cursors.push(dir);181 self.cursors.push(dir);
182 self.intermediate_failure(dir, err)182 self.intermediate_failure(dir, err)
183 }183 }
gix-glob/src/parse.rs+1−1
@@ -13,7 +13,7 @@ pub fn pattern(mut pat: &[u8], may_alter: bool) -> Option<(&[u8], pattern::Mode, · 12 unmodified lines
13 let mut mode = Mode::empty();13 let mut mode = Mode::empty();
14 if pat.is_empty() {14 if pat.is_empty() {
15 return None;15 return None;
16 };16 }
17 if may_alter {17 if may_alter {
18 if pat.first() == Some(&b'!') {18 if pat.first() == Some(&b'!') {
19 mode |= Mode::NEGATIVE;19 mode |= Mode::NEGATIVE;
gix-glob/src/wildmatch.rs+5−5
@@ -157,7 +157,7 @@ pub(crate) mod function { · 156 unmodified lines
157 t_ch = t.1;157 t_ch = t.1;
158 }158 }
159 None => break,159 None => break,
160 };160 }
161 }161 }
162 if t_ch != p_ch {162 if t_ch != p_ch {
163 return NoMatch;163 return NoMatch;
@@ -177,7 +177,7 @@ pub(crate) mod function { · 13 unmodified lines
177 t_ch = t.1;177 t_ch = t.1;
178 }178 }
179 None => break AbortAll,179 None => break AbortAll,
180 };180 }
181 };181 };
182 }182 }
183 BRACKET_OPEN => {183 BRACKET_OPEN => {
@@ -187,7 +187,7 @@ pub(crate) mod function { · 3 unmodified lines
187 p_ch = t.1;187 p_ch = t.1;
188 }188 }
189 None => return AbortAll,189 None => return AbortAll,
190 };190 }
191 191
192 if p_ch == b'^' {192 if p_ch == b'^' {
193 p_ch = NEGATE_CLASS;193 p_ch = NEGATE_CLASS;
@@ -326,7 +326,7 @@ pub(crate) mod function { · 132 unmodified lines
326 }326 }
327 }327 }
328 _ => return AbortAll,328 _ => return AbortAll,
329 };329 }
330 prev_p_ch = 0;330 prev_p_ch = 0;
331 }331 }
332 }332 }
@@ -336,7 +336,7 @@ pub(crate) mod function { · 3 unmodified lines
336 matched = true;336 matched = true;
337 }337 }
338 }338 }
339 };339 }
340 next = p.next();340 next = p.next();
341 if let Some((_, BRACKET_CLOSE)) = next {341 if let Some((_, BRACKET_CLOSE)) = next {
342 break;342 break;
gix-glob/tests/pattern/matching.rs+1−1
@@ -88,7 +88,7 @@ fn compare_baseline_with_ours() { · 87 unmodified lines
88 panics += 1;88 panics += 1;
89 continue;89 continue;
90 }90 }
91 };91 }
92 }92 }
93 }93 }
94 94
gix-hash/src/prefix.rs+1−1
@@ -100,7 +100,7 @@ impl Prefix { · 99 unmodified lines
100 return Err(from_hex::Error::TooLong { hex_len });100 return Err(from_hex::Error::TooLong { hex_len });
101 } else if hex_len < Self::MIN_HEX_LEN {101 } else if hex_len < Self::MIN_HEX_LEN {
102 return Err(from_hex::Error::TooShort { hex_len });102 return Err(from_hex::Error::TooShort { hex_len });
103 };103 }
104 104
105 let src = if value.len() % 2 == 0 {105 let src = if value.len() % 2 == 0 {
106 let mut out = Vec::from_iter(std::iter::repeat(0).take(value.len() / 2));106 let mut out = Vec::from_iter(std::iter::repeat(0).take(value.len() / 2));
gix-index/src/access/mod.rs+2−2
@@ -194,7 +194,7 @@ impl State { · 193 unmodified lines
194 let entry_path = e.path(self);194 let entry_path = e.path(self);
195 if entry_path == path {195 if entry_path == path {
196 return true;196 return true;
197 };197 }
198 if !ignore_case {198 if !ignore_case {
199 return false;199 return false;
200 }200 }
@@ -222,7 +222,7 @@ impl State { · 21 unmodified lines
222 let dir_path = dir.path(self);222 let dir_path = dir.path(self);
223 if dir_path == directory {223 if dir_path == directory {
224 return true;224 return true;
225 };225 }
226 if !ignore_case {226 if !ignore_case {
227 return false;227 return false;
228 }228 }
gix-index/src/entry/flags.rs+1−1
@@ -12,7 +12,7 @@ bitflags! { · 11 unmodified lines
12 /// The mask to obtain the length of the path associated with this entry, up to 4095 characters without extension.12 /// The mask to obtain the length of the path associated with this entry, up to 4095 characters without extension.
13 const PATH_LEN = 0x0fff;13 const PATH_LEN = 0x0fff;
14 /// The mask to apply to obtain the stage number of an entry, encoding three value: 0 = base, 1 = ours, 2 = theirs.14 /// The mask to apply to obtain the stage number of an entry, encoding three value: 0 = base, 1 = ours, 2 = theirs.
15 const STAGE_MASK = 1<<12 | 1<<13;15 const STAGE_MASK = (1<<12) | (1<<13);
16 /// If set, additional bits need to be written to storage.16 /// If set, additional bits need to be written to storage.
17 const EXTENDED = 1<<14;17 const EXTENDED = 1<<14;
18 /// If set, the entry be assumed to match with the version on the working tree, as a way to avoid `lstat()` checks.18 /// If set, the entry be assumed to match with the version on the working tree, as a way to avoid `lstat()` checks.
gix-index/src/entry/mode.rs+1−1
@@ -55,7 +55,7 @@ impl Mode { · 54 unmodified lines
55 Mode::FILE if executable_bit && stat.is_executable() => return Some(Change::ExecutableBit),55 Mode::FILE if executable_bit && stat.is_executable() => return Some(Change::ExecutableBit),
56 Mode::FILE_EXECUTABLE if executable_bit && !stat.is_executable() => return Some(Change::ExecutableBit),56 Mode::FILE_EXECUTABLE if executable_bit && !stat.is_executable() => return Some(Change::ExecutableBit),
57 _ => return None,57 _ => return None,
58 };58 }
59 let new_mode = if stat.is_dir() {59 let new_mode = if stat.is_dir() {
60 Mode::COMMIT60 Mode::COMMIT
61 } else if executable_bit && stat.is_executable() {61 } else if executable_bit && stat.is_executable() {
gix-index/src/write.rs+1−1
@@ -176,7 +176,7 @@ fn entries<T: std::io::Write>(out: &mut CountBytes<T>, state: &State, header_siz · 175 unmodified lines
176 let eight_null_bytes = [0u8; 8];176 let eight_null_bytes = [0u8; 8];
177 out.write_all(&eight_null_bytes[n as usize..])?;177 out.write_all(&eight_null_bytes[n as usize..])?;
178 }178 }
179 };179 }
180 }180 }
181 181
182 Ok(out.count)182 Ok(out.count)
gix-macros/src/momo.rs+1−1
@@ -126,7 +126,7 @@ fn parse_bounds(bounds: &Punctuated<TypeParamBound, Token![+]>) -> Option<Conver · 125 unmodified lines
126 return None;126 return None;
127 }127 }
128 if let TypeParamBound::Trait(ref tb) = bounds.first().unwrap() {128 if let TypeParamBound::Trait(ref tb) = bounds.first().unwrap() {
129 if let Some(seg) = tb.path.segments.iter().last() {129 if let Some(seg) = tb.path.segments.iter().next_back() {
130 if let PathArguments::AngleBracketed(ref gen_args) = seg.arguments {130 if let PathArguments::AngleBracketed(ref gen_args) = seg.arguments {
131 if let GenericArgument::Type(_) = gen_args.args.first().unwrap() {131 if let GenericArgument::Type(_) = gen_args.args.first().unwrap() {
132 if seg.ident == "Into" {132 if seg.ident == "Into" {
gix-mailmap/src/snapshot/mod.rs+1−1
@@ -46,7 +46,7 @@ impl Snapshot { · 45 unmodified lines
46 Err(insert_pos) => {46 Err(insert_pos) => {
47 self.entries_by_old_email.insert(insert_pos, entry.into());47 self.entries_by_old_email.insert(insert_pos, entry.into());
48 }48 }
49 };49 }
50 }50 }
51 self51 self
52 }52 }
gix-merge/src/blob/pipeline.rs+1−1
@@ -293,7 +293,7 @@ impl Pipeline { · 292 unmodified lines
293 ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {293 ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {
294 unreachable!("we prohibit this")294 unreachable!("we prohibit this")
295 }295 }
296 };296 }
297 }297 }
298 298
299 let res = self.filter.convert_to_git(299 let res = self.filter.convert_to_git(
gix-merge/src/blob/platform/set_resource.rs+1−1
@@ -97,7 +97,7 @@ impl Platform { · 96 unmodified lines
97 storage.data = out;97 storage.data = out;
98 storage.mode = mode;98 storage.mode = mode;
99 }99 }
100 };100 }
101 Ok(())101 Ok(())
102 }102 }
103}103}
gix-merge/src/tree/function.rs+13−13
@@ -22,7 +22,7 @@ use std::convert::Infallible; · 21 unmodified lines
22/// * `labels` are relevant for text-merges and will be shown in conflicts.22/// * `labels` are relevant for text-merges and will be shown in conflicts.
23/// * `objects` provides access to trees when diffing them.23/// * `objects` provides access to trees when diffing them.
24/// * `write_blob_to_odb(content) -> Result<ObjectId, E>` writes newly merged content into the odb to obtain an id24/// * `write_blob_to_odb(content) -> Result<ObjectId, E>` writes newly merged content into the odb to obtain an id
25/// that will be used in merged trees.25/// that will be used in merged trees.
26/// * `diff_state` is state used for diffing trees.26/// * `diff_state` is state used for diffing trees.
27/// * `diff_resource_cache` is used for similarity checks.27/// * `diff_resource_cache` is used for similarity checks.
28/// * `blob_merge` is a pre-configured platform to merge any content.28/// * `blob_merge` is a pre-configured platform to merge any content.
@@ -208,7 +208,7 @@ where · 179 unmodified lines
208 [None, None, None],208 [None, None, None],
209 )) {209 )) {
210 break 'outer;210 break 'outer;
211 };211 }
212 editor.remove(to_components(theirs.location()))?;212 editor.remove(to_components(theirs.location()))?;
213 }213 }
214 apply_change(&mut editor, theirs, rewritten_location.as_ref().map(|t| &t.0))?;214 apply_change(&mut editor, theirs, rewritten_location.as_ref().map(|t| &t.0))?;
@@ -274,7 +274,7 @@ where · 59 unmodified lines
274 }274 }
275 if should_fail_on_conflict(conflict) {275 if should_fail_on_conflict(conflict) {
276 break 'outer;276 break 'outer;
277 };277 }
278 } else if matches!(candidate, PossibleConflict::TreeToNonTree { .. }) {278 } else if matches!(candidate, PossibleConflict::TreeToNonTree { .. }) {
279 let (mode, id) = theirs.entry_mode_and_id();279 let (mode, id) = theirs.entry_mode_and_id();
280 let location = theirs.location();280 let location = theirs.location();
@@ -316,7 +316,7 @@ where · 35 unmodified lines
316 their_changes[theirs_idx].was_written = true;316 their_changes[theirs_idx].was_written = true;
317 if should_fail_on_conflict(conflict) {317 if should_fail_on_conflict(conflict) {
318 break 'outer;318 break 'outer;
319 };319 }
320 } else if matches!(candidate, PossibleConflict::NonTreeToTree { .. }) {320 } else if matches!(candidate, PossibleConflict::NonTreeToTree { .. }) {
321 // We are writing on top of what was a file, a conflict we probably already saw and dealt with.321 // We are writing on top of what was a file, a conflict we probably already saw and dealt with.
322 let location = theirs.location();322 let location = theirs.location();
@@ -543,7 +543,7 @@ where · 220 unmodified lines
543 ],543 ],
544 )) {544 )) {
545 break 'outer;545 break 'outer;
546 };546 }
547 }547 }
548 (548 (
549 Change::Addition {549 Change::Addition {
@@ -795,10 +795,10 @@ where · 245 unmodified lines
795 editor.remove(toc(location))?;795 editor.remove(toc(location))?;
796 }796 }
797 _ => unreachable!("parent-match assures this"),797 _ => unreachable!("parent-match assures this"),
798 };798 }
799 }799 }
800 Some(ResolveWith::Ancestor) => {}800 Some(ResolveWith::Ancestor) => {}
801 };801 }
802 should_fail_on_conflict(Conflict::without_resolution(802 should_fail_on_conflict(Conflict::without_resolution(
803 ResolutionFailure::OursModifiedTheirsDeleted,803 ResolutionFailure::OursModifiedTheirsDeleted,
804 (ours, theirs, side, outer_side),804 (ours, theirs, side, outer_side),
@@ -807,7 +807,7 @@ where · 2 unmodified lines
807 };807 };
808 if should_break {808 if should_break {
809 break 'outer;809 break 'outer;
810 };810 }
811 }811 }
812 (812 (
813 Change::Modification { .. },813 Change::Modification { .. },
@@ -921,7 +921,7 @@ where · 107 unmodified lines
921 ],921 ],
922 )) {922 )) {
923 break 'outer;923 break 'outer;
924 };924 }
925 match tree_conflicts {925 match tree_conflicts {
926 None => {926 None => {
927 let our_addition = Change::Addition {927 let our_addition = Change::Addition {
@@ -983,7 +983,7 @@ where · 55 unmodified lines
983 ],983 ],
984 )) {984 )) {
985 break 'outer;985 break 'outer;
986 };986 }
987 }987 }
988 if let Some(addition) = our_addition {988 if let Some(addition) = our_addition {
989 push_deferred((addition, Some(ours_idx)), our_changes);989 push_deferred((addition, Some(ours_idx)), our_changes);
@@ -1054,7 +1054,7 @@ where · 64 unmodified lines
1054 ],1054 ],
1055 )) {1055 )) {
1056 break 'outer;1056 break 'outer;
1057 };1057 }
1058 1058
1059 let ours_is_rewrite = side.is_swapped();1059 let ours_is_rewrite = side.is_swapped();
1060 if tree_conflicts.is_none()1060 if tree_conflicts.is_none()
@@ -1139,7 +1139,7 @@ where · 78 unmodified lines
1139 [None, index_entry(our_mode, our_id), index_entry(their_mode, their_id)],1139 [None, index_entry(our_mode, our_id), index_entry(their_mode, their_id)],
1140 )) {1140 )) {
1141 break 'outer;1141 break 'outer;
1142 };1142 }
1143 }1143 }
1144 1144
1145 // Because this constellation can only be found by the lookup tree, there is1145 // Because this constellation can only be found by the lookup tree, there is
@@ -1236,7 +1236,7 @@ where · 90 unmodified lines
1236 }1236 }
1237 if should_fail_on_conflict(Conflict::unknown((ours, theirs, Original, outer_side))) {1237 if should_fail_on_conflict(Conflict::unknown((ours, theirs, Original, outer_side))) {
1238 break 'outer;1238 break 'outer;
1239 };1239 }
1240 }1240 }
1241 }1241 }
1242 their_changes[theirs_idx].was_written = true;1242 their_changes[theirs_idx].was_written = true;
gix-merge/src/tree/mod.rs+2−2
@@ -581,7 +581,7 @@ pub mod apply_index_entries { · 580 unmodified lines
581 index.entry_index_by_path_and_stage_bounded(path, gix_index::entry::Stage::Unconflicted, len)581 index.entry_index_by_path_and_stage_bounded(path, gix_index::entry::Stage::Unconflicted, len)
582 {582 {
583 index.entries_mut()[pos].flags.insert(gix_index::entry::Flags::REMOVE);583 index.entries_mut()[pos].flags.insert(gix_index::entry::Flags::REMOVE);
584 };584 }
585 match idx_by_path_stage.entry((stage, path)) {585 match idx_by_path_stage.entry((stage, path)) {
586 hash_map::Entry::Occupied(map_entry) => {586 hash_map::Entry::Occupied(map_entry) => {
587 // This can happen due to the way the algorithm works.587 // This can happen due to the way the algorithm works.
@@ -604,7 +604,7 @@ pub mod apply_index_entries { · 16 unmodified lines
604 path,604 path,
605 );605 );
606 }606 }
607 };607 }
608 }608 }
609 }609 }
610 610
gix-merge/tests/merge/blob/builtin_driver.rs+1−1
@@ -171,7 +171,7 @@ mod text { · 170 unmodified lines
171 "{}: resolution mismatch",171 "{}: resolution mismatch",
172 case.name172 case.name
173 );173 );
174 };174 }
175 assert_str_eq!(175 assert_str_eq!(
176 out.as_bstr().to_str_lossy(),176 out.as_bstr().to_str_lossy(),
177 case.expected.to_str_lossy(),177 case.expected.to_str_lossy(),
gix-merge/tests/merge/tree/mod.rs+1−1
@@ -151,7 +151,7 @@ fn run_baseline() -> crate::Result { · 150 unmodified lines
151 if !tree_path.exists() {151 if !tree_path.exists() {
152 skipped_tree_resolve_cases += 1;152 skipped_tree_resolve_cases += 1;
153 continue;153 continue;
154 };154 }
155 let expected_tree_id = gix_hash::ObjectId::from_hex(std::fs::read_to_string(tree_path)?.trim().as_bytes())?;155 let expected_tree_id = gix_hash::ObjectId::from_hex(std::fs::read_to_string(tree_path)?.trim().as_bytes())?;
156 options.tree_merge.tree_conflicts = Some(tree_resolution);156 options.tree_merge.tree_conflicts = Some(tree_resolution);
157 let resolve_with_ours = tree_resolution == gix_merge::tree::ResolveWith::Ours;157 let resolve_with_ours = tree_resolution == gix_merge::tree::ResolveWith::Ours;
gix-object/benches/edit_tree.rs+1−1
@@ -155,7 +155,7 @@ fn new_inmemory_writes() -> (TreeStore, impl FnMut(&Tree) -> Result<ObjectId, st · 154 unmodified lines
155 Entry::Vacant(e) => {155 Entry::Vacant(e) => {
156 e.insert(tree.clone());156 e.insert(tree.clone());
157 }157 }
158 };158 }
159 Ok(id)159 Ok(id)
160 }160 }
161 };161 };
gix-object/src/tree/editor.rs+1−1
@@ -153,7 +153,7 @@ impl Editor<'_> { · 152 unmodified lines
153 }153 }
154 }154 }
155 Err(_) => break,155 Err(_) => break,
156 };156 }
157 }157 }
158 None158 None
159 }159 }
gix-odb/src/alternate/mod.rs+1−1
@@ -61,7 +61,7 @@ pub fn resolve(objects_directory: PathBuf, current_dir: &std::path::Path) -> Res · 60 unmodified lines
61 }61 }
62 Err(err) if err.kind() == io::ErrorKind::NotFound => {}62 Err(err) if err.kind() == io::ErrorKind::NotFound => {}
63 Err(err) => return Err(err.into()),63 Err(err) => return Err(err.into()),
64 };64 }
65 if depth != 0 {65 if depth != 0 {
66 out.push(dir);66 out.push(dir);
67 }67 }
gix-odb/src/store_impls/dynamic/load_index.rs+1−1
@@ -418,7 +418,7 @@ impl super::Store { · 417 unmodified lines
418 // Safety: can't race as we hold the lock, have to set the generation beforehand to help avoid others to observe the value.418 // Safety: can't race as we hold the lock, have to set the generation beforehand to help avoid others to observe the value.
419 slot.generation.store(generation, Ordering::SeqCst);419 slot.generation.store(generation, Ordering::SeqCst);
420 *files_mut = None;420 *files_mut = None;
421 };421 }
422 slot.files.store(files);422 slot.files.store(files);
423 }423 }
424 424
gix-odb/src/store_impls/dynamic/types.rs+1−1
@@ -61,7 +61,7 @@ impl PackId { · 60 unmodified lines
61 midx <= Self::max_packs_in_multi_index(),61 midx <= Self::max_packs_in_multi_index(),
62 "There shouldn't be more than 2^16 packs per multi-index"62 "There shouldn't be more than 2^16 packs per multi-index"
63 );63 );
64 ((self.index as gix_pack::data::Id | 1 << 15) | midx << 16) as gix_pack::data::Id64 (self.index as gix_pack::data::Id | (1 << 15)) | (midx << 16) as gix_pack::data::Id
65 }65 }
66 }66 }
67 }67 }
gix-odb/src/store_impls/loose/iter.rs+1−1
@@ -34,7 +34,7 @@ impl loose::Iter { · 33 unmodified lines
34 }34 }
35 }35 }
36 Err(err) => return Some(Err(err)),36 Err(err) => return Some(Err(err)),
37 };37 }
38 None38 None
39 }39 }
40}40}
gix-pack/src/bundle/write/mod.rs+2−2
@@ -51,8 +51,8 @@ impl crate::Bundle { · 50 unmodified lines
51 /// * `progress` provides detailed progress information which can be discarded with [`gix_features::progress::Discard`].51 /// * `progress` provides detailed progress information which can be discarded with [`gix_features::progress::Discard`].
52 /// * `should_interrupt` is checked regularly and when true, the whole operation will stop.52 /// * `should_interrupt` is checked regularly and when true, the whole operation will stop.
53 /// * `thin_pack_base_object_lookup` If set, we expect to see a thin-pack with objects that reference their base object by object id which is53 /// * `thin_pack_base_object_lookup` If set, we expect to see a thin-pack with objects that reference their base object by object id which is
54 /// expected to exist in the object database the bundle is contained within.54 /// expected to exist in the object database the bundle is contained within.
55 /// `options` further configure how the task is performed.55 /// `options` further configure how the task is performed.
56 ///56 ///
57 /// # Note57 /// # Note
58 ///58 ///
gix-pack/src/cache/delta/from_offsets.rs+2−2
@@ -86,7 +86,7 @@ impl<T> Tree<T> { · 85 unmodified lines
86 let pack_offset = get_pack_offset(&data);86 let pack_offset = get_pack_offset(&data);
87 if let Some(previous_offset) = previous_cursor_position {87 if let Some(previous_offset) = previous_cursor_position {
88 Self::advance_cursor_to_pack_offset(&mut r, pack_offset, previous_offset)?;88 Self::advance_cursor_to_pack_offset(&mut r, pack_offset, previous_offset)?;
89 };89 }
90 let entry = crate::data::Entry::from_read(&mut r, pack_offset, hash_len).map_err(|err| Error::Io {90 let entry = crate::data::Entry::from_read(&mut r, pack_offset, hash_len).map_err(|err| Error::Io {
91 source: err,91 source: err,
92 message: "EOF while parsing header",92 message: "EOF while parsing header",
@@ -111,7 +111,7 @@ impl<T> Tree<T> { · 18 unmodified lines
111 .expect("in bound distance for deltas");111 .expect("in bound distance for deltas");
112 tree.add_child(base_pack_offset, pack_offset, data)?;112 tree.add_child(base_pack_offset, pack_offset, data)?;
113 }113 }
114 };114 }
115 progress.inc();115 progress.inc();
116 if idx % 10_000 == 0 && should_interrupt.load(Ordering::SeqCst) {116 if idx % 10_000 == 0 && should_interrupt.load(Ordering::SeqCst) {
117 return Err(Error::Interrupted);117 return Err(Error::Interrupted);
gix-pack/src/cache/delta/traverse/resolve.rs+2−2
@@ -251,8 +251,8 @@ where · 250 unmodified lines
251}251}
252 252
253/// * `initial_threads` is the threads we may spawn, not accounting for our own thread which is still considered used by the parent253/// * `initial_threads` is the threads we may spawn, not accounting for our own thread which is still considered used by the parent
254/// system. Since this thread will take a controlling function, we may spawn one more than that. In threaded mode, we will finish254/// system. Since this thread will take a controlling function, we may spawn one more than that. In threaded mode, we will finish
255/// all remaining work.255/// all remaining work.
256#[allow(clippy::too_many_arguments)]256#[allow(clippy::too_many_arguments)]
257fn deltas_mt<T, F, MBFN, E, R>(257fn deltas_mt<T, F, MBFN, E, R>(
258 mut threads_to_create: isize,258 mut threads_to_create: isize,
gix-pack/src/data/file/decode/entry.rs+1−1
@@ -260,7 +260,7 @@ impl File { · 259 unmodified lines
260 &first_entry,260 &first_entry,
261 consumed_input.expect("consumed bytes as set by cache"),261 consumed_input.expect("consumed bytes as set by cache"),
262 ));262 ));
263 };263 }
264 264
265 // First pass will decompress all delta data and keep it in our output buffer265 // First pass will decompress all delta data and keep it in our output buffer
266 // [<possibly resolved base object>]<delta-1..delta-n>...266 // [<possibly resolved base object>]<delta-1..delta-n>...
gix-pack/src/data/file/decode/header.rs+1−1
@@ -88,7 +88,7 @@ impl File { · 87 unmodified lines
88 None => return Err(Error::DeltaBaseUnresolved(base_id)),88 None => return Err(Error::DeltaBaseUnresolved(base_id)),
89 }89 }
90 }90 }
91 };91 }
92 }92 }
93 }93 }
94 94
gix-pack/src/data/input/entry.rs+1−1
@@ -59,7 +59,7 @@ fn compress_data(obj: &gix_object::Data<'_>) -> Result<Vec<u8>, input::Error> { · 58 unmodified lines
59 unreachable!("Should never see other errors than zlib, but got {:?}", err,)59 unreachable!("Should never see other errors than zlib, but got {:?}", err,)
60 }60 }
61 }61 }
62 };62 }
63 out.flush().expect("zlib flush should never fail");63 out.flush().expect("zlib flush should never fail");
64 Ok(out.into_inner())64 Ok(out.into_inner())
65}65}
gix-pack/src/data/output/bytes.rs+2−2
@@ -107,7 +107,7 @@ where · 106 unmodified lines
107 if entry.is_invalid() {107 if entry.is_invalid() {
108 self.pack_offsets_and_validity.push((0, false));108 self.pack_offsets_and_validity.push((0, false));
109 continue;109 continue;
110 };110 }
111 self.pack_offsets_and_validity.push((self.written, true));111 self.pack_offsets_and_validity.push((self.written, true));
112 let header = entry.to_entry_header(self.entry_version, |index| {112 let header = entry.to_entry_header(self.entry_version, |index| {
113 let (base_offset, is_valid_object) = self.pack_offsets_and_validity[index];113 let (base_offset, is_valid_object) = self.pack_offsets_and_validity[index];
@@ -128,7 +128,7 @@ where · 14 unmodified lines
128 self.is_done = true;128 self.is_done = true;
129 self.trailer = Some(gix_hash::ObjectId::from(digest));129 self.trailer = Some(gix_hash::ObjectId::from(digest));
130 }130 }
131 };131 }
132 Ok(self.written - previous_written)132 Ok(self.written - previous_written)
133 }133 }
134}134}
gix-pack/src/data/output/count/objects/tree.rs+1−1
@@ -57,7 +57,7 @@ pub mod changes { · 56 unmodified lines
57 }57 }
58 }58 }
59 Change::Deletion { .. } => {}59 Change::Deletion { .. } => {}
60 };60 }
61 Action::Continue61 Action::Continue
62 }62 }
63 }63 }
gix-pack/src/data/output/entry/mod.rs+2−2
@@ -72,7 +72,7 @@ impl output::Entry { · 71 unmodified lines
72 ) -> Option<Result<Self, Error>> {72 ) -> Option<Result<Self, Error>> {
73 if entry.version != target_version {73 if entry.version != target_version {
74 return None;74 return None;
75 };75 }
76 76
77 let pack_offset_must_be_zero = 0;77 let pack_offset_must_be_zero = 0;
78 let pack_entry = match data::Entry::from_bytes(&entry.data, pack_offset_must_be_zero, count.id.as_slice().len())78 let pack_entry = match data::Entry::from_bytes(&entry.data, pack_offset_must_be_zero, count.id.as_slice().len())
@@ -144,7 +144,7 @@ impl output::Entry { · 65 unmodified lines
144 std::io::ErrorKind::Other => return Err(Error::ZlibDeflate(err)),144 std::io::ErrorKind::Other => return Err(Error::ZlibDeflate(err)),
145 err => unreachable!("Should never see other errors than zlib, but got {:?}", err,),145 err => unreachable!("Should never see other errors than zlib, but got {:?}", err,),
146 }146 }
147 };147 }
148 out.flush()?;148 out.flush()?;
149 out.into_inner()149 out.into_inner()
150 },150 },
gix-pack/src/index/traverse/with_index.rs+1−1
@@ -220,7 +220,7 @@ fn digest_statistics(traverse::Outcome { roots, children }: traverse::Outcome<En · 219 unmodified lines
220 Tree => res.num_trees += 1,220 Tree => res.num_trees += 1,
221 Tag => res.num_tags += 1,221 Tag => res.num_tags += 1,
222 Commit => res.num_commits += 1,222 Commit => res.num_commits += 1,
223 };223 }
224 }224 }
225 225
226 let num_nodes = roots.len() + children.len();226 let num_nodes = roots.len() + children.len();
gix-pack/src/index/verify.rs+1−1
@@ -262,7 +262,7 @@ impl index::File { · 261 unmodified lines
262 }262 }
263 }263 }
264 Blob => {}264 Blob => {}
265 };265 }
266 }266 }
267 Ok(())267 Ok(())
268 }268 }
gix-pack/src/index/write/mod.rs+3−3
@@ -69,10 +69,10 @@ impl crate::index::File { · 68 unmodified lines
69 /// * `kind` is the version of pack index to produce, use [`crate::index::Version::default()`] if in doubt.69 /// * `kind` is the version of pack index to produce, use [`crate::index::Version::default()`] if in doubt.
70 /// * `tread_limit` is used for a parallel tree traversal for obtaining object hashes with optimal performance.70 /// * `tread_limit` is used for a parallel tree traversal for obtaining object hashes with optimal performance.
71 /// * `root_progress` is the top-level progress to stay informed about the progress of this potentially long-running71 /// * `root_progress` is the top-level progress to stay informed about the progress of this potentially long-running
72 /// computation.72 /// computation.
73 /// * `object_hash` defines what kind of object hash we write into the index file.73 /// * `object_hash` defines what kind of object hash we write into the index file.
74 /// * `pack_version` is the version of the underlying pack for which `entries` are read. It's used in case none of these objects are provided74 /// * `pack_version` is the version of the underlying pack for which `entries` are read. It's used in case none of these objects are provided
75 /// to compute a pack-hash.75 /// to compute a pack-hash.
76 ///76 ///
77 /// # Remarks77 /// # Remarks
78 ///78 ///
@@ -164,7 +164,7 @@ impl crate::index::File { · 85 unmodified lines
164 },164 },
165 )?;165 )?;
166 }166 }
167 };167 }
168 last_seen_trailer = trailer;168 last_seen_trailer = trailer;
169 num_objects += 1;169 num_objects += 1;
170 objects_progress.inc();170 objects_progress.inc();
gix-packetline-blocking/src/read/sidebands/blocking_io.rs+3−3
@@ -164,7 +164,7 @@ where · 163 unmodified lines
164 "interrupted by user",164 "interrupted by user",
165 ))165 ))
166 }166 }
167 };167 }
168 }168 }
169 BandRef::Error(d) => {169 BandRef::Error(d) => {
170 let text = TextRef::from(d).0;170 let text = TextRef::from(d).0;
@@ -176,9 +176,9 @@ where · 5 unmodified lines
176 "interrupted by user",176 "interrupted by user",
177 ))177 ))
178 }178 }
179 };179 }
180 }180 }
181 };181 }
182 }182 }
183 None => {183 None => {
184 break match line.as_slice() {184 break match line.as_slice() {
gix-packetline/src/read/sidebands/blocking_io.rs+3−3
@@ -162,7 +162,7 @@ where · 161 unmodified lines
162 "interrupted by user",162 "interrupted by user",
163 ))163 ))
164 }164 }
165 };165 }
166 }166 }
167 BandRef::Error(d) => {167 BandRef::Error(d) => {
168 let text = TextRef::from(d).0;168 let text = TextRef::from(d).0;
@@ -174,9 +174,9 @@ where · 5 unmodified lines
174 "interrupted by user",174 "interrupted by user",
175 ))175 ))
176 }176 }
177 };177 }
178 }178 }
179 };179 }
180 }180 }
181 None => {181 None => {
182 break match line.as_slice() {182 break match line.as_slice() {
gix-path/src/lib.rs+2−2
@@ -12,8 +12,8 @@ · 11 unmodified lines
12//! - mingw [is used for the conversion](https://github.com/git/git/blob/main/compat/mingw.h#L579:L579) and it appears they handle surrogates during the conversion, maybe some sort of non-strict UTF-8 converter? Actually it uses [WideCharToMultiByte](https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte)12//! - mingw [is used for the conversion](https://github.com/git/git/blob/main/compat/mingw.h#L579:L579) and it appears they handle surrogates during the conversion, maybe some sort of non-strict UTF-8 converter? Actually it uses [WideCharToMultiByte](https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte)
13//! under the hood which by now does fail if the UTF-8 would be invalid unicode, i.e. unicode pairs.13//! under the hood which by now does fail if the UTF-8 would be invalid unicode, i.e. unicode pairs.
14//! - `OsString` on windows already stores strings as WTF-8, which supports [surrogate pairs](https://unicodebook.readthedocs.io/unicode_encodings.html),14//! - `OsString` on windows already stores strings as WTF-8, which supports [surrogate pairs](https://unicodebook.readthedocs.io/unicode_encodings.html),
15//! something that UTF-8 isn't allowed do it for security reasons, after all it's UTF-16 specific and exists only to extend15//! something that UTF-8 isn't allowed do it for security reasons, after all it's UTF-16 specific and exists only to extend
16//! the encodable code-points.16//! the encodable code-points.
17//! - informative reading on [WTF-8](https://simonsapin.github.io/wtf-8/#motivation) which is the encoding used by Rust17//! - informative reading on [WTF-8](https://simonsapin.github.io/wtf-8/#motivation) which is the encoding used by Rust
18//! internally that deals with surrogates and non-wellformed surrogates (those that aren't in pairs).18//! internally that deals with surrogates and non-wellformed surrogates (those that aren't in pairs).
19//! * **unix**19//! * **unix**
gix-pathspec/src/parse.rs+1−1
@@ -155,7 +155,7 @@ fn parse_long_keywords(input: &[u8], p: &mut Pattern, cursor: &mut usize) -> Res · 154 unmodified lines
155 keyword: BString::from(keyword),155 keyword: BString::from(keyword),
156 });156 });
157 }157 }
158 };158 }
159 Ok(())159 Ok(())
160 })160 })
161}161}
gix-pathspec/tests/parse/invalid.rs+1−1
@@ -137,7 +137,7 @@ fn missing_parentheses() { · 136 unmodified lines
137 137
138 let output = gix_pathspec::parse(input.as_bytes(), Default::default());138 let output = gix_pathspec::parse(input.as_bytes(), Default::default());
139 assert!(output.is_err());139 assert!(output.is_err());
140 assert!(matches!(output.unwrap_err(), Error::MissingClosingParenthesis { .. }));140 assert!(matches!(output.unwrap_err(), Error::MissingClosingParenthesis));
141}141}
142 142
143#[test]143#[test]
gix-protocol/src/fetch/response/blocking_io.rs+1−1
@@ -120,7 +120,7 @@ impl Response { · 119 unmodified lines
120 io::ErrorKind::UnexpectedEof,120 io::ErrorKind::UnexpectedEof,
121 "Could not read message headline",121 "Could not read message headline",
122 )));122 )));
123 };123 }
124 124
125 match line.trim_end() {125 match line.trim_end() {
126 "acknowledgments" => {126 "acknowledgments" => {
gix-protocol/src/fetch/response/mod.rs+1−1
@@ -224,7 +224,7 @@ impl Response { · 223 unmodified lines
224 }224 }
225 Err(_) => return true,225 Err(_) => return true,
226 },226 },
227 };227 }
228 false228 false
229 }229 }
230}230}
gix-protocol/src/handshake/refs/shared.rs+1−1
@@ -188,7 +188,7 @@ pub(in crate::handshake::refs) fn parse_v1( · 187 unmodified lines
188 object,188 object,
189 path: path.into(),189 path: path.into(),
190 }),190 }),
191 };191 }
192 }192 }
193 }193 }
194 Ok(())194 Ok(())
gix-protocol/src/remote_progress.rs+1−1
@@ -66,7 +66,7 @@ impl RemoteProgress<'_> { · 65 unmodified lines
66 }66 }
67 }67 }
68 None => progress.set_name(progress_name(progress.name(), text)),68 None => progress.set_name(progress_name(progress.name(), text)),
69 };69 }
70 }70 }
71 }71 }
72}72}
gix-ref/src/store/file/find.rs+8−4
@@ -188,7 +188,7 @@ impl file::Store { · 187 unmodified lines
188 res.strip_namespace(namespace);188 res.strip_namespace(namespace);
189 }189 }
190 return Ok(Some(res));190 return Ok(Some(res));
191 };191 }
192 }192 }
193 }193 }
194 Ok(None)194 Ok(None)
@@ -225,9 +225,13 @@ impl file::Store { · 30 unmodified lines
225 use crate::Category::*;225 use crate::Category::*;
226 let sn = FullNameRef::new_unchecked(sn);226 let sn = FullNameRef::new_unchecked(sn);
227 match c {227 match c {
228 LinkedPseudoRef { name: worktree_name } => is_reflog228 LinkedPseudoRef { name: worktree_name } => {
229 .then(|| (linked_git_dir(worktree_name).into(), sn))229 if is_reflog {
230 .unwrap_or((commondir.into(), name)),230 (linked_git_dir(worktree_name).into(), sn)
231 } else {
232 (commondir.into(), name)
233 }
234 }
231 Tag | LocalBranch | RemoteBranch | Note => (commondir.into(), name),235 Tag | LocalBranch | RemoteBranch | Note => (commondir.into(), name),
232 MainRef | MainPseudoRef => (commondir.into(), sn),236 MainRef | MainPseudoRef => (commondir.into(), sn),
233 LinkedRef { name: worktree_name } => sn237 LinkedRef { name: worktree_name } => sn
gix-ref/src/store/file/log/iter.rs+1−1
@@ -180,7 +180,7 @@ where · 179 unmodified lines
180 let buf = &mut self.buf[..n];180 let buf = &mut self.buf[..n];
181 if let Err(err) = read.read_exact(buf) {181 if let Err(err) = read.read_exact(buf) {
182 return Some(Err(err.into()));182 return Some(Err(err.into()));
183 };183 }
184 184
185 let last_byte = *buf.last().expect("we have read non-zero bytes before");185 let last_byte = *buf.last().expect("we have read non-zero bytes before");
186 self.last_nl_pos = Some(if last_byte != b'\n' { buf.len() } else { buf.len() - 1 });186 self.last_nl_pos = Some(if last_byte != b'\n' { buf.len() } else { buf.len() - 1 });
gix-ref/src/store/file/loose/reflog.rs+1−1
@@ -126,7 +126,7 @@ pub mod create_or_update { · 125 unmodified lines
126 }126 }
127 })?;127 })?;
128 options.create(true);128 options.create(true);
129 };129 }
130 130
131 let file_for_appending = match options.open(&log_path) {131 let file_for_appending = match options.open(&log_path) {
132 Ok(f) => Some(f),132 Ok(f) => Some(f),
gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs+1−1
@@ -112,7 +112,7 @@ fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append · 111 unmodified lines
112 "there is no logs in disabled mode"112 "there is no logs in disabled mode"
113 );113 );
114 }114 }
115 };115 }
116 116
117 // create onto existing directory117 // create onto existing directory
118 let full_name_str = "refs/heads/other";118 let full_name_str = "refs/heads/other";
gix-ref/src/store/file/raw_ext.rs+1−1
@@ -124,7 +124,7 @@ impl ReferenceExt for Reference { · 123 unmodified lines
124 })?;124 })?;
125 }125 }
126 _ => break oid,126 _ => break oid,
127 };127 }
128 };128 };
129 self.peeled = Some(peeled_id);129 self.peeled = Some(peeled_id);
130 self.target = Target::Object(peeled_id);130 self.target = Target::Object(peeled_id);
gix-ref/src/store/file/transaction/commit.rs+1−1
@@ -110,7 +110,7 @@ impl Transaction<'_, '_> { · 109 unmodified lines
110 full_name: change.name(),110 full_name: change.name(),
111 });111 });
112 }112 }
113 };113 }
114 }114 }
115 }115 }
116 Change::Delete { .. } => {}116 Change::Delete { .. } => {}
gix-ref/src/store/file/transaction/prepare.rs+2−2
@@ -159,7 +159,7 @@ impl Transaction<'_, '_> { · 158 unmodified lines
159 let full_name = change.name();159 let full_name = change.name();
160 return Err(Error::MustExist { full_name, expected });160 return Err(Error::MustExist { full_name, expected });
161 }161 }
162 };162 }
163 163
164 fn new_would_change_existing(new: &Target, existing: &Target) -> (bool, bool) {164 fn new_would_change_existing(new: &Target, existing: &Target) -> (bool, bool) {
165 match (new, existing) {165 match (new, existing) {
@@ -386,7 +386,7 @@ impl Transaction<'_, '_> { · 220 unmodified lines
386 other => other,386 other => other,
387 };387 };
388 return Err(err);388 return Err(err);
389 };389 }
390 390
391 // traverse parent chain from leaf/peeled ref and set the leaf previous oid accordingly391 // traverse parent chain from leaf/peeled ref and set the leaf previous oid accordingly
392 // to help with their reflog entries392 // to help with their reflog entries
gix-ref/src/transaction/ext.rs+1−1
@@ -66,7 +66,7 @@ where · 65 unmodified lines
66 let edit = edit.borrow_mut();66 let edit = edit.borrow_mut();
67 if !edit.deref {67 if !edit.deref {
68 continue;68 continue;
69 };69 }
70 70
71 // we can't tell what happened and we are here because it's a non-existing ref or an invalid one.71 // we can't tell what happened and we are here because it's a non-existing ref or an invalid one.
72 // In any case, we don't want the following algorithms to try dereffing it and assume they deal with72 // In any case, we don't want the following algorithms to try dereffing it and assume they deal with
gix-ref/tests/refs/file/transaction/prepare_and_commit/create_or_update/mod.rs+1−1
@@ -96,7 +96,7 @@ fn reference_with_equally_named_empty_or_non_empty_directory_already_in_place_ca · 95 unmodified lines
96 assert_eq!(source.to_string(), "Directory not empty");96 assert_eq!(source.to_string(), "Directory not empty");
97 }97 }
98 _ => unreachable!("other errors shouldn't happen here"),98 _ => unreachable!("other errors shouldn't happen here"),
99 };99 }
100 }100 }
101 }101 }
102 Ok(())102 Ok(())
gix-refspec/src/match_group/util.rs+1−1
@@ -94,7 +94,7 @@ impl<'a> Needle<'a> { · 93 unmodified lines
94 }94 }
95 None => return Match::None,95 None => return Match::None,
96 _ => {}96 _ => {}
97 };97 }
98 let tail = &name[*asterisk_pos + 1..];98 let tail = &name[*asterisk_pos + 1..];
99 if !item.full_ref_name.ends_with(tail) {99 if !item.full_ref_name.ends_with(tail) {
100 return Match::None;100 return Match::None;
gix-refspec/tests/refspec/matching.rs+1−1
@@ -264,7 +264,7 @@ pub mod baseline { · 263 unmodified lines
264 lhs = "HEAD".as_bytes();264 lhs = "HEAD".as_bytes();
265 } else {265 } else {
266 tokens.next();266 tokens.next();
267 };267 }
268 let rhs = tokens.next().unwrap().trim();268 let rhs = tokens.next().unwrap().trim();
269 let local = (rhs != b"FETCH_HEAD").then(|| full_tracking_ref(rhs.into()));269 let local = (rhs != b"FETCH_HEAD").then(|| full_tracking_ref(rhs.into()));
270 if !(lhs.as_bstr() == "HEAD" && local.is_none()) {270 if !(lhs.as_bstr() == "HEAD" && local.is_none()) {
gix-revision/src/spec/parse/delegate.rs+1−1
@@ -73,7 +73,7 @@ pub trait Navigate { · 72 unmodified lines
73 ///73 ///
74 /// * `stage` ranges from 0 to 2, with 0 being the base, 1 being ours, 2 being theirs.74 /// * `stage` ranges from 0 to 2, with 0 being the base, 1 being ours, 2 being theirs.
75 /// * `path` without prefix is relative to the root of the repository, while prefixes like `./` and `../` make it75 /// * `path` without prefix is relative to the root of the repository, while prefixes like `./` and `../` make it
76 /// relative to the current working directory.76 /// relative to the current working directory.
77 fn index_lookup(&mut self, path: &BStr, stage: u8) -> Option<()>;77 fn index_lookup(&mut self, path: &BStr, stage: u8) -> Option<()>;
78}78}
79 79
gix-revision/src/spec/parse/function.rs+5−5
@@ -201,7 +201,7 @@ fn long_describe_prefix(name: &BStr) -> Option<(&BStr, delegate::PrefixHint<'_>) · 200 unmodified lines
201 let candidate = iter.by_ref().find_map(|substr| {201 let candidate = iter.by_ref().find_map(|substr| {
202 if substr.first()? != &b'g' {202 if substr.first()? != &b'g' {
203 return None;203 return None;
204 };204 }
205 let rest = substr.get(1..)?;205 let rest = substr.get(1..)?;
206 rest.iter().all(u8::is_ascii_hexdigit).then(|| rest.as_bstr())206 rest.iter().all(u8::is_ascii_hexdigit).then(|| rest.as_bstr())
207 })?;207 })?;
@@ -213,7 +213,7 @@ fn long_describe_prefix(name: &BStr) -> Option<(&BStr, delegate::PrefixHint<'_>) · 5 unmodified lines
213 .and_then(|generation| {213 .and_then(|generation| {
214 iter.next().map(|token| {214 iter.next().map(|token| {
215 let last_token_len = token.len();215 let last_token_len = token.len();
216 let first_token_ptr = iter.last().map_or(token.as_ptr(), <[_]>::as_ptr);216 let first_token_ptr = iter.next_back().map_or(token.as_ptr(), <[_]>::as_ptr);
217 // SAFETY: both pointers are definitely part of the same object217 // SAFETY: both pointers are definitely part of the same object
218 #[allow(unsafe_code)]218 #[allow(unsafe_code)]
219 let prior_tokens_len: usize = unsafe { token.as_ptr().offset_from(first_token_ptr) }219 let prior_tokens_len: usize = unsafe { token.as_ptr().offset_from(first_token_ptr) }
@@ -274,7 +274,7 @@ fn parens(input: &[u8]) -> Result<Option<InsideParensRestConsumed<'_>>, Error> { · 54 unmodified lines
274 _ => {274 _ => {
275 if ignore_next {275 if ignore_next {
276 skip_list.pop();276 skip_list.pop();
277 };277 }
278 ignore_next = false;278 ignore_next = false;
279 }279 }
280 }280 }
@@ -307,7 +307,7 @@ fn try_parse<T: FromStr + PartialEq + Default>(input: &BStr) -> Result<Option<T> · 26 unmodified lines
307 n.parse().ok().map(|n| {307 n.parse().ok().map(|n| {
308 if n == T::default() && input[0] == b'-' {308 if n == T::default() && input[0] == b'-' {
309 return Err(Error::NegativeZero { input: input.into() });309 return Err(Error::NegativeZero { input: input.into() });
310 };310 }
311 Ok(n)311 Ok(n)
312 })312 })
313 })313 })
@@ -337,7 +337,7 @@ where · 23 unmodified lines
337 [b':', b'2', b':', path @ ..] => return consume_all(delegate.index_lookup(path.as_bstr(), 2)),337 [b':', b'2', b':', path @ ..] => return consume_all(delegate.index_lookup(path.as_bstr(), 2)),
338 [b':', path @ ..] => return consume_all(delegate.index_lookup(path.as_bstr(), 0)),338 [b':', path @ ..] => return consume_all(delegate.index_lookup(path.as_bstr(), 0)),
339 _ => {}339 _ => {}
340 };340 }
341 341
342 let mut sep_pos = None;342 let mut sep_pos = None;
343 let mut consecutive_hex_chars = Some(0);343 let mut consecutive_hex_chars = Some(0);
gix-revwalk/src/graph/mod.rs+3−3
@@ -252,7 +252,7 @@ impl<T> Graph<'_, '_, Commit<T>> { · 251 unmodified lines
252 gix_hashtable::hash_map::Entry::Occupied(mut entry) => {252 gix_hashtable::hash_map::Entry::Occupied(mut entry) => {
253 update_data(&mut entry.get_mut().data);253 update_data(&mut entry.get_mut().data);
254 }254 }
255 };255 }
256 Ok(self.map.get_mut(&id))256 Ok(self.map.get_mut(&id))
257 }257 }
258 258
@@ -303,7 +303,7 @@ impl<T: Default> Graph<'_, '_, Commit<T>> { · 44 unmodified lines
303 gix_hashtable::hash_map::Entry::Occupied(mut entry) => {303 gix_hashtable::hash_map::Entry::Occupied(mut entry) => {
304 update_commit(entry.get_mut());304 update_commit(entry.get_mut());
305 }305 }
306 };306 }
307 Ok(self.map.get_mut(&id))307 Ok(self.map.get_mut(&id))
308 }308 }
309}309}
@@ -337,7 +337,7 @@ impl<'cache, T> Graph<'_, 'cache, T> { · 27 unmodified lines
337 gix_hashtable::hash_map::Entry::Occupied(mut entry) => {337 gix_hashtable::hash_map::Entry::Occupied(mut entry) => {
338 update_data(entry.get_mut());338 update_data(entry.get_mut());
339 }339 }
340 };340 }
341 commit341 commit
342 }))342 }))
343 }343 }
gix-submodule/src/is_active_platform.rs+1−1
@@ -36,7 +36,7 @@ impl IsActivePlatform { · 35 unmodified lines
36 ) -> Result<bool, gix_config::value::Error> {36 ) -> Result<bool, gix_config::value::Error> {
37 if let Some(val) = config.boolean(format!("submodule.{name}.active")).transpose()? {37 if let Some(val) = config.boolean(format!("submodule.{name}.active")).transpose()? {
38 return Ok(val);38 return Ok(val);
39 };39 }
40 if let Some(val) = self.search.as_mut().map(|search| {40 if let Some(val) = self.search.as_mut().map(|search| {
41 search41 search
42 .pattern_matching_relative_path(name, Some(true), attributes)42 .pattern_matching_relative_path(name, Some(true), attributes)
gix-transport/src/client/blocking_io/http/curl/remote.rs+2−2
@@ -102,7 +102,7 @@ impl curl::easy::Handler for Handler { · 101 unmodified lines
102 .ok();102 .ok();
103 }103 }
104 }104 }
105 };105 }
106 true106 true
107 }107 }
108}108}
@@ -338,7 +338,7 @@ pub fn new() -> ( · 229 unmodified lines
338 body.channel.try_send(err).ok();338 body.channel.try_send(err).ok();
339 }339 }
340 (None, None) => {}340 (None, None) => {}
341 };341 }
342 } else {342 } else {
343 let handler = handle.get_mut();343 let handler = handle.get_mut();
344 if let Some((action, authenticate)) = proxy_auth_action {344 if let Some((action, authenticate)) = proxy_auth_action {
gix-transport/src/client/blocking_io/http/traits.rs+1−1
@@ -23,7 +23,7 @@ impl crate::IsSpuriousError for Error { · 22 unmodified lines
23 #[cfg(feature = "http-client-curl")]23 #[cfg(feature = "http-client-curl")]
24 if let Some(err) = source.downcast_ref::<crate::client::http::curl::Error>() {24 if let Some(err) = source.downcast_ref::<crate::client::http::curl::Error>() {
25 return err.is_spurious();25 return err.is_spurious();
26 };26 }
27 #[cfg(feature = "http-client-reqwest")]27 #[cfg(feature = "http-client-reqwest")]
28 if let Some(err) = source.downcast_ref::<crate::client::http::reqwest::remote::Error>() {28 if let Some(err) = source.downcast_ref::<crate::client::http::reqwest::remote::Error>() {
29 return err.is_spurious();29 return err.is_spurious();
gix-transport/src/client/blocking_io/ssh/program_kind.rs+1−1
@@ -61,7 +61,7 @@ impl ProgramKind { · 60 unmodified lines
61 });61 });
62 }62 }
63 }63 }
64 };64 }
65 65
66 let host_maybe_with_user_as_ssh_arg = match (url.user_as_argument(), url.host_as_argument()) {66 let host_maybe_with_user_as_ssh_arg = match (url.user_as_argument(), url.host_as_argument()) {
67 (Usable(user), Usable(host)) => format!("{user}@{host}"),67 (Usable(user), Usable(host)) => format!("{user}@{host}"),
gix-transport/src/client/non_io_types.rs+1−1
@@ -76,7 +76,7 @@ pub(crate) mod connect { · 75 unmodified lines
76 #[cfg(feature = "blocking-client")]76 #[cfg(feature = "blocking-client")]
77 if let Some(err) = err.downcast_ref::<crate::client::git::connect::Error>() {77 if let Some(err) = err.downcast_ref::<crate::client::git::connect::Error>() {
78 return err.is_spurious();78 return err.is_spurious();
79 };79 }
80 if let Some(err) = err.downcast_ref::<crate::client::Error>() {80 if let Some(err) = err.downcast_ref::<crate::client::Error>() {
81 return err.is_spurious();81 return err.is_spurious();
82 }82 }
gix-transport/tests/client/blocking_io/http/mod.rs+2−2
@@ -130,7 +130,7 @@ fn http_will_use_pipelining() { · 129 unmodified lines
130 Ok(_) => unreachable!("expecting permission denied to be detected"),130 Ok(_) => unreachable!("expecting permission denied to be detected"),
131 Err(gix_transport::client::Error::Io(err)) if err.kind() == std::io::ErrorKind::PermissionDenied => {}131 Err(gix_transport::client::Error::Io(err)) if err.kind() == std::io::ErrorKind::PermissionDenied => {}
132 Err(err) => unreachable!("{err:?}"),132 Err(err) => unreachable!("{err:?}"),
133 };133 }
134 client134 client
135 .set_identity(gix_sec::identity::Account {135 .set_identity(gix_sec::identity::Account {
136 username: "foo".into(),136 username: "foo".into(),
@@ -141,7 +141,7 @@ fn http_will_use_pipelining() { · 4 unmodified lines
141 Ok(_) => unreachable!("expecting permission denied to be detected"),141 Ok(_) => unreachable!("expecting permission denied to be detected"),
142 Err(gix_transport::client::Error::Io(err)) if err.kind() == std::io::ErrorKind::PermissionDenied => {}142 Err(gix_transport::client::Error::Io(err)) if err.kind() == std::io::ErrorKind::PermissionDenied => {}
143 Err(err) => unreachable!("{err:?}"),143 Err(err) => unreachable!("{err:?}"),
144 };144 }
145 thread.join().unwrap();145 thread.join().unwrap();
146}146}
147 147
gix-traverse/src/commit/simple.rs+2−2
@@ -203,8 +203,8 @@ mod init { · 202 unmodified lines
203 /// Create a new instance.203 /// Create a new instance.
204 ///204 ///
205 /// * `find` - a way to lookup new object data during traversal by their `ObjectId`, writing their data into buffer and returning205 /// * `find` - a way to lookup new object data during traversal by their `ObjectId`, writing their data into buffer and returning
206 /// an iterator over commit tokens if the object is present and is a commit. Caching should be implemented within this function206 /// an iterator over commit tokens if the object is present and is a commit. Caching should be implemented within this function
207 /// as needed.207 /// as needed.
208 /// * `tips`208 /// * `tips`
209 /// * the starting points of the iteration, usually commits209 /// * the starting points of the iteration, usually commits
210 /// * each commit they lead to will only be returned once, including the tip that started it210 /// * each commit they lead to will only be returned once, including the tip that started it
gix-traverse/src/commit/topo/iter.rs+2−2
@@ -208,7 +208,7 @@ where · 207 unmodified lines
208 *i = 0;208 *i = 0;
209 if let Err(e) = self.expand_topo_walk(&commit.id) {209 if let Err(e) = self.expand_topo_walk(&commit.id) {
210 return Some(Err(e));210 return Some(Err(e));
211 };211 }
212 212
213 Some(Ok(commit))213 Some(Ok(commit))
214 }214 }
@@ -289,7 +289,7 @@ where · 74 unmodified lines
289 }289 }
290 }290 }
291 }291 }
292 };292 }
293 Ok(parents)293 Ok(parents)
294}294}
295 295
gix-traverse/src/tree/breadthfirst.rs+4−4
@@ -46,10 +46,10 @@ pub(super) mod function { · 45 unmodified lines
46 /// * `state` - all state used for the iteration. If multiple iterations are performed, allocations can be minimized by reusing46 /// * `state` - all state used for the iteration. If multiple iterations are performed, allocations can be minimized by reusing
47 /// this state.47 /// this state.
48 /// * `find` - a way to lookup new object data during traversal by their `ObjectId`, writing their data into buffer and returning48 /// * `find` - a way to lookup new object data during traversal by their `ObjectId`, writing their data into buffer and returning
49 /// an iterator over entries if the object is present and is a tree. Caching should be implemented within this function49 /// an iterator over entries if the object is present and is a tree. Caching should be implemented within this function
50 /// as needed. The return value is `Option<TreeIter>` which degenerates all error information. Not finding a commit should also50 /// as needed. The return value is `Option<TreeIter>` which degenerates all error information. Not finding a commit should also
51 /// be considered an errors as all objects in the tree DAG should be present in the database. Hence [`Error::Find`] should51 /// be considered an errors as all objects in the tree DAG should be present in the database. Hence [`Error::Find`] should
52 /// be escalated into a more specific error if it's encountered by the caller.52 /// be escalated into a more specific error if it's encountered by the caller.
53 /// * `delegate` - A way to observe entries and control the iteration while allowing the optimizer to let you pay only for what you use.53 /// * `delegate` - A way to observe entries and control the iteration while allowing the optimizer to let you pay only for what you use.
54 pub fn breadthfirst<StateMut, Find, V>(54 pub fn breadthfirst<StateMut, Find, V>(
55 root: TreeRefIter<'_>,55 root: TreeRefIter<'_>,
gix-url/src/lib.rs+1−1
@@ -335,7 +335,7 @@ impl Url { · 334 unmodified lines
335 }335 }
336 (None, None) => {}336 (None, None) => {}
337 (Some(_user), None) => unreachable!("BUG: should not be possible to have a user but no host"),337 (Some(_user), None) => unreachable!("BUG: should not be possible to have a user but no host"),
338 };338 }
339 if let Some(port) = &self.port {339 if let Some(port) = &self.port {
340 write!(&mut out, ":{port}")?;340 write!(&mut out, ":{port}")?;
341 }341 }
gix-worktree-state/tests/state/checkout.rs+2−2
@@ -100,7 +100,7 @@ fn accidental_writes_through_symlinks_are_prevented_if_overwriting_is_forbidden( · 99 unmodified lines
100 assert_eq!(stripped_prefix(&source_tree, &source_files), paths(expected));100 assert_eq!(stripped_prefix(&source_tree, &source_files), paths(expected));
101 assert_eq!(stripped_prefix(&destination, &worktree_files), paths(expected));101 assert_eq!(stripped_prefix(&destination, &worktree_files), paths(expected));
102 assert!(outcome.collisions.is_empty());102 assert!(outcome.collisions.is_empty());
103 };103 }
104}104}
105 105
106#[test]106#[test]
@@ -134,7 +134,7 @@ fn writes_through_symlinks_are_prevented_even_if_overwriting_is_allowed() { · 27 unmodified lines
134 assert_eq!(stripped_prefix(&source_tree, &source_files), paths(expected));134 assert_eq!(stripped_prefix(&source_tree, &source_files), paths(expected));
135 assert_eq!(stripped_prefix(&destination, &worktree_files), paths(expected));135 assert_eq!(stripped_prefix(&destination, &worktree_files), paths(expected));
136 assert!(outcome.collisions.is_empty());136 assert!(outcome.collisions.is_empty());
137 };137 }
138}138}
139 139
140#[test]140#[test]
gix-worktree/src/stack/state/mod.rs+1−1
@@ -153,7 +153,7 @@ impl State { · 152 unmodified lines
153 return None;153 return None;
154 }154 }
155 }155 }
156 };156 }
157 }157 }
158 Some((path.to_owned(), entry.id))158 Some((path.to_owned(), entry.id))
159 } else {159 } else {
gix/src/clone/fetch/util.rs+2−2
@@ -134,7 +134,7 @@ pub fn update_head( · 133 unmodified lines
134 name: referent.clone(),134 name: referent.clone(),
135 deref: false,135 deref: false,
136 });136 });
137 };137 }
138 edits138 edits
139 },139 },
140 gix_lock::acquire::Fail::Immediately,140 gix_lock::acquire::Fail::Immediately,
@@ -179,7 +179,7 @@ pub fn update_head( · 38 unmodified lines
179 deref: false,179 deref: false,
180 })?;180 })?;
181 }181 }
182 };182 }
183 Ok(())183 Ok(())
184}184}
185 185
gix/src/config/cache/incubate.rs+2−2
@@ -72,7 +72,7 @@ impl StageOne { · 71 unmodified lines
72 lenient,72 lenient,
73 )?;73 )?;
74 config.append(worktree_config);74 config.append(worktree_config);
75 };75 }
76 let precompose_unicode = config76 let precompose_unicode = config
77 .boolean(&Core::PRECOMPOSE_UNICODE)77 .boolean(&Core::PRECOMPOSE_UNICODE)
78 .map(|v| Core::PRECOMPOSE_UNICODE.enrich_error(v))78 .map(|v| Core::PRECOMPOSE_UNICODE.enrich_error(v))
@@ -144,7 +144,7 @@ fn load_config( · 65 unmodified lines
144 } else {144 } else {
145 return Err(err);145 return Err(err);
146 }146 }
147 };147 }
148 148
149 let config = gix_config::File::from_bytes_owned(149 let config = gix_config::File::from_bytes_owned(
150 buf,150 buf,
gix/src/config/snapshot/_impls.rs+1−1
@@ -27,7 +27,7 @@ impl Drop for SnapshotMut<'_> { · 26 unmodified lines
27 fn drop(&mut self) {27 fn drop(&mut self) {
28 if let Some(repo) = self.repo.take() {28 if let Some(repo) = self.repo.take() {
29 self.commit_inner(repo).ok();29 self.commit_inner(repo).ok();
30 };30 }
31 }31 }
32}32}
33 33
gix/src/config/snapshot/credential_helpers.rs+5−3
@@ -113,9 +113,11 @@ pub(super) mod function { · 112 unmodified lines
113 let is_http = matches!(pattern.scheme, gix_url::Scheme::Https | gix_url::Scheme::Http);113 let is_http = matches!(pattern.scheme, gix_url::Scheme::Https | gix_url::Scheme::Http);
114 let scheme = &pattern.scheme;114 let scheme = &pattern.scheme;
115 let host = pattern.host();115 let host = pattern.host();
116 let ports = is_http116 let ports = if is_http {
117 .then(|| (pattern.port_or_default(), url.port_or_default()))117 (pattern.port_or_default(), url.port_or_default())
118 .unwrap_or((pattern.port, url.port));118 } else {
119 (pattern.port, url.port)
120 };
119 let path = (!(is_http && pattern.path_is_root())).then_some(&pattern.path);121 let path = (!(is_http && pattern.path_is_root())).then_some(&pattern.path);
120 122
121 if !path.map_or(true, |path| path == &url.path) {123 if !path.map_or(true, |path| path == &url.path) {
gix/src/create.rs+1−1
@@ -160,7 +160,7 @@ pub fn into( · 159 unmodified lines
160 if dot_git.is_dir() {160 if dot_git.is_dir() {
161 return Err(Error::DirectoryExists { path: dot_git });161 return Err(Error::DirectoryExists { path: dot_git });
162 }162 }
163 };163 }
164 create_dir(&dot_git)?;164 create_dir(&dot_git)?;
165 165
166 {166 {
gix/src/object/blob.rs+1−1
@@ -123,7 +123,7 @@ pub mod diff { · 122 unmodified lines
123 unreachable!("we disabled that")123 unreachable!("we disabled that")
124 }124 }
125 Operation::SourceOrDestinationIsBinary => {}125 Operation::SourceOrDestinationIsBinary => {}
126 };126 }
127 Ok(prep)127 Ok(prep)
128 }128 }
129 129
gix/src/remote/build.rs+5−3
@@ -40,9 +40,11 @@ impl Remote<'_> { · 39 unmodified lines
40 ) -> Result<Self, remote::init::Error> {40 ) -> Result<Self, remote::init::Error> {
41 self.push_url = push_url.into();41 self.push_url = push_url.into();
42 42
43 let (_, push_url_alias) = should_rewrite_urls43 let (_, push_url_alias) = if should_rewrite_urls {
44 .then(|| remote::init::rewrite_urls(&self.repo.config, None, self.push_url.as_ref()))44 remote::init::rewrite_urls(&self.repo.config, None, self.push_url.as_ref())
45 .unwrap_or(Ok((None, None)))?;45 } else {
46 Ok((None, None))
47 }?;
46 self.push_url_alias = push_url_alias;48 self.push_url_alias = push_url_alias;
47 49
48 Ok(self)50 Ok(self)
gix/src/remote/connection/fetch/update_refs/mod.rs+2−2
@@ -314,7 +314,7 @@ pub(crate) fn update( · 313 unmodified lines
314 Change::Delete { .. } => {314 Change::Delete { .. } => {
315 unreachable!("we don't do that here")315 unreachable!("we don't do that here")
316 }316 }
317 };317 }
318 }318 }
319 }319 }
320 320
@@ -376,7 +376,7 @@ fn update_needs_adjustment_as_edits_symbolic_target_is_missing( · 55 unmodified lines
376 Change::Delete { .. } => {376 Change::Delete { .. } => {
377 unreachable!("we don't ever delete here")377 unreachable!("we don't ever delete here")
378 }378 }
379 };379 }
380 let target_ref_exists_locally = repo.refs.try_find(new_target_ref).ok().flatten().is_some();380 let target_ref_exists_locally = repo.refs.try_find(new_target_ref).ok().flatten().is_some();
381 if target_ref_exists_locally {381 if target_ref_exists_locally {
382 return false;382 return false;
gix/src/remote/connection/ref_map.rs+1−1
@@ -111,7 +111,7 @@ where · 110 unmodified lines
111 if !extra_refspecs.contains(&tag_spec) {111 if !extra_refspecs.contains(&tag_spec) {
112 extra_refspecs.push(tag_spec);112 extra_refspecs.push(tag_spec);
113 }113 }
114 };114 }
115 let mut credentials_storage;115 let mut credentials_storage;
116 let url = self.transport.inner.to_url();116 let url = self.transport.inner.to_url();
117 let authenticate = match self.authenticate.as_mut() {117 let authenticate = match self.authenticate.as_mut() {
gix/src/remote/init.rs+10−6
@@ -40,9 +40,11 @@ impl<'repo> Remote<'repo> { · 39 unmodified lines
40 url.is_some() || push_url.is_some(),40 url.is_some() || push_url.is_some(),
41 "BUG: fetch or push url must be set at least"41 "BUG: fetch or push url must be set at least"
42 );42 );
43 let (url_alias, push_url_alias) = should_rewrite_urls43 let (url_alias, push_url_alias) = if should_rewrite_urls {
44 .then(|| rewrite_urls(&repo.config, url.as_ref(), push_url.as_ref()))44 rewrite_urls(&repo.config, url.as_ref(), push_url.as_ref())
45 .unwrap_or(Ok((None, None)))?;45 } else {
46 Ok((None, None))
47 }?;
46 Ok(Remote {48 Ok(Remote {
47 name: name_or_url.map(Into::into),49 name: name_or_url.map(Into::into),
48 url,50 url,
@@ -77,9 +79,11 @@ impl<'repo> Remote<'repo> { · 28 unmodified lines
77 should_rewrite_urls: bool,79 should_rewrite_urls: bool,
78 repo: &'repo Repository,80 repo: &'repo Repository,
79 ) -> Result<Self, Error> {81 ) -> Result<Self, Error> {
80 let (url_alias, _) = should_rewrite_urls82 let (url_alias, _) = if should_rewrite_urls {
81 .then(|| rewrite_urls(&repo.config, Some(&url), None))83 rewrite_urls(&repo.config, Some(&url), None)
82 .unwrap_or(Ok((None, None)))?;84 } else {
85 Ok((None, None))
86 }?;
83 Ok(Remote {87 Ok(Remote {
84 name: None,88 name: None,
85 url: Some(url),89 url: Some(url),
gix/src/remote/url/rewrite.rs+1−1
@@ -89,7 +89,7 @@ impl Rewrite { · 88 unmodified lines
89 *bytes_matched = replace.find.len();89 *bytes_matched = replace.find.len();
90 *prev_rewrite_with = replace.with.as_slice().into();90 *prev_rewrite_with = replace.with.as_slice().into();
91 }91 }
92 };92 }
93 acc93 acc
94 })94 })
95 .map(|(bytes_matched, replace_with)| {95 .map(|(bytes_matched, replace_with)| {
gix/src/repository/config/branch.rs+4−7
@@ -272,11 +272,8 @@ fn matching_remote<'a>( · 271 unmodified lines
272 })272 })
273 .into_iter(),273 .into_iter(),
274 );274 );
275 out.mappings.into_iter().next().and_then(|m| {275 out.mappings
276 m.rhs.map(|name| {276 .into_iter()
277 FullName::try_from(name.into_owned())277 .next()
278 .map(Cow::Owned)278 .and_then(|m| m.rhs.map(|name| FullName::try_from(name.into_owned()).map(Cow::Owned)))
279 .map_err(Into::into)
280 })
281 })
282}279}
gix/src/repository/init.rs+1−1
@@ -51,7 +51,7 @@ pub(crate) fn setup_objects(objects: &mut crate::OdbHandle, config: &crate::conf · 50 unmodified lines
51 Some(bytes) => objects.set_pack_cache(move || -> Box<gix_odb::cache::PackCache> {51 Some(bytes) => objects.set_pack_cache(move || -> Box<gix_odb::cache::PackCache> {
52 Box::new(gix_pack::cache::lru::MemoryCappedHashmap::new(bytes))52 Box::new(gix_pack::cache::lru::MemoryCappedHashmap::new(bytes))
53 }),53 }),
54 };54 }
55 if config.object_cache_bytes == 0 {55 if config.object_cache_bytes == 0 {
56 objects.unset_object_cache();56 objects.unset_object_cache();
57 } else {57 } else {
gix/src/revision/spec/parse/delegate/mod.rs+18−20
@@ -56,24 +56,22 @@ impl<'repo> Delegate<'repo> { · 55 unmodified lines
56 let candidates = candidates.take();56 let candidates = candidates.take();
57 match candidates {57 match candidates {
58 None => *out = None,58 None => *out = None,
59 Some(candidates) => {59 Some(candidates) => match candidates.len() {
60 match candidates.len() {60 0 => {
61 0 => unreachable!(61 unreachable!("BUG: let's avoid still being around if no candidate matched the requirements")
62 "BUG: let's avoid still being around if no candidate matched the requirements"62 }
63 ),63 1 => {
64 1 => {64 *out = candidates.into_iter().next();
65 *out = candidates.into_iter().next();65 }
66 }66 _ => {
67 _ => {67 errors.insert(
68 errors.insert(68 0,
69 0,69 Error::ambiguous(candidates, prefix.expect("set when obtaining candidates"), repo),
70 Error::ambiguous(candidates, prefix.expect("set when obtaining candidates"), repo),70 );
71 );71 return Err(Error::from_errors(errors));
72 return Err(Error::from_errors(errors));72 }
73 }73 },
74 };74 }
75 }
76 };
77 }75 }
78 Ok(out)76 Ok(out)
79 }77 }
@@ -215,8 +213,8 @@ impl Delegate<'_> { · 135 unmodified lines
215 }213 }
216 }) {214 }) {
217 obj_opt.get_or_insert_with(HashSet::default).insert(id);215 obj_opt.get_or_insert_with(HashSet::default).insert(id);
218 };216 }
219 };217 }
220 }218 }
221 Some(())219 Some(())
222 }220 }
gix/src/revision/spec/parse/delegate/revision.rs+1−1
@@ -283,7 +283,7 @@ impl delegate::Revision for Delegate<'_> { · 282 unmodified lines
283 return Some(());283 return Some(());
284 }284 }
285 },285 },
286 };286 }
287 None287 None
288 }288 }
289}289}
gix/src/revision/walk.rs+2−2
@@ -286,13 +286,13 @@ impl<'repo> Platform<'repo> { · 285 unmodified lines
286 if let Ok(idx) = grafted_parents_to_skip.binary_search(&id) {286 if let Ok(idx) = grafted_parents_to_skip.binary_search(&id) {
287 grafted_parents_to_skip.remove(idx);287 grafted_parents_to_skip.remove(idx);
288 return false;288 return false;
289 };289 }
290 if commits.binary_search(&id).is_ok() {290 if commits.binary_search(&id).is_ok() {
291 if let Ok(commit) = repo.objects.find_commit_iter(&id, &mut buf) {291 if let Ok(commit) = repo.objects.find_commit_iter(&id, &mut buf) {
292 grafted_parents_to_skip.extend(commit.parent_ids());292 grafted_parents_to_skip.extend(commit.parent_ids());
293 grafted_parents_to_skip.sort();293 grafted_parents_to_skip.sort();
294 }294 }
295 };295 }
296 true296 true
297 }297 }
298 None => true,298 None => true,
gix/src/status/iter/mod.rs+1−1
@@ -327,7 +327,7 @@ impl Iter { · 326 unmodified lines
327 self.index_changes.push((entry_index, ApplyChange::SetSizeToZero));327 self.index_changes.push((entry_index, ApplyChange::SetSizeToZero));
328 }328 }
329 _ => {}329 _ => {}
330 };330 }
331 Some(item)331 Some(item)
332 }332 }
333}333}
gix/tests/gix/object/tree/diff.rs+3−4
@@ -50,7 +50,7 @@ fn changes_against_tree_modified() -> crate::Result { · 49 unmodified lines
50 Change::Rewrite { .. } | Change::Deletion { .. } | Change::Addition { .. } => {50 Change::Rewrite { .. } | Change::Deletion { .. } | Change::Addition { .. } => {
51 unreachable!("only modification is expected")51 unreachable!("only modification is expected")
52 }52 }
53 };53 }
54 54
55 let mut diff = change.diff(&mut cache).expect("objects available");55 let mut diff = change.diff(&mut cache).expect("objects available");
56 let count = diff.line_counts().expect("no diff error").expect("no binary blobs");56 let count = diff.line_counts().expect("no diff error").expect("no binary blobs");
@@ -63,15 +63,14 @@ fn changes_against_tree_modified() -> crate::Result { · 6 unmodified lines
63 assert_eq!(lines.len(), 1);63 assert_eq!(lines.len(), 1);
64 assert_eq!(64 assert_eq!(
65 lines[0],65 lines[0],
66 expected_data[expected_previous_data.len()..]66 expected_data.as_bytes()[expected_previous_data.len()..]
67 .as_bytes()
68 .as_bstr()67 .as_bstr()
69 .trim(),68 .trim(),
70 "diffed lines don't have newlines anymore"69 "diffed lines don't have newlines anymore"
71 );70 );
72 }71 }
73 lines::Change::Modification { .. } => unreachable!("there was no modification"),72 lines::Change::Modification { .. } => unreachable!("there was no modification"),
74 };73 }
75 Ok::<_, Infallible>(())74 Ok::<_, Infallible>(())
76 })75 })
77 .expect("infallible");76 .expect("infallible");
gix/tests/gix/repository/excludes.rs+1−1
@@ -19,7 +19,7 @@ fn empty_core_excludes() -> crate::Result { · 18 unmodified lines
19 "The value for `core.excludesFile` could not be read from configuration"19 "The value for `core.excludesFile` could not be read from configuration"
20 );20 );
21 }21 }
22 };22 }
23 23
24 let repo = gix::open_opts(repo.git_dir(), repo.open_options().clone().strict_config(false))?;24 let repo = gix::open_opts(repo.git_dir(), repo.open_options().clone().strict_config(false))?;
25 repo.excludes(&index, None, Source::WorktreeThenIdMappingIfNotSkipped)25 repo.excludes(&index, None, Source::WorktreeThenIdMappingIfNotSkipped)
src/shared.rs+1−1
@@ -327,7 +327,7 @@ mod clap { · 326 unmodified lines
327 #[derive(Clone)]327 #[derive(Clone)]
328 pub struct AsPathSpec;328 pub struct AsPathSpec;
329 329
330 static PATHSPEC_DEFAULTS: once_cell::sync::Lazy<gix::pathspec::Defaults> = once_cell::sync::Lazy::new(|| {330 static PATHSPEC_DEFAULTS: std::sync::LazyLock<gix::pathspec::Defaults> = std::sync::LazyLock::new(|| {
331 gix::pathspec::Defaults::from_environment(&mut |n| std::env::var_os(n)).unwrap_or_default()331 gix::pathspec::Defaults::from_environment(&mut |n| std::env::var_os(n)).unwrap_or_default()
332 });332 });
333 333
tests/it/src/commands/check_mode.rs+2−2
@@ -1,7 +1,7 @@
1pub(super) mod function {1pub(super) mod function {
2 use anyhow::{bail, Context};2 use anyhow::{bail, Context};
3 use gix::bstr::ByteSlice;3 use gix::bstr::ByteSlice;
4 use once_cell::sync::Lazy;4
5 use regex::bytes::Regex;5 use regex::bytes::Regex;
6 use std::ffi::{OsStr, OsString};6 use std::ffi::{OsStr, OsString};
7 use std::io::{BufRead, BufReader, Read};7 use std::io::{BufRead, BufReader, Read};
@@ -66,7 +66,7 @@ pub(super) mod function { · 58 unmodified lines
66 66
67 /// On mismatch, report it and return `Some(true)`.67 /// On mismatch, report it and return `Some(true)`.
68 fn check_for_mismatch(root: &OsStr, record: &[u8]) -> anyhow::Result<bool> {68 fn check_for_mismatch(root: &OsStr, record: &[u8]) -> anyhow::Result<bool> {
69 static RECORD_REGEX: Lazy<Regex> = Lazy::new(|| {69 static RECORD_REGEX: std::sync::LazyLock<Regex> = std::sync::LazyLock::new(|| {
70 let pattern = r"(?-u)\A([0-7]+) ([[:xdigit:]]+) [[:digit:]]+\t(.+)\z";70 let pattern = r"(?-u)\A([0-7]+) ([[:xdigit:]]+) [[:digit:]]+\t(.+)\z";
71 Regex::new(pattern).expect("regex should be valid")71 Regex::new(pattern).expect("regex should be valid")
72 });72 });
tests/snapshots/panic-behaviour/expected-failure+1−0
@@ -1,3 +1,4 @@
1
1thread 'main' panicked at src/porcelain/main.rs:40:42:2thread 'main' panicked at src/porcelain/main.rs:40:42:
2something went very wrong3something went very wrong
3note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace4note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
tests/snapshots/panic-behaviour/expected-failure-in-thread+1−0
@@ -1,3 +1,4 @@
1
1thread 'main' panicked at src/porcelain/main.rs:40:42:2thread 'main' panicked at src/porcelain/main.rs:40:42:
2something went very wrong3something went very wrong
3note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace4note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
tests/snapshots/panic-behaviour/expected-failure-in-thread-with-progress+2−1
@@ -1,4 +1,5 @@
1[?1049h[?25lthread '<unnamed>' panicked at src/porcelain/main.rs:40:42:1[?1049h[?25l
2thread '<unnamed>' panicked at src/porcelain/main.rs:40:42:
2something went very wrong3something went very wrong
3note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace4note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4[?25h[?1049l5[?25h[?1049l
tests/tools/src/main.rs+1−1
@@ -21,6 +21,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { · 20 unmodified lines
21 #[cfg(unix)]21 #[cfg(unix)]
22 "umask" => umask()?,22 "umask" => umask()?,
23 _ => unreachable!("Unknown subcommand: {}", scmd),23 _ => unreachable!("Unknown subcommand: {}", scmd),
24 };24 }
25 Ok(())25 Ok(())
26}26}