@@ -6,7 +6,7 @@ pub(super) mod function {
6
6
use anyhow:: Context ;
7
7
use gix:: {
8
8
blame:: BlamePathEntry ,
9
- bstr:: { BStr , ByteSlice } ,
9
+ bstr:: { BStr , BString , ByteSlice } ,
10
10
objs:: FindExt ,
11
11
ObjectId ,
12
12
} ;
@@ -130,25 +130,31 @@ pub(super) mod function {
130
130
) ;
131
131
132
132
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 ( "" ) ) ?;
134
140
}
135
141
136
142
Ok ( ( ) )
137
143
}
138
144
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 ) ,
144
152
}
145
153
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
152
158
153
159
set -e
154
160
@@ -157,8 +163,46 @@ echo .gitignore >> .gitignore
157
163
echo assets/ >> .gitignore
158
164
echo create-history.sh >> .gitignore
159
165
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 ] ;
162
206
163
207
Self {
164
208
blame_path,
@@ -202,7 +246,7 @@ echo create-history.sh >> .gitignore
202
246
} ;
203
247
let commit_id = blame_path_entry. commit_id ;
204
248
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 {
206
250
Some ( previous_source_file_path) if source_file_path != * previous_source_file_path => {
207
251
let src = if self . options . verbatim {
208
252
previous_source_file_path. to_string ( )
@@ -215,57 +259,41 @@ echo create-history.sh >> .gitignore
215
259
crate :: commands:: copy_royal:: remapped ( source_file_path)
216
260
} ;
217
261
218
- format ! (
219
- r"# delete previous version of file
220
- git rm {src}
221
- "
222
- )
262
+ Some ( BlameScriptOperation :: RemoveFile ( src) )
223
263
}
224
- _ => String :: new ( ) ,
264
+ _ => None ,
225
265
} ;
226
266
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
-
237
267
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) ) ;
240
272
} else {
241
273
let ( [ first] , rest) = parents. split_at ( 1 ) else {
242
274
unreachable ! ( ) ;
243
275
} ;
244
276
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 ) ) ;
247
278
248
279
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) ) ;
251
284
} 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) ) ;
265
293
}
266
294
}
267
295
268
- self . script . push_str ( format ! ( "git tag tag-{ commit_id} \n \n " ) . as_str ( ) ) ;
296
+ self . script . push ( BlameScriptOperation :: CreateTag ( commit_id) ) ;
269
297
270
298
Ok ( ( ) )
271
299
}
0 commit comments