Skip to content

Commit 3bd3380

Browse files
[git-object] Encode empty tags like git does
A tag with an empty commit message is now displayed with an extra newline, consitently with the output of `git cat-file`. The test fixture for `empty.txt` was updated, which means that the `round_trip` test now expects a correct round trip with the new format. Note that the changes to tests in `immutable` reflect the new state of the code: * `TagRefIter` now parses this body with an empty message. * Where the length of the data was divided by 2, the point was to create an inconsistent dataset leading to an error. Unfortunately, with the extra character, it lines up so that the message can be parsed, so I had to change the magic number to keep the previous property. Fixes #603
1 parent 409b769 commit 3bd3380

File tree

4 files changed

+12
-14
lines changed

4 files changed

+12
-14
lines changed

git-object/src/tag/decode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ pub fn message<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], (&
5353
let (i, _) = tag(NL)(i)?;
5454
fn all_to_end<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], (&'a [u8], &'a [u8]), E> {
5555
if i.is_empty() {
56-
return Err(nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::Eof)));
56+
// Empty message. That's OK.
57+
return Ok((&[], (&[], &[])));
5758
}
5859
// an empty signature message signals that there is none - the function signature is needed
5960
// to work with 'alt(…)'. PGP signatures are never empty

git-object/src/tag/write.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ impl crate::WriteTo for Tag {
2929
encode::trusted_header_signature(b"tagger", &tagger.to_ref(), &mut out)?;
3030
}
3131

32+
out.write_all(NL)?;
3233
if !self.message.is_empty() {
33-
out.write_all(NL)?;
3434
out.write_all(&self.message)?;
3535
}
3636
if let Some(ref message) = self.pgp_signature {
@@ -49,11 +49,7 @@ impl crate::WriteTo for Tag {
4949
.as_ref()
5050
.map(|t| b"tagger".len() + 1 /* space */ + t.size() + 1 /* nl */)
5151
.unwrap_or(0)
52-
+ if self.message.is_empty() {
53-
0
54-
} else {
55-
1 /* nl */ + self.message.len()
56-
}
52+
+ 1 /* nl */ + self.message.len()
5753
+ self.pgp_signature.as_ref().map(|m| 1 /* nl */ + m.len() ).unwrap_or(0)
5854
}
5955

@@ -71,8 +67,8 @@ impl<'a> crate::WriteTo for TagRef<'a> {
7167
encode::trusted_header_signature(b"tagger", tagger, &mut out)?;
7268
}
7369

70+
out.write_all(NL)?;
7471
if !self.message.is_empty() {
75-
out.write_all(NL)?;
7672
out.write_all(self.message)?;
7773
}
7874
if let Some(message) = self.pgp_signature {
@@ -91,11 +87,7 @@ impl<'a> crate::WriteTo for TagRef<'a> {
9187
.as_ref()
9288
.map(|t| b"tagger".len() + 1 /* space */ + t.size() + 1 /* nl */)
9389
.unwrap_or(0)
94-
+ if self.message.is_empty() {
95-
0
96-
} else {
97-
1 /* nl */ + self.message.len()
98-
}
90+
+ 1 /* nl */ + self.message.len()
9991
+ self.pgp_signature.as_ref().map(|m| 1 /* nl */ + m.len()).unwrap_or(0)
10092
}
10193

git-object/tests/fixtures/tag/empty.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ object 01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc
22
type commit
33
tag empty
44
tagger Sebastian Thiel <sebastian.thiel@icloud.com> 1592381636 +0800
5+

git-object/tests/immutable/tag.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ mod iter {
3737
Token::TargetKind(Kind::Commit),
3838
Token::Name(b"empty".as_bstr()),
3939
Token::Tagger(tagger),
40+
Token::Body {
41+
message: b"".as_bstr(),
42+
pgp_signature: None,
43+
}
4044
]
4145
);
4246
assert_eq!(tag_iter.target_id()?, target_id);
@@ -103,7 +107,7 @@ KLMHist5yj0sw1E4hDTyQa0=
103107
#[test]
104108
fn error_handling() -> crate::Result {
105109
let data = fixture_bytes("tag", "empty.txt");
106-
let iter = TagRefIter::from_bytes(&data[..data.len() / 2]);
110+
let iter = TagRefIter::from_bytes(&data[..data.len() / 3]);
107111
let tokens = iter.collect::<Vec<_>>();
108112
assert!(
109113
tokens.last().expect("at least the errored token").is_err(),

0 commit comments

Comments
 (0)