@@ -809,6 +809,15 @@ int commit_contains(struct ref_filter *filter, struct commit *commit,
809809 return repo_is_descendant_of (the_repository , commit , list );
810810}
811811
812+ static int find_reachable_core (struct repository * r ,
813+ struct commit * * from , size_t from_nr ,
814+ unsigned int target_flag ,
815+ unsigned int visited_flag ,
816+ timestamp_t min_generation ,
817+ timestamp_t min_commit_date ,
818+ int fast_fail ,
819+ unsigned int mark );
820+
812821int can_all_from_reach_with_flag (struct object_array * from ,
813822 unsigned int with_flag ,
814823 unsigned int assign_flag ,
@@ -851,54 +860,12 @@ int can_all_from_reach_with_flag(struct object_array *from,
851860 nr_commits ++ ;
852861 }
853862
854- QSORT (list , nr_commits , compare_commits_by_gen );
855-
856- for (i = 0 ; i < nr_commits ; i ++ ) {
857- /* DFS from list[i] */
858- struct commit_list * stack = NULL ;
859-
860- list [i ]-> object .flags |= assign_flag ;
861- commit_list_insert (list [i ], & stack );
862-
863- while (stack ) {
864- struct commit_list * parent ;
865-
866- if (stack -> item -> object .flags & (with_flag | RESULT )) {
867- pop_commit (& stack );
868- if (stack )
869- stack -> item -> object .flags |= RESULT ;
870- continue ;
871- }
872-
873- for (parent = stack -> item -> parents ; parent ; parent = parent -> next ) {
874- if (parent -> item -> object .flags & (with_flag | RESULT ))
875- stack -> item -> object .flags |= RESULT ;
876-
877- if (!(parent -> item -> object .flags & assign_flag )) {
878- parent -> item -> object .flags |= assign_flag ;
879-
880- if (repo_parse_commit (the_repository , parent -> item ) ||
881- parent -> item -> date < min_commit_date ||
882- commit_graph_generation (parent -> item ) < min_generation )
883- continue ;
884-
885- commit_list_insert (parent -> item , & stack );
886- break ;
887- }
888- }
889-
890- if (!parent )
891- pop_commit (& stack );
892- }
893-
894- if (!(list [i ]-> object .flags & (with_flag | RESULT ))) {
895- result = 0 ;
896- goto cleanup ;
897- }
898- }
863+ result = find_reachable_core (the_repository , list , nr_commits ,
864+ with_flag , assign_flag ,
865+ min_generation , min_commit_date ,
866+ 1 , 0 ) == (int )nr_commits ;
899867
900868cleanup :
901- clear_commit_marks_many (nr_commits , list , RESULT | assign_flag );
902869 free (list );
903870
904871 for (i = 0 ; i < from -> nr ; i ++ ) {
@@ -911,64 +878,6 @@ int can_all_from_reach_with_flag(struct object_array *from,
911878 return result ;
912879}
913880
914- int can_all_from_reach (struct commit_list * from , struct commit_list * to ,
915- int cutoff_by_min_date )
916- {
917- struct object_array from_objs = OBJECT_ARRAY_INIT ;
918- struct commit_list * from_iter = from , * to_iter = to ;
919- int result ;
920- timestamp_t min_commit_date = cutoff_by_min_date ? from -> item -> date : 0 ;
921- timestamp_t min_generation = GENERATION_NUMBER_INFINITY ;
922-
923- while (from_iter ) {
924- add_object_array (& from_iter -> item -> object , NULL , & from_objs );
925-
926- if (!repo_parse_commit (the_repository , from_iter -> item )) {
927- timestamp_t generation ;
928- if (from_iter -> item -> date < min_commit_date )
929- min_commit_date = from_iter -> item -> date ;
930-
931- generation = commit_graph_generation (from_iter -> item );
932- if (generation < min_generation )
933- min_generation = generation ;
934- }
935-
936- from_iter = from_iter -> next ;
937- }
938-
939- while (to_iter ) {
940- if (!repo_parse_commit (the_repository , to_iter -> item )) {
941- timestamp_t generation ;
942- if (to_iter -> item -> date < min_commit_date )
943- min_commit_date = to_iter -> item -> date ;
944-
945- generation = commit_graph_generation (to_iter -> item );
946- if (generation < min_generation )
947- min_generation = generation ;
948- }
949-
950- to_iter -> item -> object .flags |= PARENT2 ;
951-
952- to_iter = to_iter -> next ;
953- }
954-
955- result = can_all_from_reach_with_flag (& from_objs , PARENT2 , PARENT1 ,
956- min_commit_date , min_generation );
957-
958- while (from ) {
959- clear_commit_marks (from -> item , PARENT1 );
960- from = from -> next ;
961- }
962-
963- while (to ) {
964- clear_commit_marks (to -> item , PARENT2 );
965- to = to -> next ;
966- }
967-
968- object_array_clear (& from_objs );
969- return result ;
970- }
971-
972881struct commit_list * get_reachable_subset (struct commit * * from , size_t nr_from ,
973882 struct commit * * to , size_t nr_to ,
974883 unsigned int reachable_flag )
0 commit comments