summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--commit-reach.c47
-rw-r--r--commit-reach.h2
-rw-r--r--t/helper/test-reach.c10
-rwxr-xr-xt/t6600-test-reach.sh45
4 files changed, 102 insertions, 2 deletions
diff --git a/commit-reach.c b/commit-reach.c
index d806291d5d..940fbf2e17 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -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;
+}
diff --git a/commit-reach.h b/commit-reach.h
index b28bc22fcd..aa202c9703 100644
--- a/commit-reach.h
+++ b/commit-reach.h
@@ -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
diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c
index e32e193b70..c79729cac0 100644
--- a/t/helper/test-reach.c
+++ b/t/helper/test-reach.c
@@ -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);
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index 17c6467988..e41eb397a7 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -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