Peter Hagervall | baffc0e | 2007-07-15 01:14:45 +0200 | [diff] [blame] | 1 | #include "builtin.h" |
Linus Torvalds | 6683463 | 2005-04-17 12:18:17 -0700 | [diff] [blame] | 2 | #include "cache.h" |
Daniel Barkalow | b5039db | 2005-04-18 11:39:48 -0700 | [diff] [blame] | 3 | #include "commit.h" |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 4 | #include "parse-options.h" |
Linus Torvalds | 6683463 | 2005-04-17 12:18:17 -0700 | [diff] [blame] | 5 | |
Christian Couder | 53eda89 | 2008-07-30 07:04:14 +0200 | [diff] [blame] | 6 | static int show_merge_base(struct commit **rev, int rev_nr, int show_all) |
Johannes Schindelin | 52cab8a | 2006-06-29 15:16:46 +0200 | [diff] [blame] | 7 | { |
Christian Couder | 53eda89 | 2008-07-30 07:04:14 +0200 | [diff] [blame] | 8 | struct commit_list *result; |
| 9 | |
| 10 | result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1, 0); |
Johannes Schindelin | 52cab8a | 2006-06-29 15:16:46 +0200 | [diff] [blame] | 11 | |
| 12 | if (!result) |
| 13 | return 1; |
| 14 | |
Junio C Hamano | 9585e40 | 2005-08-23 21:08:59 -0700 | [diff] [blame] | 15 | while (result) { |
Johannes Schindelin | 52cab8a | 2006-06-29 15:16:46 +0200 | [diff] [blame] | 16 | printf("%s\n", sha1_to_hex(result->item->object.sha1)); |
Junio C Hamano | 9585e40 | 2005-08-23 21:08:59 -0700 | [diff] [blame] | 17 | if (!show_all) |
| 18 | return 0; |
Johannes Schindelin | 52cab8a | 2006-06-29 15:16:46 +0200 | [diff] [blame] | 19 | result = result->next; |
Junio C Hamano | 9585e40 | 2005-08-23 21:08:59 -0700 | [diff] [blame] | 20 | } |
Johannes Schindelin | 52cab8a | 2006-06-29 15:16:46 +0200 | [diff] [blame] | 21 | |
Junio C Hamano | 9585e40 | 2005-08-23 21:08:59 -0700 | [diff] [blame] | 22 | return 0; |
Linus Torvalds | 6683463 | 2005-04-17 12:18:17 -0700 | [diff] [blame] | 23 | } |
| 24 | |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 25 | static const char * const merge_base_usage[] = { |
Vincent van Ravesteijn | 5729482 | 2011-04-15 10:34:03 +0200 | [diff] [blame] | 26 | "git merge-base [-a|--all] <commit> <commit>...", |
| 27 | "git merge-base [-a|--all] --octopus <commit>...", |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 28 | "git merge-base --independent <commit>...", |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 29 | NULL |
| 30 | }; |
Junio C Hamano | 9585e40 | 2005-08-23 21:08:59 -0700 | [diff] [blame] | 31 | |
Christian Couder | df57acc | 2008-07-29 07:42:53 +0200 | [diff] [blame] | 32 | static struct commit *get_commit_reference(const char *arg) |
| 33 | { |
| 34 | unsigned char revkey[20]; |
| 35 | struct commit *r; |
| 36 | |
| 37 | if (get_sha1(arg, revkey)) |
| 38 | die("Not a valid object name %s", arg); |
| 39 | r = lookup_commit_reference(revkey); |
| 40 | if (!r) |
| 41 | die("Not a valid commit name %s", arg); |
| 42 | |
| 43 | return r; |
| 44 | } |
| 45 | |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 46 | static int handle_octopus(int count, const char **args, int reduce, int show_all) |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 47 | { |
| 48 | struct commit_list *revs = NULL; |
| 49 | struct commit_list *result; |
| 50 | int i; |
| 51 | |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 52 | if (reduce) |
| 53 | show_all = 1; |
| 54 | |
| 55 | for (i = count - 1; i >= 0; i--) |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 56 | commit_list_insert(get_commit_reference(args[i]), &revs); |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 57 | |
| 58 | result = reduce ? reduce_heads(revs) : get_octopus_merge_bases(revs); |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 59 | |
| 60 | if (!result) |
| 61 | return 1; |
| 62 | |
| 63 | while (result) { |
| 64 | printf("%s\n", sha1_to_hex(result->item->object.sha1)); |
| 65 | if (!show_all) |
| 66 | return 0; |
| 67 | result = result->next; |
| 68 | } |
| 69 | |
| 70 | return 0; |
| 71 | } |
| 72 | |
Junio C Hamano | 71dfbf2 | 2007-01-09 00:50:02 -0800 | [diff] [blame] | 73 | int cmd_merge_base(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 6683463 | 2005-04-17 12:18:17 -0700 | [diff] [blame] | 74 | { |
Christian Couder | 53eda89 | 2008-07-30 07:04:14 +0200 | [diff] [blame] | 75 | struct commit **rev; |
| 76 | int rev_nr = 0; |
Junio C Hamano | 71dfbf2 | 2007-01-09 00:50:02 -0800 | [diff] [blame] | 77 | int show_all = 0; |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 78 | int octopus = 0; |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 79 | int reduce = 0; |
Linus Torvalds | 6683463 | 2005-04-17 12:18:17 -0700 | [diff] [blame] | 80 | |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 81 | struct option options[] = { |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 82 | OPT_BOOLEAN('a', "all", &show_all, "output all common ancestors"), |
| 83 | OPT_BOOLEAN(0, "octopus", &octopus, "find ancestors for a single n-way merge"), |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 84 | OPT_BOOLEAN(0, "independent", &reduce, "list revs not reachable from others"), |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 85 | OPT_END() |
| 86 | }; |
| 87 | |
Johannes Schindelin | ef90d6d | 2008-05-14 18:46:53 +0100 | [diff] [blame] | 88 | git_config(git_default_config, NULL); |
Stephen Boyd | 3778292 | 2009-05-23 11:53:12 -0700 | [diff] [blame] | 89 | argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 90 | if (!octopus && !reduce && argc < 2) |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 91 | usage_with_options(merge_base_usage, options); |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 92 | if (reduce && (show_all || octopus)) |
| 93 | die("--independent cannot be used with other options"); |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 94 | |
Jonathan Nieder | a1e0ad7 | 2010-08-17 02:01:54 -0500 | [diff] [blame] | 95 | if (octopus || reduce) |
| 96 | return handle_octopus(argc, argv, reduce, show_all); |
Jonathan Nieder | aa8f98c | 2010-08-17 02:01:15 -0500 | [diff] [blame] | 97 | |
Pierre Habouzit | e5d1a4d | 2008-10-02 14:59:19 +0200 | [diff] [blame] | 98 | rev = xmalloc(argc * sizeof(*rev)); |
| 99 | while (argc-- > 0) |
| 100 | rev[rev_nr++] = get_commit_reference(*argv++); |
Christian Couder | 53eda89 | 2008-07-30 07:04:14 +0200 | [diff] [blame] | 101 | return show_merge_base(rev, rev_nr, show_all); |
Linus Torvalds | 6683463 | 2005-04-17 12:18:17 -0700 | [diff] [blame] | 102 | } |