File Coverage

deps/libgit2/src/rebase.c
Criterion Covered Total %
statement 489 693 70.5
branch 227 498 45.5
condition n/a
subroutine n/a
pod n/a
total 716 1191 60.1


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