Stephen Boyd | c2e86ad | 2011-03-22 00:51:05 -0700 | [diff] [blame] | 1 | #include "builtin.h" |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 2 | #include "commit.h" |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 3 | #include "tag.h" |
Daniel Barkalow | e1b3a2c | 2008-02-07 11:40:05 -0500 | [diff] [blame] | 4 | #include "merge-recursive.h" |
Justin Frankel | 58a1ece | 2010-08-26 00:50:45 -0500 | [diff] [blame] | 5 | #include "xdiff-interface.h" |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 6 | |
Thiago Farina | e78d01b | 2010-08-30 00:30:22 -0300 | [diff] [blame] | 7 | static const char builtin_merge_recursive_usage[] = |
| 8 | "git %s <base>... -- <head> <remote> ..."; |
| 9 | |
Shawn O. Pearce | 7ba3c07 | 2006-12-28 02:35:20 -0500 | [diff] [blame] | 10 | static const char *better_branch_name(const char *branch) |
| 11 | { |
| 12 | static char githead_env[8 + 40 + 1]; |
| 13 | char *name; |
| 14 | |
| 15 | if (strlen(branch) != 40) |
| 16 | return branch; |
| 17 | sprintf(githead_env, "GITHEAD_%s", branch); |
| 18 | name = getenv(githead_env); |
| 19 | return name ? name : branch; |
| 20 | } |
| 21 | |
Daniel Barkalow | e1b3a2c | 2008-02-07 11:40:05 -0500 | [diff] [blame] | 22 | int cmd_merge_recursive(int argc, const char **argv, const char *prefix) |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 23 | { |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 24 | const unsigned char *bases[21]; |
Stephan Beyer | 73118f8 | 2008-08-12 22:13:59 +0200 | [diff] [blame] | 25 | unsigned bases_count = 0; |
| 26 | int i, failed; |
Stephan Beyer | 73118f8 | 2008-08-12 22:13:59 +0200 | [diff] [blame] | 27 | unsigned char h1[20], h2[20]; |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 28 | struct merge_options o; |
| 29 | struct commit *result; |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 30 | |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 31 | init_merge_options(&o); |
Junio C Hamano | 85e51b7 | 2008-06-30 22:18:57 -0700 | [diff] [blame] | 32 | if (argv[0] && !suffixcmp(argv[0], "-subtree")) |
| 33 | o.subtree_shift = ""; |
Junio C Hamano | 68faf68 | 2007-02-15 16:32:45 -0800 | [diff] [blame] | 34 | |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 35 | if (argc < 4) |
Thiago Farina | e78d01b | 2010-08-30 00:30:22 -0300 | [diff] [blame] | 36 | usagef(builtin_merge_recursive_usage, argv[0]); |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 37 | |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 38 | for (i = 1; i < argc; ++i) { |
Avery Pennarun | 8cc5b29 | 2009-11-25 21:23:55 -0500 | [diff] [blame] | 39 | const char *arg = argv[i]; |
| 40 | |
| 41 | if (!prefixcmp(arg, "--")) { |
| 42 | if (!arg[2]) |
| 43 | break; |
Jonathan Nieder | 635a7bb | 2010-08-26 00:47:58 -0500 | [diff] [blame] | 44 | if (parse_merge_opt(&o, arg + 2)) |
Avery Pennarun | 8cc5b29 | 2009-11-25 21:23:55 -0500 | [diff] [blame] | 45 | die("Unknown option %s", arg); |
| 46 | continue; |
| 47 | } |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 48 | if (bases_count < ARRAY_SIZE(bases)-1) { |
| 49 | unsigned char *sha = xmalloc(20); |
| 50 | if (get_sha1(argv[i], sha)) |
| 51 | die("Could not parse object '%s'", argv[i]); |
| 52 | bases[bases_count++] = sha; |
Stephan Beyer | 73118f8 | 2008-08-12 22:13:59 +0200 | [diff] [blame] | 53 | } |
Stephan Beyer | 73118f8 | 2008-08-12 22:13:59 +0200 | [diff] [blame] | 54 | else |
Johannes Schindelin | b74d779 | 2009-05-23 10:04:51 +0200 | [diff] [blame] | 55 | warning("Cannot handle more than %d bases. " |
| 56 | "Ignoring %s.", |
| 57 | (int)ARRAY_SIZE(bases)-1, argv[i]); |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 58 | } |
| 59 | if (argc - i != 3) /* "--" "<head>" "<remote>" */ |
| 60 | die("Not handling anything other than two heads merge."); |
| 61 | |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 62 | o.branch1 = argv[++i]; |
| 63 | o.branch2 = argv[++i]; |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 64 | |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 65 | if (get_sha1(o.branch1, h1)) |
| 66 | die("Could not resolve ref '%s'", o.branch1); |
| 67 | if (get_sha1(o.branch2, h2)) |
| 68 | die("Could not resolve ref '%s'", o.branch2); |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 69 | |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 70 | o.branch1 = better_branch_name(o.branch1); |
| 71 | o.branch2 = better_branch_name(o.branch2); |
Shawn O. Pearce | 3f6ee2d | 2007-01-14 00:28:58 -0500 | [diff] [blame] | 72 | |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 73 | if (o.verbosity >= 3) |
| 74 | printf("Merging %s with %s\n", o.branch1, o.branch2); |
Shawn O. Pearce | e0ec181 | 2006-12-23 03:44:47 -0500 | [diff] [blame] | 75 | |
Miklos Vajna | 8a2fce1 | 2008-08-25 16:25:57 +0200 | [diff] [blame] | 76 | failed = merge_recursive_generic(&o, h1, h2, bases_count, bases, &result); |
Stephan Beyer | 73118f8 | 2008-08-12 22:13:59 +0200 | [diff] [blame] | 77 | if (failed < 0) |
| 78 | return 128; /* die() error code */ |
| 79 | return failed; |
Johannes Schindelin | 6d297f8 | 2006-07-08 18:42:41 +0200 | [diff] [blame] | 80 | } |