@@ -2841,6 +2841,26 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
28412841 return ret ;
28422842}
28432843
2844+ static struct commit * lookup_label (const char * label , int len ,
2845+ struct strbuf * buf )
2846+ {
2847+ struct commit * commit ;
2848+
2849+ strbuf_reset (buf );
2850+ strbuf_addf (buf , "refs/rewritten/%.*s" , len , label );
2851+ commit = lookup_commit_reference_by_name (buf -> buf );
2852+ if (!commit ) {
2853+ /* fall back to non-rewritten ref or commit */
2854+ strbuf_splice (buf , 0 , strlen ("refs/rewritten/" ), "" , 0 );
2855+ commit = lookup_commit_reference_by_name (buf -> buf );
2856+ }
2857+
2858+ if (!commit )
2859+ error (_ ("could not resolve '%s'" ), buf -> buf );
2860+
2861+ return commit ;
2862+ }
2863+
28442864static int do_merge (struct commit * commit , const char * arg , int arg_len ,
28452865 int flags , struct replay_opts * opts )
28462866{
@@ -2849,8 +2869,9 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
28492869 struct strbuf ref_name = STRBUF_INIT ;
28502870 struct commit * head_commit , * merge_commit , * i ;
28512871 struct commit_list * bases , * j , * reversed = NULL ;
2872+ struct commit_list * to_merge = NULL , * * tail = & to_merge ;
28522873 struct merge_options o ;
2853- int merge_arg_len , oneline_offset , can_fast_forward , ret ;
2874+ int merge_arg_len , oneline_offset , can_fast_forward , ret , k ;
28542875 static struct lock_file lock ;
28552876 const char * p ;
28562877
@@ -2865,26 +2886,34 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
28652886 goto leave_merge ;
28662887 }
28672888
2868- oneline_offset = arg_len ;
2869- merge_arg_len = strcspn (arg , " \t\n" );
2870- p = arg + merge_arg_len ;
2871- p += strspn (p , " \t\n" );
2872- if (* p == '#' && (!p [1 ] || isspace (p [1 ]))) {
2873- p += 1 + strspn (p + 1 , " \t\n" );
2874- oneline_offset = p - arg ;
2875- } else if (p - arg < arg_len )
2876- BUG ("octopus merges are not supported yet: '%s'" , p );
2877-
2878- strbuf_addf (& ref_name , "refs/rewritten/%.*s" , merge_arg_len , arg );
2879- merge_commit = lookup_commit_reference_by_name (ref_name .buf );
2880- if (!merge_commit ) {
2881- /* fall back to non-rewritten ref or commit */
2882- strbuf_splice (& ref_name , 0 , strlen ("refs/rewritten/" ), "" , 0 );
2883- merge_commit = lookup_commit_reference_by_name (ref_name .buf );
2889+ /*
2890+ * For octopus merges, the arg starts with the list of revisions to be
2891+ * merged. The list is optionally followed by '#' and the oneline.
2892+ */
2893+ merge_arg_len = oneline_offset = arg_len ;
2894+ for (p = arg ; p - arg < arg_len ; p += strspn (p , " \t\n" )) {
2895+ if (!* p )
2896+ break ;
2897+ if (* p == '#' && (!p [1 ] || isspace (p [1 ]))) {
2898+ p += 1 + strspn (p + 1 , " \t\n" );
2899+ oneline_offset = p - arg ;
2900+ break ;
2901+ }
2902+ k = strcspn (p , " \t\n" );
2903+ if (!k )
2904+ continue ;
2905+ merge_commit = lookup_label (p , k , & ref_name );
2906+ if (!merge_commit ) {
2907+ ret = error (_ ("unable to parse '%.*s'" ), k , p );
2908+ goto leave_merge ;
2909+ }
2910+ tail = & commit_list_insert (merge_commit , tail )-> next ;
2911+ p += k ;
2912+ merge_arg_len = p - arg ;
28842913 }
28852914
2886- if (!merge_commit ) {
2887- ret = error (_ ("could not resolve '%s'" ), ref_name . buf );
2915+ if (!to_merge ) {
2916+ ret = error (_ ("nothing to merge: '%.* s'" ), arg_len , arg );
28882917 goto leave_merge ;
28892918 }
28902919
@@ -2895,8 +2924,13 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
28952924 * "[new root]", let's simply fast-forward to the merge head.
28962925 */
28972926 rollback_lock_file (& lock );
2898- ret = fast_forward_to (& merge_commit -> object .oid ,
2899- & head_commit -> object .oid , 0 , opts );
2927+ if (to_merge -> next )
2928+ ret = error (_ ("octopus merge cannot be executed on "
2929+ "top of a [new root]" ));
2930+ else
2931+ ret = fast_forward_to (& to_merge -> item -> object .oid ,
2932+ & head_commit -> object .oid , 0 ,
2933+ opts );
29002934 goto leave_merge ;
29012935 }
29022936
@@ -2932,7 +2966,8 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
29322966 p = arg + oneline_offset ;
29332967 len = arg_len - oneline_offset ;
29342968 } else {
2935- strbuf_addf (& buf , "Merge branch '%.*s'" ,
2969+ strbuf_addf (& buf , "Merge %s '%.*s'" ,
2970+ to_merge -> next ? "branches" : "branch" ,
29362971 merge_arg_len , arg );
29372972 p = buf .buf ;
29382973 len = buf .len ;
@@ -2956,28 +2991,76 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
29562991 & head_commit -> object .oid );
29572992
29582993 /*
2959- * If the merge head is different from the original one, we cannot
2994+ * If any merge head is different from the original one, we cannot
29602995 * fast-forward.
29612996 */
29622997 if (can_fast_forward ) {
2963- struct commit_list * second_parent = commit -> parents -> next ;
2998+ struct commit_list * p = commit -> parents -> next ;
29642999
2965- if (second_parent && !second_parent -> next &&
2966- oidcmp (& merge_commit -> object .oid ,
2967- & second_parent -> item -> object .oid ))
3000+ for (j = to_merge ; j && p ; j = j -> next , p = p -> next )
3001+ if (oidcmp (& j -> item -> object .oid ,
3002+ & p -> item -> object .oid )) {
3003+ can_fast_forward = 0 ;
3004+ break ;
3005+ }
3006+ /*
3007+ * If the number of merge heads differs from the original merge
3008+ * commit, we cannot fast-forward.
3009+ */
3010+ if (j || p )
29683011 can_fast_forward = 0 ;
29693012 }
29703013
2971- if (can_fast_forward && commit -> parents -> next &&
2972- !commit -> parents -> next -> next &&
2973- !oidcmp (& commit -> parents -> next -> item -> object .oid ,
2974- & merge_commit -> object .oid )) {
3014+ if (can_fast_forward ) {
29753015 rollback_lock_file (& lock );
29763016 ret = fast_forward_to (& commit -> object .oid ,
29773017 & head_commit -> object .oid , 0 , opts );
29783018 goto leave_merge ;
29793019 }
29803020
3021+ if (to_merge -> next ) {
3022+ /* Octopus merge */
3023+ struct child_process cmd = CHILD_PROCESS_INIT ;
3024+
3025+ if (read_env_script (& cmd .env_array )) {
3026+ const char * gpg_opt = gpg_sign_opt_quoted (opts );
3027+
3028+ ret = error (_ (staged_changes_advice ), gpg_opt , gpg_opt );
3029+ goto leave_merge ;
3030+ }
3031+
3032+ cmd .git_cmd = 1 ;
3033+ argv_array_push (& cmd .args , "merge" );
3034+ argv_array_push (& cmd .args , "-s" );
3035+ argv_array_push (& cmd .args , "octopus" );
3036+ argv_array_push (& cmd .args , "--no-edit" );
3037+ argv_array_push (& cmd .args , "--no-ff" );
3038+ argv_array_push (& cmd .args , "--no-log" );
3039+ argv_array_push (& cmd .args , "--no-stat" );
3040+ argv_array_push (& cmd .args , "-F" );
3041+ argv_array_push (& cmd .args , git_path_merge_msg ());
3042+ if (opts -> gpg_sign )
3043+ argv_array_push (& cmd .args , opts -> gpg_sign );
3044+
3045+ /* Add the tips to be merged */
3046+ for (j = to_merge ; j ; j = j -> next )
3047+ argv_array_push (& cmd .args ,
3048+ oid_to_hex (& j -> item -> object .oid ));
3049+
3050+ strbuf_release (& ref_name );
3051+ unlink (git_path_cherry_pick_head ());
3052+ rollback_lock_file (& lock );
3053+
3054+ rollback_lock_file (& lock );
3055+ ret = run_command (& cmd );
3056+
3057+ /* force re-reading of the cache */
3058+ if (!ret && (discard_cache () < 0 || read_cache () < 0 ))
3059+ ret = error (_ ("could not read index" ));
3060+ goto leave_merge ;
3061+ }
3062+
3063+ merge_commit = to_merge -> item ;
29813064 write_message (oid_to_hex (& merge_commit -> object .oid ), GIT_SHA1_HEXSZ ,
29823065 git_path_merge_head (), 0 );
29833066 write_message ("no-ff" , 5 , git_path_merge_mode (), 0 );
@@ -3040,6 +3123,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
30403123leave_merge :
30413124 strbuf_release (& ref_name );
30423125 rollback_lock_file (& lock );
3126+ free_commit_list (to_merge );
30433127 return ret ;
30443128}
30453129
@@ -3877,7 +3961,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
38773961 */
38783962 while ((commit = get_revision (revs ))) {
38793963 struct commit_list * to_merge ;
3880- int is_octopus ;
38813964 const char * p1 , * p2 ;
38823965 struct object_id * oid ;
38833966 int is_empty ;
@@ -3909,11 +3992,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
39093992 continue ;
39103993 }
39113994
3912- is_octopus = to_merge && to_merge -> next ;
3913-
3914- if (is_octopus )
3915- BUG ("Octopus merges not yet supported" );
3916-
39173995 /* Create a label */
39183996 strbuf_reset (& label );
39193997 if (skip_prefix (oneline .buf , "Merge " , & p1 ) &&
@@ -3935,13 +4013,17 @@ static int make_script_with_merges(struct pretty_print_context *pp,
39354013 strbuf_addf (& buf , "%s -C %s" ,
39364014 cmd_merge , oid_to_hex (& commit -> object .oid ));
39374015
3938- /* label the tip of merged branch */
3939- oid = & to_merge -> item -> object .oid ;
3940- strbuf_addch (& buf , ' ' );
4016+ /* label the tips of merged branches */
4017+ for (; to_merge ; to_merge = to_merge -> next ) {
4018+ oid = & to_merge -> item -> object .oid ;
4019+ strbuf_addch (& buf , ' ' );
4020+
4021+ if (!oidset_contains (& interesting , oid )) {
4022+ strbuf_addstr (& buf , label_oid (oid , NULL ,
4023+ & state ));
4024+ continue ;
4025+ }
39414026
3942- if (!oidset_contains (& interesting , oid ))
3943- strbuf_addstr (& buf , label_oid (oid , NULL , & state ));
3944- else {
39454027 tips_tail = & commit_list_insert (to_merge -> item ,
39464028 tips_tail )-> next ;
39474029
0 commit comments