test-reach: test can_all_from_reach_with_flags
authorDerrick Stolee <dstolee@microsoft.com>
Fri, 20 Jul 2018 16:33:23 +0000 (16:33 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Jul 2018 22:38:56 +0000 (15:38 -0700)
The can_all_from_reach_with_flags method is used by ok_to_give_up in
upload-pack.c to see if we have done enough negotiation during a fetch.
This method is intentionally created to preserve state between calls to
assist with stateful negotiation, such as over SSH.

To make this method testable, add a new can_all_from_reach method that
does the initial setup and final tear-down. We will later use this
method in production code. Call the method from 'test-tool reach' for
now.

Since this is a many-to-many reachability query, add a new type of input
to the 'test-tool reach' input format. Lines "Y:<committish>" create a
list of commits to be the reachability targets from the commits in the
'X' list. In the context of fetch negotiation, the 'X' commits are the
'want' commits and the 'Y' commits are the 'have' commits.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit-reach.c
commit-reach.h
t/helper/test-reach.c
t/t6600-test-reach.sh
index d806291d5d88aa4c94b0fc264b37cdc9674980a8..940fbf2e177c14c395e6ac6874d5aebf7fa077ec 100644 (file)
@@ -595,3 +595,50 @@ int can_all_from_reach_with_flag(struct object_array *from,
        }
        return 1;
 }
+
+int can_all_from_reach(struct commit_list *from, struct commit_list *to,
+                      int cutoff_by_min_date)
+{
+       struct object_array from_objs = OBJECT_ARRAY_INIT;
+       time_t min_commit_date = cutoff_by_min_date ? from->item->date : 0;
+       struct commit_list *from_iter = from, *to_iter = to;
+       int result;
+
+       while (from_iter) {
+               add_object_array(&from_iter->item->object, NULL, &from_objs);
+
+               if (!parse_commit(from_iter->item)) {
+                       if (from_iter->item->date < min_commit_date)
+                               min_commit_date = from_iter->item->date;
+               }
+
+               from_iter = from_iter->next;
+       }
+
+       while (to_iter) {
+               if (!parse_commit(to_iter->item)) {
+                       if (to_iter->item->date < min_commit_date)
+                               min_commit_date = to_iter->item->date;
+               }
+
+               to_iter->item->object.flags |= PARENT2;
+
+               to_iter = to_iter->next;
+       }
+
+       result = can_all_from_reach_with_flag(&from_objs, PARENT2, PARENT1,
+                                             min_commit_date);
+
+       while (from) {
+               clear_commit_marks(from->item, PARENT1);
+               from = from->next;
+       }
+
+       while (to) {
+               clear_commit_marks(to->item, PARENT2);
+               to = to->next;
+       }
+
+       object_array_clear(&from_objs);
+       return result;
+}
index b28bc22fcd4b426310b4a1feb40b13d15b766b62..aa202c97038e76ea899277338563b2b53ff75615 100644 (file)
@@ -72,5 +72,7 @@ int can_all_from_reach_with_flag(struct object_array *from,
                                 unsigned int with_flag,
                                 unsigned int assign_flag,
                                 time_t min_commit_date);
+int can_all_from_reach(struct commit_list *from, struct commit_list *to,
+                      int commit_date_cutoff);
 
 #endif
index e32e193b70e1dacb5ed056ea09fd0947cf6c8139..c79729cac02102379077d73882010df6d690c86a 100644 (file)
@@ -29,7 +29,7 @@ int cmd__reach(int ac, const char **av)
 {
        struct object_id oid_A, oid_B;
        struct commit *A, *B;
-       struct commit_list *X;
+       struct commit_list *X, *Y;
        struct commit **X_array;
        int X_nr, X_alloc;
        struct strbuf buf = STRBUF_INIT;
@@ -41,7 +41,7 @@ int cmd__reach(int ac, const char **av)
                exit(1);
 
        A = B = NULL;
-       X = NULL;
+       X = Y = NULL;
        X_nr = 0;
        X_alloc = 16;
        ALLOC_ARRAY(X_array, X_alloc);
@@ -86,6 +86,10 @@ int cmd__reach(int ac, const char **av)
                                X_array[X_nr++] = c;
                                break;
 
+                       case 'Y':
+                               commit_list_insert(c, &Y);
+                               break;
+
                        default:
                                die("unexpected start of line: %c", buf.buf[0]);
                }
@@ -106,6 +110,8 @@ int cmd__reach(int ac, const char **av)
                struct commit_list *list = reduce_heads(X);
                printf("%s(X):\n", av[1]);
                print_sorted_commit_ids(list);
+       } else if (!strcmp(av[1], "can_all_from_reach")) {
+               printf("%s(X,Y):%d\n", av[1], can_all_from_reach(X, Y, 1));
        }
 
        exit(0);
index 17c64679888913bdb72a9c03d83a93f055bc7745..e41eb397a77a8f87be907a3f8f1a778706c4499d 100755 (executable)
@@ -160,4 +160,49 @@ test_expect_success 'reduce_heads' '
        test_three_modes reduce_heads
 '
 
+test_expect_success 'can_all_from_reach:hit' '
+       cat >input <<-\EOF &&
+       X:commit-2-10
+       X:commit-3-9
+       X:commit-4-8
+       X:commit-5-7
+       X:commit-6-6
+       X:commit-7-5
+       X:commit-8-4
+       X:commit-9-3
+       Y:commit-1-9
+       Y:commit-2-8
+       Y:commit-3-7
+       Y:commit-4-6
+       Y:commit-5-5
+       Y:commit-6-4
+       Y:commit-7-3
+       Y:commit-8-1
+       EOF
+       echo "can_all_from_reach(X,Y):1" >expect &&
+       test_three_modes can_all_from_reach
+'
+
+test_expect_success 'can_all_from_reach:miss' '
+       cat >input <<-\EOF &&
+       X:commit-2-10
+       X:commit-3-9
+       X:commit-4-8
+       X:commit-5-7
+       X:commit-6-6
+       X:commit-7-5
+       X:commit-8-4
+       X:commit-9-3
+       Y:commit-1-9
+       Y:commit-2-8
+       Y:commit-3-7
+       Y:commit-4-6
+       Y:commit-5-5
+       Y:commit-6-4
+       Y:commit-8-5
+       EOF
+       echo "can_all_from_reach(X,Y):0" >expect &&
+       test_three_modes can_all_from_reach
+'
+
 test_done