2005-04-18 20:39:48 +02:00
|
|
|
#include <stdlib.h>
|
2005-04-17 21:18:17 +02:00
|
|
|
#include "cache.h"
|
2005-04-18 20:39:48 +02:00
|
|
|
#include "commit.h"
|
2005-04-17 21:18:17 +02:00
|
|
|
|
2005-04-18 20:39:48 +02:00
|
|
|
static struct commit *process_list(struct commit_list **list_p, int this_mark,
|
|
|
|
int other_mark)
|
2005-04-17 21:18:17 +02:00
|
|
|
{
|
2005-04-24 03:47:23 +02:00
|
|
|
struct commit *item = (*list_p)->item;
|
2005-04-24 05:29:22 +02:00
|
|
|
|
|
|
|
if (item->object.flags & other_mark) {
|
2005-04-24 03:47:23 +02:00
|
|
|
return item;
|
|
|
|
} else {
|
2005-04-24 05:29:22 +02:00
|
|
|
pop_most_recent_commit(list_p, this_mark);
|
2005-04-18 20:39:48 +02:00
|
|
|
}
|
|
|
|
return NULL;
|
2005-04-17 21:18:17 +02:00
|
|
|
}
|
|
|
|
|
2005-04-18 20:39:48 +02:00
|
|
|
struct commit *common_ancestor(struct commit *rev1, struct commit *rev2)
|
2005-04-17 21:18:17 +02:00
|
|
|
{
|
2005-04-24 03:47:23 +02:00
|
|
|
struct commit_list *rev1list = NULL;
|
|
|
|
struct commit_list *rev2list = NULL;
|
2005-04-18 20:39:48 +02:00
|
|
|
|
2005-04-24 03:47:23 +02:00
|
|
|
commit_list_insert(rev1, &rev1list);
|
2005-04-24 05:29:22 +02:00
|
|
|
rev1->object.flags |= 0x1;
|
2005-04-24 03:47:23 +02:00
|
|
|
commit_list_insert(rev2, &rev2list);
|
2005-04-24 05:29:22 +02:00
|
|
|
rev2->object.flags |= 0x2;
|
2005-04-17 21:18:17 +02:00
|
|
|
|
2005-04-24 03:47:23 +02:00
|
|
|
parse_commit(rev1);
|
|
|
|
parse_commit(rev2);
|
2005-04-17 21:18:17 +02:00
|
|
|
|
2005-04-18 20:39:48 +02:00
|
|
|
while (rev1list || rev2list) {
|
|
|
|
struct commit *ret;
|
2005-04-24 03:47:23 +02:00
|
|
|
if (!rev1list) {
|
|
|
|
// process 2
|
|
|
|
ret = process_list(&rev2list, 0x2, 0x1);
|
|
|
|
} else if (!rev2list) {
|
|
|
|
// process 1
|
|
|
|
ret = process_list(&rev1list, 0x1, 0x2);
|
|
|
|
} else if (rev1list->item->date < rev2list->item->date) {
|
|
|
|
// process 2
|
|
|
|
ret = process_list(&rev2list, 0x2, 0x1);
|
|
|
|
} else {
|
|
|
|
// process 1
|
|
|
|
ret = process_list(&rev1list, 0x1, 0x2);
|
2005-04-18 20:39:48 +02:00
|
|
|
}
|
|
|
|
if (ret) {
|
2005-04-24 03:47:23 +02:00
|
|
|
free_commit_list(rev1list);
|
|
|
|
free_commit_list(rev2list);
|
2005-04-18 20:39:48 +02:00
|
|
|
return ret;
|
2005-04-17 21:18:17 +02:00
|
|
|
}
|
|
|
|
}
|
2005-04-18 20:39:48 +02:00
|
|
|
return NULL;
|
2005-04-17 21:18:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2005-04-18 20:39:48 +02:00
|
|
|
struct commit *rev1, *rev2, *ret;
|
|
|
|
unsigned char rev1key[20], rev2key[20];
|
2005-04-17 21:18:17 +02:00
|
|
|
|
2005-04-18 20:39:48 +02:00
|
|
|
if (argc != 3 ||
|
2005-05-02 01:36:56 +02:00
|
|
|
get_sha1(argv[1], rev1key) ||
|
|
|
|
get_sha1(argv[2], rev2key)) {
|
2005-04-18 20:39:48 +02:00
|
|
|
usage("merge-base <commit-id> <commit-id>");
|
|
|
|
}
|
|
|
|
rev1 = lookup_commit(rev1key);
|
|
|
|
rev2 = lookup_commit(rev2key);
|
|
|
|
ret = common_ancestor(rev1, rev2);
|
2005-04-18 21:12:00 +02:00
|
|
|
if (!ret)
|
2005-04-18 20:39:48 +02:00
|
|
|
return 1;
|
2005-04-18 21:12:00 +02:00
|
|
|
printf("%s\n", sha1_to_hex(ret->object.sha1));
|
2005-04-17 21:18:17 +02:00
|
|
|
return 0;
|
|
|
|
}
|