| 1 | #ifndef COMMIT_REACH_H |
| 2 | #define COMMIT_REACH_H |
| 3 | |
| 4 | #include "commit.h" |
| 5 | #include "commit-slab.h" |
| 6 | |
| 7 | struct commit_list; |
| 8 | struct ref_filter; |
| 9 | struct object_id; |
| 10 | struct object_array; |
| 11 | |
| 12 | int repo_get_merge_bases(struct repository *r, |
| 13 | struct commit *rev1, |
| 14 | struct commit *rev2, |
| 15 | struct commit_list **result); |
| 16 | int repo_get_merge_bases_many(struct repository *r, |
| 17 | struct commit *one, size_t n, |
| 18 | struct commit **twos, |
| 19 | struct commit_list **result); |
| 20 | enum merge_base_flags { |
| 21 | MERGE_BASE_IGNORE_MISSING_COMMITS = (1 << 0), |
| 22 | MERGE_BASE_FIND_ALL = (1 << 1), |
| 23 | }; |
| 24 | |
| 25 | /* |
| 26 | * To be used only when object flags after this call no longer matter. |
| 27 | * Without MERGE_BASE_FIND_ALL and with generation numbers available, |
| 28 | * returns after finding the first merge-base, skipping the STALE drain. |
| 29 | */ |
| 30 | int repo_get_merge_bases_many_dirty(struct repository *r, |
| 31 | struct commit *one, size_t n, |
| 32 | struct commit **twos, |
| 33 | enum merge_base_flags mb_flags, |
| 34 | struct commit_list **result); |
| 35 | |
| 36 | int get_octopus_merge_bases(struct commit_list *in, struct commit_list **result); |
| 37 | |
| 38 | int repo_is_descendant_of(struct repository *r, |
| 39 | struct commit *commit, |
| 40 | struct commit_list *with_commit); |
| 41 | int repo_in_merge_bases(struct repository *r, |
| 42 | struct commit *commit, |
| 43 | struct commit *reference); |
| 44 | int repo_in_merge_bases_many(struct repository *r, |
| 45 | struct commit *commit, |
| 46 | int nr_reference, struct commit **reference, |
| 47 | int ignore_missing_commits); |
| 48 | |
| 49 | /* |
| 50 | * Takes a list of commits and returns a new list where those |
| 51 | * have been removed that can be reached from other commits in |
| 52 | * the list. It is useful for, e.g., reducing the commits |
| 53 | * randomly thrown at the git-merge command and removing |
| 54 | * redundant commits that the user shouldn't have given to it. |
| 55 | * |
| 56 | * This function destroys the STALE bit of the commit objects' |
| 57 | * flags. |
| 58 | */ |
| 59 | struct commit_list *reduce_heads(struct commit_list *heads); |
| 60 | |
| 61 | /* |
| 62 | * Like `reduce_heads()`, except it replaces the list. Use this |
| 63 | * instead of `foo = reduce_heads(foo);` to avoid memory leaks. |
| 64 | */ |
| 65 | void reduce_heads_replace(struct commit_list **heads); |
| 66 | |
| 67 | int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid); |
| 68 | |
| 69 | /* |
| 70 | * Unknown has to be "0" here, because that's the default value for |
| 71 | * contains_cache slab entries that have not yet been assigned. |
| 72 | */ |
| 73 | enum contains_result { |
| 74 | CONTAINS_UNKNOWN = 0, |
| 75 | CONTAINS_NO, |
| 76 | CONTAINS_YES |
| 77 | }; |
| 78 | |
| 79 | define_commit_slab(contains_cache, enum contains_result); |
| 80 | |
| 81 | int commit_contains(struct ref_filter *filter, struct commit *commit, |
| 82 | struct commit_list *list, struct contains_cache *cache); |
| 83 | |
| 84 | /* |
| 85 | * Determine if every commit in 'from' can reach at least one commit |
| 86 | * that is marked with 'with_flag'. As we traverse, use 'assign_flag' |
| 87 | * as a marker for commits that are already visited. Do not walk |
| 88 | * commits with date below 'min_commit_date' or generation below |
| 89 | * 'min_generation'. |
| 90 | */ |
| 91 | int can_all_from_reach_with_flag(struct object_array *from, |
| 92 | unsigned int with_flag, |
| 93 | unsigned int assign_flag, |
| 94 | timestamp_t min_commit_date, |
| 95 | timestamp_t min_generation); |
| 96 | int can_all_from_reach(struct commit_list *from, struct commit_list *to, |
| 97 | int commit_date_cutoff); |
| 98 | |
| 99 | |
| 100 | /* |
| 101 | * Return a list of commits containing the commits in the 'to' array |
| 102 | * that are reachable from at least one commit in the 'from' array. |
| 103 | * Also add the given 'flag' to each of the commits in the returned list. |
| 104 | * |
| 105 | * This method uses the PARENT1 and PARENT2 flags during its operation, |
| 106 | * so be sure these flags are not set before calling the method. |
| 107 | */ |
| 108 | struct commit_list *get_reachable_subset(struct commit **from, size_t nr_from, |
| 109 | struct commit **to, size_t nr_to, |
| 110 | unsigned int reachable_flag); |
| 111 | |
| 112 | struct ahead_behind_count { |
| 113 | /** |
| 114 | * As input, the *_index members indicate which positions in |
| 115 | * the 'tips' array correspond to the tip and base of this |
| 116 | * comparison. |
| 117 | */ |
| 118 | size_t tip_index; |
| 119 | size_t base_index; |
| 120 | |
| 121 | /** |
| 122 | * These values store the computed counts for each side of the |
| 123 | * symmetric difference: |
| 124 | * |
| 125 | * 'ahead' stores the number of commits reachable from the tip |
| 126 | * and not reachable from the base. |
| 127 | * |
| 128 | * 'behind' stores the number of commits reachable from the base |
| 129 | * and not reachable from the tip. |
| 130 | */ |
| 131 | unsigned int ahead; |
| 132 | unsigned int behind; |
| 133 | }; |
| 134 | |
| 135 | /* |
| 136 | * Given an array of commits and an array of ahead_behind_count pairs, |
| 137 | * compute the ahead/behind counts for each pair. |
| 138 | */ |
| 139 | void ahead_behind(struct repository *r, |
| 140 | struct commit **commits, size_t commits_nr, |
| 141 | struct ahead_behind_count *counts, size_t counts_nr); |
| 142 | |
| 143 | /* |
| 144 | * For all tip commits, add 'mark' to their flags if and only if they |
| 145 | * are reachable from one of the commits in 'bases'. |
| 146 | */ |
| 147 | void tips_reachable_from_bases(struct repository *r, |
| 148 | struct commit_list *bases, |
| 149 | struct commit **tips, size_t tips_nr, |
| 150 | int mark); |
| 151 | |
| 152 | /* |
| 153 | * Given a 'tip' commit and a list potential 'bases', return the index 'i' that |
| 154 | * minimizes the number of commits in the first-parent history of 'tip' and not |
| 155 | * in the first-parent history of 'bases[i]'. |
| 156 | * |
| 157 | * Among a list of long-lived branches that are updated only by merges (with the |
| 158 | * first parent being the previous position of the branch), this would inform |
| 159 | * which branch was used to create the tip reference. |
| 160 | * |
| 161 | * Returns -1 if no common point is found in first-parent histories, which is |
| 162 | * rare, but possible with multiple root commits. |
| 163 | */ |
| 164 | int get_branch_base_for_tip(struct repository *r, |
| 165 | struct commit *tip, |
| 166 | struct commit **bases, |
| 167 | size_t bases_nr); |
| 168 | |
| 169 | #endif |