File Coverage

deps/libgit2/src/libgit2/rebase.c
Criterion Covered Total %
statement 499 715 69.7
branch 231 508 45.4
condition n/a
subroutine n/a
pod n/a
total 730 1223 59.6


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