@@ -223,20 +223,33 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
223
223
strset_clear (& rinfo .positive_refs );
224
224
}
225
225
226
+ static struct commit * mapped_commit (kh_oid_map_t * replayed_commits ,
227
+ struct commit * commit ,
228
+ struct commit * fallback )
229
+ {
230
+ khint_t pos = kh_get_oid_map (replayed_commits , commit -> object .oid );
231
+ if (pos == kh_end (replayed_commits ))
232
+ return fallback ;
233
+ return kh_value (replayed_commits , pos );
234
+ }
235
+
226
236
static struct commit * pick_regular_commit (struct commit * pickme ,
227
- struct commit * last_commit ,
237
+ kh_oid_map_t * replayed_commits ,
238
+ struct commit * onto ,
228
239
struct merge_options * merge_opt ,
229
240
struct merge_result * result )
230
241
{
231
- struct commit * base ;
242
+ struct commit * base , * replayed_base ;
232
243
struct tree * pickme_tree , * base_tree ;
233
244
234
245
base = pickme -> parents -> item ;
246
+ replayed_base = mapped_commit (replayed_commits , base , onto );
235
247
248
+ result -> tree = repo_get_commit_tree (the_repository , replayed_base );
236
249
pickme_tree = repo_get_commit_tree (the_repository , pickme );
237
250
base_tree = repo_get_commit_tree (the_repository , base );
238
251
239
- merge_opt -> branch1 = short_commit_name (last_commit );
252
+ merge_opt -> branch1 = short_commit_name (replayed_base );
240
253
merge_opt -> branch2 = short_commit_name (pickme );
241
254
merge_opt -> ancestor = xstrfmt ("parent of %s" , merge_opt -> branch2 );
242
255
@@ -250,7 +263,7 @@ static struct commit *pick_regular_commit(struct commit *pickme,
250
263
merge_opt -> ancestor = NULL ;
251
264
if (!result -> clean )
252
265
return NULL ;
253
- return create_commit (result -> tree , pickme , last_commit );
266
+ return create_commit (result -> tree , pickme , replayed_base );
254
267
}
255
268
256
269
int cmd_replay (int argc , const char * * argv , const char * prefix )
@@ -266,6 +279,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
266
279
struct merge_options merge_opt ;
267
280
struct merge_result result ;
268
281
struct strset * update_refs = NULL ;
282
+ kh_oid_map_t * replayed_commits ;
269
283
int ret = 0 ;
270
284
271
285
const char * const replay_usage [] = {
@@ -363,21 +377,30 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
363
377
init_merge_options (& merge_opt , the_repository );
364
378
memset (& result , 0 , sizeof (result ));
365
379
merge_opt .show_rename_progress = 0 ;
366
-
367
- result .tree = repo_get_commit_tree (the_repository , onto );
368
380
last_commit = onto ;
381
+ replayed_commits = kh_init_oid_map ();
369
382
while ((commit = get_revision (& revs ))) {
370
383
const struct name_decoration * decoration ;
384
+ khint_t pos ;
385
+ int hr ;
371
386
372
387
if (!commit -> parents )
373
388
die (_ ("replaying down to root commit is not supported yet!" ));
374
389
if (commit -> parents -> next )
375
390
die (_ ("replaying merge commits is not supported yet!" ));
376
391
377
- last_commit = pick_regular_commit (commit , last_commit , & merge_opt , & result );
392
+ last_commit = pick_regular_commit (commit , replayed_commits , onto ,
393
+ & merge_opt , & result );
378
394
if (!last_commit )
379
395
break ;
380
396
397
+ /* Record commit -> last_commit mapping */
398
+ pos = kh_put_oid_map (replayed_commits , commit -> object .oid , & hr );
399
+ if (hr == 0 )
400
+ BUG ("Duplicate rewritten commit: %s\n" ,
401
+ oid_to_hex (& commit -> object .oid ));
402
+ kh_value (replayed_commits , pos ) = last_commit ;
403
+
381
404
/* Update any necessary branches */
382
405
if (advance_name )
383
406
continue ;
@@ -406,13 +429,14 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
406
429
}
407
430
408
431
merge_finalize (& merge_opt , & result );
409
- ret = result .clean ;
410
-
411
- cleanup :
432
+ kh_destroy_oid_map (replayed_commits );
412
433
if (update_refs ) {
413
434
strset_clear (update_refs );
414
435
free (update_refs );
415
436
}
437
+ ret = result .clean ;
438
+
439
+ cleanup :
416
440
release_revisions (& revs );
417
441
418
442
/* Return */
0 commit comments