Add a dumb-but-improvable program to find a not-too-bad commit to do a three-way-merge of two commits.
Signed-Off-By: Daniel Barkalow <[EMAIL PROTECTED]> Index: Makefile =================================================================== --- 1756b578489f93999ded68ae347bef7d6063101c/Makefile (mode:100644 sha1:b39b4ea37586693dd707d1d0750a9b580350ec50) +++ b07fe1a7e0836e7d906c16c4f63b2e42b4a5193a/Makefile (mode:100644 sha1:a2d920a36c1124fb0a031ae43fdd3a8106529c8f) @@ -14,7 +14,7 @@ PROG= update-cache show-diff init-db write-tree read-tree commit-tree \ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \ - check-files ls-tree merge-tree + check-files ls-tree merge-tree merge-base all: $(PROG) @@ -67,6 +67,9 @@ merge-tree: merge-tree.o read-cache.o $(CC) $(CFLAGS) -o merge-tree merge-tree.o read-cache.o $(LIBS) +merge-base: merge-base.o read-cache.o + $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS) + read-cache.o: cache.h show-diff.o: cache.h Index: merge-base.c =================================================================== --- /dev/null (tree:1756b578489f93999ded68ae347bef7d6063101c) +++ b07fe1a7e0836e7d906c16c4f63b2e42b4a5193a/merge-base.c (mode:100644 sha1:a3e885ef8e2ae761d76c3217002467d19bf75a8d) @@ -0,0 +1,132 @@ +#include <stdlib.h> +#include "cache.h" +#include "revision.h" + +static int parse_commit(struct revision *rev) +{ + if (!(rev->flags & SEEN)) { + void *buffer, *bufptr; + unsigned long size; + char type[20]; + unsigned char parent[20]; + + rev->flags |= SEEN; + buffer = bufptr = read_sha1_file(rev->sha1, type, &size); + if (!buffer || strcmp(type, "commit")) + return -1; + bufptr += 46; /* "tree " + "hex sha1" + "\n" */ + while (!memcmp(bufptr, "parent ", 7) && + !get_sha1_hex(bufptr+7, parent)) { + add_relationship(rev, parent); + bufptr += 48; /* "parent " + "hex sha1" + "\n" */ + } + //rev->date = parse_commit_date(bufptr); + free(buffer); + } + return 0; +} + +struct revision *common_ancestor(struct revision *rev1, struct revision *rev2) +{ + struct parent *parent; + + struct parent *rev1list = malloc(sizeof(struct parent)); + struct parent *rev2list = malloc(sizeof(struct parent)); + + struct parent *posn, *temp; + + rev1list->parent = rev1; + rev1list->next = NULL; + + rev2list->parent = rev2; + rev2list->next = NULL; + + while (rev1list || rev2list) { + posn = rev1list; + rev1list = NULL; + while (posn) { + parse_commit(posn->parent); + if (posn->parent->flags & 0x0001) { + /* + printf("1 already seen %s %x\n", + sha1_to_hex(posn->parent->sha1), + posn->parent->flags); + */ + // do nothing + } else if (posn->parent->flags & 0x0002) { + // XXXX free lists + return posn->parent; + } else { + /* + printf("1 based on %s\n", + sha1_to_hex(posn->parent->sha1)); + */ + posn->parent->flags |= 0x0001; + + parent = posn->parent->parent; + while (parent) { + temp = malloc(sizeof(struct parent)); + temp->next = rev1list; + temp->parent = parent->parent; + rev1list = temp; + parent = parent->next; + } + } + posn = posn->next; + } + posn = rev2list; + rev2list = NULL; + while (posn) { + parse_commit(posn->parent); + if (posn->parent->flags & 0x0002) { + /* + printf("2 already seen %s\n", + sha1_to_hex(posn->parent->sha1)); + */ + // do nothing + } else if (posn->parent->flags & 0x0001) { + // XXXX free lists + return posn->parent; + } else { + /* + printf("2 based on %s\n", + sha1_to_hex(posn->parent->sha1)); + */ + posn->parent->flags |= 0x0002; + + parent = posn->parent->parent; + while (parent) { + temp = malloc(sizeof(struct parent)); + temp->next = rev2list; + temp->parent = parent->parent; + rev2list = temp; + parent = parent->next; + } + } + posn = posn->next; + } + } + return NULL; +} + +int main(int argc, char **argv) +{ + struct revision *rev1, *rev2, *ret; + unsigned char rev1key[20], rev2key[20]; + if (argc != 3 || + get_sha1_hex(argv[1], rev1key) || + get_sha1_hex(argv[2], rev2key)) { + usage("mergebase <commit-id> <commit-id>"); + } + rev1 = lookup_rev(rev1key); + rev2 = lookup_rev(rev2key); + ret = common_ancestor(rev1, rev2); + if (ret) { + printf("%s\n", sha1_to_hex(ret->sha1)); + return 0; + } else { + printf("Sorry.\n"); + return 1; + } + +} - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html