@@ -115,16 +115,21 @@ static int check_stage(int stage, struct cache_entry *ce, int pos)
115115 return error (_ ("path '%s' does not have their version" ), ce -> name );
116116}
117117
118- static int check_all_stages ( struct cache_entry * ce , int pos )
118+ static int check_stages ( unsigned stages , struct cache_entry * ce , int pos )
119119{
120- if (ce_stage (ce ) != 1 ||
121- active_nr <= pos + 2 ||
122- strcmp (active_cache [pos + 1 ]-> name , ce -> name ) ||
123- ce_stage (active_cache [pos + 1 ]) != 2 ||
124- strcmp (active_cache [pos + 2 ]-> name , ce -> name ) ||
125- ce_stage (active_cache [pos + 2 ]) != 3 )
126- return error (_ ("path '%s' does not have all three versions" ),
127- ce -> name );
120+ unsigned seen = 0 ;
121+ const char * name = ce -> name ;
122+
123+ while (pos < active_nr ) {
124+ ce = active_cache [pos ];
125+ if (strcmp (name , ce -> name ))
126+ break ;
127+ seen |= (1 << ce_stage (ce ));
128+ pos ++ ;
129+ }
130+ if ((stages & seen ) != stages )
131+ return error (_ ("path '%s' does not have all necessary versions" ),
132+ name );
128133 return 0 ;
129134}
130135
@@ -151,18 +156,27 @@ static int checkout_merged(int pos, struct checkout *state)
151156 int status ;
152157 unsigned char sha1 [20 ];
153158 mmbuffer_t result_buf ;
159+ unsigned char threeway [3 ][20 ];
160+ unsigned mode = 0 ;
161+
162+ memset (threeway , 0 , sizeof (threeway ));
163+ while (pos < active_nr ) {
164+ int stage ;
165+ stage = ce_stage (ce );
166+ if (!stage || strcmp (path , ce -> name ))
167+ break ;
168+ hashcpy (threeway [stage - 1 ], ce -> sha1 );
169+ if (stage == 2 )
170+ mode = create_ce_mode (ce -> ce_mode );
171+ pos ++ ;
172+ ce = active_cache [pos ];
173+ }
174+ if (is_null_sha1 (threeway [1 ]) || is_null_sha1 (threeway [2 ]))
175+ return error (_ ("path '%s' does not have necessary versions" ), path );
154176
155- if (ce_stage (ce ) != 1 ||
156- active_nr <= pos + 2 ||
157- strcmp (active_cache [pos + 1 ]-> name , path ) ||
158- ce_stage (active_cache [pos + 1 ]) != 2 ||
159- strcmp (active_cache [pos + 2 ]-> name , path ) ||
160- ce_stage (active_cache [pos + 2 ]) != 3 )
161- return error (_ ("path '%s' does not have all 3 versions" ), path );
162-
163- read_mmblob (& ancestor , active_cache [pos ]-> sha1 );
164- read_mmblob (& ours , active_cache [pos + 1 ]-> sha1 );
165- read_mmblob (& theirs , active_cache [pos + 2 ]-> sha1 );
177+ read_mmblob (& ancestor , threeway [0 ]);
178+ read_mmblob (& ours , threeway [1 ]);
179+ read_mmblob (& theirs , threeway [2 ]);
166180
167181 /*
168182 * NEEDSWORK: re-create conflicts from merges with
@@ -193,9 +207,7 @@ static int checkout_merged(int pos, struct checkout *state)
193207 if (write_sha1_file (result_buf .ptr , result_buf .size ,
194208 blob_type , sha1 ))
195209 die (_ ("Unable to add merge result for '%s'" ), path );
196- ce = make_cache_entry (create_ce_mode (active_cache [pos + 1 ]-> ce_mode ),
197- sha1 ,
198- path , 2 , 0 );
210+ ce = make_cache_entry (mode , sha1 , path , 2 , 0 );
199211 if (!ce )
200212 die (_ ("make_cache_entry failed for path '%s'" ), path );
201213 status = checkout_entry (ce , state , NULL );
@@ -253,7 +265,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
253265 } else if (stage ) {
254266 errs |= check_stage (stage , ce , pos );
255267 } else if (opts -> merge ) {
256- errs |= check_all_stages ( ce , pos );
268+ errs |= check_stages (( 1 << 2 ) | ( 1 << 3 ), ce , pos );
257269 } else {
258270 errs = 1 ;
259271 error (_ ("path '%s' is unmerged" ), ce -> name );
0 commit comments