summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 75dedd5)
raw | patch | inline | side by side (parent: 75dedd5)
author | Johannes Schindelin <Johannes.Schindelin@gmx.de> | |
Thu, 29 Jun 2006 13:16:46 +0000 (15:16 +0200) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Thu, 29 Jun 2006 20:50:46 +0000 (13:50 -0700) |
Signed-off-by: Junio C Hamano <junkio@cox.net>
merge-base.c | patch | blob | history |
diff --git a/merge-base.c b/merge-base.c
index 4856ca01c33896843c366f3fb5edadd2ea3ced37..7d87c20b7520fbf2af6071e3965f350edf77ee49 100644 (file)
--- a/merge-base.c
+++ b/merge-base.c
* to contaminate D and E.
*/
-static int show_all = 0;
-
static void mark_reachable_commits(struct commit_list *result,
struct commit_list *list)
{
}
}
-static int merge_base(struct commit *rev1, struct commit *rev2)
+struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2)
{
struct commit_list *list = NULL;
struct commit_list *result = NULL;
struct commit_list *tmp = NULL;
- if (rev1 == rev2) {
- printf("%s\n", sha1_to_hex(rev1->object.sha1));
- return 0;
- }
+ if (rev1 == rev2)
+ return commit_list_insert(rev1, &result);
parse_commit(rev1);
parse_commit(rev2);
- rev1->object.flags |= 1;
- rev2->object.flags |= 2;
+ rev1->object.flags |= PARENT1;
+ rev2->object.flags |= PARENT2;
insert_by_date(rev1, &list);
insert_by_date(rev2, &list);
while (interesting(list)) {
struct commit *commit = list->item;
struct commit_list *parents;
- int flags = commit->object.flags & 7;
+ int flags = commit->object.flags
+ & (PARENT1 | PARENT2 | UNINTERESTING);
tmp = list;
list = list->next;
free(tmp);
- if (flags == 3) {
+ if (flags == (PARENT1 | PARENT2)) {
insert_by_date(commit, &result);
/* Mark parents of a found merge uninteresting */
}
if (!result)
- return 1;
+ return NULL;
if (result->next && list)
mark_reachable_commits(result, list);
+ /* cull duplicates */
+ for (tmp = result, list = NULL; tmp; ) {
+ struct commit *commit = tmp->item;
+ struct commit_list *next = tmp->next;
+ if (commit->object.flags & UNINTERESTING) {
+ if (list != NULL)
+ list->next = next;
+ free(tmp);
+ } else {
+ if (list == NULL)
+ result = tmp;
+ list = tmp;
+ commit->object.flags |= UNINTERESTING;
+ }
+
+ tmp = next;
+ }
+
+ /* reset flags */
+ clear_commit_marks(rev1, PARENT1 | PARENT2 | UNINTERESTING);
+ clear_commit_marks(rev2, PARENT1 | PARENT2 | UNINTERESTING);
+
+ return result;
+}
+
+static int show_all = 0;
+
+static int merge_base(struct commit *rev1, struct commit *rev2)
+{
+ struct commit_list *result = get_merge_bases(rev1, rev2);
+
+ if (!result)
+ return 1;
+
while (result) {
- struct commit *commit = result->item;
- result = result->next;
- if (commit->object.flags & UNINTERESTING)
- continue;
- printf("%s\n", sha1_to_hex(commit->object.sha1));
+ printf("%s\n", sha1_to_hex(result->item->object.sha1));
if (!show_all)
return 0;
- commit->object.flags |= UNINTERESTING;
+ result = result->next;
}
+
return 0;
}