19
19
#include "unpack-trees.h"
20
20
#include "branch.h"
21
21
#include "sequencer.h"
22
+ #include "revision.h"
23
+ #include "merge-recursive.h"
22
24
23
25
/**
24
26
* Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -83,6 +85,7 @@ struct am_state {
83
85
int prec ;
84
86
85
87
/* various operating modes and command line options */
88
+ int threeway ;
86
89
int quiet ;
87
90
int signoff ;
88
91
const char * resolvemsg ;
@@ -352,6 +355,9 @@ static void am_load(struct am_state *state)
352
355
353
356
read_commit_msg (state );
354
357
358
+ read_state_file (& sb , state , "threeway" , 1 );
359
+ state -> threeway = !strcmp (sb .buf , "t" );
360
+
355
361
read_state_file (& sb , state , "quiet" , 1 );
356
362
state -> quiet = !strcmp (sb .buf , "t" );
357
363
@@ -536,6 +542,8 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
536
542
die (_ ("Failed to split patches." ));
537
543
}
538
544
545
+ write_file (am_path (state , "threeway" ), 1 , state -> threeway ? "t" : "f" );
546
+
539
547
write_file (am_path (state , "quiet" ), 1 , state -> quiet ? "t" : "f" );
540
548
541
549
write_file (am_path (state , "sign" ), 1 , state -> signoff ? "t" : "f" );
@@ -766,25 +774,141 @@ static int parse_mail(struct am_state *state, const char *mail)
766
774
}
767
775
768
776
/**
769
- * Applies current patch with git-apply. Returns 0 on success, -1 otherwise.
777
+ * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If
778
+ * `index_file` is not NULL, the patch will be applied to that index.
770
779
*/
771
- static int run_apply (const struct am_state * state )
780
+ static int run_apply (const struct am_state * state , const char * index_file )
772
781
{
773
782
struct child_process cp = CHILD_PROCESS_INIT ;
774
783
775
784
cp .git_cmd = 1 ;
776
785
786
+ if (index_file )
787
+ argv_array_pushf (& cp .env_array , "GIT_INDEX_FILE=%s" , index_file );
788
+
789
+ /*
790
+ * If we are allowed to fall back on 3-way merge, don't give false
791
+ * errors during the initial attempt.
792
+ */
793
+ if (state -> threeway && !index_file ) {
794
+ cp .no_stdout = 1 ;
795
+ cp .no_stderr = 1 ;
796
+ }
797
+
777
798
argv_array_push (& cp .args , "apply" );
778
- argv_array_push (& cp .args , "--index" );
799
+
800
+ if (index_file )
801
+ argv_array_push (& cp .args , "--cached" );
802
+ else
803
+ argv_array_push (& cp .args , "--index" );
804
+
779
805
argv_array_push (& cp .args , am_path (state , "patch" ));
780
806
781
807
if (run_command (& cp ))
782
808
return -1 ;
783
809
784
810
/* Reload index as git-apply will have modified it. */
811
+ discard_cache ();
812
+ read_cache_from (index_file ? index_file : get_index_file ());
813
+
814
+ return 0 ;
815
+ }
816
+
817
+ /**
818
+ * Builds an index that contains just the blobs needed for a 3way merge.
819
+ */
820
+ static int build_fake_ancestor (const struct am_state * state , const char * index_file )
821
+ {
822
+ struct child_process cp = CHILD_PROCESS_INIT ;
823
+
824
+ cp .git_cmd = 1 ;
825
+ argv_array_push (& cp .args , "apply" );
826
+ argv_array_pushf (& cp .args , "--build-fake-ancestor=%s" , index_file );
827
+ argv_array_push (& cp .args , am_path (state , "patch" ));
828
+
829
+ if (run_command (& cp ))
830
+ return -1 ;
831
+
832
+ return 0 ;
833
+ }
834
+
835
+ /**
836
+ * Attempt a threeway merge, using index_path as the temporary index.
837
+ */
838
+ static int fall_back_threeway (const struct am_state * state , const char * index_path )
839
+ {
840
+ unsigned char orig_tree [GIT_SHA1_RAWSZ ], his_tree [GIT_SHA1_RAWSZ ],
841
+ our_tree [GIT_SHA1_RAWSZ ];
842
+ const unsigned char * bases [1 ] = {orig_tree };
843
+ struct merge_options o ;
844
+ struct commit * result ;
845
+ char * his_tree_name ;
846
+
847
+ if (get_sha1 ("HEAD" , our_tree ) < 0 )
848
+ hashcpy (our_tree , EMPTY_TREE_SHA1_BIN );
849
+
850
+ if (build_fake_ancestor (state , index_path ))
851
+ return error ("could not build fake ancestor" );
852
+
853
+ discard_cache ();
854
+ read_cache_from (index_path );
855
+
856
+ if (write_index_as_tree (orig_tree , & the_index , index_path , 0 , NULL ))
857
+ return error (_ ("Repository lacks necessary blobs to fall back on 3-way merge." ));
858
+
859
+ say (state , stdout , _ ("Using index info to reconstruct a base tree..." ));
860
+
861
+ if (!state -> quiet ) {
862
+ /*
863
+ * List paths that needed 3-way fallback, so that the user can
864
+ * review them with extra care to spot mismerges.
865
+ */
866
+ struct rev_info rev_info ;
867
+ const char * diff_filter_str = "--diff-filter=AM" ;
868
+
869
+ init_revisions (& rev_info , NULL );
870
+ rev_info .diffopt .output_format = DIFF_FORMAT_NAME_STATUS ;
871
+ diff_opt_parse (& rev_info .diffopt , & diff_filter_str , 1 );
872
+ add_pending_sha1 (& rev_info , "HEAD" , our_tree , 0 );
873
+ diff_setup_done (& rev_info .diffopt );
874
+ run_diff_index (& rev_info , 1 );
875
+ }
876
+
877
+ if (run_apply (state , index_path ))
878
+ return error (_ ("Did you hand edit your patch?\n"
879
+ "It does not apply to blobs recorded in its index." ));
880
+
881
+ if (write_index_as_tree (his_tree , & the_index , index_path , 0 , NULL ))
882
+ return error ("could not write tree" );
883
+
884
+ say (state , stdout , _ ("Falling back to patching base and 3-way merge..." ));
885
+
785
886
discard_cache ();
786
887
read_cache ();
787
888
889
+ /*
890
+ * This is not so wrong. Depending on which base we picked, orig_tree
891
+ * may be wildly different from ours, but his_tree has the same set of
892
+ * wildly different changes in parts the patch did not touch, so
893
+ * recursive ends up canceling them, saying that we reverted all those
894
+ * changes.
895
+ */
896
+
897
+ init_merge_options (& o );
898
+
899
+ o .branch1 = "HEAD" ;
900
+ his_tree_name = xstrfmt ("%.*s" , linelen (state -> msg ), state -> msg );
901
+ o .branch2 = his_tree_name ;
902
+
903
+ if (state -> quiet )
904
+ o .verbosity = 0 ;
905
+
906
+ if (merge_recursive_generic (& o , our_tree , his_tree , 1 , bases , & result )) {
907
+ free (his_tree_name );
908
+ return error (_ ("Failed to merge in the changes." ));
909
+ }
910
+
911
+ free (his_tree_name );
788
912
return 0 ;
789
913
}
790
914
@@ -872,6 +996,7 @@ static void am_run(struct am_state *state, int resume)
872
996
873
997
while (state -> cur <= state -> last ) {
874
998
const char * mail = am_path (state , msgnum (state ));
999
+ int apply_status ;
875
1000
876
1001
if (!file_exists (mail ))
877
1002
goto next ;
@@ -889,7 +1014,26 @@ static void am_run(struct am_state *state, int resume)
889
1014
890
1015
say (state , stdout , _ ("Applying: %.*s" ), linelen (state -> msg ), state -> msg );
891
1016
892
- if (run_apply (state ) < 0 ) {
1017
+ apply_status = run_apply (state , NULL );
1018
+
1019
+ if (apply_status && state -> threeway ) {
1020
+ struct strbuf sb = STRBUF_INIT ;
1021
+
1022
+ strbuf_addstr (& sb , am_path (state , "patch-merge-index" ));
1023
+ apply_status = fall_back_threeway (state , sb .buf );
1024
+ strbuf_release (& sb );
1025
+
1026
+ /*
1027
+ * Applying the patch to an earlier tree and merging
1028
+ * the result may have produced the same tree as ours.
1029
+ */
1030
+ if (!apply_status && !index_has_changes (NULL )) {
1031
+ say (state , stdout , _ ("No changes -- Patch already applied." ));
1032
+ goto next ;
1033
+ }
1034
+ }
1035
+
1036
+ if (apply_status ) {
893
1037
int advice_amworkdir = 1 ;
894
1038
895
1039
printf_ln (_ ("Patch failed at %s %.*s" ), msgnum (state ),
@@ -1159,6 +1303,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)
1159
1303
};
1160
1304
1161
1305
struct option options [] = {
1306
+ OPT_BOOL ('3' , "3way" , & state .threeway ,
1307
+ N_ ("allow fall back on 3way merging if needed" )),
1162
1308
OPT__QUIET (& state .quiet , N_ ("be quiet" )),
1163
1309
OPT_BOOL ('s' , "signoff" , & state .signoff ,
1164
1310
N_ ("add a Signed-off-by line to the commit message" )),
0 commit comments