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
23 out.write_all(&self.message)23 out.write_all(&self.message)
24 }24 }
25 25
26 fn kind(&self) -> Kind {
27 Kind::Commit
28 }
29
26 fn size(&self) -> usize {30 fn size(&self) -> usize {
27 let hash_in_hex = self.tree.kind().len_in_hex();31 let hash_in_hex = self.tree.kind().len_in_hex();
28 b"tree".len() + 1 /*space*/ + hash_in_hex + 1 /* nl */32 b"tree".len() + 1 /*space*/ + hash_in_hex + 1 /* nl */
@@ -45,10 +49,6 @@ impl crate::WriteTo for Commit { · 16 unmodified lines
45 + 1 /* nl */49 + 1 /* nl */
46 + self.message.len()50 + self.message.len()
47 }51 }
48
49 fn kind(&self) -> Kind {
50 Kind::Commit
51 }
52}52}
53 53
54impl<'a> crate::WriteTo for CommitRef<'a> {54impl<'a> crate::WriteTo for CommitRef<'a> {
@@ -70,6 +70,10 @@ impl<'a> crate::WriteTo for CommitRef<'a> { · 15 unmodified lines
70 out.write_all(self.message)70 out.write_all(self.message)
71 }71 }
72 72
73 fn kind(&self) -> Kind {
74 Kind::Commit
75 }
76
73 fn size(&self) -> usize {77 fn size(&self) -> usize {
74 let hash_in_hex = self.tree().kind().len_in_hex();78 let hash_in_hex = self.tree().kind().len_in_hex();
75 b"tree".len() + 1 /* space */ + hash_in_hex + 1 /* nl */79 b"tree".len() + 1 /* space */ + hash_in_hex + 1 /* nl */
@@ -92,8 +96,4 @@ impl<'a> crate::WriteTo for CommitRef<'a> { · 16 unmodified lines
92 + 1 /* nl */96 + 1 /* nl */
93 + self.message.len()97 + self.message.len()
94 }98 }
95
96 fn kind(&self) -> Kind {
97 Kind::Commit
98 }
99}99}
git-object/src/lib.rs+3−4
@@ -136,7 +136,7 @@ pub struct TagRef<'a> { · 135 unmodified lines
136 #[cfg_attr(feature = "serde1", serde(borrow))]136 #[cfg_attr(feature = "serde1", serde(borrow))]
137 pub target: &'a BStr,137 pub target: &'a BStr,
138 /// The kind of object that `target` points to.138 /// The kind of object that `target` points to.
139 pub target_kind: crate::Kind,139 pub target_kind: Kind,
140 /// The name of the tag, e.g. "v1.0".140 /// The name of the tag, e.g. "v1.0".
141 pub name: &'a BStr,141 pub name: &'a BStr,
142 /// The author of the tag.142 /// The author of the tag.
@@ -159,9 +159,8 @@ pub struct TagRefIter<'a> { · 16 unmodified lines
159#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]159#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
160#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]160#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
161pub struct Tag {161pub struct Tag {
162 /// The hash this tag is pointing to stored as hexadecimal representation from which an `ObjectId`162 /// The hash this tag is pointing to.
163 /// can be constructed. Use [`.target()`][Tag::target()] to access that `ObjectId`.163 pub target: git_hash::ObjectId,
164 pub target: BString,
165 /// The kind of object this tag is pointing to.164 /// The kind of object this tag is pointing to.
166 pub target_kind: Kind,165 pub target_kind: Kind,
167 /// The name of the tag, e.g. "v1.0".166 /// The name of the tag, e.g. "v1.0".
git-object/src/object/convert.rs+4−25
@@ -1,6 +1,6 @@
1use std::convert::TryFrom;1use std::convert::TryFrom;
2 2
3use crate::{bstr::BStr, tree, Blob, BlobRef, Commit, CommitRef, Object, ObjectRef, Tag, TagRef, Tree, TreeRef};3use crate::{tree, Blob, BlobRef, Commit, CommitRef, Object, ObjectRef, Tag, TagRef, Tree, TreeRef};
4 4
5impl From<TagRef<'_>> for Tag {5impl From<TagRef<'_>> for Tag {
6 fn from(other: TagRef<'_>) -> Tag {6 fn from(other: TagRef<'_>) -> Tag {
@@ -13,7 +13,7 @@ impl From<TagRef<'_>> for Tag { · 6 unmodified lines
13 pgp_signature,13 pgp_signature,
14 } = other;14 } = other;
15 Tag {15 Tag {
16 target: target.to_owned(),16 target: git_hash::ObjectId::from_hex(target).expect("prior parser validation"),
17 name: name.to_owned(),17 name: name.to_owned(),
18 target_kind,18 target_kind,
19 message: message.to_owned(),19 message: message.to_owned(),
@@ -23,27 +23,6 @@ impl From<TagRef<'_>> for Tag { · 3 unmodified lines
23 }23 }
24}24}
25 25
26impl<'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
47impl From<CommitRef<'_>> for Commit {26impl From<CommitRef<'_>> for Commit {
48 fn from(other: CommitRef<'_>) -> Commit {27 fn from(other: CommitRef<'_>) -> Commit {
49 let CommitRef {28 let CommitRef {
@@ -56,10 +35,10 @@ impl From<CommitRef<'_>> for Commit { · 6 unmodified lines
56 extra_headers,35 extra_headers,
57 } = other;36 } = other;
58 Commit {37 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"),
60 parents: parents39 parents: parents
61 .iter()40 .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"))
63 .collect(),42 .collect(),
64 author: author.into(),43 author: author.into(),
65 committer: committer.into(),44 committer: committer.into(),
git-object/src/tag/mod.rs+1−9
@@ -1,4 +1,4 @@
1use crate::{Tag, TagRef};1use crate::TagRef;
2 2
3mod decode;3mod decode;
4 4
@@ -20,11 +20,3 @@ impl<'a> TagRef<'a> { · 15 unmodified lines
20 git_hash::ObjectId::from_hex(self.target).expect("prior validation")20 git_hash::ObjectId::from_hex(self.target).expect("prior validation")
21 }21 }
22}22}
23
24/// Access
25impl 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
21}21}
22 22
23impl crate::WriteTo for Tag {23impl crate::WriteTo for Tag {
24 fn write_to(&self, out: impl io::Write) -> io::Result<()> {24 fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {
25 TagRef::from(self).write_to(out)25 encode::trusted_header_id(b"object", &self.target, &mut out)?;
26 }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 }
27 31
28 fn size(&self) -> usize {32 out.write_all(NL)?;
29 TagRef::from(self).size()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(())
30 }41 }
31 42
32 fn kind(&self) -> Kind {43 fn kind(&self) -> Kind {
33 Kind::Tag44 Kind::Tag
34 }45 }
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 }
35}59}
36 60
37impl<'a> crate::WriteTo for TagRef<'a> {61impl<'a> crate::WriteTo for TagRef<'a> {
38 fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {62 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)?;
40 encode::trusted_header_field(b"type", self.target_kind.as_bytes(), &mut out)?;64 encode::trusted_header_field(b"type", self.target_kind.as_bytes(), &mut out)?;
41 encode::header_field(b"tag", validated_name(self.name)?, &mut out)?;65 encode::header_field(b"tag", validated_name(self.name)?, &mut out)?;
42 if let Some(tagger) = &self.tagger {66 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