]>
Commit | Line | Data |
---|---|---|
6d297f81 | 1 | #include "cache.h" |
6d297f81 | 2 | #include "commit.h" |
6d297f81 | 3 | #include "tag.h" |
e1b3a2ca | 4 | #include "merge-recursive.h" |
6d297f81 | 5 | |
7ba3c078 SP |
6 | static const char *better_branch_name(const char *branch) |
7 | { | |
8 | static char githead_env[8 + 40 + 1]; | |
9 | char *name; | |
10 | ||
11 | if (strlen(branch) != 40) | |
12 | return branch; | |
13 | sprintf(githead_env, "GITHEAD_%s", branch); | |
14 | name = getenv(githead_env); | |
15 | return name ? name : branch; | |
16 | } | |
17 | ||
6d297f81 JS |
18 | static struct commit *get_ref(const char *ref) |
19 | { | |
20 | unsigned char sha1[20]; | |
21 | struct object *object; | |
22 | ||
23 | if (get_sha1(ref, sha1)) | |
24 | die("Could not resolve ref '%s'", ref); | |
25 | object = deref_tag(parse_object(sha1), ref, strlen(ref)); | |
affeef12 MK |
26 | if (!object) |
27 | return NULL; | |
a970e84e SP |
28 | if (object->type == OBJ_TREE) |
29 | return make_virtual_commit((struct tree*)object, | |
30 | better_branch_name(ref)); | |
bf6d324e | 31 | if (object->type != OBJ_COMMIT) |
6d297f81 JS |
32 | return NULL; |
33 | if (parse_commit((struct commit *)object)) | |
34 | die("Could not parse commit '%s'", sha1_to_hex(object->sha1)); | |
35 | return (struct commit *)object; | |
36 | } | |
37 | ||
e1b3a2ca | 38 | int cmd_merge_recursive(int argc, const char **argv, const char *prefix) |
6d297f81 | 39 | { |
8b944b56 | 40 | static const char *bases[20]; |
6d297f81 | 41 | static unsigned bases_count = 0; |
3af244ca JS |
42 | int i, clean; |
43 | const char *branch1, *branch2; | |
44 | struct commit *result, *h1, *h2; | |
8b944b56 JH |
45 | struct commit_list *ca = NULL; |
46 | struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); | |
47 | int index_fd; | |
9047ebbc | 48 | int subtree_merge = 0; |
6d297f81 | 49 | |
68faf689 JH |
50 | if (argv[0]) { |
51 | int namelen = strlen(argv[0]); | |
52 | if (8 < namelen && | |
53 | !strcmp(argv[0] + namelen - 8, "-subtree")) | |
54 | subtree_merge = 1; | |
55 | } | |
56 | ||
9047ebbc MV |
57 | git_config(merge_recursive_config, NULL); |
58 | merge_recursive_setup(subtree_merge); | |
6d297f81 JS |
59 | if (argc < 4) |
60 | die("Usage: %s <base>... -- <head> <remote> ...\n", argv[0]); | |
61 | ||
6d297f81 JS |
62 | for (i = 1; i < argc; ++i) { |
63 | if (!strcmp(argv[i], "--")) | |
64 | break; | |
65 | if (bases_count < sizeof(bases)/sizeof(*bases)) | |
66 | bases[bases_count++] = argv[i]; | |
67 | } | |
68 | if (argc - i != 3) /* "--" "<head>" "<remote>" */ | |
69 | die("Not handling anything other than two heads merge."); | |
70 | ||
6d297f81 JS |
71 | branch1 = argv[++i]; |
72 | branch2 = argv[++i]; | |
6d297f81 | 73 | |
3af244ca JS |
74 | h1 = get_ref(branch1); |
75 | h2 = get_ref(branch2); | |
6d297f81 | 76 | |
e0ec1819 SP |
77 | branch1 = better_branch_name(branch1); |
78 | branch2 = better_branch_name(branch2); | |
3f6ee2d1 | 79 | |
9047ebbc | 80 | if (merge_recursive_verbosity >= 3) |
8c3275ab | 81 | printf("Merging %s with %s\n", branch1, branch2); |
e0ec1819 | 82 | |
30ca07a2 | 83 | index_fd = hold_locked_index(lock, 1); |
6d297f81 | 84 | |
8b944b56 JH |
85 | for (i = 0; i < bases_count; i++) { |
86 | struct commit *ancestor = get_ref(bases[i]); | |
87 | ca = commit_list_insert(ancestor, &ca); | |
88 | } | |
e1b3a2ca | 89 | clean = merge_recursive(h1, h2, branch1, branch2, ca, &result); |
8b944b56 JH |
90 | |
91 | if (active_cache_changed && | |
92 | (write_cache(index_fd, active_cache, active_nr) || | |
4ed7cd3a | 93 | commit_locked_index(lock))) |
8b944b56 | 94 | die ("unable to write %s", get_index_file()); |
6d297f81 | 95 | |
3af244ca | 96 | return clean ? 0: 1; |
6d297f81 | 97 | } |