From 71dfbf224ff980f4085f75868dc409118418731e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 9 Jan 2007 00:50:02 -0800 Subject: Make merge-base a built-in. Signed-off-by: Junio C Hamano diff --git a/Makefile b/Makefile index 43113e9..eb88860 100644 --- a/Makefile +++ b/Makefile @@ -194,7 +194,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ PROGRAMS = \ git-convert-objects$X git-fetch-pack$X git-fsck-objects$X \ git-hash-object$X git-index-pack$X git-local-fetch$X \ - git-merge-base$X \ git-daemon$X \ git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \ git-peek-remote$X git-receive-pack$X \ @@ -289,6 +288,7 @@ BUILTIN_OBJS = \ builtin-ls-tree.o \ builtin-mailinfo.o \ builtin-mailsplit.o \ + builtin-merge-base.o \ builtin-merge-file.o \ builtin-mv.o \ builtin-name-rev.o \ diff --git a/builtin-merge-base.c b/builtin-merge-base.c new file mode 100644 index 0000000..e35d362 --- /dev/null +++ b/builtin-merge-base.c @@ -0,0 +1,51 @@ +#include "cache.h" +#include "commit.h" + +static int show_merge_base(struct commit *rev1, struct commit *rev2, int show_all) +{ + struct commit_list *result = get_merge_bases(rev1, rev2, 0); + + if (!result) + return 1; + + while (result) { + printf("%s\n", sha1_to_hex(result->item->object.sha1)); + if (!show_all) + return 0; + result = result->next; + } + + return 0; +} + +static const char merge_base_usage[] = +"git-merge-base [--all] "; + +int cmd_merge_base(int argc, const char **argv, const char *prefix) +{ + struct commit *rev1, *rev2; + unsigned char rev1key[20], rev2key[20]; + int show_all = 0; + + git_config(git_default_config); + + while (1 < argc && argv[1][0] == '-') { + const char *arg = argv[1]; + if (!strcmp(arg, "-a") || !strcmp(arg, "--all")) + show_all = 1; + else + usage(merge_base_usage); + argc--; argv++; + } + if (argc != 3) + usage(merge_base_usage); + if (get_sha1(argv[1], rev1key)) + die("Not a valid object name %s", argv[1]); + if (get_sha1(argv[2], rev2key)) + die("Not a valid object name %s", argv[2]); + rev1 = lookup_commit_reference(rev1key); + rev2 = lookup_commit_reference(rev2key); + if (!rev1 || !rev2) + return 1; + return show_merge_base(rev1, rev2, show_all); +} diff --git a/builtin.h b/builtin.h index df72d09..ae32993 100644 --- a/builtin.h +++ b/builtin.h @@ -42,6 +42,7 @@ extern int cmd_ls_files(int argc, const char **argv, const char *prefix); extern int cmd_ls_tree(int argc, const char **argv, const char *prefix); extern int cmd_mailinfo(int argc, const char **argv, const char *prefix); extern int cmd_mailsplit(int argc, const char **argv, const char *prefix); +extern int cmd_merge_base(int argc, const char **argv, const char *prefix); extern int cmd_merge_file(int argc, const char **argv, const char *prefix); extern int cmd_mv(int argc, const char **argv, const char *prefix); extern int cmd_name_rev(int argc, const char **argv, const char *prefix); diff --git a/git.c b/git.c index bf55499..e7bc79a 100644 --- a/git.c +++ b/git.c @@ -238,6 +238,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "ls-tree", cmd_ls_tree, RUN_SETUP }, { "mailinfo", cmd_mailinfo }, { "mailsplit", cmd_mailsplit }, + { "merge-base", cmd_merge_base, RUN_SETUP }, { "merge-file", cmd_merge_file }, { "mv", cmd_mv, RUN_SETUP }, { "name-rev", cmd_name_rev, RUN_SETUP }, diff --git a/merge-base.c b/merge-base.c deleted file mode 100644 index 385f4ba..0000000 --- a/merge-base.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "cache.h" -#include "commit.h" - -static int show_all; - -static int merge_base(struct commit *rev1, struct commit *rev2) -{ - struct commit_list *result = get_merge_bases(rev1, rev2, 0); - - if (!result) - return 1; - - while (result) { - printf("%s\n", sha1_to_hex(result->item->object.sha1)); - if (!show_all) - return 0; - result = result->next; - } - - return 0; -} - -static const char merge_base_usage[] = -"git-merge-base [--all] "; - -int main(int argc, char **argv) -{ - struct commit *rev1, *rev2; - unsigned char rev1key[20], rev2key[20]; - - setup_git_directory(); - git_config(git_default_config); - - while (1 < argc && argv[1][0] == '-') { - char *arg = argv[1]; - if (!strcmp(arg, "-a") || !strcmp(arg, "--all")) - show_all = 1; - else - usage(merge_base_usage); - argc--; argv++; - } - if (argc != 3) - usage(merge_base_usage); - if (get_sha1(argv[1], rev1key)) - die("Not a valid object name %s", argv[1]); - if (get_sha1(argv[2], rev2key)) - die("Not a valid object name %s", argv[2]); - rev1 = lookup_commit_reference(rev1key); - rev2 = lookup_commit_reference(rev2key); - if (!rev1 || !rev2) - return 1; - return merge_base(rev1, rev2); -} -- cgit v0.10.2-6-g49f6 From 03840fc32d783be6750bf7e41a89687b8c3053eb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 8 Jan 2007 23:22:31 -0800 Subject: Allow in_merge_bases() to take more than one reference commits. The internal function in_merge_bases(A, B) is used to make sure that commit A is an ancestor of commit B. This changes the signature of it to take an array of B's and updates its current callers. Signed-off-by: Junio C Hamano diff --git a/builtin-branch.c b/builtin-branch.c index d3df5a5..020ed6b 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -134,7 +134,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) */ if (!force && - !in_merge_bases(rev, head_rev)) { + !in_merge_bases(rev, &head_rev, 1)) { error("The branch '%s' is not a strict subset of " "your current HEAD.\n" "If you are sure you want to delete it, " diff --git a/builtin-reflog.c b/builtin-reflog.c index a967117..fb37984 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -217,8 +217,8 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1, if ((timestamp < cb->cmd->expire_unreachable) && (!cb->ref_commit || - (old && !in_merge_bases(old, cb->ref_commit)) || - (new && !in_merge_bases(new, cb->ref_commit)))) + (old && !in_merge_bases(old, &cb->ref_commit, 1)) || + (new && !in_merge_bases(new, &cb->ref_commit, 1)))) goto prune; if (cb->newlog) diff --git a/commit.c b/commit.c index 496d37a..aa14c5a 100644 --- a/commit.c +++ b/commit.c @@ -1158,14 +1158,17 @@ struct commit_list *get_merge_bases(struct commit *one, return result; } -int in_merge_bases(struct commit *rev1, struct commit *rev2) +int in_merge_bases(struct commit *commit, struct commit **reference, int num) { struct commit_list *bases, *b; int ret = 0; - bases = get_merge_bases(rev1, rev2, 1); + if (num == 1) + bases = get_merge_bases(commit, *reference, 1); + else + die("not yet"); for (b = bases; b; b = b->next) { - if (!hashcmp(rev1->object.sha1, b->item->object.sha1)) { + if (!hashcmp(commit->object.sha1, b->item->object.sha1)) { ret = 1; break; } diff --git a/commit.h b/commit.h index 936f8fc..b8e6e18 100644 --- a/commit.h +++ b/commit.h @@ -114,5 +114,5 @@ extern int is_repository_shallow(); extern struct commit_list *get_shallow_commits(struct object_array *heads, int depth, int shallow_flag, int not_shallow_flag); -int in_merge_bases(struct commit *rev1, struct commit *rev2); +int in_merge_bases(struct commit *, struct commit **, int); #endif /* COMMIT_H */ -- cgit v0.10.2-6-g49f6