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