@@ -22,6 +22,59 @@ pub struct HeadersV2 {
2222 pub conflicted : Option < u64 > ,
2323}
2424
25+ impl HeadersV2 {
26+ /// Extract header information from the given `commit`, or return `None` if not present.
27+ pub fn try_from_commit ( commit : & gix:: objs:: Commit ) -> Option < Self > {
28+ if let Some ( header) = commit. extra_headers ( ) . find ( HEADERS_VERSION_FIELD ) {
29+ let version = header. to_owned ( ) ;
30+
31+ if version == HEADERS_VERSION {
32+ let change_id = commit. extra_headers ( ) . find ( HEADERS_CHANGE_ID_FIELD ) ?;
33+ let change_id = change_id. to_str ( ) . ok ( ) ?. to_string ( ) ;
34+
35+ let conflicted = commit
36+ . extra_headers ( )
37+ . find ( HEADERS_CONFLICTED_FIELD )
38+ . and_then ( |value| value. to_str ( ) . ok ( ) ?. parse :: < u64 > ( ) . ok ( ) ) ;
39+
40+ Some ( HeadersV2 {
41+ change_id,
42+ conflicted,
43+ } )
44+ } else {
45+ tracing:: warn!(
46+ "Ignoring unknown commit header version '{version}' in commit {commit:?}" ,
47+ ) ;
48+ None
49+ }
50+ } else {
51+ // Parse v1 headers
52+ let change_id = commit. extra_headers ( ) . find ( "change-id" ) ?;
53+ let change_id = change_id. to_str ( ) . ok ( ) ?. to_string ( ) ;
54+ let headers = HeadersV1 { change_id } ;
55+ Some ( headers. into ( ) )
56+ }
57+ }
58+
59+ /// Write the values from this instance to the given `commit`, fully replacing any header
60+ /// that might have been there before.
61+ pub fn set_in_commit ( & self , commit : & mut gix:: objs:: Commit ) {
62+ for field in [
63+ HEADERS_VERSION_FIELD ,
64+ HEADERS_CHANGE_ID_FIELD ,
65+ HEADERS_CONFLICTED_FIELD ,
66+ ] {
67+ if let Some ( pos) = commit. extra_headers ( ) . find_pos ( field) {
68+ commit. extra_headers . remove ( pos) ;
69+ }
70+ }
71+
72+ commit
73+ . extra_headers
74+ . extend ( Vec :: < ( BString , BString ) > :: from ( self ) ) ;
75+ }
76+ }
77+
2578impl Default for HeadersV2 {
2679 fn default ( ) -> Self {
2780 HeadersV2 {
@@ -123,18 +176,7 @@ impl<'repo> Commit<'repo> {
123176impl Commit < ' _ > {
124177 /// Set this commit to use the given `headers`, completely replacing the ones it might currently have.
125178 pub fn set_headers ( & mut self , header : & HeadersV2 ) {
126- for field in [
127- HEADERS_VERSION_FIELD ,
128- HEADERS_CHANGE_ID_FIELD ,
129- HEADERS_CONFLICTED_FIELD ,
130- ] {
131- if let Some ( pos) = self . extra_headers ( ) . find_pos ( field) {
132- self . extra_headers . remove ( pos) ;
133- }
134- }
135-
136- self . extra_headers
137- . extend ( Vec :: < ( BString , BString ) > :: from ( header) ) ;
179+ header. set_in_commit ( self )
138180 }
139181}
140182
@@ -203,36 +245,6 @@ impl<'repo> Commit<'repo> {
203245
204246 /// Return our custom headers, of present.
205247 pub fn headers ( & self ) -> Option < HeadersV2 > {
206- let decoded = & self . inner ;
207- if let Some ( header) = decoded. extra_headers ( ) . find ( HEADERS_VERSION_FIELD ) {
208- let version = header. to_owned ( ) ;
209-
210- if version == HEADERS_VERSION {
211- let change_id = decoded. extra_headers ( ) . find ( HEADERS_CHANGE_ID_FIELD ) ?;
212- let change_id = change_id. to_str ( ) . ok ( ) ?. to_string ( ) ;
213-
214- let conflicted = decoded
215- . extra_headers ( )
216- . find ( HEADERS_CONFLICTED_FIELD )
217- . and_then ( |value| value. to_str ( ) . ok ( ) ?. parse :: < u64 > ( ) . ok ( ) ) ;
218-
219- Some ( HeadersV2 {
220- change_id,
221- conflicted,
222- } )
223- } else {
224- tracing:: warn!(
225- "Ignoring unknown commit header version '{version}' in commit {}" ,
226- self . id
227- ) ;
228- None
229- }
230- } else {
231- // Parse v1 headers
232- let change_id = decoded. extra_headers ( ) . find ( "change-id" ) ?;
233- let change_id = change_id. to_str ( ) . ok ( ) ?. to_string ( ) ;
234- let headers = HeadersV1 { change_id } ;
235- Some ( headers. into ( ) )
236- }
248+ HeadersV2 :: try_from_commit ( & self . inner )
237249 }
238250}
0 commit comments