Skip to content

Commit bc3a8a2

Browse files
committed
chore!: update gix to v0.57
1 parent 167a34a commit bc3a8a2

File tree

5 files changed

+110
-68
lines changed

5 files changed

+110
-68
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ http-reqwest = ["gix/blocking-http-transport-reqwest-rust-tls"]
3737

3838

3939
[dependencies]
40-
gix = { version = "0.55.2", default-features = false, features = ["blocking-network-client", "blob-diff", "revision"] }
40+
gix = { version = "0.57.0", default-features = false, features = ["blocking-network-client", "blob-diff", "revision"] }
4141
serde = { version = "1", features = ["std", "derive"] }
4242
hex = { version = "0.4.3", features = ["serde"] }
4343
smartstring = { version = "1.0.1", features = ["serde"] }

src/index/diff/delegate.rs

Lines changed: 84 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,35 @@ use hashbrown::raw::RawTable;
66
use std::hash::Hasher;
77
use std::ops::Deref;
88

9-
#[derive(Default)]
109
pub(crate) struct Delegate {
1110
changes: Vec<Change>,
11+
resource_cache: gix::diff::blob::Platform,
1212
/// All changes that happen within a file, along the line-number it happens in .
1313
per_file_changes: Vec<(usize, Change)>,
1414
err: Option<Error>,
1515
}
1616

17+
impl Delegate {
18+
pub(crate) fn new(resource_cache: gix::diff::blob::Platform) -> Self {
19+
Delegate {
20+
resource_cache,
21+
changes: Default::default(),
22+
per_file_changes: Default::default(),
23+
err: None,
24+
}
25+
}
26+
}
27+
1728
impl Delegate {
1829
pub fn handle(
1930
&mut self,
2031
change: gix::object::tree::diff::Change<'_, '_, '_>,
2132
) -> Result<gix::object::tree::diff::Action, Error> {
2233
use gix::bstr::ByteSlice;
2334
use gix::object::tree::diff::change::Event::*;
24-
use gix::objs::tree::EntryMode::*;
35+
use gix::objs::tree::EntryKind::*;
2536
fn entry_data(
26-
entry: gix::objs::tree::EntryMode,
37+
entry: gix::objs::tree::EntryKind,
2738
id: gix::Id<'_>,
2839
) -> Result<Option<gix::Object<'_>>, Error> {
2940
matches!(entry, Blob | BlobExecutable)
@@ -40,7 +51,7 @@ impl Delegate {
4051
unreachable!("BUG: this is disabled so shouldn't happen")
4152
}
4253
Addition { entry_mode, id } => {
43-
if let Some(obj) = entry_data(entry_mode, id)? {
54+
if let Some(obj) = entry_data(entry_mode.kind(), id)? {
4455
for line in obj.data.lines() {
4556
let version = version_from_json_line(line, change.location)?;
4657
let change = if version.yanked {
@@ -65,66 +76,82 @@ impl Delegate {
6576
});
6677
}
6778
}
68-
Modification { .. } => {
69-
if let Some(diff) = change.event.diff().transpose()? {
70-
let mut old_lines = AHashSet::with_capacity(1024);
71-
let location = change.location;
72-
for (number, line) in diff.old.data.lines().enumerate() {
73-
old_lines.insert(Line(number, line));
74-
}
79+
Modification { entry_mode, .. } => {
80+
if entry_mode.is_blob() {
81+
self.resource_cache.clear_resource_cache();
82+
let platform = change.diff(&mut self.resource_cache)?;
83+
if let Some((old, new)) = platform.resource_cache.resources() {
84+
let mut old_lines = AHashSet::with_capacity(1024);
85+
let location = change.location;
86+
for (number, line) in old
87+
.data
88+
.as_slice()
89+
.expect("present in modification")
90+
.lines()
91+
.enumerate()
92+
{
93+
old_lines.insert(Line(number, line));
94+
}
7595

76-
// A RawTable is used to represent a Checksum -> CrateVersion map
77-
// because the checksum is already stored in the CrateVersion
78-
// and we want to avoid storing the checksum twice for performance reasons
79-
let mut new_versions = RawTable::with_capacity(old_lines.len().min(1024));
80-
let hasher = RandomState::new();
96+
// A RawTable is used to represent a Checksum -> CrateVersion map
97+
// because the checksum is already stored in the CrateVersion
98+
// and we want to avoid storing the checksum twice for performance reasons
99+
let mut new_versions = RawTable::with_capacity(old_lines.len().min(1024));
100+
let hasher = RandomState::new();
81101

82-
for (number, line) in diff.new.data.lines().enumerate() {
83-
// first quickly check if the exact same line is already present in this file in that case we don't need to do anything else
84-
if old_lines.remove(&Line(number, line)) {
85-
continue;
102+
for (number, line) in new
103+
.data
104+
.as_slice()
105+
.expect("present in modification")
106+
.lines()
107+
.enumerate()
108+
{
109+
// first quickly check if the exact same line is already present in this file in that case we don't need to do anything else
110+
if old_lines.remove(&Line(number, line)) {
111+
continue;
112+
}
113+
// no need to check if the checksum already exists in the hashmap
114+
// as each checksum appears only once
115+
let new_version = version_from_json_line(line, location)?;
116+
new_versions.insert(
117+
hasher.hash_one(new_version.checksum),
118+
(number, new_version),
119+
|rehashed| hasher.hash_one(rehashed.1.checksum),
120+
);
86121
}
87-
// no need to check if the checksum already exists in the hashmap
88-
// as each checksum appears only once
89-
let new_version = version_from_json_line(line, location)?;
90-
new_versions.insert(
91-
hasher.hash_one(new_version.checksum),
92-
(number, new_version),
93-
|rehashed| hasher.hash_one(rehashed.1.checksum),
94-
);
95-
}
96122

97-
for line in old_lines.drain() {
98-
let old_version = version_from_json_line(&line, location)?;
99-
let new_version = new_versions
100-
.remove_entry(hasher.hash_one(old_version.checksum), |version| {
101-
version.1.checksum == old_version.checksum
102-
});
103-
match new_version {
104-
Some((_, new_version)) => {
105-
let change = match (old_version.yanked, new_version.yanked) {
106-
(true, false) => Change::Unyanked(new_version),
107-
(false, true) => Change::Yanked(new_version),
108-
_ => continue,
109-
};
110-
self.per_file_changes.push((line.0, change))
123+
for line in old_lines.drain() {
124+
let old_version = version_from_json_line(&line, location)?;
125+
let new_version = new_versions
126+
.remove_entry(hasher.hash_one(old_version.checksum), |version| {
127+
version.1.checksum == old_version.checksum
128+
});
129+
match new_version {
130+
Some((_, new_version)) => {
131+
let change = match (old_version.yanked, new_version.yanked) {
132+
(true, false) => Change::Unyanked(new_version),
133+
(false, true) => Change::Yanked(new_version),
134+
_ => continue,
135+
};
136+
self.per_file_changes.push((line.0, change))
137+
}
138+
None => self
139+
.per_file_changes
140+
.push((line.0, Change::VersionDeleted(old_version))),
111141
}
112-
None => self
113-
.per_file_changes
114-
.push((line.0, Change::VersionDeleted(old_version))),
115142
}
143+
for (number, version) in new_versions.drain() {
144+
let change = if version.yanked {
145+
Change::AddedAndYanked(version)
146+
} else {
147+
Change::Added(version)
148+
};
149+
self.per_file_changes.push((number, change));
150+
}
151+
self.per_file_changes.sort_by_key(|t| t.0);
152+
self.changes
153+
.extend(self.per_file_changes.drain(..).map(|t| t.1));
116154
}
117-
for (number, version) in new_versions.drain() {
118-
let change = if version.yanked {
119-
Change::AddedAndYanked(version)
120-
} else {
121-
Change::Added(version)
122-
};
123-
self.per_file_changes.push((number, change));
124-
}
125-
self.per_file_changes.sort_by_key(|t| t.0);
126-
self.changes
127-
.extend(self.per_file_changes.drain(..).map(|t| t.1));
128155
}
129156
}
130157
}

src/index/diff/mod.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{Change, Index};
2+
use bstr::ByteSlice;
23
use gix::prelude::ObjectIdExt;
34
use std::sync::atomic::AtomicBool;
45

@@ -32,7 +33,9 @@ pub enum Error {
3233
#[error("Failed to parse rev-spec to determine which revisions to diff")]
3334
RevParse(#[from] gix::revision::spec::parse::Error),
3435
#[error(transparent)]
35-
DiffRewrites(#[from] gix::object::tree::diff::rewrites::Error),
36+
DiffRewrites(#[from] gix::diff::new_rewrites::Error),
37+
#[error(transparent)]
38+
DiffResourceCache(#[from] gix::diff::resource_cache::Error),
3639
#[error("Couldn't find blob that showed up when diffing trees")]
3740
FindObject(#[from] gix::object::find::existing::Error),
3841
#[error("Couldn't get the tree of a commit for diffing purposes")]
@@ -127,7 +130,7 @@ impl Index {
127130
.remote_name
128131
.as_deref()
129132
.and_then(|name| {
130-
self.repo.find_remote(name).ok().or_else(|| {
133+
self.repo.find_remote(name.as_bstr()).ok().or_else(|| {
131134
self.repo
132135
.head()
133136
.ok()
@@ -162,7 +165,11 @@ impl Index {
162165
if remote.refspecs(gix::remote::Direction::Fetch).is_empty() {
163166
let spec = format!(
164167
"+refs/heads/{branch}:refs/remotes/{remote}/{branch}",
165-
remote = self.remote_name.as_deref().unwrap_or("origin"),
168+
remote = self
169+
.remote_name
170+
.as_ref()
171+
.map(|n| n.as_bstr())
172+
.unwrap_or("origin".into()),
166173
branch = self.branch_name,
167174
);
168175
remote
@@ -233,14 +240,24 @@ impl Index {
233240
};
234241
let from = into_tree(from.into())?;
235242
let to = into_tree(to.into())?;
236-
let mut delegate = Delegate::default();
243+
let mut delegate = Delegate::new(self.resource_cache()?);
237244
from.changes()?
238245
.track_filename()
239246
.track_rewrites(None)
240247
.for_each_to_obtain_tree(&to, |change| delegate.handle(change))?;
241248
delegate.into_result()
242249
}
243250

251+
fn resource_cache(&self) -> Result<gix::diff::blob::Platform, Error> {
252+
Ok(gix::diff::resource_cache(
253+
&self.repo,
254+
&gix::index::State::new(self.repo.object_hash()),
255+
gix::diff::blob::pipeline::Mode::ToGit,
256+
gix::worktree::stack::state::attributes::Source::IdMapping,
257+
Default::default(),
258+
)?)
259+
}
260+
244261
/// Similar to [`Self::changes()`], but requires `ancestor_commit` and `current_commit` objects to be provided
245262
/// with `ancestor_commit` being in the ancestry of `current_commit`.
246263
///

src/index/init.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::index::{CloneOptions, LAST_SEEN_REFNAME};
22
use crate::Index;
3+
use std::borrow::Cow;
34
use std::path::Path;
45
use std::sync::atomic::AtomicBool;
56

@@ -61,11 +62,7 @@ impl Index {
6162
};
6263

6364
repo.object_cache_size_if_unset(4 * 1024 * 1024);
64-
let remote_name = repo
65-
.remote_names()
66-
.into_iter()
67-
.next()
68-
.map(ToOwned::to_owned);
65+
let remote_name = repo.remote_names().into_iter().next().map(Cow::into_owned);
6966
Ok(Index {
7067
repo,
7168
remote_name,

src/types.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::HashMap;
22

3+
use bstr::BString;
34
use smartstring::alias::String as SmolString;
45
use std::hash::Hash;
56
use std::{fmt, slice};
@@ -13,7 +14,7 @@ pub struct Index {
1314
pub branch_name: &'static str,
1415
/// The name of the symbolic name of the remote to fetch from.
1516
/// If `None`, obtain the remote name from the configuration of the currently checked-out branch.
16-
pub remote_name: Option<String>,
17+
pub remote_name: Option<BString>,
1718
/// The git repository to use for diffing
1819
pub(crate) repo: gix::Repository,
1920
}

0 commit comments

Comments
 (0)