@@ -43,6 +43,7 @@ static const char *commit_name;
43
43
static int allow_rerere_auto ;
44
44
45
45
static const char * me ;
46
+ static const char * strategy ;
46
47
47
48
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
48
49
@@ -62,6 +63,7 @@ static void parse_args(int argc, const char **argv)
62
63
OPT_BOOLEAN ('s' , "signoff" , & signoff , "add Signed-off-by:" ),
63
64
OPT_INTEGER ('m' , "mainline" , & mainline , "parent number" ),
64
65
OPT_RERERE_AUTOUPDATE (& allow_rerere_auto ),
66
+ OPT_STRING (0 , "strategy" , & strategy , "strategy" , "merge strategy" ),
65
67
OPT_END (),
66
68
OPT_END (),
67
69
OPT_END (),
@@ -174,28 +176,17 @@ static char *get_encoding(const char *message)
174
176
return NULL ;
175
177
}
176
178
177
- static struct lock_file msg_file ;
178
- static int msg_fd ;
179
-
180
- static void add_to_msg (const char * string )
181
- {
182
- int len = strlen (string );
183
- if (write_in_full (msg_fd , string , len ) < 0 )
184
- die_errno ("Could not write to MERGE_MSG" );
185
- }
186
-
187
- static void add_message_to_msg (const char * message )
179
+ static void add_message_to_msg (struct strbuf * msgbuf , const char * message )
188
180
{
189
181
const char * p = message ;
190
182
while (* p && (* p != '\n' || p [1 ] != '\n' ))
191
183
p ++ ;
192
184
193
185
if (!* p )
194
- add_to_msg ( sha1_to_hex (commit -> object .sha1 ));
186
+ strbuf_addstr ( msgbuf , sha1_to_hex (commit -> object .sha1 ));
195
187
196
188
p += 2 ;
197
- add_to_msg (p );
198
- return ;
189
+ strbuf_addstr (msgbuf , p );
199
190
}
200
191
201
192
static void set_author_ident_env (const char * message )
@@ -271,6 +262,19 @@ static char *help_msg(const char *name)
271
262
return strbuf_detach (& helpbuf , NULL );
272
263
}
273
264
265
+ static void write_message (struct strbuf * msgbuf , const char * filename )
266
+ {
267
+ static struct lock_file msg_file ;
268
+
269
+ int msg_fd = hold_lock_file_for_update (& msg_file , filename ,
270
+ LOCK_DIE_ON_ERROR );
271
+ if (write_in_full (msg_fd , msgbuf -> buf , msgbuf -> len ) < 0 )
272
+ die_errno ("Could not write to %s." , filename );
273
+ strbuf_release (msgbuf );
274
+ if (commit_lock_file (& msg_file ) < 0 )
275
+ die ("Error wrapping up %s" , filename );
276
+ }
277
+
274
278
static struct tree * empty_tree (void )
275
279
{
276
280
struct tree * tree = xcalloc (1 , sizeof (struct tree ));
@@ -305,17 +309,70 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from)
305
309
return write_ref_sha1 (ref_lock , to , "cherry-pick" );
306
310
}
307
311
312
+ static void do_recursive_merge (struct commit * base , struct commit * next ,
313
+ const char * base_label , const char * next_label ,
314
+ unsigned char * head , struct strbuf * msgbuf ,
315
+ char * defmsg )
316
+ {
317
+ struct merge_options o ;
318
+ struct tree * result , * next_tree , * base_tree , * head_tree ;
319
+ int clean , index_fd ;
320
+ static struct lock_file index_lock ;
321
+
322
+ index_fd = hold_locked_index (& index_lock , 1 );
323
+
324
+ read_cache ();
325
+ init_merge_options (& o );
326
+ o .ancestor = base ? base_label : "(empty tree)" ;
327
+ o .branch1 = "HEAD" ;
328
+ o .branch2 = next ? next_label : "(empty tree)" ;
329
+
330
+ head_tree = parse_tree_indirect (head );
331
+ next_tree = next ? next -> tree : empty_tree ();
332
+ base_tree = base ? base -> tree : empty_tree ();
333
+
334
+ clean = merge_trees (& o ,
335
+ head_tree ,
336
+ next_tree , base_tree , & result );
337
+
338
+ if (active_cache_changed &&
339
+ (write_cache (index_fd , active_cache , active_nr ) ||
340
+ commit_locked_index (& index_lock )))
341
+ die ("%s: Unable to write new index file" , me );
342
+ rollback_lock_file (& index_lock );
343
+
344
+ if (!clean ) {
345
+ int i ;
346
+ strbuf_addstr (msgbuf , "\nConflicts:\n\n" );
347
+ for (i = 0 ; i < active_nr ;) {
348
+ struct cache_entry * ce = active_cache [i ++ ];
349
+ if (ce_stage (ce )) {
350
+ strbuf_addch (msgbuf , '\t' );
351
+ strbuf_addstr (msgbuf , ce -> name );
352
+ strbuf_addch (msgbuf , '\n' );
353
+ while (i < active_nr && !strcmp (ce -> name ,
354
+ active_cache [i ]-> name ))
355
+ i ++ ;
356
+ }
357
+ }
358
+ write_message (msgbuf , defmsg );
359
+ fprintf (stderr , "Automatic %s failed.%s\n" ,
360
+ me , help_msg (commit_name ));
361
+ rerere (allow_rerere_auto );
362
+ exit (1 );
363
+ }
364
+ write_message (msgbuf , defmsg );
365
+ fprintf (stderr , "Finished one %s.\n" , me );
366
+ }
367
+
308
368
static int revert_or_cherry_pick (int argc , const char * * argv )
309
369
{
310
370
unsigned char head [20 ];
311
371
struct commit * base , * next , * parent ;
312
372
const char * base_label , * next_label ;
313
- int i , index_fd , clean ;
314
373
struct commit_message msg = { NULL , NULL , NULL , NULL , NULL };
315
374
char * defmsg = NULL ;
316
- struct merge_options o ;
317
- struct tree * result , * next_tree , * base_tree , * head_tree ;
318
- static struct lock_file index_lock ;
375
+ struct strbuf msgbuf = STRBUF_INIT ;
319
376
320
377
git_config (git_default_config , NULL );
321
378
me = action == REVERT ? "revert" : "cherry-pick" ;
@@ -403,83 +460,57 @@ static int revert_or_cherry_pick(int argc, const char **argv)
403
460
*/
404
461
405
462
defmsg = git_pathdup ("MERGE_MSG" );
406
- msg_fd = hold_lock_file_for_update (& msg_file , defmsg ,
407
- LOCK_DIE_ON_ERROR );
408
-
409
- index_fd = hold_locked_index (& index_lock , 1 );
410
463
411
464
if (action == REVERT ) {
412
465
base = commit ;
413
466
base_label = msg .label ;
414
467
next = parent ;
415
468
next_label = msg .parent_label ;
416
- add_to_msg ( "Revert \"" );
417
- add_to_msg ( msg .subject );
418
- add_to_msg ( "\"\n\nThis reverts commit " );
419
- add_to_msg ( sha1_to_hex (commit -> object .sha1 ));
469
+ strbuf_addstr ( & msgbuf , "Revert \"" );
470
+ strbuf_addstr ( & msgbuf , msg .subject );
471
+ strbuf_addstr ( & msgbuf , "\"\n\nThis reverts commit " );
472
+ strbuf_addstr ( & msgbuf , sha1_to_hex (commit -> object .sha1 ));
420
473
421
474
if (commit -> parents -> next ) {
422
- add_to_msg ( ", reversing\nchanges made to " );
423
- add_to_msg ( sha1_to_hex (parent -> object .sha1 ));
475
+ strbuf_addstr ( & msgbuf , ", reversing\nchanges made to " );
476
+ strbuf_addstr ( & msgbuf , sha1_to_hex (parent -> object .sha1 ));
424
477
}
425
- add_to_msg ( ".\n" );
478
+ strbuf_addstr ( & msgbuf , ".\n" );
426
479
} else {
427
480
base = parent ;
428
481
base_label = msg .parent_label ;
429
482
next = commit ;
430
483
next_label = msg .label ;
431
484
set_author_ident_env (msg .message );
432
- add_message_to_msg (msg .message );
485
+ add_message_to_msg (& msgbuf , msg .message );
433
486
if (no_replay ) {
434
- add_to_msg ( "(cherry picked from commit " );
435
- add_to_msg ( sha1_to_hex (commit -> object .sha1 ));
436
- add_to_msg ( ")\n" );
487
+ strbuf_addstr ( & msgbuf , "(cherry picked from commit " );
488
+ strbuf_addstr ( & msgbuf , sha1_to_hex (commit -> object .sha1 ));
489
+ strbuf_addstr ( & msgbuf , ")\n" );
437
490
}
438
491
}
439
492
440
- read_cache ();
441
- init_merge_options (& o );
442
- o .ancestor = base ? base_label : "(empty tree)" ;
443
- o .branch1 = "HEAD" ;
444
- o .branch2 = next ? next_label : "(empty tree)" ;
445
-
446
- head_tree = parse_tree_indirect (head );
447
- next_tree = next ? next -> tree : empty_tree ();
448
- base_tree = base ? base -> tree : empty_tree ();
449
-
450
- clean = merge_trees (& o ,
451
- head_tree ,
452
- next_tree , base_tree , & result );
453
-
454
- if (active_cache_changed &&
455
- (write_cache (index_fd , active_cache , active_nr ) ||
456
- commit_locked_index (& index_lock )))
457
- die ("%s: Unable to write new index file" , me );
458
- rollback_lock_file (& index_lock );
459
-
460
- if (!clean ) {
461
- add_to_msg ("\nConflicts:\n\n" );
462
- for (i = 0 ; i < active_nr ;) {
463
- struct cache_entry * ce = active_cache [i ++ ];
464
- if (ce_stage (ce )) {
465
- add_to_msg ("\t" );
466
- add_to_msg (ce -> name );
467
- add_to_msg ("\n" );
468
- while (i < active_nr && !strcmp (ce -> name ,
469
- active_cache [i ]-> name ))
470
- i ++ ;
471
- }
493
+ if (!strategy || !strcmp (strategy , "recursive" ) || action == REVERT )
494
+ do_recursive_merge (base , next , base_label , next_label ,
495
+ head , & msgbuf , defmsg );
496
+ else {
497
+ int res ;
498
+ struct commit_list * common = NULL ;
499
+ struct commit_list * remotes = NULL ;
500
+ write_message (& msgbuf , defmsg );
501
+ commit_list_insert (base , & common );
502
+ commit_list_insert (next , & remotes );
503
+ res = try_merge_command (strategy , common ,
504
+ sha1_to_hex (head ), remotes );
505
+ free_commit_list (common );
506
+ free_commit_list (remotes );
507
+ if (res ) {
508
+ fprintf (stderr , "Automatic %s with strategy %s failed.%s\n" ,
509
+ me , strategy , help_msg (commit_name ));
510
+ rerere (allow_rerere_auto );
511
+ exit (1 );
472
512
}
473
- if (commit_lock_file (& msg_file ) < 0 )
474
- die ("Error wrapping up %s" , defmsg );
475
- fprintf (stderr , "Automatic %s failed.%s\n" ,
476
- me , help_msg (commit_name ));
477
- rerere (allow_rerere_auto );
478
- exit (1 );
479
513
}
480
- if (commit_lock_file (& msg_file ) < 0 )
481
- die ("Error wrapping up %s" , defmsg );
482
- fprintf (stderr , "Finished one %s.\n" , me );
483
514
484
515
/*
485
516
*
0 commit comments