@@ -2850,6 +2850,26 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
28502850 return ret ;
28512851}
28522852
2853+ static struct commit * lookup_label (const char * label , int len ,
2854+ struct strbuf * buf )
2855+ {
2856+ struct commit * commit ;
2857+
2858+ strbuf_reset (buf );
2859+ strbuf_addf (buf , "refs/rewritten/%.*s" , len , label );
2860+ commit = lookup_commit_reference_by_name (buf -> buf );
2861+ if (!commit ) {
2862+ /* fall back to non-rewritten ref or commit */
2863+ strbuf_splice (buf , 0 , strlen ("refs/rewritten/" ), "" , 0 );
2864+ commit = lookup_commit_reference_by_name (buf -> buf );
2865+ }
2866+
2867+ if (!commit )
2868+ error (_ ("could not resolve '%s'" ), buf -> buf );
2869+
2870+ return commit ;
2871+ }
2872+
28532873static int do_merge (struct commit * commit , const char * arg , int arg_len ,
28542874 int flags , struct replay_opts * opts )
28552875{
@@ -2858,8 +2878,9 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
28582878 struct strbuf ref_name = STRBUF_INIT ;
28592879 struct commit * head_commit , * merge_commit , * i ;
28602880 struct commit_list * bases , * j , * reversed = NULL ;
2881+ struct commit_list * to_merge = NULL , * * tail = & to_merge ;
28612882 struct merge_options o ;
2862- int merge_arg_len , oneline_offset , can_fast_forward , ret ;
2883+ int merge_arg_len , oneline_offset , can_fast_forward , ret , k ;
28632884 static struct lock_file lock ;
28642885 const char * p ;
28652886
@@ -2874,26 +2895,34 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
28742895 goto leave_merge ;
28752896 }
28762897
2877- oneline_offset = arg_len ;
2878- merge_arg_len = strcspn (arg , " \t\n" );
2879- p = arg + merge_arg_len ;
2880- p += strspn (p , " \t\n" );
2881- if (* p == '#' && (!p [1 ] || isspace (p [1 ]))) {
2882- p += 1 + strspn (p + 1 , " \t\n" );
2883- oneline_offset = p - arg ;
2884- } else if (p - arg < arg_len )
2885- BUG ("octopus merges are not supported yet: '%s'" , p );
2886-
2887- strbuf_addf (& ref_name , "refs/rewritten/%.*s" , merge_arg_len , arg );
2888- merge_commit = lookup_commit_reference_by_name (ref_name .buf );
2889- if (!merge_commit ) {
2890- /* fall back to non-rewritten ref or commit */
2891- strbuf_splice (& ref_name , 0 , strlen ("refs/rewritten/" ), "" , 0 );
2892- merge_commit = lookup_commit_reference_by_name (ref_name .buf );
2898+ /*
2899+ * For octopus merges, the arg starts with the list of revisions to be
2900+ * merged. The list is optionally followed by '#' and the oneline.
2901+ */
2902+ merge_arg_len = oneline_offset = arg_len ;
2903+ for (p = arg ; p - arg < arg_len ; p += strspn (p , " \t\n" )) {
2904+ if (!* p )
2905+ break ;
2906+ if (* p == '#' && (!p [1 ] || isspace (p [1 ]))) {
2907+ p += 1 + strspn (p + 1 , " \t\n" );
2908+ oneline_offset = p - arg ;
2909+ break ;
2910+ }
2911+ k = strcspn (p , " \t\n" );
2912+ if (!k )
2913+ continue ;
2914+ merge_commit = lookup_label (p , k , & ref_name );
2915+ if (!merge_commit ) {
2916+ ret = error (_ ("unable to parse '%.*s'" ), k , p );
2917+ goto leave_merge ;
2918+ }
2919+ tail = & commit_list_insert (merge_commit , tail )-> next ;
2920+ p += k ;
2921+ merge_arg_len = p - arg ;
28932922 }
28942923
2895- if (!merge_commit ) {
2896- ret = error (_ ("could not resolve '%s'" ), ref_name . buf );
2924+ if (!to_merge ) {
2925+ ret = error (_ ("nothing to merge: '%.* s'" ), arg_len , arg );
28972926 goto leave_merge ;
28982927 }
28992928
@@ -2904,8 +2933,13 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
29042933 * "[new root]", let's simply fast-forward to the merge head.
29052934 */
29062935 rollback_lock_file (& lock );
2907- ret = fast_forward_to (& merge_commit -> object .oid ,
2908- & head_commit -> object .oid , 0 , opts );
2936+ if (to_merge -> next )
2937+ ret = error (_ ("octopus merge cannot be executed on "
2938+ "top of a [new root]" ));
2939+ else
2940+ ret = fast_forward_to (& to_merge -> item -> object .oid ,
2941+ & head_commit -> object .oid , 0 ,
2942+ opts );
29092943 goto leave_merge ;
29102944 }
29112945
@@ -2941,7 +2975,8 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
29412975 p = arg + oneline_offset ;
29422976 len = arg_len - oneline_offset ;
29432977 } else {
2944- strbuf_addf (& buf , "Merge branch '%.*s'" ,
2978+ strbuf_addf (& buf , "Merge %s '%.*s'" ,
2979+ to_merge -> next ? "branches" : "branch" ,
29452980 merge_arg_len , arg );
29462981 p = buf .buf ;
29472982 len = buf .len ;
@@ -2965,28 +3000,76 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
29653000 & head_commit -> object .oid );
29663001
29673002 /*
2968- * If the merge head is different from the original one, we cannot
3003+ * If any merge head is different from the original one, we cannot
29693004 * fast-forward.
29703005 */
29713006 if (can_fast_forward ) {
2972- struct commit_list * second_parent = commit -> parents -> next ;
3007+ struct commit_list * p = commit -> parents -> next ;
29733008
2974- if (second_parent && !second_parent -> next &&
2975- oidcmp (& merge_commit -> object .oid ,
2976- & second_parent -> item -> object .oid ))
3009+ for (j = to_merge ; j && p ; j = j -> next , p = p -> next )
3010+ if (oidcmp (& j -> item -> object .oid ,
3011+ & p -> item -> object .oid )) {
3012+ can_fast_forward = 0 ;
3013+ break ;
3014+ }
3015+ /*
3016+ * If the number of merge heads differs from the original merge
3017+ * commit, we cannot fast-forward.
3018+ */
3019+ if (j || p )
29773020 can_fast_forward = 0 ;
29783021 }
29793022
2980- if (can_fast_forward && commit -> parents -> next &&
2981- !commit -> parents -> next -> next &&
2982- !oidcmp (& commit -> parents -> next -> item -> object .oid ,
2983- & merge_commit -> object .oid )) {
3023+ if (can_fast_forward ) {
29843024 rollback_lock_file (& lock );
29853025 ret = fast_forward_to (& commit -> object .oid ,
29863026 & head_commit -> object .oid , 0 , opts );
29873027 goto leave_merge ;
29883028 }
29893029
3030+ if (to_merge -> next ) {
3031+ /* Octopus merge */
3032+ struct child_process cmd = CHILD_PROCESS_INIT ;
3033+
3034+ if (read_env_script (& cmd .env_array )) {
3035+ const char * gpg_opt = gpg_sign_opt_quoted (opts );
3036+
3037+ ret = error (_ (staged_changes_advice ), gpg_opt , gpg_opt );
3038+ goto leave_merge ;
3039+ }
3040+
3041+ cmd .git_cmd = 1 ;
3042+ argv_array_push (& cmd .args , "merge" );
3043+ argv_array_push (& cmd .args , "-s" );
3044+ argv_array_push (& cmd .args , "octopus" );
3045+ argv_array_push (& cmd .args , "--no-edit" );
3046+ argv_array_push (& cmd .args , "--no-ff" );
3047+ argv_array_push (& cmd .args , "--no-log" );
3048+ argv_array_push (& cmd .args , "--no-stat" );
3049+ argv_array_push (& cmd .args , "-F" );
3050+ argv_array_push (& cmd .args , git_path_merge_msg (the_repository ));
3051+ if (opts -> gpg_sign )
3052+ argv_array_push (& cmd .args , opts -> gpg_sign );
3053+
3054+ /* Add the tips to be merged */
3055+ for (j = to_merge ; j ; j = j -> next )
3056+ argv_array_push (& cmd .args ,
3057+ oid_to_hex (& j -> item -> object .oid ));
3058+
3059+ strbuf_release (& ref_name );
3060+ unlink (git_path_cherry_pick_head (the_repository ));
3061+ rollback_lock_file (& lock );
3062+
3063+ rollback_lock_file (& lock );
3064+ ret = run_command (& cmd );
3065+
3066+ /* force re-reading of the cache */
3067+ if (!ret && (discard_cache () < 0 || read_cache () < 0 ))
3068+ ret = error (_ ("could not read index" ));
3069+ goto leave_merge ;
3070+ }
3071+
3072+ merge_commit = to_merge -> item ;
29903073 write_message (oid_to_hex (& merge_commit -> object .oid ), GIT_SHA1_HEXSZ ,
29913074 git_path_merge_head (the_repository ), 0 );
29923075 write_message ("no-ff" , 5 , git_path_merge_mode (the_repository ), 0 );
@@ -3049,6 +3132,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
30493132leave_merge :
30503133 strbuf_release (& ref_name );
30513134 rollback_lock_file (& lock );
3135+ free_commit_list (to_merge );
30523136 return ret ;
30533137}
30543138
@@ -3905,7 +3989,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
39053989 */
39063990 while ((commit = get_revision (revs ))) {
39073991 struct commit_list * to_merge ;
3908- int is_octopus ;
39093992 const char * p1 , * p2 ;
39103993 struct object_id * oid ;
39113994 int is_empty ;
@@ -3937,11 +4020,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
39374020 continue ;
39384021 }
39394022
3940- is_octopus = to_merge && to_merge -> next ;
3941-
3942- if (is_octopus )
3943- BUG ("Octopus merges not yet supported" );
3944-
39454023 /* Create a label */
39464024 strbuf_reset (& label );
39474025 if (skip_prefix (oneline .buf , "Merge " , & p1 ) &&
@@ -3963,13 +4041,17 @@ static int make_script_with_merges(struct pretty_print_context *pp,
39634041 strbuf_addf (& buf , "%s -C %s" ,
39644042 cmd_merge , oid_to_hex (& commit -> object .oid ));
39654043
3966- /* label the tip of merged branch */
3967- oid = & to_merge -> item -> object .oid ;
3968- strbuf_addch (& buf , ' ' );
4044+ /* label the tips of merged branches */
4045+ for (; to_merge ; to_merge = to_merge -> next ) {
4046+ oid = & to_merge -> item -> object .oid ;
4047+ strbuf_addch (& buf , ' ' );
4048+
4049+ if (!oidset_contains (& interesting , oid )) {
4050+ strbuf_addstr (& buf , label_oid (oid , NULL ,
4051+ & state ));
4052+ continue ;
4053+ }
39694054
3970- if (!oidset_contains (& interesting , oid ))
3971- strbuf_addstr (& buf , label_oid (oid , NULL , & state ));
3972- else {
39734055 tips_tail = & commit_list_insert (to_merge -> item ,
39744056 tips_tail )-> next ;
39754057
0 commit comments