Merge branch 'seq-builtin-dev' into mymaster
[git/sbeyer.git] / pick.c
blobf0a290519bf540c0fba4fa8fffc7993d78aaf9b6
1 #include "cache.h"
2 #include "commit.h"
3 #include "run-command.h"
4 #include "cache-tree.h"
5 #include "pick.h"
6 #include "merge-recursive.h"
8 static struct commit *commit;
10 static char *get_oneline(const char *message)
12 char *result;
13 const char *p = message, *abbrev, *eol;
14 int abbrev_len, oneline_len;
16 if (!p)
17 return NULL;
18 while (*p && (*p != '\n' || p[1] != '\n'))
19 p++;
21 if (*p) {
22 p += 2;
23 for (eol = p + 1; *eol && *eol != '\n'; eol++)
24 ; /* do nothing */
25 } else
26 eol = p;
27 abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
28 abbrev_len = strlen(abbrev);
29 oneline_len = eol - p;
30 result = xmalloc(abbrev_len + 5 + oneline_len);
31 memcpy(result, abbrev, abbrev_len);
32 memcpy(result + abbrev_len, "... ", 4);
33 memcpy(result + abbrev_len + 4, p, oneline_len);
34 result[abbrev_len + 4 + oneline_len] = '\0';
35 return result;
38 static void add_message_to_msg(struct strbuf *msg, const char *message)
40 const char *p = message;
41 while (*p && (*p != '\n' || p[1] != '\n'))
42 p++;
44 if (!*p)
45 strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
47 p += 2;
48 strbuf_addstr(msg, p);
49 return;
52 static struct tree *empty_tree(void)
54 struct tree *tree = xcalloc(1, sizeof(struct tree));
56 tree->object.parsed = 1;
57 tree->object.type = OBJ_TREE;
58 pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
59 return tree;
63 * Pick changes introduced by "commit" argument into current working
64 * tree and index.
66 * It starts from the current index (not HEAD), and allow the effect
67 * of one commit replayed (either forward or backward) to that state,
68 * leaving the result in the index.
70 * You do not have to start from a commit, so you can replay many
71 * commits to the index in sequence without commiting in between to
72 * squash multiple steps if you wanted to.
74 * Return 0 on success.
75 * Return negative value on error before picking,
76 * and a positive value after picking,
77 * and return 1 if and only if a conflict occurs but no other error.
79 int pick_commit(struct commit *pick_commit, int mainline, int flags,
80 struct strbuf *msg)
82 unsigned char head[20];
83 struct commit *base, *next, *parent;
84 int i, index_fd, clean;
85 int ret = 0;
86 char *oneline;
87 const char *message;
88 struct merge_options o;
89 struct tree *result, *next_tree, *base_tree, *head_tree;
90 static struct lock_file index_lock;
92 strbuf_init(msg, 0);
93 commit = pick_commit;
96 * Let's compute the tree that represents the "current" state
97 * for merge-recursive to work on.
99 if (write_cache_as_tree(head, 0, NULL))
100 return error("Your index file is unmerged.");
101 discard_cache();
103 index_fd = hold_locked_index(&index_lock, 0);
104 if (index_fd < 0)
105 return error("Unable to create locked index: %s",
106 strerror(errno));
108 if (!commit->parents) {
109 if (flags & PICK_REVERSE)
110 return error("Cannot revert a root commit");
111 parent = NULL;
113 else if (commit->parents->next) {
114 /* Reverting or cherry-picking a merge commit */
115 int cnt;
116 struct commit_list *p;
118 if (!mainline)
119 return error("Commit %s is a merge but no mainline was given.",
120 sha1_to_hex(commit->object.sha1));
122 for (cnt = 1, p = commit->parents;
123 cnt != mainline && p;
124 cnt++)
125 p = p->next;
126 if (cnt != mainline || !p)
127 return error("Commit %s does not have parent %d",
128 sha1_to_hex(commit->object.sha1),
129 mainline);
130 parent = p->item;
131 } else if (0 < mainline)
132 return error("Mainline was specified but commit %s is not a merge.",
133 sha1_to_hex(commit->object.sha1));
134 else
135 parent = commit->parents->item;
137 if (!(message = commit->buffer))
138 return error("Cannot get commit message for %s",
139 sha1_to_hex(commit->object.sha1));
141 if (parent && parse_commit(parent) < 0)
142 return error("Cannot parse parent commit %s",
143 sha1_to_hex(parent->object.sha1));
145 oneline = get_oneline(message);
147 if (flags & PICK_REVERSE) {
148 char *oneline_body = strchr(oneline, ' ');
150 base = commit;
151 next = parent;
152 strbuf_addstr(msg, "Revert \"");
153 strbuf_addstr(msg, oneline_body + 1);
154 strbuf_addstr(msg, "\"\n\nThis reverts commit ");
155 strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
157 if (commit->parents->next) {
158 strbuf_addstr(msg, ", reversing\nchanges made to ");
159 strbuf_addstr(msg, sha1_to_hex(parent->object.sha1));
161 strbuf_addstr(msg, ".\n");
162 } else {
163 base = parent;
164 next = commit;
165 add_message_to_msg(msg, message);
166 if (flags & PICK_ADD_NOTE) {
167 strbuf_addstr(msg, "(cherry picked from commit ");
168 strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
169 strbuf_addstr(msg, ")\n");
173 read_cache();
174 init_merge_options(&o);
175 o.branch1 = "HEAD";
176 o.branch2 = oneline;
178 head_tree = parse_tree_indirect(head);
179 next_tree = next ? next->tree : empty_tree();
180 base_tree = base ? base->tree : empty_tree();
182 clean = merge_trees(&o,
183 head_tree,
184 next_tree, base_tree, &result);
185 free_merge_options(&o);
187 if (active_cache_changed &&
188 (write_cache(index_fd, active_cache, active_nr) ||
189 commit_locked_index(&index_lock))) {
190 error("Unable to write new index file");
191 return 2;
193 rollback_lock_file(&index_lock);
195 if (!clean) {
196 strbuf_addstr(msg, "\nConflicts:\n\n");
197 for (i = 0; i < active_nr;) {
198 struct cache_entry *ce = active_cache[i++];
199 if (ce_stage(ce)) {
200 strbuf_addstr(msg, "\t");
201 strbuf_addstr(msg, ce->name);
202 strbuf_addstr(msg, "\n");
203 while (i < active_nr && !strcmp(ce->name,
204 active_cache[i]->name))
205 i++;
208 ret = 1;
210 free(oneline);
212 discard_cache();
213 if (read_cache() < 0) {
214 error("Cannot read the index");
215 return 2;
218 return ret;