Line Flow Count Block(s) Source
1 - /*
2 - * Copyright (C) the libgit2 contributors. All rights reserved.
3 - *
4 - * This file is part of libgit2, distributed under the GNU GPL v2 with
5 - * a Linking Exception. For full terms see the included COPYING file.
6 - */
7 -
8 - #include "common.h"
9 -
10 - #include "buffer.h"
11 - #include "repository.h"
12 - #include "posix.h"
13 - #include "filebuf.h"
14 - #include "merge.h"
15 - #include "array.h"
16 - #include "config.h"
17 - #include "annotated_commit.h"
18 - #include "index.h"
19 -
20 - #include <git2/types.h>
21 - #include <git2/annotated_commit.h>
22 - #include <git2/rebase.h>
23 - #include <git2/commit.h>
24 - #include <git2/reset.h>
25 - #include <git2/revwalk.h>
26 - #include <git2/notes.h>
27 -
28 - #define REBASE_APPLY_DIR "rebase-apply"
29 - #define REBASE_MERGE_DIR "rebase-merge"
30 -
31 - #define HEAD_NAME_FILE "head-name"
32 - #define ORIG_HEAD_FILE "orig-head"
33 - #define HEAD_FILE "head"
34 - #define ONTO_FILE "onto"
35 - #define ONTO_NAME_FILE "onto_name"
36 - #define QUIET_FILE "quiet"
37 -
38 - #define MSGNUM_FILE "msgnum"
39 - #define END_FILE "end"
40 - #define CMT_FILE_FMT "cmt.%" PRIuZ
41 - #define CURRENT_FILE "current"
42 - #define REWRITTEN_FILE "rewritten"
43 -
44 - #define ORIG_DETACHED_HEAD "detached HEAD"
45 -
46 - #define NOTES_DEFAULT_REF NULL
47 -
48 - #define REBASE_DIR_MODE 0777
49 - #define REBASE_FILE_MODE 0666
50 -
51 - typedef enum {
52 - GIT_REBASE_NONE = 0,
53 - GIT_REBASE_APPLY = 1,
54 - GIT_REBASE_MERGE = 2,
55 - GIT_REBASE_INTERACTIVE = 3,
56 - } git_rebase_t;
57 -
58 - struct git_rebase {
59 - git_repository *repo;
60 -
61 - git_rebase_options options;
62 -
63 - git_rebase_t type;
64 - char *state_path;
65 -
66 - int head_detached : 1,
67 - inmemory : 1,
68 - quiet : 1,
69 - started : 1;
70 -
71 - git_array_t(git_rebase_operation) operations;
72 - size_t current;
73 -
74 - /* Used by in-memory rebase */
75 - git_index *index;
76 - git_commit *last_commit;
77 -
78 - /* Used by regular (not in-memory) merge-style rebase */
79 - git_oid orig_head_id;
80 - char *orig_head_name;
81 -
82 - git_oid onto_id;
83 - char *onto_name;
84 - };
85 -
86 - #define GIT_REBASE_STATE_INIT {0}
87 -
88 53 2 static int rebase_state_type(
89 - git_rebase_t *type_out,
90 - char **path_out,
91 - git_repository *repo)
92 - {
93 53 2 git_buf path = GIT_BUF_INIT;
94 53 2 git_rebase_t type = GIT_REBASE_NONE;
95 -
96 53 2,3 if (git_buf_joinpath(&path, repo->gitdir, REBASE_APPLY_DIR) < 0)
97 ##### 4 return -1;
98 -
99 53 5-7 if (git_path_isdir(git_buf_cstr(&path))) {
100 ##### 8 type = GIT_REBASE_APPLY;
101 ##### 8 goto done;
102 - }
103 -
104 53 9 git_buf_clear(&path);
105 53 10,11 if (git_buf_joinpath(&path, repo->gitdir, REBASE_MERGE_DIR) < 0)
106 ##### 12 return -1;
107 -
108 53 13-15 if (git_path_isdir(git_buf_cstr(&path))) {
109 8 16 type = GIT_REBASE_MERGE;
110 8 16 goto done;
111 - }
112 -
113 - done:
114 53 17 *type_out = type;
115 -
116 53 17,18 if (type != GIT_REBASE_NONE && path_out)
117 7 19,20 *path_out = git_buf_detach(&path);
118 -
119 53 21 git_buf_dispose(&path);
120 -
121 53 22 return 0;
122 - }
123 -
124 63 2 GIT_INLINE(int) rebase_readfile(
125 - git_buf *out,
126 - git_buf *state_path,
127 - const char *filename)
128 - {
129 63 2 size_t state_path_len = state_path->size;
130 - int error;
131 -
132 63 2 git_buf_clear(out);
133 -
134 63 3-6 if ((error = git_buf_joinpath(state_path, state_path->ptr, filename)) < 0 ||
135 63 5 (error = git_futils_readbuffer(out, state_path->ptr)) < 0)
136 - goto done;
137 -
138 51 7 git_buf_rtrim(out);
139 -
140 - done:
141 63 8 git_buf_truncate(state_path, state_path_len);
142 63 9 return error;
143 - }
144 -
145 14 2 GIT_INLINE(int) rebase_readint(
146 - size_t *out, git_buf *asc_out, git_buf *state_path, const char *filename)
147 - {
148 - int32_t num;
149 - const char *eol;
150 14 2 int error = 0;
151 -
152 14 2,3 if ((error = rebase_readfile(asc_out, state_path, filename)) < 0)
153 6 4 return error;
154 -
155 8 5-8 if (git__strntol32(&num, asc_out->ptr, asc_out->size, &eol, 10) < 0 || num < 0 || *eol) {
156 ##### 9 git_error_set(GIT_ERROR_REBASE, "the file '%s' contains an invalid numeric value", filename);
157 ##### 10 return -1;
158 - }
159 -
160 8 11 *out = (size_t) num;
161 -
162 8 11 return 0;
163 - }
164 -
165 42 2 GIT_INLINE(int) rebase_readoid(
166 - git_oid *out, git_buf *str_out, git_buf *state_path, const char *filename)
167 - {
168 - int error;
169 -
170 42 2,3 if ((error = rebase_readfile(str_out, state_path, filename)) < 0)
171 6 4 return error;
172 -
173 36 5-7 if (str_out->size != GIT_OID_HEXSZ || git_oid_fromstr(out, str_out->ptr) < 0) {
174 ##### 8 git_error_set(GIT_ERROR_REBASE, "the file '%s' contains an invalid object ID", filename);
175 ##### 9 return -1;
176 - }
177 -
178 36 10 return 0;
179 - }
180 -
181 212 2 static git_rebase_operation *rebase_operation_alloc(
182 - git_rebase *rebase,
183 - git_rebase_operation_t type,
184 - git_oid *id,
185 - const char *exec)
186 - {
187 - git_rebase_operation *operation;
188 -
189 212 2,3 assert((type == GIT_REBASE_OPERATION_EXEC) == !id);
190 212 4,5 assert((type == GIT_REBASE_OPERATION_EXEC) == !!exec);
191 -
192 212 6-12 if ((operation = git_array_alloc(rebase->operations)) == NULL)
193 ##### 13 return NULL;
194 -
195 212 14 operation->type = type;
196 212 14 git_oid_cpy((git_oid *)&operation->id, id);
197 212 15 operation->exec = exec;
198 -
199 212 15 return operation;
200 - }
201 -
202 7 2 static int rebase_open_merge(git_rebase *rebase)
203 - {
204 7 2 git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT;
205 - git_oid id;
206 - git_rebase_operation *operation;
207 7 2 size_t i, msgnum = 0, end;
208 - int error;
209 -
210 7 2,3 if ((error = git_buf_puts(&state_path, rebase->state_path)) < 0)
211 ##### 4 goto done;
212 -
213 - /* Read 'msgnum' if it exists (otherwise, let msgnum = 0) */
214 7 5-7 if ((error = rebase_readint(&msgnum, &buf, &state_path, MSGNUM_FILE)) < 0 &&
215 - error != GIT_ENOTFOUND)
216 ##### 8 goto done;
217 -
218 7 9 if (msgnum) {
219 1 10 rebase->started = 1;
220 1 10 rebase->current = msgnum - 1;
221 - }
222 -
223 - /* Read 'end' */
224 7 11,12 if ((error = rebase_readint(&end, &buf, &state_path, END_FILE)) < 0)
225 ##### 13 goto done;
226 -
227 - /* Read 'current' if it exists */
228 7 14-16 if ((error = rebase_readoid(&id, &buf, &state_path, CURRENT_FILE)) < 0 &&
229 - error != GIT_ENOTFOUND)
230 ##### 17 goto done;
231 -
232 - /* Read cmt.* */
233 7 18 git_array_init_to_size(rebase->operations, end);
234 7 19,20 GIT_ERROR_CHECK_ARRAY(rebase->operations);
235 -
236 42 21,30,31 for (i = 0; i < end; i++) {
237 35 22 git_buf_clear(&cmt);
238 -
239 35 23-26 if ((error = git_buf_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 ||
240 35 25 (error = rebase_readoid(&id, &buf, &state_path, cmt.ptr)) < 0)
241 - goto done;
242 -
243 35 27 operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
244 35 28,29 GIT_ERROR_CHECK_ALLOC(operation);
245 - }
246 -
247 - /* Read 'onto_name' */
248 7 32,33 if ((error = rebase_readfile(&buf, &state_path, ONTO_NAME_FILE)) < 0)
249 ##### 34 goto done;
250 -
251 7 35,36 rebase->onto_name = git_buf_detach(&buf);
252 -
253 - done:
254 7 37 git_buf_dispose(&cmt);
255 7 38 git_buf_dispose(&state_path);
256 7 39 git_buf_dispose(&buf);
257 -
258 7 40 return error;
259 - }
260 -
261 55 2 static int rebase_alloc(git_rebase **out, const git_rebase_options *rebase_opts)
262 - {
263 55 2 git_rebase *rebase = git__calloc(1, sizeof(git_rebase));
264 55 3,4 GIT_ERROR_CHECK_ALLOC(rebase);
265 -
266 55 5 *out = NULL;
267 -
268 55 5 if (rebase_opts)
269 12 6 memcpy(&rebase->options, rebase_opts, sizeof(git_rebase_options));
270 - else
271 43 7 git_rebase_options_init(&rebase->options, GIT_REBASE_OPTIONS_VERSION);
272 -
273 55 8,9 if (rebase_opts && rebase_opts->rewrite_notes_ref) {
274 1 10 rebase->options.rewrite_notes_ref = git__strdup(rebase_opts->rewrite_notes_ref);
275 1 11,12 GIT_ERROR_CHECK_ALLOC(rebase->options.rewrite_notes_ref);
276 - }
277 -
278 55 13 *out = rebase;
279 -
280 55 13 return 0;
281 - }
282 -
283 58 2 static int rebase_check_versions(const git_rebase_options *given_opts)
284 - {
285 58 2-4 GIT_ERROR_CHECK_VERSION(given_opts, GIT_REBASE_OPTIONS_VERSION, "git_rebase_options");
286 -
287 58 5 if (given_opts)
288 12 6-8 GIT_ERROR_CHECK_VERSION(&given_opts->checkout_options, GIT_CHECKOUT_OPTIONS_VERSION, "git_checkout_options");
289 -
290 58 9 return 0;
291 - }
292 -
293 7 2 int git_rebase_open(
294 - git_rebase **out,
295 - git_repository *repo,
296 - const git_rebase_options *given_opts)
297 - {
298 - git_rebase *rebase;
299 7 2 git_buf path = GIT_BUF_INIT, orig_head_name = GIT_BUF_INIT,
300 7 2 orig_head_id = GIT_BUF_INIT, onto_id = GIT_BUF_INIT;
301 - size_t state_path_len;
302 - int error;
303 -
304 7 2,3 assert(repo);
305 -
306 7 4,5 if ((error = rebase_check_versions(given_opts)) < 0)
307 ##### 6 return error;
308 -
309 7 7,8 if (rebase_alloc(&rebase, given_opts) < 0)
310 ##### 9 return -1;
311 -
312 7 10 rebase->repo = repo;
313 -
314 7 10,11 if ((error = rebase_state_type(&rebase->type, &rebase->state_path, repo)) < 0)
315 ##### 12 goto done;
316 -
317 7 13 if (rebase->type == GIT_REBASE_NONE) {
318 ##### 14 git_error_set(GIT_ERROR_REBASE, "there is no rebase in progress");
319 ##### 15 error = GIT_ENOTFOUND;
320 ##### 15 goto done;
321 - }
322 -
323 7 16,17 if ((error = git_buf_puts(&path, rebase->state_path)) < 0)
324 ##### 18 goto done;
325 -
326 7 19 state_path_len = git_buf_len(&path);
327 -
328 7 20-23 if ((error = git_buf_joinpath(&path, path.ptr, HEAD_NAME_FILE)) < 0 ||
329 7 22 (error = git_futils_readbuffer(&orig_head_name, path.ptr)) < 0)
330 - goto done;
331 -
332 7 24 git_buf_rtrim(&orig_head_name);
333 -
334 7 25 if (strcmp(ORIG_DETACHED_HEAD, orig_head_name.ptr) == 0)
335 3 26 rebase->head_detached = 1;
336 -
337 7 27 git_buf_truncate(&path, state_path_len);
338 -
339 7 28,29 if ((error = git_buf_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0)
340 ##### 30 goto done;
341 -
342 7 31,32 if (!git_path_isfile(path.ptr)) {
343 - /* Previous versions of git.git used 'head' here; support that. */
344 ##### 33 git_buf_truncate(&path, state_path_len);
345 -
346 ##### 34,35 if ((error = git_buf_joinpath(&path, path.ptr, HEAD_FILE)) < 0)
347 ##### 36 goto done;
348 - }
349 -
350 7 37,38 if ((error = git_futils_readbuffer(&orig_head_id, path.ptr)) < 0)
351 ##### 39 goto done;
352 -
353 7 40 git_buf_rtrim(&orig_head_id);
354 -
355 7 41,42 if ((error = git_oid_fromstr(&rebase->orig_head_id, orig_head_id.ptr)) < 0)
356 ##### 43 goto done;
357 -
358 7 44 git_buf_truncate(&path, state_path_len);
359 -
360 7 45-48 if ((error = git_buf_joinpath(&path, path.ptr, ONTO_FILE)) < 0 ||
361 7 47 (error = git_futils_readbuffer(&onto_id, path.ptr)) < 0)
362 - goto done;
363 -
364 7 49 git_buf_rtrim(&onto_id);
365 -
366 7 50,51 if ((error = git_oid_fromstr(&rebase->onto_id, onto_id.ptr)) < 0)
367 ##### 52 goto done;
368 -
369 7 53 if (!rebase->head_detached)
370 4 54,55 rebase->orig_head_name = git_buf_detach(&orig_head_name);
371 -
372 7 56 switch (rebase->type) {
373 - case GIT_REBASE_INTERACTIVE:
374 ##### 57 git_error_set(GIT_ERROR_REBASE, "interactive rebase is not supported");
375 ##### 58 error = -1;
376 ##### 58 break;
377 - case GIT_REBASE_MERGE:
378 7 59 error = rebase_open_merge(rebase);
379 7 63 break;
380 - case GIT_REBASE_APPLY:
381 ##### 60 git_error_set(GIT_ERROR_REBASE, "patch application rebase is not supported");
382 ##### 61 error = -1;
383 ##### 61 break;
384 - default:
385 - 62 abort();
386 - }
387 -
388 - done:
389 7 64 if (error == 0)
390 7 65 *out = rebase;
391 - else
392 ##### 66 git_rebase_free(rebase);
393 -
394 7 67 git_buf_dispose(&path);
395 7 68 git_buf_dispose(&orig_head_name);
396 7 69 git_buf_dispose(&orig_head_id);
397 7 70 git_buf_dispose(&onto_id);
398 7 71 return error;
399 - }
400 -
401 19 2 static int rebase_cleanup(git_rebase *rebase)
402 - {
403 19 2,3 if (!rebase || rebase->inmemory)
404 3 4 return 0;
405 -
406 16 5 return git_path_isdir(rebase->state_path) ?
407 16 6-8 git_futils_rmdir_r(rebase->state_path, NULL, GIT_RMDIR_REMOVE_FILES) :
408 - 0;
409 - }
410 -
411 525 2 static int rebase_setupfile(git_rebase *rebase, const char *filename, int flags, const char *fmt, ...)
412 - {
413 525 2 git_buf path = GIT_BUF_INIT,
414 525 2 contents = GIT_BUF_INIT;
415 - va_list ap;
416 - int error;
417 -
418 525 2 va_start(ap, fmt);
419 525 2 git_buf_vprintf(&contents, fmt, ap);
420 525 3 va_end(ap);
421 -
422 525 3,4 if ((error = git_buf_joinpath(&path, rebase->state_path, filename)) == 0)
423 525 5 error = git_futils_writebuffer(&contents, path.ptr, flags, REBASE_FILE_MODE);
424 -
425 525 6 git_buf_dispose(&path);
426 525 7 git_buf_dispose(&contents);
427 -
428 525 8 return error;
429 - }
430 -
431 86 2 static const char *rebase_onto_name(const git_annotated_commit *onto)
432 - {
433 86 2,3 if (onto->ref_name && git__strncmp(onto->ref_name, "refs/heads/", 11) == 0)
434 70 4 return onto->ref_name + 11;
435 16 5 else if (onto->ref_name)
436 ##### 6 return onto->ref_name;
437 - else
438 16 7 return onto->id_str;
439 - }
440 -
441 43 2 static int rebase_setupfiles_merge(git_rebase *rebase)
442 - {
443 43 2 git_buf commit_filename = GIT_BUF_INIT;
444 - char id_str[GIT_OID_HEXSZ];
445 - git_rebase_operation *operation;
446 - size_t i;
447 43 2 int error = 0;
448 -
449 43 2-5 if ((error = rebase_setupfile(rebase, END_FILE, 0, "%" PRIuZ "\n", git_array_size(rebase->operations))) < 0 ||
450 43 4 (error = rebase_setupfile(rebase, ONTO_NAME_FILE, 0, "%s\n", rebase->onto_name)) < 0)
451 - goto done;
452 -
453 199 6,16,17 for (i = 0; i < git_array_size(rebase->operations); i++) {
454 156 7-9 operation = git_array_get(rebase->operations, i);
455 -
456 156 10 git_buf_clear(&commit_filename);
457 156 11 git_buf_printf(&commit_filename, CMT_FILE_FMT, i+1);
458 -
459 156 12 git_oid_fmt(id_str, &operation->id);
460 -
461 156 13,14 if ((error = rebase_setupfile(rebase, commit_filename.ptr, 0,
462 - "%.*s\n", GIT_OID_HEXSZ, id_str)) < 0)
463 ##### 15 goto done;
464 - }
465 -
466 - done:
467 43 18 git_buf_dispose(&commit_filename);
468 43 19 return error;
469 - }
470 -
471 43 2 static int rebase_setupfiles(git_rebase *rebase)
472 - {
473 - char onto[GIT_OID_HEXSZ], orig_head[GIT_OID_HEXSZ];
474 - const char *orig_head_name;
475 -
476 43 2 git_oid_fmt(onto, &rebase->onto_id);
477 43 3 git_oid_fmt(orig_head, &rebase->orig_head_id);
478 -
479 43 4,5 if (p_mkdir(rebase->state_path, REBASE_DIR_MODE) < 0) {
480 ##### 6 git_error_set(GIT_ERROR_OS, "failed to create rebase directory '%s'", rebase->state_path);
481 ##### 7 return -1;
482 - }
483 -
484 43 8-10 orig_head_name = rebase->head_detached ? ORIG_DETACHED_HEAD :
485 - rebase->orig_head_name;
486 -
487 43 11,12,14 if (git_repository__set_orig_head(rebase->repo, &rebase->orig_head_id) < 0 ||
488 43 13,16 rebase_setupfile(rebase, HEAD_NAME_FILE, 0, "%s\n", orig_head_name) < 0 ||
489 43 15,18 rebase_setupfile(rebase, ONTO_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, onto) < 0 ||
490 43 17,23 rebase_setupfile(rebase, ORIG_HEAD_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, orig_head) < 0 ||
491 43 19-22 rebase_setupfile(rebase, QUIET_FILE, 0, rebase->quiet ? "t\n" : "\n") < 0)
492 ##### 24 return -1;
493 -
494 43 25 return rebase_setupfiles_merge(rebase);
495 - }
496 -
497 43 2 int git_rebase_options_init(git_rebase_options *opts, unsigned int version)
498 - {
499 43 2-4 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
500 - opts, version, git_rebase_options, GIT_REBASE_OPTIONS_INIT);
501 43 5 return 0;
502 - }
503 -
504 - #ifndef GIT_DEPRECATE_HARD
505 ##### 2 int git_rebase_init_options(git_rebase_options *opts, unsigned int version)
506 - {
507 ##### 2 return git_rebase_options_init(opts, version);
508 - }
509 - #endif
510 -
511 46 2 static int rebase_ensure_not_in_progress(git_repository *repo)
512 - {
513 - int error;
514 - git_rebase_t type;
515 -
516 46 2,3 if ((error = rebase_state_type(&type, NULL, repo)) < 0)
517 ##### 4 return error;
518 -
519 46 5 if (type != GIT_REBASE_NONE) {
520 1 6 git_error_set(GIT_ERROR_REBASE, "there is an existing rebase in progress");
521 1 7 return -1;
522 - }
523 -
524 45 8 return 0;
525 - }
526 -
527 81 2 static int rebase_ensure_not_dirty(
528 - git_repository *repo,
529 - bool check_index,
530 - bool check_workdir,
531 - int fail_with)
532 - {
533 81 2 git_tree *head = NULL;
534 81 2 git_index *index = NULL;
535 81 2 git_diff *diff = NULL;
536 81 2 int error = 0;
537 -
538 81 2 if (check_index) {
539 45 3-6 if ((error = git_repository_head_tree(&head, repo)) < 0 ||
540 45 7,8 (error = git_repository_index(&index, repo)) < 0 ||
541 45 7 (error = git_diff_tree_to_index(&diff, repo, head, index, NULL)) < 0)
542 - goto done;
543 -
544 45 9,10 if (git_diff_num_deltas(diff) > 0) {
545 1 11 git_error_set(GIT_ERROR_REBASE, "uncommitted changes exist in index");
546 1 12 error = fail_with;
547 1 12 goto done;
548 - }
549 -
550 44 13 git_diff_free(diff);
551 44 14 diff = NULL;
552 - }
553 -
554 80 15 if (check_workdir) {
555 80 16 git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
556 80 16 diff_opts.ignore_submodules = GIT_SUBMODULE_IGNORE_UNTRACKED;
557 80 16,17 if ((error = git_diff_index_to_workdir(&diff, repo, index, &diff_opts)) < 0)
558 3 18,24 goto done;
559 -
560 80 19,20 if (git_diff_num_deltas(diff) > 0) {
561 3 21 git_error_set(GIT_ERROR_REBASE, "unstaged changes exist in workdir");
562 3 22 error = fail_with;
563 77 22,23 goto done;
564 - }
565 - }
566 -
567 - done:
568 81 25 git_diff_free(diff);
569 81 26 git_index_free(index);
570 81 27 git_tree_free(head);
571 -
572 81 28 return error;
573 - }
574 -
575 48 2 static int rebase_init_operations(
576 - git_rebase *rebase,
577 - git_repository *repo,
578 - const git_annotated_commit *branch,
579 - const git_annotated_commit *upstream,
580 - const git_annotated_commit *onto)
581 - {
582 48 2 git_revwalk *revwalk = NULL;
583 - git_commit *commit;
584 - git_oid id;
585 - bool merge;
586 - git_rebase_operation *operation;
587 - int error;
588 -
589 48 2 if (!upstream)
590 8 3 upstream = onto;
591 -
592 48 4,5,7,8 if ((error = git_revwalk_new(&revwalk, rebase->repo)) < 0 ||
593 48 6,10,11 (error = git_revwalk_push(revwalk, git_annotated_commit_id(branch))) < 0 ||
594 48 9 (error = git_revwalk_hide(revwalk, git_annotated_commit_id(upstream))) < 0)
595 - goto done;
596 -
597 48 12 git_revwalk_sorting(revwalk, GIT_SORT_REVERSE);
598 -
599 227 23-25 while ((error = git_revwalk_next(&id, revwalk)) == 0) {
600 179 13,14 if ((error = git_commit_lookup(&commit, repo, &id)) < 0)
601 ##### 15 goto done;
602 -
603 179 16 merge = (git_commit_parentcount(commit) > 1);
604 179 17 git_commit_free(commit);
605 -
606 179 18 if (merge)
607 2 19 continue;
608 -
609 177 20 operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
610 177 21,22 GIT_ERROR_CHECK_ALLOC(operation);
611 - }
612 -
613 48 26 error = 0;
614 -
615 - done:
616 48 27 git_revwalk_free(revwalk);
617 48 28 return error;
618 - }
619 -
620 43 2 static int rebase_init_merge(
621 - git_rebase *rebase,
622 - git_repository *repo,
623 - const git_annotated_commit *branch,
624 - const git_annotated_commit *upstream,
625 - const git_annotated_commit *onto)
626 - {
627 43 2 git_reference *head_ref = NULL;
628 43 2 git_commit *onto_commit = NULL;
629 43 2 git_buf reflog = GIT_BUF_INIT;
630 43 2 git_buf state_path = GIT_BUF_INIT;
631 - int error;
632 -
633 - GIT_UNUSED(upstream);
634 -
635 43 2,3 if ((error = git_buf_joinpath(&state_path, repo->gitdir, REBASE_MERGE_DIR)) < 0)
636 ##### 4 goto done;
637 -
638 43 5 rebase->state_path = git_buf_detach(&state_path);
639 43 6,7 GIT_ERROR_CHECK_ALLOC(rebase->state_path);
640 -
641 43 8,9 if (branch->ref_name && strcmp(branch->ref_name, "HEAD")) {
642 34 10 rebase->orig_head_name = git__strdup(branch->ref_name);
643 34 11-13 GIT_ERROR_CHECK_ALLOC(rebase->orig_head_name);
644 - } else {
645 9 14 rebase->head_detached = 1;
646 - }
647 -
648 43 15,16 rebase->onto_name = git__strdup(rebase_onto_name(onto));
649 43 17,18 GIT_ERROR_CHECK_ALLOC(rebase->onto_name);
650 -
651 43 19 rebase->quiet = rebase->options.quiet;
652 -
653 43 19,20 git_oid_cpy(&rebase->orig_head_id, git_annotated_commit_id(branch));
654 43 21,22 git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto));
655 -
656 43 23,24,26,27 if ((error = rebase_setupfiles(rebase)) < 0 ||
657 43 25 (error = git_buf_printf(&reflog,
658 43 29,30 "rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
659 43 28 (error = git_commit_lookup(
660 43 31,32 &onto_commit, repo, git_annotated_commit_id(onto))) < 0 ||
661 43 31 (error = git_checkout_tree(repo,
662 43 31,34 (git_object *)onto_commit, &rebase->options.checkout_options)) < 0 ||
663 43 33 (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
664 43 33 git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
665 - goto done;
666 -
667 - done:
668 43 35 git_reference_free(head_ref);
669 43 36 git_commit_free(onto_commit);
670 43 37 git_buf_dispose(&reflog);
671 43 38 git_buf_dispose(&state_path);
672 -
673 43 39 return error;
674 - }
675 -
676 5 2 static int rebase_init_inmemory(
677 - git_rebase *rebase,
678 - git_repository *repo,
679 - const git_annotated_commit *branch,
680 - const git_annotated_commit *upstream,
681 - const git_annotated_commit *onto)
682 - {
683 - GIT_UNUSED(branch);
684 - GIT_UNUSED(upstream);
685 -
686 5 2 return git_commit_lookup(
687 - &rebase->last_commit, repo, git_annotated_commit_id(onto));
688 - }
689 -
690 51 2 int git_rebase_init(
691 - git_rebase **out,
692 - git_repository *repo,
693 - const git_annotated_commit *branch,
694 - const git_annotated_commit *upstream,
695 - const git_annotated_commit *onto,
696 - const git_rebase_options *given_opts)
697 - {
698 51 2 git_rebase *rebase = NULL;
699 51 2 git_annotated_commit *head_branch = NULL;
700 51 2 git_reference *head_ref = NULL;
701 51 2-5 bool inmemory = (given_opts && given_opts->inmemory);
702 - int error;
703 -
704 51 6-9 assert(repo && (upstream || onto));
705 -
706 51 10 *out = NULL;
707 -
708 51 10 if (!onto)
709 40 11 onto = upstream;
710 -
711 51 12,13 if ((error = rebase_check_versions(given_opts)) < 0)
712 ##### 14 goto done;
713 -
714 51 15 if (!inmemory) {
715 46 16-19 if ((error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
716 45 20,21 (error = rebase_ensure_not_in_progress(repo)) < 0 ||
717 - (error = rebase_ensure_not_dirty(repo, true, true, GIT_ERROR)) < 0)
718 - goto done;
719 - }
720 -
721 48 22 if (!branch) {
722 2 23-26 if ((error = git_repository_head(&head_ref, repo)) < 0 ||
723 2 25 (error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
724 - goto done;
725 -
726 2 27 branch = head_branch;
727 - }
728 -
729 48 28,29 if (rebase_alloc(&rebase, given_opts) < 0)
730 ##### 30 return -1;
731 -
732 48 31 rebase->repo = repo;
733 48 31 rebase->inmemory = inmemory;
734 48 31 rebase->type = GIT_REBASE_MERGE;
735 -
736 48 31,32 if ((error = rebase_init_operations(rebase, repo, branch, upstream, onto)) < 0)
737 ##### 33 goto done;
738 -
739 48 34 if (inmemory)
740 5 35 error = rebase_init_inmemory(rebase, repo, branch, upstream, onto);
741 - else
742 43 36 error = rebase_init_merge(rebase, repo, branch ,upstream, onto);
743 -
744 48 37 if (error == 0)
745 48 38 *out = rebase;
746 -
747 - done:
748 51 39 git_reference_free(head_ref);
749 51 40 git_annotated_commit_free(head_branch);
750 -
751 51 41 if (error < 0) {
752 3 42 rebase_cleanup(rebase);
753 3 43 git_rebase_free(rebase);
754 - }
755 -
756 51 44 return error;
757 - }
758 -
759 39 2 static void normalize_checkout_options_for_apply(
760 - git_checkout_options *checkout_opts,
761 - git_rebase *rebase,
762 - git_commit *current_commit)
763 - {
764 39 2 memcpy(checkout_opts, &rebase->options.checkout_options, sizeof(git_checkout_options));
765 -
766 39 2 if (!checkout_opts->ancestor_label)
767 39 3 checkout_opts->ancestor_label = "ancestor";
768 -
769 39 4 if (rebase->type == GIT_REBASE_MERGE) {
770 39 5 if (!checkout_opts->our_label)
771 39 6 checkout_opts->our_label = rebase->onto_name;
772 -
773 39 7 if (!checkout_opts->their_label)
774 39 8-10 checkout_opts->their_label = git_commit_summary(current_commit);
775 - } else {
776 - 11 abort();
777 - }
778 39 12 }
779 -
780 63 2 GIT_INLINE(int) rebase_movenext(git_rebase *rebase)
781 - {
782 63 2-4 size_t next = rebase->started ? rebase->current + 1 : 0;
783 -
784 63 5 if (next == git_array_size(rebase->operations))
785 11 6 return GIT_ITEROVER;
786 -
787 52 7 rebase->started = 1;
788 52 7 rebase->current = next;
789 -
790 52 7 return 0;
791 - }
792 -
793 39 2 static int rebase_next_merge(
794 - git_rebase_operation **out,
795 - git_rebase *rebase)
796 - {
797 39 2 git_buf path = GIT_BUF_INIT;
798 39 2 git_commit *current_commit = NULL, *parent_commit = NULL;
799 39 2 git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
800 39 2 git_index *index = NULL;
801 39 2 git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
802 - git_rebase_operation *operation;
803 - git_checkout_options checkout_opts;
804 - char current_idstr[GIT_OID_HEXSZ];
805 - unsigned int parent_count;
806 - int error;
807 -
808 39 2 *out = NULL;
809 -
810 39 2-4 operation = git_array_get(rebase->operations, rebase->current);
811 -
812 39 5-8 if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
813 39 7,9,10 (error = git_commit_tree(&current_tree, current_commit)) < 0 ||
814 39 9 (error = git_repository_head_tree(&head_tree, rebase->repo)) < 0)
815 - goto done;
816 -
817 39 11,12 if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
818 ##### 13 git_error_set(GIT_ERROR_REBASE, "cannot rebase a merge commit");
819 ##### 14 error = -1;
820 ##### 14 goto done;
821 39 15 } else if (parent_count) {
822 38 16-19 if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
823 38 18 (error = git_commit_tree(&parent_tree, parent_commit)) < 0)
824 - goto done;
825 - }
826 -
827 39 20 git_oid_fmt(current_idstr, &operation->id);
828 -
829 39 21 normalize_checkout_options_for_apply(&checkout_opts, rebase, current_commit);
830 -
831 39 22-25 if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 ||
832 39 24,26,27 (error = rebase_setupfile(rebase, MSGNUM_FILE, 0, "%" PRIuZ "\n", rebase->current+1)) < 0 ||
833 39 28,29 (error = rebase_setupfile(rebase, CURRENT_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 ||
834 39 28,30,31 (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0 ||
835 38 30,32,33 (error = git_merge__check_result(rebase->repo, index)) < 0 ||
836 38 32,34,35 (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 ||
837 - (error = git_indexwriter_commit(&indexwriter)) < 0)
838 - goto done;
839 -
840 38 36 *out = operation;
841 -
842 - done:
843 39 37 git_indexwriter_cleanup(&indexwriter);
844 39 38 git_index_free(index);
845 39 39 git_tree_free(current_tree);
846 39 40 git_tree_free(head_tree);
847 39 41 git_tree_free(parent_tree);
848 39 42 git_commit_free(parent_commit);
849 39 43 git_commit_free(current_commit);
850 39 44 git_buf_dispose(&path);
851 -
852 39 45 return error;
853 - }
854 -
855 13 2 static int rebase_next_inmemory(
856 - git_rebase_operation **out,
857 - git_rebase *rebase)
858 - {
859 13 2 git_commit *current_commit = NULL, *parent_commit = NULL;
860 13 2 git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
861 - git_rebase_operation *operation;
862 13 2 git_index *index = NULL;
863 - unsigned int parent_count;
864 - int error;
865 -
866 13 2 *out = NULL;
867 -
868 13 2-4 operation = git_array_get(rebase->operations, rebase->current);
869 -
870 13 5-8 if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
871 13 7 (error = git_commit_tree(&current_tree, current_commit)) < 0)
872 - goto done;
873 -
874 13 9,10 if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
875 ##### 11 git_error_set(GIT_ERROR_REBASE, "cannot rebase a merge commit");
876 ##### 12 error = -1;
877 ##### 12 goto done;
878 13 13 } else if (parent_count) {
879 12 14-17 if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
880 12 16 (error = git_commit_tree(&parent_tree, parent_commit)) < 0)
881 - goto done;
882 - }
883 -
884 13 18-21 if ((error = git_commit_tree(&head_tree, rebase->last_commit)) < 0 ||
885 13 20 (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0)
886 - goto done;
887 -
888 13 22 if (!rebase->index) {
889 4 23 rebase->index = index;
890 4 23 index = NULL;
891 - } else {
892 9 24,25 if ((error = git_index_read_index(rebase->index, index)) < 0)
893 ##### 26 goto done;
894 - }
895 -
896 13 27 *out = operation;
897 -
898 - done:
899 13 28 git_commit_free(current_commit);
900 13 29 git_commit_free(parent_commit);
901 13 30 git_tree_free(current_tree);
902 13 31 git_tree_free(head_tree);
903 13 32 git_tree_free(parent_tree);
904 13 33 git_index_free(index);
905 -
906 13 34 return error;
907 - }
908 -
909 63 2 int git_rebase_next(
910 - git_rebase_operation **out,
911 - git_rebase *rebase)
912 - {
913 - int error;
914 -
915 63 2-4 assert(out && rebase);
916 -
917 63 5,6 if ((error = rebase_movenext(rebase)) < 0)
918 11 7 return error;
919 -
920 52 8 if (rebase->inmemory)
921 13 9 error = rebase_next_inmemory(out, rebase);
922 39 10 else if (rebase->type == GIT_REBASE_MERGE)
923 39 11 error = rebase_next_merge(out, rebase);
924 - else
925 - 12 abort();
926 -
927 52 13 return error;
928 - }
929 -
930 1 2 int git_rebase_inmemory_index(
931 - git_index **out,
932 - git_rebase *rebase)
933 - {
934 1 2-5 assert(out && rebase && rebase->index);
935 -
936 1 6 GIT_REFCOUNT_INC(rebase->index);
937 1 7 *out = rebase->index;
938 -
939 1 7 return 0;
940 - }
941 -
942 48 2 static int rebase_commit__create(
943 - git_commit **out,
944 - git_rebase *rebase,
945 - git_index *index,
946 - git_commit *parent_commit,
947 - const git_signature *author,
948 - const git_signature *committer,
949 - const char *message_encoding,
950 - const char *message)
951 - {
952 - git_rebase_operation *operation;
953 48 2 git_commit *current_commit = NULL, *commit = NULL;
954 48 2 git_tree *parent_tree = NULL, *tree = NULL;
955 - git_oid tree_id, commit_id;
956 48 2 git_buf commit_content = GIT_BUF_INIT, commit_signature = GIT_BUF_INIT,
957 48 2 signature_field = GIT_BUF_INIT;
958 48 2 const char *signature_field_string = NULL,
959 48 2 *commit_signature_string = NULL;
960 - int error;
961 -
962 48 2-4 operation = git_array_get(rebase->operations, rebase->current);
963 -
964 48 5,6 if (git_index_has_conflicts(index)) {
965 1 7 git_error_set(GIT_ERROR_REBASE, "conflicts have not been resolved");
966 1 8 error = GIT_EUNMERGED;
967 1 8 goto done;
968 - }
969 -
970 47 9-12 if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
971 47 11,13,14 (error = git_commit_tree(&parent_tree, parent_commit)) < 0 ||
972 47 13,15,16 (error = git_index_write_tree_to(&tree_id, index, rebase->repo)) < 0 ||
973 47 15 (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0)
974 - goto done;
975 -
976 47 17-19 if (git_oid_equal(&tree_id, git_tree_id(parent_tree))) {
977 1 20 git_error_set(GIT_ERROR_REBASE, "this patch has already been applied");
978 1 21 error = GIT_EAPPLIED;
979 1 21 goto done;
980 - }
981 -
982 46 22 if (!author)
983 46 23 author = git_commit_author(current_commit);
984 -
985 46 24 if (!message) {
986 46 25 message_encoding = git_commit_message_encoding(current_commit);
987 46 26 message = git_commit_message(current_commit);
988 - }
989 -
990 46 27,28 if ((error = git_commit_create_buffer(&commit_content, rebase->repo, author, committer,
991 - message_encoding, message, tree, 1, (const git_commit **)&parent_commit)) < 0)
992 ##### 29 goto done;
993 -
994 46 30 if (rebase->options.signing_cb) {
995 3 31 git_error_clear();
996 3 32-34 error = git_error_set_after_callback_function(rebase->options.signing_cb(
997 - &commit_signature, &signature_field, git_buf_cstr(&commit_content),
998 - rebase->options.payload), "commit signing_cb failed");
999 3 35 if (error == GIT_PASSTHROUGH) {
1000 1 36 git_buf_dispose(&commit_signature);
1001 1 37 git_buf_dispose(&signature_field);
1002 1 38 git_error_clear();
1003 1 39 error = GIT_OK;
1004 2 40 } else if (error < 0)
1005 ##### 41 goto done;
1006 - }
1007 -
1008 46 42,43 if (git_buf_is_allocated(&commit_signature)) {
1009 2 44-46 assert(git_buf_contains_nul(&commit_signature));
1010 2 47 commit_signature_string = git_buf_cstr(&commit_signature);
1011 - }
1012 -
1013 46 48,49 if (git_buf_is_allocated(&signature_field)) {
1014 1 50-52 assert(git_buf_contains_nul(&signature_field));
1015 1 53 signature_field_string = git_buf_cstr(&signature_field);
1016 - }
1017 -
1018 46 54-56 if ((error = git_commit_create_with_signature(&commit_id, rebase->repo,
1019 - git_buf_cstr(&commit_content), commit_signature_string,
1020 - signature_field_string)))
1021 ##### 57 goto done;
1022 -
1023 46 58,59 if ((error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0)
1024 ##### 60 goto done;
1025 -
1026 46 61 *out = commit;
1027 -
1028 - done:
1029 48 62 if (error < 0)
1030 2 63 git_commit_free(commit);
1031 -
1032 48 64 git_buf_dispose(&commit_signature);
1033 48 65 git_buf_dispose(&signature_field);
1034 48 66 git_buf_dispose(&commit_content);
1035 48 67 git_commit_free(current_commit);
1036 48 68 git_tree_free(parent_tree);
1037 48 69 git_tree_free(tree);
1038 -
1039 48 70 return error;
1040 - }
1041 -
1042 36 2 static int rebase_commit_merge(
1043 - git_oid *commit_id,
1044 - git_rebase *rebase,
1045 - const git_signature *author,
1046 - const git_signature *committer,
1047 - const char *message_encoding,
1048 - const char *message)
1049 - {
1050 - git_rebase_operation *operation;
1051 36 2 git_reference *head = NULL;
1052 36 2 git_commit *head_commit = NULL, *commit = NULL;
1053 36 2 git_index *index = NULL;
1054 - char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
1055 - int error;
1056 -
1057 36 2-4 operation = git_array_get(rebase->operations, rebase->current);
1058 36 5,6 assert(operation);
1059 -
1060 36 7-10 if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 ||
1061 34 9,11,12 (error = git_repository_head(&head, rebase->repo)) < 0 ||
1062 34 11,13,14 (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)) < 0 ||
1063 34 13,15,16 (error = git_repository_index(&index, rebase->repo)) < 0 ||
1064 34 15 (error = rebase_commit__create(&commit, rebase, index, head_commit,
1065 33 18,19 author, committer, message_encoding, message)) < 0 ||
1066 33 17 (error = git_reference__update_for_commit(
1067 - rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0)
1068 - goto done;
1069 -
1070 33 20 git_oid_fmt(old_idstr, &operation->id);
1071 33 21,22 git_oid_fmt(new_idstr, git_commit_id(commit));
1072 -
1073 33 23,24 if ((error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND,
1074 - "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr)) < 0)
1075 ##### 25 goto done;
1076 -
1077 33 26,27 git_oid_cpy(commit_id, git_commit_id(commit));
1078 -
1079 - done:
1080 36 28 git_index_free(index);
1081 36 29 git_reference_free(head);
1082 36 30 git_commit_free(head_commit);
1083 36 31 git_commit_free(commit);
1084 36 32 return error;
1085 - }
1086 -
1087 14 2 static int rebase_commit_inmemory(
1088 - git_oid *commit_id,
1089 - git_rebase *rebase,
1090 - const git_signature *author,
1091 - const git_signature *committer,
1092 - const char *message_encoding,
1093 - const char *message)
1094 - {
1095 14 2 git_commit *commit = NULL;
1096 14 2 int error = 0;
1097 -
1098 14 2,3 assert(rebase->index);
1099 14 4,5 assert(rebase->last_commit);
1100 14 6,7 assert(rebase->current < rebase->operations.size);
1101 -
1102 14 8,9 if ((error = rebase_commit__create(&commit, rebase, rebase->index,
1103 - rebase->last_commit, author, committer, message_encoding, message)) < 0)
1104 1 10 goto done;
1105 -
1106 13 11 git_commit_free(rebase->last_commit);
1107 13 12 rebase->last_commit = commit;
1108 -
1109 13 12,13 git_oid_cpy(commit_id, git_commit_id(commit));
1110 -
1111 - done:
1112 14 14 if (error < 0)
1113 1 15 git_commit_free(commit);
1114 -
1115 14 16 return error;
1116 - }
1117 -
1118 50 2 int git_rebase_commit(
1119 - git_oid *id,
1120 - git_rebase *rebase,
1121 - const git_signature *author,
1122 - const git_signature *committer,
1123 - const char *message_encoding,
1124 - const char *message)
1125 - {
1126 - int error;
1127 -
1128 50 2-4 assert(rebase && committer);
1129 -
1130 50 5 if (rebase->inmemory)
1131 14 6 error = rebase_commit_inmemory(
1132 - id, rebase, author, committer, message_encoding, message);
1133 36 7 else if (rebase->type == GIT_REBASE_MERGE)
1134 36 8 error = rebase_commit_merge(
1135 - id, rebase, author, committer, message_encoding, message);
1136 - else
1137 - 9 abort();
1138 -
1139 50 10 return error;
1140 - }
1141 -
1142 8 2 int git_rebase_abort(git_rebase *rebase)
1143 - {
1144 8 2 git_reference *orig_head_ref = NULL;
1145 8 2 git_commit *orig_head_commit = NULL;
1146 - int error;
1147 -
1148 8 2,3 assert(rebase);
1149 -
1150 8 4 if (rebase->inmemory)
1151 ##### 5 return 0;
1152 -
1153 8 6,9 error = rebase->head_detached ?
1154 4 7 git_reference_create(&orig_head_ref, rebase->repo, GIT_HEAD_FILE,
1155 8 6-8 &rebase->orig_head_id, 1, "rebase: aborting") :
1156 4 8 git_reference_symbolic_create(
1157 4 8 &orig_head_ref, rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1158 - "rebase: aborting");
1159 -
1160 8 9 if (error < 0)
1161 ##### 10 goto done;
1162 -
1163 8 11,12 if ((error = git_commit_lookup(
1164 8 11,13,14 &orig_head_commit, rebase->repo, &rebase->orig_head_id)) < 0 ||
1165 8 13 (error = git_reset(rebase->repo, (git_object *)orig_head_commit,
1166 8 13 GIT_RESET_HARD, &rebase->options.checkout_options)) < 0)
1167 - goto done;
1168 -
1169 8 15 error = rebase_cleanup(rebase);
1170 -
1171 - done:
1172 8 16 git_commit_free(orig_head_commit);
1173 8 17 git_reference_free(orig_head_ref);
1174 -
1175 8 18 return error;
1176 - }
1177 -
1178 8 2 static int notes_ref_lookup(git_buf *out, git_rebase *rebase)
1179 - {
1180 8 2 git_config *config = NULL;
1181 - int do_rewrite, error;
1182 -
1183 8 2 if (rebase->options.rewrite_notes_ref) {
1184 1 3 git_buf_attach_notowned(out,
1185 - rebase->options.rewrite_notes_ref,
1186 - strlen(rebase->options.rewrite_notes_ref));
1187 1 4 return 0;
1188 - }
1189 -
1190 7 5-8 if ((error = git_repository_config(&config, rebase->repo)) < 0 ||
1191 7 7 (error = git_config_get_bool(&do_rewrite, config, "notes.rewrite.rebase")) < 0) {
1192 -
1193 6 9 if (error != GIT_ENOTFOUND)
1194 ##### 10 goto done;
1195 -
1196 6 11 git_error_clear();
1197 6 12 do_rewrite = 1;
1198 - }
1199 -
1200 7 13,16 error = do_rewrite ?
1201 7 13-15 git_config_get_string_buf(out, config, "notes.rewriteref") :
1202 - GIT_ENOTFOUND;
1203 -
1204 - done:
1205 7 17 git_config_free(config);
1206 7 18 return error;
1207 - }
1208 -
1209 2 2 static int rebase_copy_note(
1210 - git_rebase *rebase,
1211 - const char *notes_ref,
1212 - git_oid *from,
1213 - git_oid *to,
1214 - const git_signature *committer)
1215 - {
1216 2 2 git_note *note = NULL;
1217 - git_oid note_id;
1218 2 2 git_signature *who = NULL;
1219 - int error;
1220 -
1221 2 2,3 if ((error = git_note_read(&note, rebase->repo, notes_ref, from)) < 0) {
1222 ##### 4 if (error == GIT_ENOTFOUND) {
1223 ##### 5 git_error_clear();
1224 ##### 6 error = 0;
1225 - }
1226 -
1227 ##### 7 goto done;
1228 - }
1229 -
1230 2 8 if (!committer) {
1231 ##### 9,10 if((error = git_signature_default(&who, rebase->repo)) < 0) {
1232 ##### 11-13 if (error != GIT_ENOTFOUND ||
1233 - (error = git_signature_now(&who, "unknown", "unknown")) < 0)
1234 - goto done;
1235 -
1236 ##### 14 git_error_clear();
1237 - }
1238 -
1239 ##### 15 committer = who;
1240 - }
1241 -
1242 2 16-18 error = git_note_create(&note_id, rebase->repo, notes_ref,
1243 - git_note_author(note), committer, to, git_note_message(note), 0);
1244 -
1245 - done:
1246 2 19 git_note_free(note);
1247 2 20 git_signature_free(who);
1248 -
1249 2 21 return error;
1250 - }
1251 -
1252 8 2 static int rebase_copy_notes(
1253 - git_rebase *rebase,
1254 - const git_signature *committer)
1255 - {
1256 8 2 git_buf path = GIT_BUF_INIT, rewritten = GIT_BUF_INIT, notes_ref = GIT_BUF_INIT;
1257 - char *pair_list, *fromstr, *tostr, *end;
1258 - git_oid from, to;
1259 8 2 unsigned int linenum = 1;
1260 8 2 int error = 0;
1261 -
1262 8 2,3 if ((error = notes_ref_lookup(&notes_ref, rebase)) < 0) {
1263 6 4 if (error == GIT_ENOTFOUND) {
1264 6 5 git_error_clear();
1265 6 6 error = 0;
1266 - }
1267 -
1268 6 7 goto done;
1269 - }
1270 -
1271 2 8-11 if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 ||
1272 2 10 (error = git_futils_readbuffer(&rewritten, path.ptr)) < 0)
1273 - goto done;
1274 -
1275 2 12 pair_list = rewritten.ptr;
1276 -
1277 4 12,27 while (*pair_list) {
1278 2 13 fromstr = pair_list;
1279 -
1280 2 13 if ((end = strchr(fromstr, '\n')) == NULL)
1281 ##### 14 goto on_error;
1282 -
1283 2 15 pair_list = end+1;
1284 2 15 *end = '\0';
1285 -
1286 2 15 if ((end = strchr(fromstr, ' ')) == NULL)
1287 ##### 16 goto on_error;
1288 -
1289 2 17 tostr = end+1;
1290 2 17 *end = '\0';
1291 -
1292 2 17,18 if (strlen(fromstr) != GIT_OID_HEXSZ ||
1293 2 18,20 strlen(tostr) != GIT_OID_HEXSZ ||
1294 2 19,22 git_oid_fromstr(&from, fromstr) < 0 ||
1295 2 21 git_oid_fromstr(&to, tostr) < 0)
1296 - goto on_error;
1297 -
1298 2 23,24 if ((error = rebase_copy_note(rebase, notes_ref.ptr, &from, &to, committer)) < 0)
1299 ##### 25 goto done;
1300 -
1301 2 26 linenum++;
1302 - }
1303 -
1304 2 28 goto done;
1305 -
1306 - on_error:
1307 ##### 29 git_error_set(GIT_ERROR_REBASE, "invalid rewritten file at line %d", linenum);
1308 ##### 30 error = -1;
1309 -
1310 - done:
1311 8 31 git_buf_dispose(&rewritten);
1312 8 32 git_buf_dispose(&path);
1313 8 33 git_buf_dispose(&notes_ref);
1314 -
1315 8 34 return error;
1316 - }
1317 -
1318 6 2 static int return_to_orig_head(git_rebase *rebase)
1319 - {
1320 6 2 git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL;
1321 6 2 git_commit *terminal_commit = NULL;
1322 6 2 git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT;
1323 - char onto[GIT_OID_HEXSZ];
1324 6 2 int error = 0;
1325 -
1326 6 2 git_oid_fmt(onto, &rebase->onto_id);
1327 -
1328 6 3,4 if ((error = git_buf_printf(&branch_msg,
1329 - "rebase finished: %s onto %.*s",
1330 6 5,6 rebase->orig_head_name, GIT_OID_HEXSZ, onto)) == 0 &&
1331 6 5 (error = git_buf_printf(&head_msg,
1332 - "rebase finished: returning to %s",
1333 6 7,8 rebase->orig_head_name)) == 0 &&
1334 6 7,9,10 (error = git_repository_head(&terminal_ref, rebase->repo)) == 0 &&
1335 6 9 (error = git_reference_peel((git_object **)&terminal_commit,
1336 6 12,13 terminal_ref, GIT_OBJECT_COMMIT)) == 0 &&
1337 6 11,12 (error = git_reference_create_matching(&branch_ref,
1338 6 12 rebase->repo, rebase->orig_head_name,
1339 - git_commit_id(terminal_commit), 1,
1340 6 11 &rebase->orig_head_id, branch_msg.ptr)) == 0)
1341 6 14 error = git_reference_symbolic_create(&head_ref,
1342 6 14 rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1343 6 14 head_msg.ptr);
1344 -
1345 6 15 git_buf_dispose(&head_msg);
1346 6 16 git_buf_dispose(&branch_msg);
1347 6 17 git_commit_free(terminal_commit);
1348 6 18 git_reference_free(head_ref);
1349 6 19 git_reference_free(branch_ref);
1350 6 20 git_reference_free(terminal_ref);
1351 -
1352 6 21 return error;
1353 - }
1354 -
1355 9 2 int git_rebase_finish(
1356 - git_rebase *rebase,
1357 - const git_signature *signature)
1358 - {
1359 9 2 int error = 0;
1360 -
1361 9 2,3 assert(rebase);
1362 -
1363 9 4 if (rebase->inmemory)
1364 1 5 return 0;
1365 -
1366 8 6 if (!rebase->head_detached)
1367 6 7 error = return_to_orig_head(rebase);
1368 -
1369 8 8-10 if (error == 0 && (error = rebase_copy_notes(rebase, signature)) == 0)
1370 8 11 error = rebase_cleanup(rebase);
1371 -
1372 8 12 return error;
1373 - }
1374 -
1375 1 2 const char *git_rebase_orig_head_name(git_rebase *rebase) {
1376 1 2 return rebase->orig_head_name;
1377 - }
1378 -
1379 1 2 const git_oid *git_rebase_orig_head_id(git_rebase *rebase) {
1380 1 2 return &rebase->orig_head_id;
1381 - }
1382 -
1383 1 2 const char *git_rebase_onto_name(git_rebase *rebase) {
1384 1 2 return rebase->onto_name;
1385 - }
1386 -
1387 1 2 const git_oid *git_rebase_onto_id(git_rebase *rebase) {
1388 1 2 return &rebase->onto_id;
1389 - }
1390 -
1391 14 2 size_t git_rebase_operation_entrycount(git_rebase *rebase)
1392 - {
1393 14 2,3 assert(rebase);
1394 -
1395 14 4 return git_array_size(rebase->operations);
1396 - }
1397 -
1398 14 2 size_t git_rebase_operation_current(git_rebase *rebase)
1399 - {
1400 14 2,3 assert(rebase);
1401 -
1402 14 4 return rebase->started ? rebase->current : GIT_REBASE_NO_OPERATION;
1403 - }
1404 -
1405 70 2 git_rebase_operation *git_rebase_operation_byindex(git_rebase *rebase, size_t idx)
1406 - {
1407 70 2,3 assert(rebase);
1408 -
1409 70 4 return git_array_get(rebase->operations, idx);
1410 - }
1411 -
1412 60 2 void git_rebase_free(git_rebase *rebase)
1413 - {
1414 60 2 if (rebase == NULL)
1415 60 3,12 return;
1416 -
1417 55 4 git_index_free(rebase->index);
1418 55 5 git_commit_free(rebase->last_commit);
1419 55 6 git__free(rebase->onto_name);
1420 55 7 git__free(rebase->orig_head_name);
1421 55 8 git__free(rebase->state_path);
1422 55 9 git_array_clear(rebase->operations);
1423 55 10 git__free((char *)rebase->options.rewrite_notes_ref);
1424 55 11 git__free(rebase);
1425 - }