Skip to content

Commit 16a248b

Browse files
authored
Merge pull request #1854 from GitoxideLabs/montly-report
montly report
2 parents 2efce72 + d28ff1b commit 16a248b

File tree

136 files changed

+309
-270
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+309
-270
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ bin-dir = "gitoxide-max-pure-v{ version }-{ target }/{ bin }{ binary-ext }"
325325
pedantic = { level = "warn", priority = -1 }
326326
#
327327
# Reviewed and allowed lints
328+
needless_continue = "allow"
328329
enum_glob_use = "allow" # x97
329330
missing_errors_doc = "allow" # x1792
330331
missing_panics_doc = "allow" # x447

deny.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# More documentation for the advisories section can be found here:
99
# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
1010
[advisories]
11-
ignore = []
11+
ignore = ['RUSTSEC-2025-0007']
1212

1313

1414

etc/reports/25-02.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Like 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+
3+
Sure, there were a couple of smaller API improvements, but nothing that would inspire me.
4+
So 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+
10+
I 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+
16+
Christoph 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.
17+
Admittedly, 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.
18+
It'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+
22+
A 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!
23+
Of 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+
27+
With `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+
29+
Cheers
30+
Sebastian
31+
32+
PS: 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
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ where
180180
break;
181181
}
182182
Err(err) => return Err(err.into()),
183-
};
183+
}
184184
}
185185
if let Some(tx) = tx_tree_id {
186186
tx.send(chunk).ok();

gitoxide-core/src/index/information.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ mod serde_only {
9292
});
9393
if f.link().is_some() {
9494
names.push("link");
95-
};
95+
}
9696
if f.resolve_undo().is_some() {
9797
names.push("resolve-undo (REUC)");
98-
};
98+
}
9999
if f.untracked().is_some() {
100100
names.push("untracked (UNTR)");
101-
};
101+
}
102102
if f.fs_monitor().is_some() {
103103
names.push("fs-monitor (FSMN)");
104-
};
104+
}
105105
if f.had_offset_table() {
106106
names.push("offset-table (IEOT)");
107107
}

gitoxide-core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub use discover::discover;
8686
pub fn env(mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
8787
if format != OutputFormat::Human {
8888
bail!("JSON output isn't supported");
89-
};
89+
}
9090

9191
let width = 15;
9292
writeln!(

gitoxide-core/src/pack/explode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub fn pack_or_pack_index(
161161
)
162162
})?;
163163

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()) {
165165
return Err(anyhow!(
166166
"The object directory at '{}' is inaccessible",
167167
object_path

gitoxide-core/src/pack/index.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub fn from_pack(
114114
OutputFormat::Human => drop(human_output(out, res)),
115115
#[cfg(feature = "serde")]
116116
OutputFormat::Json => serde_json::to_writer_pretty(out, &res)?,
117-
};
117+
}
118118
Ok(())
119119
}
120120

gitoxide-core/src/pack/receive.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,6 @@ fn receive_pack_blocking(
306306
OutputFormat::Json => {
307307
serde_json::to_writer_pretty(&mut out, &JsonOutcome::from_outcome_and_refs(outcome, refs))?;
308308
}
309-
};
309+
}
310310
Ok(())
311311
}

gitoxide-core/src/pack/verify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ where
177177
#[cfg(feature = "serde")]
178178
Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, &multi_index.index_names().iter().zip(res.pack_traverse_statistics).collect::<Vec<_>>())?,
179179
_ => {}
180-
};
180+
}
181181
return Ok(())
182182
},
183183
_ => return Err(anyhow!(
@@ -195,7 +195,7 @@ where
195195
#[cfg(feature = "serde")]
196196
Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, stats)?,
197197
_ => {}
198-
};
198+
}
199199
}
200200
Ok(())
201201
}

gitoxide-core/src/query/engine/update.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ pub fn update(
447447
break;
448448
}
449449
Err(err) => return Err(err.into()),
450-
};
450+
}
451451
}
452452
db.send_last_chunk();
453453
let saw_new_commits = !commits.is_empty();

gitoxide-core/src/repository/clean.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ pub(crate) mod function {
213213
continue;
214214
}
215215
}
216-
};
216+
}
217217

218218
let is_ignored = matches!(entry.status, gix::dir::entry::Status::Ignored(_));
219219
let entry_path = gix::path::from_bstr(entry.rela_path);

gitoxide-core/src/repository/clone.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub(crate) mod function {
114114
&mut err,
115115
)?;
116116
}
117-
};
117+
}
118118

119119
if let Some(gix::worktree::state::checkout::Outcome { collisions, errors, .. }) = outcome {
120120
if !(collisions.is_empty() && errors.is_empty()) {

gitoxide-core/src/repository/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl Filter {
8484
}
8585
(None, _) => {}
8686
(Some(_), None) => return false,
87-
};
87+
}
8888
true
8989
}
9090
}

gitoxide-core/src/repository/diff.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn write_changes(
9999
writeln!(out, " {:o} -> {:o}", source_entry_mode.0, entry_mode.0)?;
100100
}
101101
}
102-
};
102+
}
103103
}
104104

105105
Ok(())

gitoxide-core/src/repository/fetch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub(crate) mod function {
264264
gix::remote::fetch::refmap::Source::Ref(r) => {
265265
crate::repository::remote::refs::print_ref(&mut out, r)?;
266266
}
267-
};
267+
}
268268
let mode_and_type = update.type_change.map_or_else(
269269
|| format!("{}", update.mode),
270270
|type_change| {

gitoxide-core/src/repository/index/entries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub(crate) mod function {
184184
.unwrap_or_default()
185185
},
186186
)
187-
.map_or(true, |m| m.is_excluded());
187+
.is_none_or(|m| m.is_excluded());
188188

189189
let entry_is_submodule = entry.mode.is_submodule();
190190
if entry_is_excluded && (!entry_is_submodule || !recurse_submodules) {

gitoxide-core/src/repository/remote.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ mod refs_impl {
105105
out,
106106
&map.remote_refs.into_iter().map(JsonRef::from).collect::<Vec<_>>(),
107107
)?,
108-
};
108+
}
109109
Ok(())
110110
}
111111
}

gitoxide-core/src/repository/submodule.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn print_sm(sm: Submodule<'_>, dirty_suffix: Option<&str>, out: &mut impl std::i
2828
let mut sm_repo = sm.open()?;
2929
if let Some(repo) = sm_repo.as_mut() {
3030
repo.object_cache_size_if_unset(4 * 1024 * 1024);
31-
};
31+
}
3232
writeln!(
3333
out,
3434
" {is_active} {path} {config} head:{head_id} index:{index_id} ({worktree}) [{url}]",

gix-attributes/src/search/outcome.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,7 @@ impl Outcome {
237237
}
238238

239239
fn reduce_and_check_if_done(&mut self, attr: AttributeId) -> bool {
240-
if self.selected.is_empty()
241-
|| self
242-
.selected
243-
.iter()
244-
.any(|(_name, id)| id.map_or(false, |id| id == attr))
245-
{
240+
if self.selected.is_empty() || self.selected.iter().any(|(_name, id)| *id == Some(attr)) {
246241
*self.remaining.as_mut().expect("initialized") -= 1;
247242
}
248243
self.is_done()

gix-blame/src/file/function.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ fn collect_parents(
684684
parent_ids.push((id, parent_commit_time));
685685
}
686686
}
687-
};
687+
}
688688
Ok(parent_ids)
689689
}
690690

gix-commitgraph/src/file/init.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl File {
8585
x => {
8686
return Err(Error::UnsupportedVersion(x));
8787
}
88-
};
88+
}
8989
ofs += 1;
9090

9191
let object_hash = gix_hash::Kind::try_from(data[ofs]).map_err(Error::UnsupportedHashVersion)?;

gix-config-value/src/path.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ impl<'a> Path<'a> {
122122
/// the `home_for_user` function to be provided.
123123
/// The interpolation uses `getpwnam` sys call and is therefore not available on windows.
124124
/// - `%(prefix)/` is expanded to the location where `gitoxide` is installed.
125-
/// This location is not known at compile time and therefore need to be
126-
/// optionally provided by the caller through `git_install_dir`.
125+
/// This location is not known at compile time and therefore need to be
126+
/// optionally provided by the caller through `git_install_dir`.
127127
///
128128
/// Any other, non-empty path value is returned unchanged and error is returned in case of an empty path value or if required input
129129
/// wasn't provided.

gix-config/src/file/includes/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl File<'static> {
3232
/// which later overwrite portions of the included file, which seems unusual as these would be related to `includes`.
3333
/// We can fix this by 'splitting' the include section if needed so the included sections are put into the right place.
3434
/// - `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.
3636
pub fn resolve_includes(&mut self, options: init::Options<'_>) -> Result<(), Error> {
3737
if options.includes.max_depth == 0 {
3838
return Ok(());

gix-config/src/file/init/from_paths.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl File<'static> {
116116
return Err(Error::Io { source: err, path });
117117
}
118118
}
119-
};
119+
}
120120
meta.path = Some(path);
121121

122122
let config = Self::from_bytes_owned(buf, meta, options)?;

gix-config/src/file/section/body.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl Body<'_> {
151151
value_range.end = i;
152152
} else {
153153
value_range.start = i;
154-
};
154+
}
155155
}
156156
_ => (),
157157
}

gix-config/src/parse/events.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ fn from_bytes<'a, 'b>(
305305
events: std::mem::take(&mut events),
306306
});
307307
}
308-
};
308+
}
309309
header = match convert(Event::SectionHeader(next_header)) {
310310
Event::SectionHeader(h) => h,
311311
_ => unreachable!("BUG: convert must not change the event type, just the lifetime"),

gix-credentials/tests/program/from_custom_definition.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const SH: &str = "/bin/sh";
1212
fn empty() {
1313
let prog = Program::from_custom_definition("");
1414
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()));
1616
assert_eq!(
1717
format!("{:?}", prog.to_command(&helper::Action::Store("egal".into()))),
1818
format!(r#""{git}" "credential-" "store""#),

gix-date/src/parse.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub(crate) mod function {
7777
let mut offset_in_seconds = hours * 3600 + minutes * 60;
7878
if sign == Sign::Minus {
7979
offset_in_seconds *= -1;
80-
};
80+
}
8181
let time = Time {
8282
seconds,
8383
offset: offset_in_seconds,

gix-diff/src/blob/pipeline.rs

+20-22
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ impl Pipeline {
395395
&& header.size > self.options.large_file_threshold_bytes
396396
{
397397
is_binary = Some(true);
398-
};
398+
}
399399
let data = if is_binary == Some(true) {
400400
Data::Binary { size: header.size }
401401
} else {
@@ -461,27 +461,25 @@ impl Pipeline {
461461
out.clear();
462462
run_cmd(rela_path, cmd, out)?;
463463
}
464-
None => {
465-
match res {
466-
ToWorktreeOutcome::Unchanged(_) => {}
467-
ToWorktreeOutcome::Buffer(src) => {
468-
out.clear();
469-
out.try_reserve(src.len())?;
470-
out.extend_from_slice(src);
471-
}
472-
ToWorktreeOutcome::Process(MaybeDelayed::Immediate(mut stream)) => {
473-
std::io::copy(&mut stream, out).map_err(|err| {
474-
convert_to_diffable::Error::StreamCopy {
475-
rela_path: rela_path.to_owned(),
476-
source: err,
477-
}
478-
})?;
479-
}
480-
ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {
481-
unreachable!("we prohibit this")
482-
}
483-
};
484-
}
464+
None => match res {
465+
ToWorktreeOutcome::Unchanged(_) => {}
466+
ToWorktreeOutcome::Buffer(src) => {
467+
out.clear();
468+
out.try_reserve(src.len())?;
469+
out.extend_from_slice(src);
470+
}
471+
ToWorktreeOutcome::Process(MaybeDelayed::Immediate(mut stream)) => {
472+
std::io::copy(&mut stream, out).map_err(|err| {
473+
convert_to_diffable::Error::StreamCopy {
474+
rela_path: rela_path.to_owned(),
475+
source: err,
476+
}
477+
})?;
478+
}
479+
ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {
480+
unreachable!("we prohibit this")
481+
}
482+
},
485483
}
486484
}
487485

gix-diff/src/blob/platform.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl Platform {
362362
/// * `mode` is the kind of object (only blobs and links are allowed)
363363
/// * `rela_path` is the relative path as seen from the (work)tree root.
364364
/// * `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`.
366366
/// * `objects` provides access to the object database in case the resource can't be read from a worktree.
367367
///
368368
/// Note that it's assumed that either `id + mode (` or `rela_path` can serve as unique identifier for the resource,

0 commit comments

Comments
 (0)