@@ -114,16 +114,21 @@ static int check_stage(int stage, struct cache_entry *ce, int pos)
114114 return error (_ ("path '%s' does not have their version" ), ce -> name );
115115}
116116
117- static int check_all_stages ( struct cache_entry * ce , int pos )
117+ static int check_stages ( unsigned stages , struct cache_entry * ce , int pos )
118118{
119- if (ce_stage (ce ) != 1 ||
120- active_nr <= pos + 2 ||
121- strcmp (active_cache [pos + 1 ]-> name , ce -> name ) ||
122- ce_stage (active_cache [pos + 1 ]) != 2 ||
123- strcmp (active_cache [pos + 2 ]-> name , ce -> name ) ||
124- ce_stage (active_cache [pos + 2 ]) != 3 )
125- return error (_ ("path '%s' does not have all three versions" ),
126- ce -> name );
119+ unsigned seen = 0 ;
120+ const char * name = ce -> name ;
121+
122+ while (pos < active_nr ) {
123+ ce = active_cache [pos ];
124+ if (strcmp (name , ce -> name ))
125+ break ;
126+ seen |= (1 << ce_stage (ce ));
127+ pos ++ ;
128+ }
129+ if ((stages & seen ) != stages )
130+ return error (_ ("path '%s' does not have all necessary versions" ),
131+ name );
127132 return 0 ;
128133}
129134
@@ -150,18 +155,27 @@ static int checkout_merged(int pos, struct checkout *state)
150155 int status ;
151156 unsigned char sha1 [20 ];
152157 mmbuffer_t result_buf ;
158+ unsigned char threeway [3 ][20 ];
159+ unsigned mode = 0 ;
160+
161+ memset (threeway , 0 , sizeof (threeway ));
162+ while (pos < active_nr ) {
163+ int stage ;
164+ stage = ce_stage (ce );
165+ if (!stage || strcmp (path , ce -> name ))
166+ break ;
167+ hashcpy (threeway [stage - 1 ], ce -> sha1 );
168+ if (stage == 2 )
169+ mode = create_ce_mode (ce -> ce_mode );
170+ pos ++ ;
171+ ce = active_cache [pos ];
172+ }
173+ if (is_null_sha1 (threeway [1 ]) || is_null_sha1 (threeway [2 ]))
174+ return error (_ ("path '%s' does not have necessary versions" ), path );
153175
154- if (ce_stage (ce ) != 1 ||
155- active_nr <= pos + 2 ||
156- strcmp (active_cache [pos + 1 ]-> name , path ) ||
157- ce_stage (active_cache [pos + 1 ]) != 2 ||
158- strcmp (active_cache [pos + 2 ]-> name , path ) ||
159- ce_stage (active_cache [pos + 2 ]) != 3 )
160- return error (_ ("path '%s' does not have all 3 versions" ), path );
161-
162- read_mmblob (& ancestor , active_cache [pos ]-> sha1 );
163- read_mmblob (& ours , active_cache [pos + 1 ]-> sha1 );
164- read_mmblob (& theirs , active_cache [pos + 2 ]-> sha1 );
176+ read_mmblob (& ancestor , threeway [0 ]);
177+ read_mmblob (& ours , threeway [1 ]);
178+ read_mmblob (& theirs , threeway [2 ]);
165179
166180 /*
167181 * NEEDSWORK: re-create conflicts from merges with
@@ -192,9 +206,7 @@ static int checkout_merged(int pos, struct checkout *state)
192206 if (write_sha1_file (result_buf .ptr , result_buf .size ,
193207 blob_type , sha1 ))
194208 die (_ ("Unable to add merge result for '%s'" ), path );
195- ce = make_cache_entry (create_ce_mode (active_cache [pos + 1 ]-> ce_mode ),
196- sha1 ,
197- path , 2 , 0 );
209+ ce = make_cache_entry (mode , sha1 , path , 2 , 0 );
198210 if (!ce )
199211 die (_ ("make_cache_entry failed for path '%s'" ), path );
200212 status = checkout_entry (ce , state , NULL );
@@ -252,7 +264,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
252264 } else if (stage ) {
253265 errs |= check_stage (stage , ce , pos );
254266 } else if (opts -> merge ) {
255- errs |= check_all_stages ( ce , pos );
267+ errs |= check_stages (( 1 << 2 ) | ( 1 << 3 ), ce , pos );
256268 } else {
257269 errs = 1 ;
258270 error (_ ("path '%s' is unmerged" ), ce -> name );
0 commit comments