|
9 | 9 | #include "git2/object.h"
|
10 | 10 | #include "git2/repository.h"
|
11 | 11 | #include "git2/signature.h"
|
| 12 | +#include "git2/index.h" |
12 | 13 | #include "git2/sys/commit.h"
|
13 | 14 |
|
14 | 15 | #include "common.h"
|
@@ -302,6 +303,79 @@ int git_commit_amend(
|
302 | 303 | return error;
|
303 | 304 | }
|
304 | 305 |
|
| 306 | +static int insert_commit(git_vector *v, git_repository *repo, git_oid *id) |
| 307 | +{ |
| 308 | + int error; |
| 309 | + git_commit *commit; |
| 310 | + |
| 311 | + if ((error = git_commit_lookup(&commit, repo, id)) < 0) |
| 312 | + return error; |
| 313 | + |
| 314 | + if ((error = git_vector_insert(v, commit)) < 0) { |
| 315 | + git_commit_free(commit); |
| 316 | + return error; |
| 317 | + } |
| 318 | + |
| 319 | + return 0; |
| 320 | +} |
| 321 | + |
| 322 | +int git_commit_create_fromstate( |
| 323 | + git_oid *id, |
| 324 | + git_repository *repo, |
| 325 | + const git_signature *author, |
| 326 | + const git_signature *committer, |
| 327 | + const char *message_encoding, |
| 328 | + const char *message) |
| 329 | +{ |
| 330 | + int error; |
| 331 | + size_t i; |
| 332 | + git_tree *tree = NULL; |
| 333 | + git_index *index = NULL; |
| 334 | + git_oid current_id, tree_id; |
| 335 | + git_commit *commit; |
| 336 | + git_vector commits = GIT_VECTOR_INIT; |
| 337 | + git_repository_state_t state; |
| 338 | + |
| 339 | + state = git_repository_state(repo); |
| 340 | + |
| 341 | + if ((error = git_reference_name_to_id(¤t_id, repo, GIT_HEAD_FILE)) < 0) |
| 342 | + return error; |
| 343 | + |
| 344 | + if ((error = insert_commit(&commits, repo, ¤t_id)) < 0) |
| 345 | + goto cleanup; |
| 346 | + |
| 347 | + /* TODO: how do we handle octopus merges? */ |
| 348 | + if (state == GIT_REPOSITORY_STATE_MERGE) { |
| 349 | + if ((error = git_reference_name_to_id(¤t_id, repo, GIT_MERGE_HEAD_FILE)) < 0) |
| 350 | + goto cleanup; |
| 351 | + |
| 352 | + if ((error = insert_commit(&commits, repo, ¤t_id)) < 0) |
| 353 | + goto cleanup; |
| 354 | + } |
| 355 | + |
| 356 | + if ((error = git_repository_index(&index, repo)) < 0) |
| 357 | + goto cleanup; |
| 358 | + |
| 359 | + error = git_index_write_tree(&tree_id, index); |
| 360 | + git_index_free(index); |
| 361 | + if (error < 0) |
| 362 | + goto cleanup; |
| 363 | + |
| 364 | + if ((error = git_tree_lookup(&tree, repo, &tree_id)) < 0) |
| 365 | + goto cleanup; |
| 366 | + |
| 367 | + error = git_commit_create(id, repo, GIT_HEAD_FILE, |
| 368 | + author, committer, message_encoding, message, |
| 369 | + tree, commits.length, (const git_commit **) commits.contents); |
| 370 | + |
| 371 | +cleanup: |
| 372 | + git_tree_free(tree); |
| 373 | + git_vector_foreach(&commits, i, commit) { |
| 374 | + git_commit_free(commit); |
| 375 | + } |
| 376 | + return 0; |
| 377 | +} |
| 378 | + |
305 | 379 | int git_commit__parse(void *_commit, git_odb_object *odb_obj)
|
306 | 380 | {
|
307 | 381 | git_commit *commit = _commit;
|
|
0 commit comments