diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-07-06 15:38:28 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-07-06 15:38:28 -0700 |
commit | 25d33546d474c7c28b72013c262fc23337cb3b21 (patch) | |
tree | 7551eb457a33329be6b3bb0fc11f76118a6e2c42 /builtin/merge-base.c | |
parent | Merge commit 'v1.7.0' into jc/checkout-reflog-fix (diff) | |
parent | Git 1.7.6 (diff) | |
download | tgif-25d33546d474c7c28b72013c262fc23337cb3b21.tar.xz |
Merge commit 'v1.7.6' into jc/checkout-reflog-fix
* commit 'v1.7.6': (3211 commits)
Git 1.7.6
completion: replace core.abbrevguard to core.abbrev
Git 1.7.6-rc3
Documentation: git diff --check respects core.whitespace
gitweb: 'pickaxe' and 'grep' features requires 'search' to be enabled
t7810: avoid unportable use of "echo"
plug a few coverity-spotted leaks
builtin/gc.c: add missing newline in message
tests: link shell libraries into valgrind directory
t/Makefile: pass test opts to valgrind target properly
sh-i18n--envsubst.c: do not #include getopt.h
Fix typo: existant->existent
Git 1.7.6-rc2
gitweb: do not misparse nonnumeric content tag files that contain a digit
Git 1.7.6-rc1
fetch: do not leak a refspec
t3703: skip more tests using colons in file names on Windows
gitweb: Fix usability of $prevent_xss
gitweb: Move "Requirements" up in gitweb/INSTALL
gitweb: Describe CSSMIN and JSMIN in gitweb/INSTALL
...
Diffstat (limited to 'builtin/merge-base.c')
-rw-r--r-- | builtin/merge-base.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/builtin/merge-base.c b/builtin/merge-base.c new file mode 100644 index 0000000000..4f30f1b0c8 --- /dev/null +++ b/builtin/merge-base.c @@ -0,0 +1,102 @@ +#include "builtin.h" +#include "cache.h" +#include "commit.h" +#include "parse-options.h" + +static int show_merge_base(struct commit **rev, int rev_nr, int show_all) +{ + struct commit_list *result; + + result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1, 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 * const merge_base_usage[] = { + "git merge-base [-a|--all] <commit> <commit>...", + "git merge-base [-a|--all] --octopus <commit>...", + "git merge-base --independent <commit>...", + NULL +}; + +static struct commit *get_commit_reference(const char *arg) +{ + unsigned char revkey[20]; + struct commit *r; + + if (get_sha1(arg, revkey)) + die("Not a valid object name %s", arg); + r = lookup_commit_reference(revkey); + if (!r) + die("Not a valid commit name %s", arg); + + return r; +} + +static int handle_octopus(int count, const char **args, int reduce, int show_all) +{ + struct commit_list *revs = NULL; + struct commit_list *result; + int i; + + if (reduce) + show_all = 1; + + for (i = count - 1; i >= 0; i--) + commit_list_insert(get_commit_reference(args[i]), &revs); + + result = reduce ? reduce_heads(revs) : get_octopus_merge_bases(revs); + + 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; +} + +int cmd_merge_base(int argc, const char **argv, const char *prefix) +{ + struct commit **rev; + int rev_nr = 0; + int show_all = 0; + int octopus = 0; + int reduce = 0; + + struct option options[] = { + OPT_BOOLEAN('a', "all", &show_all, "output all common ancestors"), + OPT_BOOLEAN(0, "octopus", &octopus, "find ancestors for a single n-way merge"), + OPT_BOOLEAN(0, "independent", &reduce, "list revs not reachable from others"), + OPT_END() + }; + + git_config(git_default_config, NULL); + argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); + if (!octopus && !reduce && argc < 2) + usage_with_options(merge_base_usage, options); + if (reduce && (show_all || octopus)) + die("--independent cannot be used with other options"); + + if (octopus || reduce) + return handle_octopus(argc, argv, reduce, show_all); + + rev = xmalloc(argc * sizeof(*rev)); + while (argc-- > 0) + rev[rev_nr++] = get_commit_reference(*argv++); + return show_merge_base(rev, rev_nr, show_all); +} |