blob: c2ce044a201366d7eea11ab3d2eeed2c15113af4 [file] [log] [blame]
Stephen Boydc2e86ad2011-03-22 00:51:05 -07001#include "builtin.h"
Elijah Newren6c6ddf92023-04-11 03:00:39 +00002#include "advice.h"
Elijah Newrenf394e092023-03-21 06:25:54 +00003#include "gettext.h"
Elijah Newrend1cbe1e2023-04-22 20:17:20 +00004#include "hash.h"
Daniel Barkalowe1b3a2c2008-02-07 11:40:05 -05005#include "merge-recursive.h"
Elijah Newrendabab1d2023-04-11 00:41:49 -07006#include "object-name.h"
Elijah Newrend1cbe1e2023-04-22 20:17:20 +00007#include "repository.h"
Johannes Schindelin6d297f82006-07-08 18:42:41 +02008
Thiago Farinae78d01b2010-08-30 00:30:22 -03009static const char builtin_merge_recursive_usage[] =
10 "git %s <base>... -- <head> <remote> ...";
11
Jeff Kingd64bb062019-01-11 17:16:55 -050012static char *better_branch_name(const char *branch)
Shawn O. Pearce7ba3c072006-12-28 02:35:20 -050013{
brian m. carlsonb7f20f72018-07-16 01:28:04 +000014 static char githead_env[8 + GIT_MAX_HEXSZ + 1];
Shawn O. Pearce7ba3c072006-12-28 02:35:20 -050015 char *name;
16
brian m. carlsonb7f20f72018-07-16 01:28:04 +000017 if (strlen(branch) != the_hash_algo->hexsz)
Jeff Kingd64bb062019-01-11 17:16:55 -050018 return xstrdup(branch);
Jeff King5096d492015-09-24 17:06:08 -040019 xsnprintf(githead_env, sizeof(githead_env), "GITHEAD_%s", branch);
Shawn O. Pearce7ba3c072006-12-28 02:35:20 -050020 name = getenv(githead_env);
Jeff Kingd64bb062019-01-11 17:16:55 -050021 return xstrdup(name ? name : branch);
Shawn O. Pearce7ba3c072006-12-28 02:35:20 -050022}
23
Jeff King5247b762023-03-28 16:56:55 -040024int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
Johannes Schindelin6d297f82006-07-08 18:42:41 +020025{
brian m. carlson4e8161a2016-06-24 23:09:28 +000026 const struct object_id *bases[21];
Stephan Beyer73118f82008-08-12 22:13:59 +020027 unsigned bases_count = 0;
28 int i, failed;
brian m. carlson4e8161a2016-06-24 23:09:28 +000029 struct object_id h1, h2;
Miklos Vajna8a2fce12008-08-25 16:25:57 +020030 struct merge_options o;
Jeff Kingd64bb062019-01-11 17:16:55 -050031 char *better1, *better2;
Miklos Vajna8a2fce12008-08-25 16:25:57 +020032 struct commit *result;
Johannes Schindelin6d297f82006-07-08 18:42:41 +020033
Nguyễn Thái Ngọc Duy0d6caa22019-01-12 09:13:29 +070034 init_merge_options(&o, the_repository);
Christian Couder59556542013-11-30 21:55:40 +010035 if (argv[0] && ends_with(argv[0], "-subtree"))
Junio C Hamano85e51b72008-06-30 22:18:57 -070036 o.subtree_shift = "";
Junio C Hamano68faf682007-02-15 16:32:45 -080037
Johannes Schindelin6d297f82006-07-08 18:42:41 +020038 if (argc < 4)
Thiago Farinae78d01b2010-08-30 00:30:22 -030039 usagef(builtin_merge_recursive_usage, argv[0]);
Johannes Schindelin6d297f82006-07-08 18:42:41 +020040
Johannes Schindelin6d297f82006-07-08 18:42:41 +020041 for (i = 1; i < argc; ++i) {
Avery Pennarun8cc5b292009-11-25 21:23:55 -050042 const char *arg = argv[i];
43
Christian Couder59556542013-11-30 21:55:40 +010044 if (starts_with(arg, "--")) {
Avery Pennarun8cc5b292009-11-25 21:23:55 -050045 if (!arg[2])
46 break;
Jonathan Nieder635a7bb2010-08-26 00:47:58 -050047 if (parse_merge_opt(&o, arg + 2))
Vasco Almeidaccf78132016-09-15 14:59:01 +000048 die(_("unknown option %s"), arg);
Avery Pennarun8cc5b292009-11-25 21:23:55 -050049 continue;
50 }
Miklos Vajna8a2fce12008-08-25 16:25:57 +020051 if (bases_count < ARRAY_SIZE(bases)-1) {
brian m. carlson4e8161a2016-06-24 23:09:28 +000052 struct object_id *oid = xmalloc(sizeof(struct object_id));
Ævar Arnfjörð Bjarmasond850b7a2023-03-28 15:58:46 +020053 if (repo_get_oid(the_repository, argv[i], oid))
Vasco Almeidaccf78132016-09-15 14:59:01 +000054 die(_("could not parse object '%s'"), argv[i]);
brian m. carlson4e8161a2016-06-24 23:09:28 +000055 bases[bases_count++] = oid;
Stephan Beyer73118f82008-08-12 22:13:59 +020056 }
Stephan Beyer73118f82008-08-12 22:13:59 +020057 else
Vasco Almeidaccf78132016-09-15 14:59:01 +000058 warning(Q_("cannot handle more than %d base. "
59 "Ignoring %s.",
60 "cannot handle more than %d bases. "
61 "Ignoring %s.",
Ævar Arnfjörð Bjarmason6f693252022-03-07 16:27:07 +010062 ARRAY_SIZE(bases)-1),
Johannes Schindelinb74d7792009-05-23 10:04:51 +020063 (int)ARRAY_SIZE(bases)-1, argv[i]);
Johannes Schindelin6d297f82006-07-08 18:42:41 +020064 }
65 if (argc - i != 3) /* "--" "<head>" "<remote>" */
Vasco Almeidaccf78132016-09-15 14:59:01 +000066 die(_("not handling anything other than two heads merge."));
Johannes Schindelin6d297f82006-07-08 18:42:41 +020067
Elijah Newren98221752019-08-17 11:41:28 -070068 if (repo_read_index_unmerged(the_repository))
69 die_resolve_conflict("merge");
70
Miklos Vajna8a2fce12008-08-25 16:25:57 +020071 o.branch1 = argv[++i];
72 o.branch2 = argv[++i];
Johannes Schindelin6d297f82006-07-08 18:42:41 +020073
Ævar Arnfjörð Bjarmasond850b7a2023-03-28 15:58:46 +020074 if (repo_get_oid(the_repository, o.branch1, &h1))
Vasco Almeidaccf78132016-09-15 14:59:01 +000075 die(_("could not resolve ref '%s'"), o.branch1);
Ævar Arnfjörð Bjarmasond850b7a2023-03-28 15:58:46 +020076 if (repo_get_oid(the_repository, o.branch2, &h2))
Vasco Almeidaccf78132016-09-15 14:59:01 +000077 die(_("could not resolve ref '%s'"), o.branch2);
Johannes Schindelin6d297f82006-07-08 18:42:41 +020078
Jeff Kingd64bb062019-01-11 17:16:55 -050079 o.branch1 = better1 = better_branch_name(o.branch1);
80 o.branch2 = better2 = better_branch_name(o.branch2);
Shawn O. Pearce3f6ee2d2007-01-14 00:28:58 -050081
Miklos Vajna8a2fce12008-08-25 16:25:57 +020082 if (o.verbosity >= 3)
Vasco Almeida765773c2016-09-15 14:59:02 +000083 printf(_("Merging %s with %s\n"), o.branch1, o.branch2);
Shawn O. Pearcee0ec1812006-12-23 03:44:47 -050084
brian m. carlson4e8161a2016-06-24 23:09:28 +000085 failed = merge_recursive_generic(&o, &h1, &h2, bases_count, bases, &result);
Jeff Kingd64bb062019-01-11 17:16:55 -050086
87 free(better1);
88 free(better2);
89
Stephan Beyer73118f82008-08-12 22:13:59 +020090 if (failed < 0)
91 return 128; /* die() error code */
92 return failed;
Johannes Schindelin6d297f82006-07-08 18:42:41 +020093}