rebase.c 35.3 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
9

10 11 12 13 14 15
#include "buffer.h"
#include "repository.h"
#include "posix.h"
#include "filebuf.h"
#include "merge.h"
#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 23 24 25
#include <git2/rebase.h>
#include <git2/commit.h>
#include <git2/reset.h>
#include <git2/revwalk.h>
26
#include <git2/notes.h>
27

28 29
#define REBASE_APPLY_DIR    "rebase-apply"
#define REBASE_MERGE_DIR    "rebase-merge"
30

31 32 33 34 35 36
#define HEAD_NAME_FILE      "head-name"
#define ORIG_HEAD_FILE      "orig-head"
#define HEAD_FILE           "head"
#define ONTO_FILE           "onto"
#define ONTO_NAME_FILE      "onto_name"
#define QUIET_FILE          "quiet"
37

38 39 40 41 42
#define MSGNUM_FILE         "msgnum"
#define END_FILE            "end"
#define CMT_FILE_FMT        "cmt.%" PRIuZ
#define CURRENT_FILE        "current"
#define REWRITTEN_FILE      "rewritten"
43

44
#define ORIG_DETACHED_HEAD  "detached HEAD"
45

46
#define NOTES_DEFAULT_REF   NULL
47

48 49
#define REBASE_DIR_MODE     0777
#define REBASE_FILE_MODE    0666
50 51

typedef enum {
52 53 54 55 56
	GIT_REBASE_NONE = 0,
	GIT_REBASE_APPLY = 1,
	GIT_REBASE_MERGE = 2,
	GIT_REBASE_INTERACTIVE = 3,
} git_rebase_t;
57

58 59 60
struct git_rebase {
	git_repository *repo;

61 62
	git_rebase_options options;

63
	git_rebase_t type;
64 65
	char *state_path;

66
	int head_detached : 1,
67
		inmemory : 1,
68 69
		quiet : 1,
		started : 1;
70

71 72 73 74
	git_array_t(git_rebase_operation) operations;
	size_t current;

	/* Used by in-memory rebase */
75
	git_index *index;
76 77 78
	git_commit *last_commit;

	/* 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 87

#define GIT_REBASE_STATE_INIT {0}

88
static int rebase_state_type(
89
	git_rebase_t *type_out,
90 91 92 93
	char **path_out,
	git_repository *repo)
{
	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 98 99
		return -1;

	if (git_path_isdir(git_buf_cstr(&path))) {
100
		type = GIT_REBASE_APPLY;
101 102 103 104
		goto done;
	}

	git_buf_clear(&path);
105
	if (git_buf_joinpath(&path, repo->gitdir, REBASE_MERGE_DIR) < 0)
106 107 108
		return -1;

	if (git_path_isdir(git_buf_cstr(&path))) {
109
		type = GIT_REBASE_MERGE;
110 111 112 113 114 115
		goto done;
	}

done:
	*type_out = type;

116
	if (type != GIT_REBASE_NONE && path_out)
117 118
		*path_out = git_buf_detach(&path);

119
	git_buf_dispose(&path);
120 121 122 123

	return 0;
}

124 125 126 127
GIT_INLINE(int) rebase_readfile(
	git_buf *out,
	git_buf *state_path,
	const char *filename)
128
{
129 130
	size_t state_path_len = state_path->size;
	int error;
131

132 133 134 135
	git_buf_clear(out);

	if ((error = git_buf_joinpath(state_path, state_path->ptr, filename)) < 0 ||
		(error = git_futils_readbuffer(out, state_path->ptr)) < 0)
136 137
		goto done;

138
	git_buf_rtrim(out);
139

140 141 142 143
done:
	git_buf_truncate(state_path, state_path_len);
	return error;
}
144

145 146 147 148
GIT_INLINE(int) rebase_readint(
	size_t *out, git_buf *asc_out, git_buf *state_path, const char *filename)
{
	int32_t num;
149
	const char *eol;
150
	int error = 0;
151

152 153
	if ((error = rebase_readfile(asc_out, state_path, filename)) < 0)
		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 158
		return -1;
	}
159

160
	*out = (size_t) num;
161

162 163
	return 0;
}
164

165 166 167 168
GIT_INLINE(int) rebase_readoid(
	git_oid *out, git_buf *str_out, git_buf *state_path, const char *filename)
{
	int error;
169

170 171
	if ((error = rebase_readfile(str_out, state_path, filename)) < 0)
		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 176
		return -1;
	}
177

178 179
	return 0;
}
180

181 182 183 184 185 186 187 188
static git_rebase_operation *rebase_operation_alloc(
	git_rebase *rebase,
	git_rebase_operation_t type,
	git_oid *id,
	const char *exec)
{
	git_rebase_operation *operation;

189 190
	GIT_ASSERT_WITH_RETVAL((type == GIT_REBASE_OPERATION_EXEC) == !id, NULL);
	GIT_ASSERT_WITH_RETVAL((type == GIT_REBASE_OPERATION_EXEC) == !!exec, NULL);
191 192 193 194 195 196 197 198 199 200 201

	if ((operation = git_array_alloc(rebase->operations)) == NULL)
		return NULL;

	operation->type = type;
	git_oid_cpy((git_oid *)&operation->id, id);
	operation->exec = exec;

	return operation;
}

202 203 204
static int rebase_open_merge(git_rebase *rebase)
{
	git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT;
205
	git_oid id;
206 207 208
	git_rebase_operation *operation;
	size_t i, msgnum = 0, end;
	int error;
209

210 211
	if ((error = git_buf_puts(&state_path, rebase->state_path)) < 0)
		goto done;
212

213 214 215 216
	/* Read 'msgnum' if it exists (otherwise, let msgnum = 0) */
	if ((error = rebase_readint(&msgnum, &buf, &state_path, MSGNUM_FILE)) < 0 &&
		error != GIT_ENOTFOUND)
		goto done;
217

218 219 220 221
	if (msgnum) {
		rebase->started = 1;
		rebase->current = msgnum - 1;
	}
222

223 224
	/* Read 'end' */
	if ((error = rebase_readint(&end, &buf, &state_path, END_FILE)) < 0)
225 226
		goto done;

227
	/* Read 'current' if it exists */
228
	if ((error = rebase_readoid(&id, &buf, &state_path, CURRENT_FILE)) < 0 &&
229 230 231 232 233
		error != GIT_ENOTFOUND)
		goto done;

	/* Read cmt.* */
	git_array_init_to_size(rebase->operations, end);
234
	GIT_ERROR_CHECK_ARRAY(rebase->operations);
235

236 237 238 239
	for (i = 0; i < end; i++) {
		git_buf_clear(&cmt);

		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 248 249 250 251 252
	/* Read 'onto_name' */
	if ((error = rebase_readfile(&buf, &state_path, ONTO_NAME_FILE)) < 0)
		goto done;

	rebase->onto_name = git_buf_detach(&buf);

253
done:
254 255 256
	git_buf_dispose(&cmt);
	git_buf_dispose(&state_path);
	git_buf_dispose(&buf);
257 258 259 260

	return error;
}

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 269 270

	if (rebase_opts)
		memcpy(&rebase->options, rebase_opts, sizeof(git_rebase_options));
	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 279 280
	*out = rebase;

	return 0;
281 282 283 284
}

static int rebase_check_versions(const git_rebase_options *given_opts)
{
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 291 292 293 294 295 296

	return 0;
}

int git_rebase_open(
	git_rebase **out,
	git_repository *repo,
	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 302
	size_t state_path_len;
	int error;
303

304
	GIT_ASSERT_ARG(repo);
305

306 307 308
	if ((error = rebase_check_versions(given_opts)) < 0)
		return error;

309 310
	if (rebase_alloc(&rebase, given_opts) < 0)
		return -1;
311

312 313 314
	rebase->repo = repo;

	if ((error = rebase_state_type(&rebase->type, &rebase->state_path, repo)) < 0)
315 316
		goto done;

317
	if (rebase->type == GIT_REBASE_NONE) {
318
		git_error_set(GIT_ERROR_REBASE, "there is no rebase in progress");
Jacques Germishuys committed
319 320
		error = GIT_ENOTFOUND;
		goto done;
321 322
	}

323
	if ((error = git_buf_puts(&path, rebase->state_path)) < 0)
324 325 326 327 328 329 330 331 332 333 334
		goto done;

	state_path_len = git_buf_len(&path);

	if ((error = git_buf_joinpath(&path, path.ptr, HEAD_NAME_FILE)) < 0 ||
		(error = git_futils_readbuffer(&orig_head_name, path.ptr)) < 0)
		goto done;

	git_buf_rtrim(&orig_head_name);

	if (strcmp(ORIG_DETACHED_HEAD, orig_head_name.ptr) == 0)
335
		rebase->head_detached = 1;
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354

	git_buf_truncate(&path, state_path_len);

	if ((error = git_buf_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0)
		goto done;

	if (!git_path_isfile(path.ptr)) {
		/* Previous versions of git.git used 'head' here; support that. */
		git_buf_truncate(&path, state_path_len);

		if ((error = git_buf_joinpath(&path, path.ptr, HEAD_FILE)) < 0)
			goto done;
	}

	if ((error = git_futils_readbuffer(&orig_head_id, path.ptr)) < 0)
		goto done;

	git_buf_rtrim(&orig_head_id);

355
	if ((error = git_oid_fromstr(&rebase->orig_head_id, orig_head_id.ptr)) < 0)
356 357
		goto done;

358 359 360 361 362 363 364 365
	git_buf_truncate(&path, state_path_len);

	if ((error = git_buf_joinpath(&path, path.ptr, ONTO_FILE)) < 0 ||
		(error = git_futils_readbuffer(&onto_id, path.ptr)) < 0)
		goto done;

	git_buf_rtrim(&onto_id);

366
	if ((error = git_oid_fromstr(&rebase->onto_id, onto_id.ptr)) < 0)
367 368
		goto done;

369 370
	if (!rebase->head_detached)
		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 376
		error = -1;
		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 383 384 385 386 387
		error = -1;
		break;
	default:
		abort();
	}

388
done:
389 390 391 392 393
	if (error == 0)
		*out = rebase;
	else
		git_rebase_free(rebase);

394 395 396 397
	git_buf_dispose(&path);
	git_buf_dispose(&orig_head_name);
	git_buf_dispose(&orig_head_id);
	git_buf_dispose(&onto_id);
398 399 400
	return error;
}

401
static int rebase_cleanup(git_rebase *rebase)
402
{
403 404 405
	if (!rebase || rebase->inmemory)
		return 0;

406 407
	return git_path_isdir(rebase->state_path) ?
		git_futils_rmdir_r(rebase->state_path, NULL, GIT_RMDIR_REMOVE_FILES) :
408 409 410
		0;
}

411
static int rebase_setupfile(git_rebase *rebase, const char *filename, int flags, const char *fmt, ...)
412 413 414 415 416 417 418 419 420 421
{
	git_buf path = GIT_BUF_INIT,
		contents = GIT_BUF_INIT;
	va_list ap;
	int error;

	va_start(ap, fmt);
	git_buf_vprintf(&contents, fmt, ap);
	va_end(ap);

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 426
	git_buf_dispose(&path);
	git_buf_dispose(&contents);
427 428 429 430

	return error;
}

431
static const char *rebase_onto_name(const git_annotated_commit *onto)
432 433 434 435 436 437
{
	if (onto->ref_name && git__strncmp(onto->ref_name, "refs/heads/", 11) == 0)
		return onto->ref_name + 11;
	else if (onto->ref_name)
		return onto->ref_name;
	else
438
		return onto->id_str;
439 440
}

441
static int rebase_setupfiles_merge(git_rebase *rebase)
442 443 444
{
	git_buf commit_filename = GIT_BUF_INIT;
	char id_str[GIT_OID_HEXSZ];
445 446 447
	git_rebase_operation *operation;
	size_t i;
	int error = 0;
448

449 450
	if ((error = rebase_setupfile(rebase, END_FILE, 0, "%" PRIuZ "\n", git_array_size(rebase->operations))) < 0 ||
		(error = rebase_setupfile(rebase, ONTO_NAME_FILE, 0, "%s\n", rebase->onto_name)) < 0)
451 452
		goto done;

453 454
	for (i = 0; i < git_array_size(rebase->operations); i++) {
		operation = git_array_get(rebase->operations, i);
455 456

		git_buf_clear(&commit_filename);
457 458 459
		git_buf_printf(&commit_filename, CMT_FILE_FMT, i+1);

		git_oid_fmt(id_str, &operation->id);
460

461
		if ((error = rebase_setupfile(rebase, commit_filename.ptr, 0,
462 463 464 465 466
				"%.*s\n", GIT_OID_HEXSZ, id_str)) < 0)
			goto done;
	}

done:
467
	git_buf_dispose(&commit_filename);
468 469 470
	return error;
}

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 477
	git_oid_fmt(onto, &rebase->onto_id);
	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 485 486
	orig_head_name = rebase->head_detached ? ORIG_DETACHED_HEAD :
		rebase->orig_head_name;

487
	if (git_repository__set_orig_head(rebase->repo, &rebase->orig_head_id) < 0 ||
488 489 490 491
		rebase_setupfile(rebase, HEAD_NAME_FILE, 0, "%s\n", orig_head_name) < 0 ||
		rebase_setupfile(rebase, ONTO_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, onto) < 0 ||
		rebase_setupfile(rebase, ORIG_HEAD_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, orig_head) < 0 ||
		rebase_setupfile(rebase, QUIET_FILE, 0, rebase->quiet ? "t\n" : "\n") < 0)
492
		return -1;
493

494
	return rebase_setupfiles_merge(rebase);
495 496
}

497
int git_rebase_options_init(git_rebase_options *opts, unsigned int version)
498 499 500 501 502 503
{
	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
		opts, version, git_rebase_options, GIT_REBASE_OPTIONS_INIT);
	return 0;
}

504
#ifndef GIT_DEPRECATE_HARD
505 506 507 508
int git_rebase_init_options(git_rebase_options *opts, unsigned int version)
{
	return git_rebase_options_init(opts, version);
}
509
#endif
510

511 512 513
static int rebase_ensure_not_in_progress(git_repository *repo)
{
	int error;
514
	git_rebase_t type;
515 516 517 518

	if ((error = rebase_state_type(&type, NULL, repo)) < 0)
		return error;

519
	if (type != GIT_REBASE_NONE) {
520
		git_error_set(GIT_ERROR_REBASE, "there is an existing rebase in progress");
521 522 523 524 525 526
		return -1;
	}

	return 0;
}

527 528 529 530 531
static int rebase_ensure_not_dirty(
	git_repository *repo,
	bool check_index,
	bool check_workdir,
	int fail_with)
532 533 534 535
{
	git_tree *head = NULL;
	git_index *index = NULL;
	git_diff *diff = NULL;
536
	int error = 0;
537

538 539 540 541 542
	if (check_index) {
		if ((error = git_repository_head_tree(&head, repo)) < 0 ||
			(error = git_repository_index(&index, repo)) < 0 ||
			(error = git_diff_tree_to_index(&diff, repo, head, index, NULL)) < 0)
			goto done;
543

544
		if (git_diff_num_deltas(diff) > 0) {
545
			git_error_set(GIT_ERROR_REBASE, "uncommitted changes exist in index");
546 547 548
			error = fail_with;
			goto done;
		}
549

550 551 552
		git_diff_free(diff);
		diff = NULL;
	}
553

554
	if (check_workdir) {
555 556 557
		git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
		diff_opts.ignore_submodules = GIT_SUBMODULE_IGNORE_UNTRACKED;
		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 563 564
			error = fail_with;
			goto done;
		}
565 566 567 568 569 570 571 572 573 574
	}

done:
	git_diff_free(diff);
	git_index_free(index);
	git_tree_free(head);

	return error;
}

575 576 577
static int rebase_init_operations(
	git_rebase *rebase,
	git_repository *repo,
578 579 580
	const git_annotated_commit *branch,
	const git_annotated_commit *upstream,
	const git_annotated_commit *onto)
581 582 583 584 585 586 587 588 589 590 591 592
{
	git_revwalk *revwalk = NULL;
	git_commit *commit;
	git_oid id;
	bool merge;
	git_rebase_operation *operation;
	int error;

	if (!upstream)
		upstream = onto;

	if ((error = git_revwalk_new(&revwalk, rebase->repo)) < 0 ||
593 594
		(error = git_revwalk_push(revwalk, git_annotated_commit_id(branch))) < 0 ||
		(error = git_revwalk_hide(revwalk, git_annotated_commit_id(upstream))) < 0)
595 596
		goto done;

597
	git_revwalk_sorting(revwalk, GIT_SORT_REVERSE);
598 599 600 601 602 603 604 605 606 607 608

	while ((error = git_revwalk_next(&id, revwalk)) == 0) {
		if ((error = git_commit_lookup(&commit, repo, &id)) < 0)
			goto done;

		merge = (git_commit_parentcount(commit) > 1);
		git_commit_free(commit);

		if (merge)
			continue;

609
		operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
610
		GIT_ERROR_CHECK_ALLOC(operation);
611 612 613 614 615 616 617 618 619 620 621 622
	}

	error = 0;

done:
	git_revwalk_free(revwalk);
	return error;
}

static int rebase_init_merge(
	git_rebase *rebase,
	git_repository *repo,
623 624 625
	const git_annotated_commit *branch,
	const git_annotated_commit *upstream,
	const git_annotated_commit *onto)
626
{
627
	git_reference *head_ref = NULL;
628 629
	git_commit *onto_commit = NULL;
	git_buf reflog = GIT_BUF_INIT;
630 631 632
	git_buf state_path = GIT_BUF_INIT;
	int error;

633 634
	GIT_UNUSED(upstream);

635
	if ((error = git_buf_joinpath(&state_path, repo->gitdir, REBASE_MERGE_DIR)) < 0)
636 637
		goto done;

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 645 646
	} else {
		rebase->head_detached = 1;
	}
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 654
	git_oid_cpy(&rebase->orig_head_id, git_annotated_commit_id(branch));
	git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto));
655

656 657 658 659 660 661 662 663 664 665
	if ((error = rebase_setupfiles(rebase)) < 0 ||
		(error = git_buf_printf(&reflog,
			"rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
		(error = git_commit_lookup(
			&onto_commit, repo, git_annotated_commit_id(onto))) < 0 ||
		(error = git_checkout_tree(repo,
			(git_object *)onto_commit, &rebase->options.checkout_options)) < 0 ||
		(error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
			git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
		goto done;
666

667 668
done:
	git_reference_free(head_ref);
669
	git_commit_free(onto_commit);
670 671
	git_buf_dispose(&reflog);
	git_buf_dispose(&state_path);
672

673 674 675
	return error;
}

676 677 678 679 680 681 682 683 684 685 686 687 688 689
static int rebase_init_inmemory(
	git_rebase *rebase,
	git_repository *repo,
	const git_annotated_commit *branch,
	const git_annotated_commit *upstream,
	const git_annotated_commit *onto)
{
	GIT_UNUSED(branch);
	GIT_UNUSED(upstream);

	return git_commit_lookup(
		&rebase->last_commit, repo, git_annotated_commit_id(onto));
}

690 691
int git_rebase_init(
	git_rebase **out,
692
	git_repository *repo,
693 694 695
	const git_annotated_commit *branch,
	const git_annotated_commit *upstream,
	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 703
	int error;

704 705
	GIT_ASSERT_ARG(repo);
	GIT_ASSERT_ARG(upstream || onto);
706

707 708 709 710 711
	*out = NULL;

	if (!onto)
		onto = upstream;

712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
	if ((error = rebase_check_versions(given_opts)) < 0)
		goto done;

	if (!inmemory) {
		if ((error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
			(error = rebase_ensure_not_in_progress(repo)) < 0 ||
			(error = rebase_ensure_not_dirty(repo, true, true, GIT_ERROR)) < 0)
			goto done;
	}

	if (!branch) {
		if ((error = git_repository_head(&head_ref, repo)) < 0 ||
			(error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
			goto done;

		branch = head_branch;
	}
729

730 731
	if (rebase_alloc(&rebase, given_opts) < 0)
		return -1;
732

733 734
	rebase->repo = repo;
	rebase->inmemory = inmemory;
735
	rebase->type = GIT_REBASE_MERGE;
736 737

	if ((error = rebase_init_operations(rebase, repo, branch, upstream, onto)) < 0)
738 739
		goto done;

740 741 742
	if (inmemory)
		error = rebase_init_inmemory(rebase, repo, branch, upstream, onto);
	else
743
		error = rebase_init_merge(rebase, repo, branch ,upstream, onto);
744 745 746

	if (error == 0)
		*out = rebase;
747 748

done:
749
	git_reference_free(head_ref);
750 751
	git_annotated_commit_free(head_branch);

752 753 754 755 756
	if (error < 0) {
		rebase_cleanup(rebase);
		git_rebase_free(rebase);
	}

757 758
	return error;
}
759

760
static void normalize_checkout_options_for_apply(
761
	git_checkout_options *checkout_opts,
762 763
	git_rebase *rebase,
	git_commit *current_commit)
764
{
765
	memcpy(checkout_opts, &rebase->options.checkout_options, sizeof(git_checkout_options));
766 767 768 769

	if (!checkout_opts->ancestor_label)
		checkout_opts->ancestor_label = "ancestor";

770
	if (rebase->type == GIT_REBASE_MERGE) {
771
		if (!checkout_opts->our_label)
772
			checkout_opts->our_label = rebase->onto_name;
773

774 775
		if (!checkout_opts->their_label)
			checkout_opts->their_label = git_commit_summary(current_commit);
776 777 778 779 780
	} else {
		abort();
	}
}

781 782 783 784 785 786 787 788 789 790 791 792 793
GIT_INLINE(int) rebase_movenext(git_rebase *rebase)
{
	size_t next = rebase->started ? rebase->current + 1 : 0;

	if (next == git_array_size(rebase->operations))
		return GIT_ITEROVER;

	rebase->started = 1;
	rebase->current = next;

	return 0;
}

794
static int rebase_next_merge(
795
	git_rebase_operation **out,
796
	git_rebase *rebase)
797
{
798 799
	git_buf path = GIT_BUF_INIT;
	git_commit *current_commit = NULL, *parent_commit = NULL;
800 801
	git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
	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 807 808
	unsigned int parent_count;
	int error;

809
	*out = NULL;
810

811
	operation = git_array_get(rebase->operations, rebase->current);
812

813 814
	if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
		(error = git_commit_tree(&current_tree, current_commit)) < 0 ||
815
		(error = git_repository_head_tree(&head_tree, rebase->repo)) < 0)
816 817
		goto done;

818
	if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
819
		git_error_set(GIT_ERROR_REBASE, "cannot rebase a merge commit");
820 821 822
		error = -1;
		goto done;
	} else if (parent_count) {
823
		if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
824 825 826 827
			(error = git_commit_tree(&parent_tree, parent_commit)) < 0)
			goto done;
	}

828 829
	git_oid_fmt(current_idstr, &operation->id);

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 834
		(error = rebase_setupfile(rebase, MSGNUM_FILE, 0, "%" PRIuZ "\n", rebase->current+1)) < 0 ||
		(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 838
		(error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 ||
		(error = git_indexwriter_commit(&indexwriter)) < 0)
839 840
		goto done;

841
	*out = operation;
842

843
done:
844
	git_indexwriter_cleanup(&indexwriter);
845 846 847 848 849
	git_index_free(index);
	git_tree_free(current_tree);
	git_tree_free(head_tree);
	git_tree_free(parent_tree);
	git_commit_free(parent_commit);
850
	git_commit_free(current_commit);
851
	git_buf_dispose(&path);
852 853 854 855

	return error;
}

856 857 858 859 860 861 862 863
static int rebase_next_inmemory(
	git_rebase_operation **out,
	git_rebase *rebase)
{
	git_commit *current_commit = NULL, *parent_commit = NULL;
	git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
	git_rebase_operation *operation;
	git_index *index = NULL;
864
	unsigned int parent_count;
865 866 867 868 869 870 871
	int error;

	*out = NULL;

	operation = git_array_get(rebase->operations, rebase->current);

	if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
872 873 874 875
		(error = git_commit_tree(&current_tree, current_commit)) < 0)
		goto done;

	if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
876
		git_error_set(GIT_ERROR_REBASE, "cannot rebase a merge commit");
877 878 879 880 881 882 883 884 885
		error = -1;
		goto done;
	} else if (parent_count) {
		if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
			(error = git_commit_tree(&parent_tree, parent_commit)) < 0)
			goto done;
	}

	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 888
		goto done;

889 890 891 892 893 894 895
	if (!rebase->index) {
		rebase->index = index;
		index = NULL;
	} else {
		if ((error = git_index_read_index(rebase->index, index)) < 0)
			goto done;
	}
896 897 898 899 900 901 902 903 904 905 906 907 908 909

	*out = operation;

done:
	git_commit_free(current_commit);
	git_commit_free(parent_commit);
	git_tree_free(current_tree);
	git_tree_free(head_tree);
	git_tree_free(parent_tree);
	git_index_free(index);

	return error;
}

910
int git_rebase_next(
911
	git_rebase_operation **out,
912
	git_rebase *rebase)
913 914 915
{
	int error;

916 917
	GIT_ASSERT_ARG(out);
	GIT_ASSERT_ARG(rebase);
918

919 920 921 922 923
	if ((error = rebase_movenext(rebase)) < 0)
		return error;

	if (rebase->inmemory)
		error = rebase_next_inmemory(out, rebase);
924
	else if (rebase->type == GIT_REBASE_MERGE)
925
		error = rebase_next_merge(out, rebase);
926
	else
927 928
		abort();

929 930 931
	return error;
}

932 933 934 935
int git_rebase_inmemory_index(
	git_index **out,
	git_rebase *rebase)
{
936 937 938
	GIT_ASSERT_ARG(out);
	GIT_ASSERT_ARG(rebase);
	GIT_ASSERT_ARG(rebase->index);
939 940 941 942 943 944 945

	GIT_REFCOUNT_INC(rebase->index);
	*out = rebase->index;

	return 0;
}

946 947
static int rebase_commit__create(
	git_commit **out,
948
	git_rebase *rebase,
949 950
	git_index *index,
	git_commit *parent_commit,
951 952 953 954 955
	const git_signature *author,
	const git_signature *committer,
	const char *message_encoding,
	const char *message)
{
956
	git_rebase_operation *operation;
957 958 959
	git_commit *current_commit = NULL, *commit = NULL;
	git_tree *parent_tree = NULL, *tree = NULL;
	git_oid tree_id, commit_id;
960 961
	git_buf commit_content = GIT_BUF_INIT, commit_signature = GIT_BUF_INIT,
		signature_field = GIT_BUF_INIT;
962 963
	const char *signature_field_string = NULL,
		*commit_signature_string = NULL;
964 965
	int error;

966
	operation = git_array_get(rebase->operations, rebase->current);
967 968

	if (git_index_has_conflicts(index)) {
969
		git_error_set(GIT_ERROR_REBASE, "conflicts have not been resolved");
970
		error = GIT_EUNMERGED;
971 972 973
		goto done;
	}

974 975 976 977
	if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
		(error = git_commit_tree(&parent_tree, parent_commit)) < 0 ||
		(error = git_index_write_tree_to(&tree_id, index, rebase->repo)) < 0 ||
		(error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0)
978 979
		goto done;

980
	if (git_oid_equal(&tree_id, git_tree_id(parent_tree))) {
981
		git_error_set(GIT_ERROR_REBASE, "this patch has already been applied");
982 983 984 985
		error = GIT_EAPPLIED;
		goto done;
	}

986
	if (!author)
987
		author = git_commit_author(current_commit);
988 989

	if (!message) {
990 991
		message_encoding = git_commit_message_encoding(current_commit);
		message = git_commit_message(current_commit);
992 993
	}

994 995 996 997
	if ((error = git_commit_create_buffer(&commit_content, rebase->repo, author, committer,
			message_encoding, message, tree, 1, (const git_commit **)&parent_commit)) < 0)
		goto done;

998
	if (rebase->options.signing_cb) {
999 1000 1001 1002 1003 1004 1005 1006 1007 1008
		git_error_clear();
		error = git_error_set_after_callback_function(rebase->options.signing_cb(
			&commit_signature, &signature_field, git_buf_cstr(&commit_content),
			rebase->options.payload), "commit signing_cb failed");
		if (error == GIT_PASSTHROUGH) {
			git_buf_dispose(&commit_signature);
			git_buf_dispose(&signature_field);
			git_error_clear();
			error = GIT_OK;
		} else if (error < 0)
1009
			goto done;
1010
	}
1011

1012
	if (git_buf_is_allocated(&commit_signature)) {
1013
		GIT_ASSERT(git_buf_contains_nul(&commit_signature));
1014
		commit_signature_string = git_buf_cstr(&commit_signature);
1015 1016
	}

1017
	if (git_buf_is_allocated(&signature_field)) {
1018
		GIT_ASSERT(git_buf_contains_nul(&signature_field));
1019 1020 1021 1022 1023 1024
		signature_field_string = git_buf_cstr(&signature_field);
	}

	if ((error = git_commit_create_with_signature(&commit_id, rebase->repo,
			git_buf_cstr(&commit_content), commit_signature_string,
			signature_field_string)))
1025 1026 1027
		goto done;

	if ((error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0)
1028 1029 1030 1031 1032 1033 1034 1035
		goto done;

	*out = commit;

done:
	if (error < 0)
		git_commit_free(commit);

1036 1037
	git_buf_dispose(&commit_signature);
	git_buf_dispose(&signature_field);
1038
	git_buf_dispose(&commit_content);
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
	git_commit_free(current_commit);
	git_tree_free(parent_tree);
	git_tree_free(tree);

	return error;
}

static int 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)
{
	git_rebase_operation *operation;
	git_reference *head = NULL;
	git_commit *head_commit = NULL, *commit = NULL;
	git_index *index = NULL;
	char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
	int error;

	operation = git_array_get(rebase->operations, rebase->current);
1062
	GIT_ASSERT(operation);
1063 1064 1065

	if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 ||
		(error = git_repository_head(&head, rebase->repo)) < 0 ||
1066
		(error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)) < 0 ||
1067 1068 1069
		(error = git_repository_index(&index, rebase->repo)) < 0 ||
		(error = rebase_commit__create(&commit, rebase, index, head_commit,
			author, committer, message_encoding, message)) < 0 ||
1070
		(error = git_reference__update_for_commit(
1071
			rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0)
1072 1073
		goto done;

1074 1075 1076 1077 1078 1079
	git_oid_fmt(old_idstr, &operation->id);
	git_oid_fmt(new_idstr, git_commit_id(commit));

	if ((error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND,
		"%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr)) < 0)
		goto done;
1080

1081
	git_oid_cpy(commit_id, git_commit_id(commit));
1082 1083 1084

done:
	git_index_free(index);
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
	git_reference_free(head);
	git_commit_free(head_commit);
	git_commit_free(commit);
	return error;
}

static int 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)
{
	git_commit *commit = NULL;
	int error = 0;

1102 1103 1104
	GIT_ASSERT_ARG(rebase->index);
	GIT_ASSERT_ARG(rebase->last_commit);
	GIT_ASSERT_ARG(rebase->current < rebase->operations.size);
1105

1106
	if ((error = rebase_commit__create(&commit, rebase, rebase->index,
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
		rebase->last_commit, author, committer, message_encoding, message)) < 0)
		goto done;

	git_commit_free(rebase->last_commit);
	rebase->last_commit = commit;

	git_oid_cpy(commit_id, git_commit_id(commit));

done:
	if (error < 0)
		git_commit_free(commit);
1118 1119 1120 1121 1122 1123

	return error;
}

int git_rebase_commit(
	git_oid *id,
1124
	git_rebase *rebase,
1125 1126 1127 1128 1129 1130 1131
	const git_signature *author,
	const git_signature *committer,
	const char *message_encoding,
	const char *message)
{
	int error;

1132 1133
	GIT_ASSERT_ARG(rebase);
	GIT_ASSERT_ARG(committer);
1134

1135 1136 1137
	if (rebase->inmemory)
		error = rebase_commit_inmemory(
			id, rebase, author, committer, message_encoding, message);
1138
	else if (rebase->type == GIT_REBASE_MERGE)
1139
		error = rebase_commit_merge(
1140
			id, rebase, author, committer, message_encoding, message);
1141
	else
1142 1143
		abort();

1144 1145 1146
	return error;
}

1147
int git_rebase_abort(git_rebase *rebase)
1148 1149 1150 1151 1152
{
	git_reference *orig_head_ref = NULL;
	git_commit *orig_head_commit = NULL;
	int error;

1153
	GIT_ASSERT_ARG(rebase);
1154

1155 1156 1157
	if (rebase->inmemory)
		return 0;

1158 1159
	error = rebase->head_detached ?
		git_reference_create(&orig_head_ref, rebase->repo, GIT_HEAD_FILE,
1160
			 &rebase->orig_head_id, 1, "rebase: aborting") :
1161
		git_reference_symbolic_create(
1162
			&orig_head_ref, rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1163
			"rebase: aborting");
1164 1165 1166 1167 1168

	if (error < 0)
		goto done;

	if ((error = git_commit_lookup(
1169 1170
			&orig_head_commit, rebase->repo, &rebase->orig_head_id)) < 0 ||
		(error = git_reset(rebase->repo, (git_object *)orig_head_commit,
1171
			GIT_RESET_HARD, &rebase->options.checkout_options)) < 0)
1172 1173
		goto done;

1174
	error = rebase_cleanup(rebase);
1175 1176 1177 1178 1179 1180 1181

done:
	git_commit_free(orig_head_commit);
	git_reference_free(orig_head_ref);

	return error;
}
1182

1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
static int notes_ref_lookup(git_buf *out, git_rebase *rebase)
{
	git_config *config = NULL;
	int do_rewrite, error;

	if (rebase->options.rewrite_notes_ref) {
		git_buf_attach_notowned(out,
			rebase->options.rewrite_notes_ref,
			strlen(rebase->options.rewrite_notes_ref));
		return 0;
	}

	if ((error = git_repository_config(&config, rebase->repo)) < 0 ||
		(error = git_config_get_bool(&do_rewrite, config, "notes.rewrite.rebase")) < 0) {

		if (error != GIT_ENOTFOUND)
			goto done;

1201
		git_error_clear();
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
		do_rewrite = 1;
	}

	error = do_rewrite ?
		git_config_get_string_buf(out, config, "notes.rewriteref") :
		GIT_ENOTFOUND;

done:
	git_config_free(config);
	return error;
}

1214
static int rebase_copy_note(
1215
	git_rebase *rebase,
1216
	const char *notes_ref,
1217 1218
	git_oid *from,
	git_oid *to,
1219
	const git_signature *committer)
1220
{
1221 1222
	git_note *note = NULL;
	git_oid note_id;
1223
	git_signature *who = NULL;
1224 1225
	int error;

1226
	if ((error = git_note_read(&note, rebase->repo, notes_ref, from)) < 0) {
1227
		if (error == GIT_ENOTFOUND) {
1228
			git_error_clear();
1229 1230 1231 1232 1233 1234
			error = 0;
		}

		goto done;
	}

1235 1236 1237 1238 1239 1240
	if (!committer) {
		if((error = git_signature_default(&who, rebase->repo)) < 0) {
			if (error != GIT_ENOTFOUND ||
				(error = git_signature_now(&who, "unknown", "unknown")) < 0)
				goto done;

1241
			git_error_clear();
1242 1243 1244 1245 1246
		}

		committer = who;
	}

1247
	error = git_note_create(&note_id, rebase->repo, notes_ref,
1248
		git_note_author(note), committer, to, git_note_message(note), 0);
1249 1250 1251

done:
	git_note_free(note);
1252
	git_signature_free(who);
1253 1254 1255 1256 1257

	return error;
}

static int rebase_copy_notes(
1258
	git_rebase *rebase,
1259
	const git_signature *committer)
1260
{
1261
	git_buf path = GIT_BUF_INIT, rewritten = GIT_BUF_INIT, notes_ref = GIT_BUF_INIT;
1262 1263 1264 1265 1266
	char *pair_list, *fromstr, *tostr, *end;
	git_oid from, to;
	unsigned int linenum = 1;
	int error = 0;

1267 1268
	if ((error = notes_ref_lookup(&notes_ref, rebase)) < 0) {
		if (error == GIT_ENOTFOUND) {
1269
			git_error_clear();
1270 1271 1272
			error = 0;
		}

1273
		goto done;
1274
	}
1275

1276
	if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 ||
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302
		(error = git_futils_readbuffer(&rewritten, path.ptr)) < 0)
		goto done;

	pair_list = rewritten.ptr;

	while (*pair_list) {
		fromstr = pair_list;

		if ((end = strchr(fromstr, '\n')) == NULL)
			goto on_error;

		pair_list = end+1;
		*end = '\0';

		if ((end = strchr(fromstr, ' ')) == NULL)
			goto on_error;

		tostr = end+1;
		*end = '\0';

		if (strlen(fromstr) != GIT_OID_HEXSZ ||
			strlen(tostr) != GIT_OID_HEXSZ ||
			git_oid_fromstr(&from, fromstr) < 0 ||
			git_oid_fromstr(&to, tostr) < 0)
			goto on_error;

1303
		if ((error = rebase_copy_note(rebase, notes_ref.ptr, &from, &to, committer)) < 0)
1304 1305 1306 1307 1308 1309 1310 1311
			goto done;

		linenum++;
	}

	goto done;

on_error:
1312
	git_error_set(GIT_ERROR_REBASE, "invalid rewritten file at line %d", linenum);
1313 1314 1315
	error = -1;

done:
1316 1317 1318
	git_buf_dispose(&rewritten);
	git_buf_dispose(&path);
	git_buf_dispose(&notes_ref);
1319 1320 1321 1322

	return error;
}

1323
static int return_to_orig_head(git_rebase *rebase)
1324
{
1325 1326 1327 1328
	git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL;
	git_commit *terminal_commit = NULL;
	git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT;
	char onto[GIT_OID_HEXSZ];
1329
	int error = 0;
1330

1331
	git_oid_fmt(onto, &rebase->onto_id);
1332

1333 1334 1335 1336 1337 1338 1339
	if ((error = git_buf_printf(&branch_msg,
			"rebase finished: %s onto %.*s",
			rebase->orig_head_name, GIT_OID_HEXSZ, onto)) == 0 &&
		(error = git_buf_printf(&head_msg,
			"rebase finished: returning to %s",
			rebase->orig_head_name)) == 0 &&
		(error = git_repository_head(&terminal_ref, rebase->repo)) == 0 &&
1340
		(error = git_reference_peel((git_object **)&terminal_commit,
1341
			terminal_ref, GIT_OBJECT_COMMIT)) == 0 &&
1342
		(error = git_reference_create_matching(&branch_ref,
1343 1344 1345 1346
			rebase->repo, rebase->orig_head_name,
			git_commit_id(terminal_commit), 1,
			&rebase->orig_head_id, branch_msg.ptr)) == 0)
		error = git_reference_symbolic_create(&head_ref,
1347
			rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1348
			head_msg.ptr);
1349

1350 1351
	git_buf_dispose(&head_msg);
	git_buf_dispose(&branch_msg);
1352 1353 1354 1355 1356 1357 1358 1359
	git_commit_free(terminal_commit);
	git_reference_free(head_ref);
	git_reference_free(branch_ref);
	git_reference_free(terminal_ref);

	return error;
}

1360 1361 1362 1363 1364 1365
int git_rebase_finish(
	git_rebase *rebase,
	const git_signature *signature)
{
	int error = 0;

1366
	GIT_ASSERT_ARG(rebase);
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379

	if (rebase->inmemory)
		return 0;

	if (!rebase->head_detached)
		error = return_to_orig_head(rebase);

	if (error == 0 && (error = rebase_copy_notes(rebase, signature)) == 0)
		error = rebase_cleanup(rebase);

	return error;
}

1380
const char *git_rebase_orig_head_name(git_rebase *rebase) {
1381
	GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL);
1382 1383 1384 1385
	return rebase->orig_head_name;
}

const git_oid *git_rebase_orig_head_id(git_rebase *rebase) {
1386
	GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL);
1387 1388 1389 1390
	return &rebase->orig_head_id;
}

const char *git_rebase_onto_name(git_rebase *rebase) {
1391
	GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL);
1392 1393 1394 1395 1396 1397 1398
	return rebase->onto_name;
}

const git_oid *git_rebase_onto_id(git_rebase *rebase) {
	return &rebase->onto_id;
}

1399 1400
size_t git_rebase_operation_entrycount(git_rebase *rebase)
{
1401
	GIT_ASSERT_ARG_WITH_RETVAL(rebase, 0);
1402 1403 1404 1405 1406 1407

	return git_array_size(rebase->operations);
}

size_t git_rebase_operation_current(git_rebase *rebase)
{
1408
	GIT_ASSERT_ARG_WITH_RETVAL(rebase, 0);
1409

1410
	return rebase->started ? rebase->current : GIT_REBASE_NO_OPERATION;
1411 1412 1413 1414
}

git_rebase_operation *git_rebase_operation_byindex(git_rebase *rebase, size_t idx)
{
1415
	GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL);
1416 1417 1418 1419

	return git_array_get(rebase->operations, idx);
}

1420 1421 1422 1423 1424
void git_rebase_free(git_rebase *rebase)
{
	if (rebase == NULL)
		return;

1425
	git_index_free(rebase->index);
1426
	git_commit_free(rebase->last_commit);
1427
	git__free(rebase->onto_name);
1428 1429
	git__free(rebase->orig_head_name);
	git__free(rebase->state_path);
1430
	git_array_clear(rebase->operations);
1431
	git__free((char *)rebase->options.rewrite_notes_ref);
1432
	git__free(rebase);
1433
}