@@ -6,7 +6,7 @@ pub(super) mod function {
66 use anyhow:: Context ;
77 use gix:: {
88 blame:: BlamePathEntry ,
9- bstr:: { BStr , ByteSlice } ,
9+ bstr:: { BStr , BString , ByteSlice } ,
1010 objs:: FindExt ,
1111 ObjectId ,
1212 } ;
@@ -130,25 +130,31 @@ pub(super) mod function {
130130 ) ;
131131
132132 if !dry_run {
133- std:: fs:: write ( script_file, blame_script. script ) ?;
133+ let blocks: Vec < _ > = blame_script
134+ . script
135+ . iter ( )
136+ . map ( |operation| operation. to_string ( ) )
137+ . collect ( ) ;
138+
139+ std:: fs:: write ( script_file, blocks. join ( "" ) ) ?;
134140 }
135141
136142 Ok ( ( ) )
137143 }
138144
139- struct BlameScript {
140- blame_path : Vec < BlamePathEntry > ,
141- seen : BTreeSet < ObjectId > ,
142- script : String ,
143- options : Options ,
145+ enum BlameScriptOperation {
146+ InitRepository ,
147+ RemoveFile ( String ) ,
148+ CommitFile ( BString , ObjectId ) ,
149+ CheckoutTag ( ObjectId ) ,
150+ PrepareMerge ( Vec < ObjectId > ) ,
151+ CreateTag ( ObjectId ) ,
144152 }
145153
146- impl BlameScript {
147- fn new ( blame_path : Vec < BlamePathEntry > , options : Options ) -> Self {
148- let mut script = String :: new ( ) ;
149-
150- script. push_str (
151- r"#!/bin/sh
154+ impl BlameScriptOperation {
155+ fn to_string ( & self ) -> String {
156+ match self {
157+ BlameScriptOperation :: InitRepository => r"#!/bin/sh
152158
153159set -e
154160
@@ -157,8 +163,46 @@ echo .gitignore >> .gitignore
157163echo assets/ >> .gitignore
158164echo create-history.sh >> .gitignore
159165
160- " ,
161- ) ;
166+ "
167+ . into ( ) ,
168+ BlameScriptOperation :: RemoveFile ( src) => format ! (
169+ r"# delete previous version of file
170+ git rm {src}
171+ "
172+ ) ,
173+ BlameScriptOperation :: CommitFile ( src, commit_id) => format ! (
174+ r"# make file {src} contain content at commit {commit_id}
175+ mkdir -p $(dirname {src})
176+ cp ./assets/{commit_id}.commit ./{src}
177+ # create commit
178+ git add {src}
179+ git commit -m {commit_id}
180+ "
181+ ) ,
182+ BlameScriptOperation :: CheckoutTag ( commit_id) => format ! ( "git checkout tag-{}\n " , commit_id) ,
183+ BlameScriptOperation :: PrepareMerge ( commit_ids) => format ! (
184+ "git merge --no-commit {} || true\n " ,
185+ commit_ids
186+ . iter( )
187+ . map( |commit_id| format!( "tag-{commit_id}" ) )
188+ . collect:: <Vec <_>>( )
189+ . join( " " )
190+ ) ,
191+ BlameScriptOperation :: CreateTag ( commit_id) => format ! ( "git tag tag-{commit_id}\n \n " ) ,
192+ }
193+ }
194+ }
195+
196+ struct BlameScript {
197+ blame_path : Vec < BlamePathEntry > ,
198+ seen : BTreeSet < ObjectId > ,
199+ script : Vec < BlameScriptOperation > ,
200+ options : Options ,
201+ }
202+
203+ impl BlameScript {
204+ fn new ( blame_path : Vec < BlamePathEntry > , options : Options ) -> Self {
205+ let script = vec ! [ BlameScriptOperation :: InitRepository ] ;
162206
163207 Self {
164208 blame_path,
@@ -202,7 +246,7 @@ echo create-history.sh >> .gitignore
202246 } ;
203247 let commit_id = blame_path_entry. commit_id ;
204248
205- let delete_previous_file_script = match & blame_path_entry. previous_source_file_path {
249+ let delete_previous_file_operation = match & blame_path_entry. previous_source_file_path {
206250 Some ( previous_source_file_path) if source_file_path != * previous_source_file_path => {
207251 let src = if self . options . verbatim {
208252 previous_source_file_path. to_string ( )
@@ -215,57 +259,41 @@ echo create-history.sh >> .gitignore
215259 crate :: commands:: copy_royal:: remapped ( source_file_path)
216260 } ;
217261
218- format ! (
219- r"# delete previous version of file
220- git rm {src}
221- "
222- )
262+ Some ( BlameScriptOperation :: RemoveFile ( src) )
223263 }
224- _ => String :: new ( ) ,
264+ _ => None ,
225265 } ;
226266
227- let script = format ! (
228- r"# make file {src} contain content at commit {commit_id}
229- mkdir -p $(dirname {src})
230- cp ./assets/{commit_id}.commit ./{src}
231- # create commit
232- git add {src}
233- git commit -m {commit_id}
234- "
235- ) ;
236-
237267 if parents. is_empty ( ) {
238- self . script . push_str ( delete_previous_file_script. as_str ( ) ) ;
239- self . script . push_str ( script. as_str ( ) ) ;
268+ if let Some ( delete_previous_file_operation) = delete_previous_file_operation {
269+ self . script . push ( delete_previous_file_operation) ;
270+ }
271+ self . script . push ( BlameScriptOperation :: CommitFile ( src, commit_id) ) ;
240272 } else {
241273 let ( [ first] , rest) = parents. split_at ( 1 ) else {
242274 unreachable ! ( ) ;
243275 } ;
244276
245- self . script
246- . push_str ( format ! ( "git checkout tag-{}\n " , first. commit_id) . as_str ( ) ) ;
277+ self . script . push ( BlameScriptOperation :: CheckoutTag ( first. commit_id ) ) ;
247278
248279 if rest. is_empty ( ) {
249- self . script . push_str ( delete_previous_file_script. as_str ( ) ) ;
250- self . script . push_str ( script. as_str ( ) ) ;
280+ if let Some ( delete_previous_file_operation) = delete_previous_file_operation {
281+ self . script . push ( delete_previous_file_operation) ;
282+ }
283+ self . script . push ( BlameScriptOperation :: CommitFile ( src, commit_id) ) ;
251284 } else {
252- self . script . push_str (
253- format ! (
254- "git merge --no-commit {} || true\n " ,
255- rest. iter( )
256- . map( |blame_path_entry| format!( "tag-{}" , blame_path_entry. commit_id) )
257- . collect:: <Vec <_>>( )
258- . join( " " )
259- )
260- . as_str ( ) ,
261- ) ;
262-
263- self . script . push_str ( delete_previous_file_script. as_str ( ) ) ;
264- self . script . push_str ( script. as_str ( ) ) ;
285+ self . script . push ( BlameScriptOperation :: PrepareMerge (
286+ rest. iter ( ) . map ( |blame_path_entry| blame_path_entry. commit_id ) . collect ( ) ,
287+ ) ) ;
288+
289+ if let Some ( delete_previous_file_operation) = delete_previous_file_operation {
290+ self . script . push ( delete_previous_file_operation) ;
291+ }
292+ self . script . push ( BlameScriptOperation :: CommitFile ( src, commit_id) ) ;
265293 }
266294 }
267295
268- self . script . push_str ( format ! ( "git tag tag-{ commit_id} \n \n " ) . as_str ( ) ) ;
296+ self . script . push ( BlameScriptOperation :: CreateTag ( commit_id) ) ;
269297
270298 Ok ( ( ) )
271299 }
0 commit comments