History

restore original representation of `Tag` at the cost of some duplication

That way both representations are optimal in memory for their intended usecase. - `TagRef` is decodable from a buffer refers to it with all of its fields. That way round-trips are cheapest. - `Tag` does not allocate for hashes as there is a more compact representation: `git_hash::ObjectId`.

Sebastian Thiel committed 3 years ago

Commit dd0a23d1 parent 7242d1f6 files · +49 −59Browse files

Showing the changes to git-object/src (5 of 6 files). Show all

Unified · Split

5 files
  1. git-object/src/commit/write.rs +8 −8
  2. git-object/src/lib.rs +3 −4
  3. git-object/src/object/convert.rs +4 −25
  4. git-object/src/tag/mod.rs +1 −9
  5. git-object/src/tag/write.rs +30 −6
git-object/src/commit/write.rs+8−8
@@ -23,6 +23,10 @@ impl crate::WriteTo for Commit { · 22 unmodified lines
2323 out.write_all(&self.message)
2424 }
2525
26+ fn kind(&self) -> Kind {
27+ Kind::Commit
28+ }
29+
2630 fn size(&self) -> usize {
2731 let hash_in_hex = self.tree.kind().len_in_hex();
2832 b"tree".len() + 1 /*space*/ + hash_in_hex + 1 /* nl */
@@ -45,10 +49,6 @@ impl crate::WriteTo for Commit { · 16 unmodified lines
4549 + 1 /* nl */
4650 + self.message.len()
4751 }
48−
49− fn kind(&self) -> Kind {
50− Kind::Commit
51− }
5252 }
5353
5454 impl<'a> crate::WriteTo for CommitRef<'a> {
@@ -70,6 +70,10 @@ impl<'a> crate::WriteTo for CommitRef<'a> { · 15 unmodified lines
7070 out.write_all(self.message)
7171 }
7272
73+ fn kind(&self) -> Kind {
74+ Kind::Commit
75+ }
76+
7377 fn size(&self) -> usize {
7478 let hash_in_hex = self.tree().kind().len_in_hex();
7579 b"tree".len() + 1 /* space */ + hash_in_hex + 1 /* nl */
@@ -92,8 +96,4 @@ impl<'a> crate::WriteTo for CommitRef<'a> { · 16 unmodified lines
9296 + 1 /* nl */
9397 + self.message.len()
9498 }
95−
96− fn kind(&self) -> Kind {
97− Kind::Commit
98− }
9999 }
git-object/src/lib.rs+3−4
@@ -136,7 +136,7 @@ pub struct TagRef<'a> { · 135 unmodified lines
136136 #[cfg_attr(feature = "serde1", serde(borrow))]
137137 pub target: &'a BStr,
138138 /// The kind of object that `target` points to.
139− pub target_kind: crate::Kind,
139+ pub target_kind: Kind,
140140 /// The name of the tag, e.g. "v1.0".
141141 pub name: &'a BStr,
142142 /// The author of the tag.
@@ -159,9 +159,8 @@ pub struct TagRefIter<'a> { · 16 unmodified lines
159159 #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
160160 #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
161161 pub struct Tag {
162− /// The hash this tag is pointing to stored as hexadecimal representation from which an `ObjectId`
163− /// can be constructed. Use [`.target()`][Tag::target()] to access that `ObjectId`.
164− pub target: BString,
162+ /// The hash this tag is pointing to.
163+ pub target: git_hash::ObjectId,
165164 /// The kind of object this tag is pointing to.
166165 pub target_kind: Kind,
167166 /// The name of the tag, e.g. "v1.0".
git-object/src/object/convert.rs+4−25
@@ -1,6 +1,6 @@
11 use std::convert::TryFrom;
22
3−use crate::{bstr::BStr, tree, Blob, BlobRef, Commit, CommitRef, Object, ObjectRef, Tag, TagRef, Tree, TreeRef};
3+use crate::{tree, Blob, BlobRef, Commit, CommitRef, Object, ObjectRef, Tag, TagRef, Tree, TreeRef};
44
55 impl From<TagRef<'_>> for Tag {
66 fn from(other: TagRef<'_>) -> Tag {
@@ -13,7 +13,7 @@ impl From<TagRef<'_>> for Tag { · 6 unmodified lines
1313 pgp_signature,
1414 } = other;
1515 Tag {
16− target: target.to_owned(),
16+ target: git_hash::ObjectId::from_hex(target).expect("prior parser validation"),
1717 name: name.to_owned(),
1818 target_kind,
1919 message: message.to_owned(),
@@ -23,27 +23,6 @@ impl From<TagRef<'_>> for Tag { · 3 unmodified lines
2323 }
2424 }
2525
26−impl<'a> From<&'a Tag> for TagRef<'a> {
27− fn from(other: &'a Tag) -> TagRef<'a> {
28− let Tag {
29− target,
30− target_kind,
31− name,
32− tagger,
33− message,
34− pgp_signature,
35− } = other;
36− TagRef {
37− target: target.as_ref(),
38− target_kind: *target_kind,
39− name: name.as_ref(),
40− tagger: tagger.as_ref().map(|s| s.to_ref()),
41− message: message.as_ref(),
42− pgp_signature: pgp_signature.as_deref().map(BStr::new),
43− }
44− }
45−}
46−
4726 impl From<CommitRef<'_>> for Commit {
4827 fn from(other: CommitRef<'_>) -> Commit {
4928 let CommitRef {
@@ -56,10 +35,10 @@ impl From<CommitRef<'_>> for Commit { · 6 unmodified lines
5635 extra_headers,
5736 } = other;
5837 Commit {
59− tree: git_hash::ObjectId::from_hex(tree).expect("40 bytes hex sha1"),
38+ tree: git_hash::ObjectId::from_hex(tree).expect("prior parser validation"),
6039 parents: parents
6140 .iter()
62− .map(|parent| git_hash::ObjectId::from_hex(parent).expect("40 bytes hex sha1"))
41+ .map(|parent| git_hash::ObjectId::from_hex(parent).expect("prior parser validation"))
6342 .collect(),
6443 author: author.into(),
6544 committer: committer.into(),
git-object/src/tag/mod.rs+1−9
@@ -1,4 +1,4 @@
1−use crate::{Tag, TagRef};
1+use crate::TagRef;
22
33 mod decode;
44
@@ -20,11 +20,3 @@ impl<'a> TagRef<'a> { · 15 unmodified lines
2020 git_hash::ObjectId::from_hex(self.target).expect("prior validation")
2121 }
2222 }
23−
24−/// Access
25−impl Tag {
26− /// The hash this tag is pointing to.
27− pub fn target(&self) -> git_hash::ObjectId {
28− git_hash::ObjectId::from_hex(&self.target).expect("parser assured this is a valid hash")
29− }
30−}
git-object/src/tag/write.rs+30−6
@@ -21,22 +21,46 @@ impl From<Error> for io::Error { · 20 unmodified lines
2121 }
2222
2323 impl crate::WriteTo for Tag {
24− fn write_to(&self, out: impl io::Write) -> io::Result<()> {
25− TagRef::from(self).write_to(out)
26− }
24+ fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {
25+ encode::trusted_header_id(b"object", &self.target, &mut out)?;
26+ encode::trusted_header_field(b"type", self.target_kind.as_bytes(), &mut out)?;
27+ encode::header_field(b"tag", validated_name(self.name.as_ref())?, &mut out)?;
28+ if let Some(tagger) = &self.tagger {
29+ encode::trusted_header_signature(b"tagger", &tagger.to_ref(), &mut out)?;
30+ }
2731
28− fn size(&self) -> usize {
29− TagRef::from(self).size()
32+ out.write_all(NL)?;
33+ if !self.message.is_empty() {
34+ out.write_all(self.message.as_ref())?;
35+ }
36+ if let Some(message) = &self.pgp_signature {
37+ out.write_all(NL)?;
38+ out.write_all(message.as_ref())?;
39+ }
40+ Ok(())
3041 }
3142
3243 fn kind(&self) -> Kind {
3344 Kind::Tag
3445 }
46+
47+ fn size(&self) -> usize {
48+ b"object".len() + 1 /* space */ + self.target.kind().len_in_hex() + 1 /* nl */
49+ + b"type".len() + 1 /* space */ + self.target_kind.as_bytes().len() + 1 /* nl */
50+ + b"tag".len() + 1 /* space */ + self.name.len() + 1 /* nl */
51+ + self
52+ .tagger
53+ .as_ref()
54+ .map(|t| b"tagger".len() + 1 /* space */ + t.size() + 1 /* nl */)
55+ .unwrap_or(0)
56+ + 1 /* nl */ + self.message.len()
57+ + self.pgp_signature.as_ref().map(|m| 1 /* nl */ + m.len()).unwrap_or(0)
58+ }
3559 }
3660
3761 impl<'a> crate::WriteTo for TagRef<'a> {
3862 fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {
39− encode::trusted_header_id(b"object", &self.target(), &mut out)?;
63+ encode::trusted_header_field(b"object", &self.target, &mut out)?;
4064 encode::trusted_header_field(b"type", self.target_kind.as_bytes(), &mut out)?;
4165 encode::header_field(b"tag", validated_name(self.name)?, &mut out)?;
4266 if let Some(tagger) = &self.tagger {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

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

Repository code

Go to file
t