@@ -74,7 +74,9 @@ static void assign_variant(struct rerere_id *id)
74
74
75
75
variant = id -> variant ;
76
76
if (variant < 0 ) {
77
- variant = 0 ; /* for now */
77
+ for (variant = 0 ; variant < rr_dir -> status_nr ; variant ++ )
78
+ if (!rr_dir -> status [variant ])
79
+ break ;
78
80
}
79
81
fit_variant (rr_dir , variant );
80
82
id -> variant = variant ;
@@ -177,15 +179,6 @@ static int has_rerere_resolution(const struct rerere_id *id)
177
179
return ((id -> collection -> status [variant ] & both ) == both );
178
180
}
179
181
180
- static int has_rerere_preimage (const struct rerere_id * id )
181
- {
182
- int variant = id -> variant ;
183
-
184
- if (variant < 0 )
185
- return 0 ;
186
- return (id -> collection -> status [variant ] & RR_HAS_PREIMAGE );
187
- }
188
-
189
182
static struct rerere_id * new_rerere_id_hex (char * hex )
190
183
{
191
184
struct rerere_id * id = xmalloc (sizeof (* id ));
@@ -818,6 +811,13 @@ static void update_paths(struct string_list *update)
818
811
rollback_lock_file (& index_lock );
819
812
}
820
813
814
+ static void remove_variant (struct rerere_id * id )
815
+ {
816
+ unlink_or_warn (rerere_path (id , "postimage" ));
817
+ unlink_or_warn (rerere_path (id , "preimage" ));
818
+ id -> collection -> status [id -> variant ] = 0 ;
819
+ }
820
+
821
821
/*
822
822
* The path indicated by rr_item may still have conflict for which we
823
823
* have a recorded resolution, in which case replay it and optionally
@@ -830,49 +830,71 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
830
830
{
831
831
const char * path = rr_item -> string ;
832
832
struct rerere_id * id = rr_item -> util ;
833
+ struct rerere_dir * rr_dir = id -> collection ;
833
834
int variant ;
834
835
835
- if (id -> variant < 0 )
836
- assign_variant (id );
837
836
variant = id -> variant ;
838
837
839
- if (!has_rerere_preimage (id )) {
838
+ /* Has the user resolved it already? */
839
+ if (variant >= 0 ) {
840
+ if (!handle_file (path , NULL , NULL )) {
841
+ copy_file (rerere_path (id , "postimage" ), path , 0666 );
842
+ id -> collection -> status [variant ] |= RR_HAS_POSTIMAGE ;
843
+ fprintf (stderr , "Recorded resolution for '%s'.\n" , path );
844
+ free_rerere_id (rr_item );
845
+ rr_item -> util = NULL ;
846
+ return ;
847
+ }
840
848
/*
841
- * We are the first to encounter this conflict. Ask
842
- * handle_file() to write the normalized contents to
843
- * the "preimage" file .
849
+ * There may be other variants that can cleanly
850
+ * replay. Try them and update the variant number for
851
+ * this one .
844
852
*/
845
- handle_file (path , NULL , rerere_path (id , "preimage" ));
846
- if (id -> collection -> status [variant ] & RR_HAS_POSTIMAGE ) {
847
- const char * path = rerere_path (id , "postimage" );
848
- if (unlink (path ))
849
- die_errno ("cannot unlink stray '%s'" , path );
850
- id -> collection -> status [variant ] &= ~RR_HAS_POSTIMAGE ;
851
- }
852
- id -> collection -> status [variant ] |= RR_HAS_PREIMAGE ;
853
- fprintf (stderr , "Recorded preimage for '%s'\n" , path );
854
- return ;
855
- } else if (has_rerere_resolution (id )) {
856
- /* Is there a recorded resolution we could attempt to apply? */
857
- if (merge (id , path ))
858
- return ; /* failed to replay */
853
+ }
854
+
855
+ /* Does any existing resolution apply cleanly? */
856
+ for (variant = 0 ; variant < rr_dir -> status_nr ; variant ++ ) {
857
+ const int both = RR_HAS_PREIMAGE | RR_HAS_POSTIMAGE ;
858
+ struct rerere_id vid = * id ;
859
+
860
+ if ((rr_dir -> status [variant ] & both ) != both )
861
+ continue ;
862
+
863
+ vid .variant = variant ;
864
+ if (merge (& vid , path ))
865
+ continue ; /* failed to replay */
866
+
867
+ /*
868
+ * If there already is a different variant that applies
869
+ * cleanly, there is no point maintaining our own variant.
870
+ */
871
+ if (0 <= id -> variant && id -> variant != variant )
872
+ remove_variant (id );
859
873
860
874
if (rerere_autoupdate )
861
875
string_list_insert (update , path );
862
876
else
863
877
fprintf (stderr ,
864
878
"Resolved '%s' using previous resolution.\n" ,
865
879
path );
866
- } else if (!handle_file (path , NULL , NULL )) {
867
- /* The user has resolved it. */
868
- copy_file (rerere_path (id , "postimage" ), path , 0666 );
869
- id -> collection -> status [variant ] |= RR_HAS_POSTIMAGE ;
870
- fprintf (stderr , "Recorded resolution for '%s'.\n" , path );
871
- } else {
880
+ free_rerere_id (rr_item );
881
+ rr_item -> util = NULL ;
872
882
return ;
873
883
}
874
- free_rerere_id (rr_item );
875
- rr_item -> util = NULL ;
884
+
885
+ /* None of the existing one applies; we need a new variant */
886
+ assign_variant (id );
887
+
888
+ variant = id -> variant ;
889
+ handle_file (path , NULL , rerere_path (id , "preimage" ));
890
+ if (id -> collection -> status [variant ] & RR_HAS_POSTIMAGE ) {
891
+ const char * path = rerere_path (id , "postimage" );
892
+ if (unlink (path ))
893
+ die_errno ("cannot unlink stray '%s'" , path );
894
+ id -> collection -> status [variant ] &= ~RR_HAS_POSTIMAGE ;
895
+ }
896
+ id -> collection -> status [variant ] |= RR_HAS_PREIMAGE ;
897
+ fprintf (stderr , "Recorded preimage for '%s'\n" , path );
876
898
}
877
899
878
900
static int do_plain_rerere (struct string_list * rr , int fd )
0 commit comments