| 1092 | } |
| 1093 | |
| 1094 | struct commit *get_fork_point(const char *refname, struct commit *commit) |
| 1095 | { |
| 1096 | struct object_id oid; |
| 1097 | struct rev_collect revs; |
| 1098 | struct commit_list *bases = NULL; |
| 1099 | size_t i; |
| 1100 | struct commit *ret = NULL; |
| 1101 | char *full_refname; |
| 1102 | |
| 1103 | switch (repo_dwim_ref(the_repository, refname, strlen(refname), &oid, |
| 1104 | &full_refname, 0)) { |
| 1105 | case 0: |
| 1106 | die("No such ref: '%s'", refname); |
| 1107 | case 1: |
| 1108 | break; /* good */ |
| 1109 | default: |
| 1110 | die("Ambiguous refname: '%s'", refname); |
| 1111 | } |
| 1112 | |
| 1113 | commit_stack_init(&revs.stack); |
| 1114 | revs.initial = 1; |
| 1115 | refs_for_each_reflog_ent(get_main_ref_store(the_repository), |
| 1116 | full_refname, collect_one_reflog_ent, &revs); |
| 1117 | |
| 1118 | if (!revs.stack.nr) |
| 1119 | add_one_commit(&oid, &revs); |
| 1120 | |
| 1121 | for (i = 0; i < revs.stack.nr; i++) |
| 1122 | revs.stack.items[i]->object.flags &= ~TMP_MARK; |
| 1123 | |
| 1124 | if (repo_get_merge_bases_many(the_repository, commit, revs.stack.nr, |
| 1125 | revs.stack.items, &bases) < 0) |
| 1126 | exit(128); |
| 1127 | |
| 1128 | /* |
| 1129 | * There should be one and only one merge base, when we found |
| 1130 | * a common ancestor among reflog entries. |
| 1131 | */ |
| 1132 | if (!bases || bases->next) |
| 1133 | goto cleanup_return; |
| 1134 | |
| 1135 | /* And the found one must be one of the reflog entries */ |
| 1136 | for (i = 0; i < revs.stack.nr; i++) |
| 1137 | if (&bases->item->object == &revs.stack.items[i]->object) |
| 1138 | break; /* found */ |
| 1139 | if (revs.stack.nr <= i) |
| 1140 | goto cleanup_return; |
| 1141 | |
| 1142 | ret = bases->item; |
| 1143 | |
| 1144 | cleanup_return: |
| 1145 | commit_stack_clear(&revs.stack); |
| 1146 | commit_list_free(bases); |
| 1147 | free(full_refname); |
| 1148 | return ret; |
| 1149 | } |
| 1150 | |
| 1151 | /* |
no test coverage detected