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             #ifndef GIT_DEPRECATE_HARD
505 0           int git_rebase_init_options(git_rebase_options *opts, unsigned int version)
506             {
507 0           return git_rebase_options_init(opts, version);
508             }
509             #endif
510              
511 2           static int rebase_ensure_not_in_progress(git_repository *repo)
512             {
513             int error;
514             git_rebase_t type;
515              
516 2 50         if ((error = rebase_state_type(&type, NULL, repo)) < 0)
517 0           return error;
518              
519 2 50         if (type != GIT_REBASE_NONE) {
520 0           git_error_set(GIT_ERROR_REBASE, "there is an existing rebase in progress");
521 0           return -1;
522             }
523              
524 2           return 0;
525             }
526              
527 5           static int rebase_ensure_not_dirty(
528             git_repository *repo,
529             bool check_index,
530             bool check_workdir,
531             int fail_with)
532             {
533 5           git_tree *head = NULL;
534 5           git_index *index = NULL;
535 5           git_diff *diff = NULL;
536 5           int error = 0;
537              
538 5 100         if (check_index) {
539 2 50         if ((error = git_repository_head_tree(&head, repo)) < 0 ||
    50          
540 2 50         (error = git_repository_index(&index, repo)) < 0 ||
541 2           (error = git_diff_tree_to_index(&diff, repo, head, index, NULL)) < 0)
542             goto done;
543              
544 2 50         if (git_diff_num_deltas(diff) > 0) {
545 0           git_error_set(GIT_ERROR_REBASE, "uncommitted changes exist in index");
546 0           error = fail_with;
547 0           goto done;
548             }
549              
550 2           git_diff_free(diff);
551 2           diff = NULL;
552             }
553              
554 5 50         if (check_workdir) {
555 5           git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
556 5           diff_opts.ignore_submodules = GIT_SUBMODULE_IGNORE_UNTRACKED;
557 5 50         if ((error = git_diff_index_to_workdir(&diff, repo, index, &diff_opts)) < 0)
558 0           goto done;
559              
560 5 50         if (git_diff_num_deltas(diff) > 0) {
561 0           git_error_set(GIT_ERROR_REBASE, "unstaged changes exist in workdir");
562 0           error = fail_with;
563 5           goto done;
564             }
565             }
566              
567             done:
568 5           git_diff_free(diff);
569 5           git_index_free(index);
570 5           git_tree_free(head);
571              
572 5           return error;
573             }
574              
575 3           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 3           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 3 50         if (!upstream)
590 0           upstream = onto;
591              
592 6 50         if ((error = git_revwalk_new(&revwalk, rebase->repo)) < 0 ||
    50          
593 6 50         (error = git_revwalk_push(revwalk, git_annotated_commit_id(branch))) < 0 ||
594 3           (error = git_revwalk_hide(revwalk, git_annotated_commit_id(upstream))) < 0)
595             goto done;
596              
597 3           git_revwalk_sorting(revwalk, GIT_SORT_REVERSE);
598              
599 9 100         while ((error = git_revwalk_next(&id, revwalk)) == 0) {
600 6 50         if ((error = git_commit_lookup(&commit, repo, &id)) < 0)
601 0           goto done;
602              
603 6           merge = (git_commit_parentcount(commit) > 1);
604 6           git_commit_free(commit);
605              
606 6 50         if (merge)
607 0           continue;
608              
609 6           operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
610 6 50         GIT_ERROR_CHECK_ALLOC(operation);
611             }
612              
613 3           error = 0;
614              
615             done:
616 3           git_revwalk_free(revwalk);
617 3           return error;
618             }
619              
620 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 2           git_reference *head_ref = NULL;
628 2           git_commit *onto_commit = NULL;
629 2           git_buf reflog = GIT_BUF_INIT;
630 2           git_buf state_path = GIT_BUF_INIT;
631             int error;
632              
633             GIT_UNUSED(upstream);
634              
635 2 50         if ((error = git_buf_joinpath(&state_path, repo->gitdir, REBASE_MERGE_DIR)) < 0)
636 0           goto done;
637              
638 2           rebase->state_path = git_buf_detach(&state_path);
639 2 50         GIT_ERROR_CHECK_ALLOC(rebase->state_path);
640              
641 2 50         if (branch->ref_name && strcmp(branch->ref_name, "HEAD")) {
    0          
642 0           rebase->orig_head_name = git__strdup(branch->ref_name);
643 0 0         GIT_ERROR_CHECK_ALLOC(rebase->orig_head_name);
644             } else {
645 2           rebase->head_detached = 1;
646             }
647              
648 2           rebase->onto_name = git__strdup(rebase_onto_name(onto));
649 2 50         GIT_ERROR_CHECK_ALLOC(rebase->onto_name);
650              
651 2           rebase->quiet = rebase->options.quiet;
652              
653 2           git_oid_cpy(&rebase->orig_head_id, git_annotated_commit_id(branch));
654 2           git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto));
655              
656 4 50         if ((error = rebase_setupfiles(rebase)) < 0 ||
    50          
657 2           (error = git_buf_printf(&reflog,
658 2 50         "rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
659 2           (error = git_commit_lookup(
660 2 50         &onto_commit, repo, git_annotated_commit_id(onto))) < 0 ||
661 2           (error = git_checkout_tree(repo,
662 2           (git_object *)onto_commit, &rebase->options.checkout_options)) < 0 ||
663 2           (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
664 2           git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
665             goto done;
666              
667             done:
668 2           git_reference_free(head_ref);
669 2           git_commit_free(onto_commit);
670 2           git_buf_dispose(&reflog);
671 2           git_buf_dispose(&state_path);
672              
673 2           return error;
674             }
675              
676 1           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 1           return git_commit_lookup(
687             &rebase->last_commit, repo, git_annotated_commit_id(onto));
688             }
689              
690 3           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 3           git_rebase *rebase = NULL;
699 3           git_annotated_commit *head_branch = NULL;
700 3           git_reference *head_ref = NULL;
701 3 50         bool inmemory = (given_opts && given_opts->inmemory);
    100          
702             int error;
703              
704 3 50         assert(repo && (upstream || onto));
    50          
    0          
705              
706 3           *out = NULL;
707              
708 3 50         if (!onto)
709 0           onto = upstream;
710              
711 3 50         if ((error = rebase_check_versions(given_opts)) < 0)
712 0           goto done;
713              
714 3 100         if (!inmemory) {
715 2 50         if ((error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
    50          
716 2 50         (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 3 50         if (!branch) {
722 0 0         if ((error = git_repository_head(&head_ref, repo)) < 0 ||
    0          
723 0           (error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
724             goto done;
725              
726 0           branch = head_branch;
727             }
728              
729 3 50         if (rebase_alloc(&rebase, given_opts) < 0)
730 0           return -1;
731              
732 3           rebase->repo = repo;
733 3           rebase->inmemory = inmemory;
734 3           rebase->type = GIT_REBASE_MERGE;
735              
736 3 50         if ((error = rebase_init_operations(rebase, repo, branch, upstream, onto)) < 0)
737 0           goto done;
738              
739 3 100         if (inmemory)
740 1           error = rebase_init_inmemory(rebase, repo, branch, upstream, onto);
741             else
742 2           error = rebase_init_merge(rebase, repo, branch ,upstream, onto);
743              
744 3 50         if (error == 0)
745 3           *out = rebase;
746              
747             done:
748 3           git_reference_free(head_ref);
749 3           git_annotated_commit_free(head_branch);
750              
751 3 50         if (error < 0) {
752 0           rebase_cleanup(rebase);
753 0           git_rebase_free(rebase);
754             }
755              
756 3           return error;
757             }
758              
759 3           static void normalize_checkout_options_for_apply(
760             git_checkout_options *checkout_opts,
761             git_rebase *rebase,
762             git_commit *current_commit)
763             {
764 3           memcpy(checkout_opts, &rebase->options.checkout_options, sizeof(git_checkout_options));
765              
766 3 50         if (!checkout_opts->ancestor_label)
767 3           checkout_opts->ancestor_label = "ancestor";
768              
769 3 50         if (rebase->type == GIT_REBASE_MERGE) {
770 3 50         if (!checkout_opts->our_label)
771 3           checkout_opts->our_label = rebase->onto_name;
772              
773 3 50         if (!checkout_opts->their_label)
774 3           checkout_opts->their_label = git_commit_summary(current_commit);
775             } else {
776 0           abort();
777             }
778 3           }
779              
780 5           GIT_INLINE(int) rebase_movenext(git_rebase *rebase)
781             {
782 5 100         size_t next = rebase->started ? rebase->current + 1 : 0;
783              
784 5 100         if (next == git_array_size(rebase->operations))
785 1           return GIT_ITEROVER;
786              
787 4           rebase->started = 1;
788 4           rebase->current = next;
789              
790 4           return 0;
791             }
792              
793 3           static int rebase_next_merge(
794             git_rebase_operation **out,
795             git_rebase *rebase)
796             {
797 3           git_buf path = GIT_BUF_INIT;
798 3           git_commit *current_commit = NULL, *parent_commit = NULL;
799 3           git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
800 3           git_index *index = NULL;
801 3           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 3           *out = NULL;
809              
810 3 50         operation = git_array_get(rebase->operations, rebase->current);
811              
812 3 50         if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 ||
    50          
813 3 50         (error = git_commit_tree(¤t_tree, current_commit)) < 0 ||
814 3           (error = git_repository_head_tree(&head_tree, rebase->repo)) < 0)
815             goto done;
816              
817 3 50         if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
818 0           git_error_set(GIT_ERROR_REBASE, "cannot rebase a merge commit");
819 0           error = -1;
820 0           goto done;
821 3 50         } else if (parent_count) {
822 3 50         if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
    50          
823 3           (error = git_commit_tree(&parent_tree, parent_commit)) < 0)
824             goto done;
825             }
826              
827 3           git_oid_fmt(current_idstr, &operation->id);
828              
829 3           normalize_checkout_options_for_apply(&checkout_opts, rebase, current_commit);
830              
831 3 50         if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 ||
    50          
832 3 50         (error = rebase_setupfile(rebase, MSGNUM_FILE, 0, "%" PRIuZ "\n", rebase->current+1)) < 0 ||
833 3 50         (error = rebase_setupfile(rebase, CURRENT_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 ||
834 3 50         (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0 ||
835 3 50         (error = git_merge__check_result(rebase->repo, index)) < 0 ||
836 3 50         (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 ||
837             (error = git_indexwriter_commit(&indexwriter)) < 0)
838             goto done;
839              
840 3           *out = operation;
841              
842             done:
843 3           git_indexwriter_cleanup(&indexwriter);
844 3           git_index_free(index);
845 3           git_tree_free(current_tree);
846 3           git_tree_free(head_tree);
847 3           git_tree_free(parent_tree);
848 3           git_commit_free(parent_commit);
849 3           git_commit_free(current_commit);
850 3           git_buf_dispose(&path);
851              
852 3           return error;
853             }
854              
855 1           static int rebase_next_inmemory(
856             git_rebase_operation **out,
857             git_rebase *rebase)
858             {
859 1           git_commit *current_commit = NULL, *parent_commit = NULL;
860 1           git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
861             git_rebase_operation *operation;
862 1           git_index *index = NULL;
863             unsigned int parent_count;
864             int error;
865              
866 1           *out = NULL;
867              
868 1 50         operation = git_array_get(rebase->operations, rebase->current);
869              
870 1 50         if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 ||
    50          
871 1           (error = git_commit_tree(¤t_tree, current_commit)) < 0)
872             goto done;
873              
874 1 50         if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
875 0           git_error_set(GIT_ERROR_REBASE, "cannot rebase a merge commit");
876 0           error = -1;
877 0           goto done;
878 1 50         } else if (parent_count) {
879 1 50         if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
    50          
880 1           (error = git_commit_tree(&parent_tree, parent_commit)) < 0)
881             goto done;
882             }
883              
884 1 50         if ((error = git_commit_tree(&head_tree, rebase->last_commit)) < 0 ||
    50          
885 1           (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0)
886             goto done;
887              
888 1 50         if (!rebase->index) {
889 1           rebase->index = index;
890 1           index = NULL;
891             } else {
892 0 0         if ((error = git_index_read_index(rebase->index, index)) < 0)
893 0           goto done;
894             }
895              
896 1           *out = operation;
897              
898             done:
899 1           git_commit_free(current_commit);
900 1           git_commit_free(parent_commit);
901 1           git_tree_free(current_tree);
902 1           git_tree_free(head_tree);
903 1           git_tree_free(parent_tree);
904 1           git_index_free(index);
905              
906 1           return error;
907             }
908              
909 5           int git_rebase_next(
910             git_rebase_operation **out,
911             git_rebase *rebase)
912             {
913             int error;
914              
915 5 50         assert(out && rebase);
    50          
916              
917 5 100         if ((error = rebase_movenext(rebase)) < 0)
918 1           return error;
919              
920 4 100         if (rebase->inmemory)
921 1           error = rebase_next_inmemory(out, rebase);
922 3 50         else if (rebase->type == GIT_REBASE_MERGE)
923 3           error = rebase_next_merge(out, rebase);
924             else
925 0           abort();
926              
927 4           return error;
928             }
929              
930 1           int git_rebase_inmemory_index(
931             git_index **out,
932             git_rebase *rebase)
933             {
934 1 50         assert(out && rebase && rebase->index);
    50          
    50          
935              
936 1           GIT_REFCOUNT_INC(rebase->index);
937 1           *out = rebase->index;
938              
939 1           return 0;
940             }
941              
942 3           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 3           git_commit *current_commit = NULL, *commit = NULL;
954 3           git_tree *parent_tree = NULL, *tree = NULL;
955             git_oid tree_id, commit_id;
956 3           git_buf commit_content = GIT_BUF_INIT, commit_signature = GIT_BUF_INIT,
957 3           signature_field = GIT_BUF_INIT;
958 3           const char *signature_field_string = NULL,
959 3           *commit_signature_string = NULL;
960             int error;
961              
962 3 50         operation = git_array_get(rebase->operations, rebase->current);
963              
964 3 50         if (git_index_has_conflicts(index)) {
965 0           git_error_set(GIT_ERROR_REBASE, "conflicts have not been resolved");
966 0           error = GIT_EUNMERGED;
967 0           goto done;
968             }
969              
970 3 50         if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 ||
    50          
971 3 50         (error = git_commit_tree(&parent_tree, parent_commit)) < 0 ||
972 3 50         (error = git_index_write_tree_to(&tree_id, index, rebase->repo)) < 0 ||
973 3           (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0)
974             goto done;
975              
976 3 50         if (git_oid_equal(&tree_id, git_tree_id(parent_tree))) {
977 0           git_error_set(GIT_ERROR_REBASE, "this patch has already been applied");
978 0           error = GIT_EAPPLIED;
979 0           goto done;
980             }
981              
982 3 50         if (!author)
983 0           author = git_commit_author(current_commit);
984              
985 3 50         if (!message) {
986 3           message_encoding = git_commit_message_encoding(current_commit);
987 3           message = git_commit_message(current_commit);
988             }
989              
990 3 50         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 0           goto done;
993              
994 3 50         if (rebase->options.signing_cb) {
995 0           git_error_clear();
996 0           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 0 0         if (error == GIT_PASSTHROUGH) {
1000 0           git_buf_dispose(&commit_signature);
1001 0           git_buf_dispose(&signature_field);
1002 0           git_error_clear();
1003 0           error = GIT_OK;
1004 0 0         } else if (error < 0)
1005 0           goto done;
1006             }
1007              
1008 3 50         if (git_buf_is_allocated(&commit_signature)) {
1009 0 0         assert(git_buf_contains_nul(&commit_signature));
1010 0           commit_signature_string = git_buf_cstr(&commit_signature);
1011             }
1012              
1013 3 50         if (git_buf_is_allocated(&signature_field)) {
1014 0 0         assert(git_buf_contains_nul(&signature_field));
1015 0           signature_field_string = git_buf_cstr(&signature_field);
1016             }
1017              
1018 3 50         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 0           goto done;
1022              
1023 3 50         if ((error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0)
1024 0           goto done;
1025              
1026 3           *out = commit;
1027              
1028             done:
1029 3 50         if (error < 0)
1030 0           git_commit_free(commit);
1031              
1032 3           git_buf_dispose(&commit_signature);
1033 3           git_buf_dispose(&signature_field);
1034 3           git_buf_dispose(&commit_content);
1035 3           git_commit_free(current_commit);
1036 3           git_tree_free(parent_tree);
1037 3           git_tree_free(tree);
1038              
1039 3           return error;
1040             }
1041              
1042 3           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 3           git_reference *head = NULL;
1052 3           git_commit *head_commit = NULL, *commit = NULL;
1053 3           git_index *index = NULL;
1054             char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
1055             int error;
1056              
1057 3 50         operation = git_array_get(rebase->operations, rebase->current);
1058 3 50         assert(operation);
1059              
1060 3 50         if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 ||
    50          
1061 3 50         (error = git_repository_head(&head, rebase->repo)) < 0 ||
1062 3 50         (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)) < 0 ||
1063 3 50         (error = git_repository_index(&index, rebase->repo)) < 0 ||
1064 3           (error = rebase_commit__create(&commit, rebase, index, head_commit,
1065 3 50         author, committer, message_encoding, message)) < 0 ||
1066 3           (error = git_reference__update_for_commit(
1067             rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0)
1068             goto done;
1069              
1070 3           git_oid_fmt(old_idstr, &operation->id);
1071 3           git_oid_fmt(new_idstr, git_commit_id(commit));
1072              
1073 3 50         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 0           goto done;
1076              
1077 3           git_oid_cpy(commit_id, git_commit_id(commit));
1078              
1079             done:
1080 3           git_index_free(index);
1081 3           git_reference_free(head);
1082 3           git_commit_free(head_commit);
1083 3           git_commit_free(commit);
1084 3           return error;
1085             }
1086              
1087 0           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 0           git_commit *commit = NULL;
1096 0           int error = 0;
1097              
1098 0 0         assert(rebase->index);
1099 0 0         assert(rebase->last_commit);
1100 0 0         assert(rebase->current < rebase->operations.size);
1101              
1102 0 0         if ((error = rebase_commit__create(&commit, rebase, rebase->index,
1103             rebase->last_commit, author, committer, message_encoding, message)) < 0)
1104 0           goto done;
1105              
1106 0           git_commit_free(rebase->last_commit);
1107 0           rebase->last_commit = commit;
1108              
1109 0           git_oid_cpy(commit_id, git_commit_id(commit));
1110              
1111             done:
1112 0 0         if (error < 0)
1113 0           git_commit_free(commit);
1114              
1115 0           return error;
1116             }
1117              
1118 3           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 3 50         assert(rebase && committer);
    50          
1129              
1130 3 50         if (rebase->inmemory)
1131 0           error = rebase_commit_inmemory(
1132             id, rebase, author, committer, message_encoding, message);
1133 3 50         else if (rebase->type == GIT_REBASE_MERGE)
1134 3           error = rebase_commit_merge(
1135             id, rebase, author, committer, message_encoding, message);
1136             else
1137 0           abort();
1138              
1139 3           return error;
1140             }
1141              
1142 1           int git_rebase_abort(git_rebase *rebase)
1143             {
1144 1           git_reference *orig_head_ref = NULL;
1145 1           git_commit *orig_head_commit = NULL;
1146             int error;
1147              
1148 1 50         assert(rebase);
1149              
1150 1 50         if (rebase->inmemory)
1151 0           return 0;
1152              
1153 2           error = rebase->head_detached ?
1154 1           git_reference_create(&orig_head_ref, rebase->repo, GIT_HEAD_FILE,
1155 1 50         &rebase->orig_head_id, 1, "rebase: aborting") :
1156 0           git_reference_symbolic_create(
1157 0           &orig_head_ref, rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1158             "rebase: aborting");
1159              
1160 1 50         if (error < 0)
1161 0           goto done;
1162              
1163 1 50         if ((error = git_commit_lookup(
1164 1 50         &orig_head_commit, rebase->repo, &rebase->orig_head_id)) < 0 ||
1165 1           (error = git_reset(rebase->repo, (git_object *)orig_head_commit,
1166 1           GIT_RESET_HARD, &rebase->options.checkout_options)) < 0)
1167             goto done;
1168              
1169 1           error = rebase_cleanup(rebase);
1170              
1171             done:
1172 1           git_commit_free(orig_head_commit);
1173 1           git_reference_free(orig_head_ref);
1174              
1175 1           return error;
1176             }
1177              
1178 1           static int notes_ref_lookup(git_buf *out, git_rebase *rebase)
1179             {
1180 1           git_config *config = NULL;
1181             int do_rewrite, error;
1182              
1183 1 50         if (rebase->options.rewrite_notes_ref) {
1184 0           git_buf_attach_notowned(out,
1185             rebase->options.rewrite_notes_ref,
1186             strlen(rebase->options.rewrite_notes_ref));
1187 0           return 0;
1188             }
1189              
1190 1 50         if ((error = git_repository_config(&config, rebase->repo)) < 0 ||
    50          
1191 1           (error = git_config_get_bool(&do_rewrite, config, "notes.rewrite.rebase")) < 0) {
1192              
1193 1 50         if (error != GIT_ENOTFOUND)
1194 0           goto done;
1195              
1196 1           git_error_clear();
1197 1           do_rewrite = 1;
1198             }
1199              
1200 1           error = do_rewrite ?
1201 1 50         git_config_get_string_buf(out, config, "notes.rewriteref") :
1202             GIT_ENOTFOUND;
1203              
1204             done:
1205 1           git_config_free(config);
1206 1           return error;
1207             }
1208              
1209 0           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 0           git_note *note = NULL;
1217             git_oid note_id;
1218 0           git_signature *who = NULL;
1219             int error;
1220              
1221 0 0         if ((error = git_note_read(¬e, rebase->repo, notes_ref, from)) < 0) {
1222 0 0         if (error == GIT_ENOTFOUND) {
1223 0           git_error_clear();
1224 0           error = 0;
1225             }
1226              
1227 0           goto done;
1228             }
1229              
1230 0 0         if (!committer) {
1231 0 0         if((error = git_signature_default(&who, rebase->repo)) < 0) {
1232 0 0         if (error != GIT_ENOTFOUND ||
    0          
1233             (error = git_signature_now(&who, "unknown", "unknown")) < 0)
1234             goto done;
1235              
1236 0           git_error_clear();
1237             }
1238              
1239 0           committer = who;
1240             }
1241              
1242 0           error = git_note_create(¬e_id, rebase->repo, notes_ref,
1243             git_note_author(note), committer, to, git_note_message(note), 0);
1244              
1245             done:
1246 0           git_note_free(note);
1247 0           git_signature_free(who);
1248              
1249 0           return error;
1250             }
1251              
1252 1           static int rebase_copy_notes(
1253             git_rebase *rebase,
1254             const git_signature *committer)
1255             {
1256 1           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 1           unsigned int linenum = 1;
1260 1           int error = 0;
1261              
1262 1 50         if ((error = notes_ref_lookup(¬es_ref, rebase)) < 0) {
1263 1 50         if (error == GIT_ENOTFOUND) {
1264 1           git_error_clear();
1265 1           error = 0;
1266             }
1267              
1268 1           goto done;
1269             }
1270              
1271 0 0         if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 ||
    0          
1272 0           (error = git_futils_readbuffer(&rewritten, path.ptr)) < 0)
1273             goto done;
1274              
1275 0           pair_list = rewritten.ptr;
1276              
1277 0 0         while (*pair_list) {
1278 0           fromstr = pair_list;
1279              
1280 0 0         if ((end = strchr(fromstr, '\n')) == NULL)
1281 0           goto on_error;
1282              
1283 0           pair_list = end+1;
1284 0           *end = '\0';
1285              
1286 0 0         if ((end = strchr(fromstr, ' ')) == NULL)
1287 0           goto on_error;
1288              
1289 0           tostr = end+1;
1290 0           *end = '\0';
1291              
1292 0 0         if (strlen(fromstr) != GIT_OID_HEXSZ ||
    0          
1293 0 0         strlen(tostr) != GIT_OID_HEXSZ ||
1294 0 0         git_oid_fromstr(&from, fromstr) < 0 ||
1295 0           git_oid_fromstr(&to, tostr) < 0)
1296             goto on_error;
1297              
1298 0 0         if ((error = rebase_copy_note(rebase, notes_ref.ptr, &from, &to, committer)) < 0)
1299 0           goto done;
1300              
1301 0           linenum++;
1302             }
1303              
1304 0           goto done;
1305              
1306             on_error:
1307 0           git_error_set(GIT_ERROR_REBASE, "invalid rewritten file at line %d", linenum);
1308 0           error = -1;
1309              
1310             done:
1311 1           git_buf_dispose(&rewritten);
1312 1           git_buf_dispose(&path);
1313 1           git_buf_dispose(¬es_ref);
1314              
1315 1           return error;
1316             }
1317              
1318 0           static int return_to_orig_head(git_rebase *rebase)
1319             {
1320 0           git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL;
1321 0           git_commit *terminal_commit = NULL;
1322 0           git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT;
1323             char onto[GIT_OID_HEXSZ];
1324 0           int error = 0;
1325              
1326 0           git_oid_fmt(onto, &rebase->onto_id);
1327              
1328 0 0         if ((error = git_buf_printf(&branch_msg,
1329             "rebase finished: %s onto %.*s",
1330 0 0         rebase->orig_head_name, GIT_OID_HEXSZ, onto)) == 0 &&
1331 0           (error = git_buf_printf(&head_msg,
1332             "rebase finished: returning to %s",
1333 0 0         rebase->orig_head_name)) == 0 &&
1334 0 0         (error = git_repository_head(&terminal_ref, rebase->repo)) == 0 &&
1335 0           (error = git_reference_peel((git_object **)&terminal_commit,
1336 0 0         terminal_ref, GIT_OBJECT_COMMIT)) == 0 &&
1337 0           (error = git_reference_create_matching(&branch_ref,
1338 0           rebase->repo, rebase->orig_head_name,
1339             git_commit_id(terminal_commit), 1,
1340 0           &rebase->orig_head_id, branch_msg.ptr)) == 0)
1341 0           error = git_reference_symbolic_create(&head_ref,
1342 0           rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1343 0           head_msg.ptr);
1344              
1345 0           git_buf_dispose(&head_msg);
1346 0           git_buf_dispose(&branch_msg);
1347 0           git_commit_free(terminal_commit);
1348 0           git_reference_free(head_ref);
1349 0           git_reference_free(branch_ref);
1350 0           git_reference_free(terminal_ref);
1351              
1352 0           return error;
1353             }
1354              
1355 1           int git_rebase_finish(
1356             git_rebase *rebase,
1357             const git_signature *signature)
1358             {
1359 1           int error = 0;
1360              
1361 1 50         assert(rebase);
1362              
1363 1 50         if (rebase->inmemory)
1364 0           return 0;
1365              
1366 1 50         if (!rebase->head_detached)
1367 0           error = return_to_orig_head(rebase);
1368              
1369 1 50         if (error == 0 && (error = rebase_copy_notes(rebase, signature)) == 0)
    50          
1370 1           error = rebase_cleanup(rebase);
1371              
1372 1           return error;
1373             }
1374              
1375 1           const char *git_rebase_orig_head_name(git_rebase *rebase) {
1376 1           return rebase->orig_head_name;
1377             }
1378              
1379 1           const git_oid *git_rebase_orig_head_id(git_rebase *rebase) {
1380 1           return &rebase->orig_head_id;
1381             }
1382              
1383 1           const char *git_rebase_onto_name(git_rebase *rebase) {
1384 1           return rebase->onto_name;
1385             }
1386              
1387 1           const git_oid *git_rebase_onto_id(git_rebase *rebase) {
1388 1           return &rebase->onto_id;
1389             }
1390              
1391 10           size_t git_rebase_operation_entrycount(git_rebase *rebase)
1392             {
1393 10 50         assert(rebase);
1394              
1395 10           return git_array_size(rebase->operations);
1396             }
1397              
1398 3           size_t git_rebase_operation_current(git_rebase *rebase)
1399             {
1400 3 50         assert(rebase);
1401              
1402 3 100         return rebase->started ? rebase->current : GIT_REBASE_NO_OPERATION;
1403             }
1404              
1405 6           git_rebase_operation *git_rebase_operation_byindex(git_rebase *rebase, size_t idx)
1406             {
1407 6 50         assert(rebase);
1408              
1409 6 100         return git_array_get(rebase->operations, idx);
1410             }
1411              
1412 4           void git_rebase_free(git_rebase *rebase)
1413             {
1414 4 50         if (rebase == NULL)
1415 0           return;
1416              
1417 4           git_index_free(rebase->index);
1418 4           git_commit_free(rebase->last_commit);
1419 4           git__free(rebase->onto_name);
1420 4           git__free(rebase->orig_head_name);
1421 4           git__free(rebase->state_path);
1422 4           git_array_clear(rebase->operations);
1423 4           git__free((char *)rebase->options.rewrite_notes_ref);
1424 4           git__free(rebase);
1425             }