]> git.proxmox.com Git - libgit2.git/blob - src/stash.c
5fc01ac36ddd2d3f86a3a329d03972e2bb2db9e9
[libgit2.git] / src / stash.c
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 "repository.h"
11 #include "commit.h"
12 #include "tree.h"
13 #include "reflog.h"
14 #include "blob.h"
15 #include "git2/diff.h"
16 #include "git2/stash.h"
17 #include "git2/status.h"
18 #include "git2/checkout.h"
19 #include "git2/index.h"
20 #include "git2/transaction.h"
21 #include "git2/merge.h"
22 #include "index.h"
23 #include "signature.h"
24 #include "iterator.h"
25 #include "merge.h"
26 #include "diff.h"
27 #include "diff_generate.h"
28
29 static int create_error(int error, const char *msg)
30 {
31 git_error_set(GIT_ERROR_STASH, "cannot stash changes - %s", msg);
32 return error;
33 }
34
35 static int retrieve_head(git_reference **out, git_repository *repo)
36 {
37 int error = git_repository_head(out, repo);
38
39 if (error == GIT_EUNBORNBRANCH)
40 return create_error(error, "you do not have the initial commit yet.");
41
42 return error;
43 }
44
45 static int append_abbreviated_oid(git_str *out, const git_oid *b_commit)
46 {
47 char *formatted_oid;
48
49 formatted_oid = git_oid_allocfmt(b_commit);
50 GIT_ERROR_CHECK_ALLOC(formatted_oid);
51
52 git_str_put(out, formatted_oid, 7);
53 git__free(formatted_oid);
54
55 return git_str_oom(out) ? -1 : 0;
56 }
57
58 static int append_commit_description(git_str *out, git_commit *commit)
59 {
60 const char *summary = git_commit_summary(commit);
61 GIT_ERROR_CHECK_ALLOC(summary);
62
63 if (append_abbreviated_oid(out, git_commit_id(commit)) < 0)
64 return -1;
65
66 git_str_putc(out, ' ');
67 git_str_puts(out, summary);
68 git_str_putc(out, '\n');
69
70 return git_str_oom(out) ? -1 : 0;
71 }
72
73 static int retrieve_base_commit_and_message(
74 git_commit **b_commit,
75 git_str *stash_message,
76 git_repository *repo)
77 {
78 git_reference *head = NULL;
79 int error;
80
81 if ((error = retrieve_head(&head, repo)) < 0)
82 return error;
83
84 if (strcmp("HEAD", git_reference_name(head)) == 0)
85 error = git_str_puts(stash_message, "(no branch): ");
86 else
87 error = git_str_printf(
88 stash_message,
89 "%s: ",
90 git_reference_name(head) + strlen(GIT_REFS_HEADS_DIR));
91 if (error < 0)
92 goto cleanup;
93
94 if ((error = git_commit_lookup(
95 b_commit, repo, git_reference_target(head))) < 0)
96 goto cleanup;
97
98 if ((error = append_commit_description(stash_message, *b_commit)) < 0)
99 goto cleanup;
100
101 cleanup:
102 git_reference_free(head);
103 return error;
104 }
105
106 static int build_tree_from_index(
107 git_tree **out,
108 git_repository *repo,
109 git_index *index)
110 {
111 int error;
112 git_oid i_tree_oid;
113
114 if ((error = git_index_write_tree_to(&i_tree_oid, index, repo)) < 0)
115 return error;
116
117 return git_tree_lookup(out, repo, &i_tree_oid);
118 }
119
120 static int commit_index(
121 git_commit **i_commit,
122 git_repository *repo,
123 git_index *index,
124 const git_signature *stasher,
125 const char *message,
126 const git_commit *parent)
127 {
128 git_tree *i_tree = NULL;
129 git_oid i_commit_oid;
130 git_str msg = GIT_STR_INIT;
131 int error;
132
133 if ((error = build_tree_from_index(&i_tree, repo, index)) < 0)
134 goto cleanup;
135
136 if ((error = git_str_printf(&msg, "index on %s\n", message)) < 0)
137 goto cleanup;
138
139 if ((error = git_commit_create(
140 &i_commit_oid,
141 git_index_owner(index),
142 NULL,
143 stasher,
144 stasher,
145 NULL,
146 git_str_cstr(&msg),
147 i_tree,
148 1,
149 &parent)) < 0)
150 goto cleanup;
151
152 error = git_commit_lookup(i_commit, git_index_owner(index), &i_commit_oid);
153
154 cleanup:
155 git_tree_free(i_tree);
156 git_str_dispose(&msg);
157 return error;
158 }
159
160 struct stash_update_rules {
161 bool include_changed;
162 bool include_untracked;
163 bool include_ignored;
164 };
165
166 /*
167 * Similar to git_index_add_bypath but able to operate on any
168 * index without making assumptions about the repository's index
169 */
170 static int stash_to_index(
171 git_repository *repo,
172 git_index *index,
173 const char *path)
174 {
175 git_index *repo_index = NULL;
176 git_index_entry entry = {{0}};
177 struct stat st;
178 int error;
179
180 if (!git_repository_is_bare(repo) &&
181 (error = git_repository_index__weakptr(&repo_index, repo)) < 0)
182 return error;
183
184 if ((error = git_blob__create_from_paths(
185 &entry.id, &st, repo, NULL, path, 0, true)) < 0)
186 return error;
187
188 git_index_entry__init_from_stat(&entry, &st,
189 (repo_index == NULL || !repo_index->distrust_filemode));
190
191 entry.path = path;
192
193 return git_index_add(index, &entry);
194 }
195
196 static int stash_update_index_from_diff(
197 git_repository *repo,
198 git_index *index,
199 const git_diff *diff,
200 struct stash_update_rules *data)
201 {
202 int error = 0;
203 size_t d, max_d = git_diff_num_deltas(diff);
204
205 for (d = 0; !error && d < max_d; ++d) {
206 const char *add_path = NULL;
207 const git_diff_delta *delta = git_diff_get_delta(diff, d);
208
209 switch (delta->status) {
210 case GIT_DELTA_IGNORED:
211 if (data->include_ignored)
212 add_path = delta->new_file.path;
213 break;
214
215 case GIT_DELTA_UNTRACKED:
216 if (data->include_untracked &&
217 delta->new_file.mode != GIT_FILEMODE_TREE)
218 add_path = delta->new_file.path;
219 break;
220
221 case GIT_DELTA_ADDED:
222 case GIT_DELTA_MODIFIED:
223 if (data->include_changed)
224 add_path = delta->new_file.path;
225 break;
226
227 case GIT_DELTA_DELETED:
228 if (data->include_changed &&
229 !git_index_find(NULL, index, delta->old_file.path))
230 error = git_index_remove(index, delta->old_file.path, 0);
231 break;
232
233 default:
234 /* Unimplemented */
235 git_error_set(
236 GIT_ERROR_INVALID,
237 "cannot update index. Unimplemented status (%d)",
238 delta->status);
239 return -1;
240 }
241
242 if (add_path != NULL)
243 error = stash_to_index(repo, index, add_path);
244 }
245
246 return error;
247 }
248
249 static int build_untracked_tree(
250 git_tree **tree_out,
251 git_repository *repo,
252 git_commit *i_commit,
253 uint32_t flags)
254 {
255 git_index *i_index = NULL;
256 git_tree *i_tree = NULL;
257 git_diff *diff = NULL;
258 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
259 struct stash_update_rules data = {0};
260 int error;
261
262 if ((error = git_index_new(&i_index)) < 0)
263 goto cleanup;
264
265 if (flags & GIT_STASH_INCLUDE_UNTRACKED) {
266 opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
267 GIT_DIFF_RECURSE_UNTRACKED_DIRS;
268 data.include_untracked = true;
269 }
270
271 if (flags & GIT_STASH_INCLUDE_IGNORED) {
272 opts.flags |= GIT_DIFF_INCLUDE_IGNORED |
273 GIT_DIFF_RECURSE_IGNORED_DIRS;
274 data.include_ignored = true;
275 }
276
277 if ((error = git_commit_tree(&i_tree, i_commit)) < 0)
278 goto cleanup;
279
280 if ((error = git_diff_tree_to_workdir(&diff, repo, i_tree, &opts)) < 0)
281 goto cleanup;
282
283 if ((error = stash_update_index_from_diff(repo, i_index, diff, &data)) < 0)
284 goto cleanup;
285
286 error = build_tree_from_index(tree_out, repo, i_index);
287
288 cleanup:
289 git_diff_free(diff);
290 git_tree_free(i_tree);
291 git_index_free(i_index);
292 return error;
293 }
294
295 static int commit_untracked(
296 git_commit **u_commit,
297 git_repository *repo,
298 const git_signature *stasher,
299 const char *message,
300 git_commit *i_commit,
301 uint32_t flags)
302 {
303 git_tree *u_tree = NULL;
304 git_oid u_commit_oid;
305 git_str msg = GIT_STR_INIT;
306 int error;
307
308 if ((error = build_untracked_tree(&u_tree, repo, i_commit, flags)) < 0)
309 goto cleanup;
310
311 if ((error = git_str_printf(&msg, "untracked files on %s\n", message)) < 0)
312 goto cleanup;
313
314 if ((error = git_commit_create(
315 &u_commit_oid,
316 repo,
317 NULL,
318 stasher,
319 stasher,
320 NULL,
321 git_str_cstr(&msg),
322 u_tree,
323 0,
324 NULL)) < 0)
325 goto cleanup;
326
327 error = git_commit_lookup(u_commit, repo, &u_commit_oid);
328
329 cleanup:
330 git_tree_free(u_tree);
331 git_str_dispose(&msg);
332 return error;
333 }
334
335 static git_diff_delta *stash_delta_merge(
336 const git_diff_delta *a,
337 const git_diff_delta *b,
338 git_pool *pool)
339 {
340 /* Special case for stash: if a file is deleted in the index, but exists
341 * in the working tree, we need to stash the workdir copy for the workdir.
342 */
343 if (a->status == GIT_DELTA_DELETED && b->status == GIT_DELTA_UNTRACKED) {
344 git_diff_delta *dup = git_diff__delta_dup(b, pool);
345
346 if (dup)
347 dup->status = GIT_DELTA_MODIFIED;
348 return dup;
349 }
350
351 return git_diff__merge_like_cgit(a, b, pool);
352 }
353
354 static int build_workdir_tree(
355 git_tree **tree_out,
356 git_repository *repo,
357 git_index *i_index,
358 git_commit *b_commit)
359 {
360 git_tree *b_tree = NULL;
361 git_diff *diff = NULL, *idx_to_wd = NULL;
362 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
363 struct stash_update_rules data = {0};
364 int error;
365
366 opts.flags = GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_INCLUDE_UNTRACKED;
367
368 if ((error = git_commit_tree(&b_tree, b_commit)) < 0)
369 goto cleanup;
370
371 if ((error = git_diff_tree_to_index(&diff, repo, b_tree, i_index, &opts)) < 0 ||
372 (error = git_diff_index_to_workdir(&idx_to_wd, repo, i_index, &opts)) < 0 ||
373 (error = git_diff__merge(diff, idx_to_wd, stash_delta_merge)) < 0)
374 goto cleanup;
375
376 data.include_changed = true;
377
378 if ((error = stash_update_index_from_diff(repo, i_index, diff, &data)) < 0)
379 goto cleanup;
380
381 error = build_tree_from_index(tree_out, repo, i_index);
382
383 cleanup:
384 git_diff_free(idx_to_wd);
385 git_diff_free(diff);
386 git_tree_free(b_tree);
387
388 return error;
389 }
390
391 static int commit_worktree(
392 git_oid *w_commit_oid,
393 git_repository *repo,
394 const git_signature *stasher,
395 const char *message,
396 git_commit *i_commit,
397 git_commit *b_commit,
398 git_commit *u_commit)
399 {
400 const git_commit *parents[] = { NULL, NULL, NULL };
401 git_index *i_index = NULL, *r_index = NULL;
402 git_tree *w_tree = NULL;
403 int error = 0, ignorecase;
404
405 parents[0] = b_commit;
406 parents[1] = i_commit;
407 parents[2] = u_commit;
408
409 if ((error = git_repository_index(&r_index, repo) < 0) ||
410 (error = git_index_new(&i_index)) < 0 ||
411 (error = git_index__fill(i_index, &r_index->entries) < 0) ||
412 (error = git_repository__configmap_lookup(&ignorecase, repo, GIT_CONFIGMAP_IGNORECASE)) < 0)
413 goto cleanup;
414
415 git_index__set_ignore_case(i_index, ignorecase);
416
417 if ((error = build_workdir_tree(&w_tree, repo, i_index, b_commit)) < 0)
418 goto cleanup;
419
420 error = git_commit_create(
421 w_commit_oid,
422 repo,
423 NULL,
424 stasher,
425 stasher,
426 NULL,
427 message,
428 w_tree,
429 u_commit ? 3 : 2,
430 parents);
431
432 cleanup:
433 git_tree_free(w_tree);
434 git_index_free(i_index);
435 git_index_free(r_index);
436 return error;
437 }
438
439 static int prepare_worktree_commit_message(git_str *out, const char *user_message)
440 {
441 git_str buf = GIT_STR_INIT;
442 int error = 0;
443
444 if (!user_message) {
445 git_str_printf(&buf, "WIP on %s", git_str_cstr(out));
446 } else {
447 const char *colon;
448
449 if ((colon = strchr(git_str_cstr(out), ':')) == NULL)
450 goto cleanup;
451
452 git_str_puts(&buf, "On ");
453 git_str_put(&buf, git_str_cstr(out), colon - out->ptr);
454 git_str_printf(&buf, ": %s\n", user_message);
455 }
456
457 if (git_str_oom(&buf)) {
458 error = -1;
459 goto cleanup;
460 }
461
462 git_str_swap(out, &buf);
463
464 cleanup:
465 git_str_dispose(&buf);
466 return error;
467 }
468
469 static int update_reflog(
470 git_oid *w_commit_oid,
471 git_repository *repo,
472 const char *message)
473 {
474 git_reference *stash;
475 int error;
476
477 if ((error = git_reference_ensure_log(repo, GIT_REFS_STASH_FILE)) < 0)
478 return error;
479
480 error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, w_commit_oid, 1, message);
481
482 git_reference_free(stash);
483
484 return error;
485 }
486
487 static int is_dirty_cb(const char *path, unsigned int status, void *payload)
488 {
489 GIT_UNUSED(path);
490 GIT_UNUSED(status);
491 GIT_UNUSED(payload);
492
493 return GIT_PASSTHROUGH;
494 }
495
496 static int ensure_there_are_changes_to_stash(git_repository *repo, uint32_t flags)
497 {
498 int error;
499 git_status_options opts = GIT_STATUS_OPTIONS_INIT;
500
501 opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
502 opts.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
503
504 if (flags & GIT_STASH_INCLUDE_UNTRACKED)
505 opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
506 GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
507
508 if (flags & GIT_STASH_INCLUDE_IGNORED)
509 opts.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED |
510 GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
511
512 error = git_status_foreach_ext(repo, &opts, is_dirty_cb, NULL);
513
514 if (error == GIT_PASSTHROUGH)
515 return 0;
516
517 if (!error)
518 return create_error(GIT_ENOTFOUND, "there is nothing to stash.");
519
520 return error;
521 }
522
523 static int reset_index_and_workdir(git_repository *repo, git_commit *commit, uint32_t flags)
524 {
525 git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
526
527 opts.checkout_strategy = GIT_CHECKOUT_FORCE;
528 if (flags & GIT_STASH_INCLUDE_UNTRACKED)
529 opts.checkout_strategy |= GIT_CHECKOUT_REMOVE_UNTRACKED;
530 if (flags & GIT_STASH_INCLUDE_IGNORED)
531 opts.checkout_strategy |= GIT_CHECKOUT_REMOVE_IGNORED;
532
533 return git_checkout_tree(repo, (git_object *)commit, &opts);
534 }
535
536 int git_stash_save(
537 git_oid *out,
538 git_repository *repo,
539 const git_signature *stasher,
540 const char *message,
541 uint32_t flags)
542 {
543 git_index *index = NULL;
544 git_commit *b_commit = NULL, *i_commit = NULL, *u_commit = NULL;
545 git_str msg = GIT_STR_INIT;
546 int error;
547
548 GIT_ASSERT_ARG(out);
549 GIT_ASSERT_ARG(repo);
550 GIT_ASSERT_ARG(stasher);
551
552 if ((error = git_repository__ensure_not_bare(repo, "stash save")) < 0)
553 return error;
554
555 if ((error = retrieve_base_commit_and_message(&b_commit, &msg, repo)) < 0)
556 goto cleanup;
557
558 if ((error = ensure_there_are_changes_to_stash(repo, flags)) < 0)
559 goto cleanup;
560
561 if ((error = git_repository_index(&index, repo)) < 0)
562 goto cleanup;
563
564 if ((error = commit_index(&i_commit, repo, index, stasher,
565 git_str_cstr(&msg), b_commit)) < 0)
566 goto cleanup;
567
568 if ((flags & (GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)) &&
569 (error = commit_untracked(&u_commit, repo, stasher,
570 git_str_cstr(&msg), i_commit, flags)) < 0)
571 goto cleanup;
572
573 if ((error = prepare_worktree_commit_message(&msg, message)) < 0)
574 goto cleanup;
575
576 if ((error = commit_worktree(out, repo, stasher, git_str_cstr(&msg),
577 i_commit, b_commit, u_commit)) < 0)
578 goto cleanup;
579
580 git_str_rtrim(&msg);
581
582 if ((error = update_reflog(out, repo, git_str_cstr(&msg))) < 0)
583 goto cleanup;
584
585 if ((error = reset_index_and_workdir(repo, (flags & GIT_STASH_KEEP_INDEX) ? i_commit : b_commit,
586 flags)) < 0)
587 goto cleanup;
588
589 cleanup:
590
591 git_str_dispose(&msg);
592 git_commit_free(i_commit);
593 git_commit_free(b_commit);
594 git_commit_free(u_commit);
595 git_index_free(index);
596
597 return error;
598 }
599
600 static int retrieve_stash_commit(
601 git_commit **commit,
602 git_repository *repo,
603 size_t index)
604 {
605 git_reference *stash = NULL;
606 git_reflog *reflog = NULL;
607 int error;
608 size_t max;
609 const git_reflog_entry *entry;
610
611 if ((error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE)) < 0)
612 goto cleanup;
613
614 if ((error = git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE)) < 0)
615 goto cleanup;
616
617 max = git_reflog_entrycount(reflog);
618 if (!max || index > max - 1) {
619 error = GIT_ENOTFOUND;
620 git_error_set(GIT_ERROR_STASH, "no stashed state at position %" PRIuZ, index);
621 goto cleanup;
622 }
623
624 entry = git_reflog_entry_byindex(reflog, index);
625 if ((error = git_commit_lookup(commit, repo, git_reflog_entry_id_new(entry))) < 0)
626 goto cleanup;
627
628 cleanup:
629 git_reference_free(stash);
630 git_reflog_free(reflog);
631 return error;
632 }
633
634 static int retrieve_stash_trees(
635 git_tree **out_stash_tree,
636 git_tree **out_base_tree,
637 git_tree **out_index_tree,
638 git_tree **out_index_parent_tree,
639 git_tree **out_untracked_tree,
640 git_commit *stash_commit)
641 {
642 git_tree *stash_tree = NULL;
643 git_commit *base_commit = NULL;
644 git_tree *base_tree = NULL;
645 git_commit *index_commit = NULL;
646 git_tree *index_tree = NULL;
647 git_commit *index_parent_commit = NULL;
648 git_tree *index_parent_tree = NULL;
649 git_commit *untracked_commit = NULL;
650 git_tree *untracked_tree = NULL;
651 int error;
652
653 if ((error = git_commit_tree(&stash_tree, stash_commit)) < 0)
654 goto cleanup;
655
656 if ((error = git_commit_parent(&base_commit, stash_commit, 0)) < 0)
657 goto cleanup;
658 if ((error = git_commit_tree(&base_tree, base_commit)) < 0)
659 goto cleanup;
660
661 if ((error = git_commit_parent(&index_commit, stash_commit, 1)) < 0)
662 goto cleanup;
663 if ((error = git_commit_tree(&index_tree, index_commit)) < 0)
664 goto cleanup;
665
666 if ((error = git_commit_parent(&index_parent_commit, index_commit, 0)) < 0)
667 goto cleanup;
668 if ((error = git_commit_tree(&index_parent_tree, index_parent_commit)) < 0)
669 goto cleanup;
670
671 if (git_commit_parentcount(stash_commit) == 3) {
672 if ((error = git_commit_parent(&untracked_commit, stash_commit, 2)) < 0)
673 goto cleanup;
674 if ((error = git_commit_tree(&untracked_tree, untracked_commit)) < 0)
675 goto cleanup;
676 }
677
678 *out_stash_tree = stash_tree;
679 *out_base_tree = base_tree;
680 *out_index_tree = index_tree;
681 *out_index_parent_tree = index_parent_tree;
682 *out_untracked_tree = untracked_tree;
683
684 cleanup:
685 git_commit_free(untracked_commit);
686 git_commit_free(index_parent_commit);
687 git_commit_free(index_commit);
688 git_commit_free(base_commit);
689 if (error < 0) {
690 git_tree_free(stash_tree);
691 git_tree_free(base_tree);
692 git_tree_free(index_tree);
693 git_tree_free(index_parent_tree);
694 git_tree_free(untracked_tree);
695 }
696 return error;
697 }
698
699 static int merge_indexes(
700 git_index **out,
701 git_repository *repo,
702 git_tree *ancestor_tree,
703 git_index *ours_index,
704 git_index *theirs_index)
705 {
706 git_iterator *ancestor = NULL, *ours = NULL, *theirs = NULL;
707 git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
708 int error;
709
710 iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
711
712 if ((error = git_iterator_for_tree(&ancestor, ancestor_tree, &iter_opts)) < 0 ||
713 (error = git_iterator_for_index(&ours, repo, ours_index, &iter_opts)) < 0 ||
714 (error = git_iterator_for_index(&theirs, repo, theirs_index, &iter_opts)) < 0)
715 goto done;
716
717 error = git_merge__iterators(out, repo, ancestor, ours, theirs, NULL);
718
719 done:
720 git_iterator_free(ancestor);
721 git_iterator_free(ours);
722 git_iterator_free(theirs);
723 return error;
724 }
725
726 static int merge_index_and_tree(
727 git_index **out,
728 git_repository *repo,
729 git_tree *ancestor_tree,
730 git_index *ours_index,
731 git_tree *theirs_tree)
732 {
733 git_iterator *ancestor = NULL, *ours = NULL, *theirs = NULL;
734 git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
735 int error;
736
737 iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
738
739 if ((error = git_iterator_for_tree(&ancestor, ancestor_tree, &iter_opts)) < 0 ||
740 (error = git_iterator_for_index(&ours, repo, ours_index, &iter_opts)) < 0 ||
741 (error = git_iterator_for_tree(&theirs, theirs_tree, &iter_opts)) < 0)
742 goto done;
743
744 error = git_merge__iterators(out, repo, ancestor, ours, theirs, NULL);
745
746 done:
747 git_iterator_free(ancestor);
748 git_iterator_free(ours);
749 git_iterator_free(theirs);
750 return error;
751 }
752
753 static void normalize_apply_options(
754 git_stash_apply_options *opts,
755 const git_stash_apply_options *given_apply_opts)
756 {
757 if (given_apply_opts != NULL) {
758 memcpy(opts, given_apply_opts, sizeof(git_stash_apply_options));
759 } else {
760 git_stash_apply_options default_apply_opts = GIT_STASH_APPLY_OPTIONS_INIT;
761 memcpy(opts, &default_apply_opts, sizeof(git_stash_apply_options));
762 }
763
764 opts->checkout_options.checkout_strategy |= GIT_CHECKOUT_NO_REFRESH;
765
766 if (!opts->checkout_options.our_label)
767 opts->checkout_options.our_label = "Updated upstream";
768
769 if (!opts->checkout_options.their_label)
770 opts->checkout_options.their_label = "Stashed changes";
771 }
772
773 int git_stash_apply_options_init(git_stash_apply_options *opts, unsigned int version)
774 {
775 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
776 opts, version, git_stash_apply_options, GIT_STASH_APPLY_OPTIONS_INIT);
777 return 0;
778 }
779
780 #ifndef GIT_DEPRECATE_HARD
781 int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int version)
782 {
783 return git_stash_apply_options_init(opts, version);
784 }
785 #endif
786
787 #define NOTIFY_PROGRESS(opts, progress_type) \
788 do { \
789 if ((opts).progress_cb && \
790 (error = (opts).progress_cb((progress_type), (opts).progress_payload))) { \
791 error = (error < 0) ? error : -1; \
792 goto cleanup; \
793 } \
794 } while(false);
795
796 static int ensure_clean_index(git_repository *repo, git_index *index)
797 {
798 git_tree *head_tree = NULL;
799 git_diff *index_diff = NULL;
800 int error = 0;
801
802 if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
803 (error = git_diff_tree_to_index(
804 &index_diff, repo, head_tree, index, NULL)) < 0)
805 goto done;
806
807 if (git_diff_num_deltas(index_diff) > 0) {
808 git_error_set(GIT_ERROR_STASH, "%" PRIuZ " uncommitted changes exist in the index",
809 git_diff_num_deltas(index_diff));
810 error = GIT_EUNCOMMITTED;
811 }
812
813 done:
814 git_diff_free(index_diff);
815 git_tree_free(head_tree);
816 return error;
817 }
818
819 static int stage_new_file(const git_index_entry **entries, void *data)
820 {
821 git_index *index = data;
822
823 if(entries[0] == NULL)
824 return git_index_add(index, entries[1]);
825 else
826 return git_index_add(index, entries[0]);
827 }
828
829 static int stage_new_files(
830 git_index **out,
831 git_tree *parent_tree,
832 git_tree *tree)
833 {
834 git_iterator *iterators[2] = { NULL, NULL };
835 git_iterator_options iterator_options = GIT_ITERATOR_OPTIONS_INIT;
836 git_index *index = NULL;
837 int error;
838
839 if ((error = git_index_new(&index)) < 0 ||
840 (error = git_iterator_for_tree(
841 &iterators[0], parent_tree, &iterator_options)) < 0 ||
842 (error = git_iterator_for_tree(
843 &iterators[1], tree, &iterator_options)) < 0)
844 goto done;
845
846 error = git_iterator_walk(iterators, 2, stage_new_file, index);
847
848 done:
849 if (error < 0)
850 git_index_free(index);
851 else
852 *out = index;
853
854 git_iterator_free(iterators[0]);
855 git_iterator_free(iterators[1]);
856
857 return error;
858 }
859
860 int git_stash_apply(
861 git_repository *repo,
862 size_t index,
863 const git_stash_apply_options *given_opts)
864 {
865 git_stash_apply_options opts;
866 unsigned int checkout_strategy;
867 git_commit *stash_commit = NULL;
868 git_tree *stash_tree = NULL;
869 git_tree *stash_parent_tree = NULL;
870 git_tree *index_tree = NULL;
871 git_tree *index_parent_tree = NULL;
872 git_tree *untracked_tree = NULL;
873 git_index *stash_adds = NULL;
874 git_index *repo_index = NULL;
875 git_index *unstashed_index = NULL;
876 git_index *modified_index = NULL;
877 git_index *untracked_index = NULL;
878 int error;
879
880 GIT_ERROR_CHECK_VERSION(given_opts, GIT_STASH_APPLY_OPTIONS_VERSION, "git_stash_apply_options");
881
882 normalize_apply_options(&opts, given_opts);
883 checkout_strategy = opts.checkout_options.checkout_strategy;
884
885 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_LOADING_STASH);
886
887 /* Retrieve commit corresponding to the given stash */
888 if ((error = retrieve_stash_commit(&stash_commit, repo, index)) < 0)
889 goto cleanup;
890
891 /* Retrieve all trees in the stash */
892 if ((error = retrieve_stash_trees(
893 &stash_tree, &stash_parent_tree, &index_tree,
894 &index_parent_tree, &untracked_tree, stash_commit)) < 0)
895 goto cleanup;
896
897 /* Load repo index */
898 if ((error = git_repository_index(&repo_index, repo)) < 0)
899 goto cleanup;
900
901 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX);
902
903 if ((error = ensure_clean_index(repo, repo_index)) < 0)
904 goto cleanup;
905
906 /* Restore index if required */
907 if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) &&
908 git_oid_cmp(git_tree_id(stash_parent_tree), git_tree_id(index_tree))) {
909
910 if ((error = merge_index_and_tree(
911 &unstashed_index, repo, index_parent_tree, repo_index, index_tree)) < 0)
912 goto cleanup;
913
914 if (git_index_has_conflicts(unstashed_index)) {
915 error = GIT_ECONFLICT;
916 goto cleanup;
917 }
918
919 /* Otherwise, stage any new files in the stash tree. (Note: their
920 * previously unstaged contents are staged, not the previously staged.)
921 */
922 } else if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) == 0) {
923 if ((error = stage_new_files(
924 &stash_adds, stash_parent_tree, stash_tree)) < 0 ||
925 (error = merge_indexes(
926 &unstashed_index, repo, stash_parent_tree, repo_index, stash_adds)) < 0)
927 goto cleanup;
928 }
929
930 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED);
931
932 /* Restore modified files in workdir */
933 if ((error = merge_index_and_tree(
934 &modified_index, repo, stash_parent_tree, repo_index, stash_tree)) < 0)
935 goto cleanup;
936
937 /* If applicable, restore untracked / ignored files in workdir */
938 if (untracked_tree) {
939 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED);
940
941 if ((error = merge_index_and_tree(&untracked_index, repo, NULL, repo_index, untracked_tree)) < 0)
942 goto cleanup;
943 }
944
945 if (untracked_index) {
946 opts.checkout_options.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
947
948 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED);
949
950 if ((error = git_checkout_index(repo, untracked_index, &opts.checkout_options)) < 0)
951 goto cleanup;
952
953 opts.checkout_options.checkout_strategy = checkout_strategy;
954 }
955
956
957 /* If there are conflicts in the modified index, then we need to actually
958 * check that out as the repo's index. Otherwise, we don't update the
959 * index.
960 */
961
962 if (!git_index_has_conflicts(modified_index))
963 opts.checkout_options.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
964
965 /* Check out the modified index using the existing repo index as baseline,
966 * so that existing modifications in the index can be rewritten even when
967 * checking out safely.
968 */
969 opts.checkout_options.baseline_index = repo_index;
970
971 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED);
972
973 if ((error = git_checkout_index(repo, modified_index, &opts.checkout_options)) < 0)
974 goto cleanup;
975
976 if (unstashed_index && !git_index_has_conflicts(modified_index)) {
977 if ((error = git_index_read_index(repo_index, unstashed_index)) < 0)
978 goto cleanup;
979 }
980
981 NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_DONE);
982
983 error = git_index_write(repo_index);
984
985 cleanup:
986 git_index_free(untracked_index);
987 git_index_free(modified_index);
988 git_index_free(unstashed_index);
989 git_index_free(stash_adds);
990 git_index_free(repo_index);
991 git_tree_free(untracked_tree);
992 git_tree_free(index_parent_tree);
993 git_tree_free(index_tree);
994 git_tree_free(stash_parent_tree);
995 git_tree_free(stash_tree);
996 git_commit_free(stash_commit);
997 return error;
998 }
999
1000 int git_stash_foreach(
1001 git_repository *repo,
1002 git_stash_cb callback,
1003 void *payload)
1004 {
1005 git_reference *stash;
1006 git_reflog *reflog = NULL;
1007 int error;
1008 size_t i, max;
1009 const git_reflog_entry *entry;
1010
1011 error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE);
1012 if (error == GIT_ENOTFOUND) {
1013 git_error_clear();
1014 return 0;
1015 }
1016 if (error < 0)
1017 goto cleanup;
1018
1019 if ((error = git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE)) < 0)
1020 goto cleanup;
1021
1022 max = git_reflog_entrycount(reflog);
1023 for (i = 0; i < max; i++) {
1024 entry = git_reflog_entry_byindex(reflog, i);
1025
1026 error = callback(i,
1027 git_reflog_entry_message(entry),
1028 git_reflog_entry_id_new(entry),
1029 payload);
1030
1031 if (error) {
1032 git_error_set_after_callback(error);
1033 break;
1034 }
1035 }
1036
1037 cleanup:
1038 git_reference_free(stash);
1039 git_reflog_free(reflog);
1040 return error;
1041 }
1042
1043 int git_stash_drop(
1044 git_repository *repo,
1045 size_t index)
1046 {
1047 git_transaction *tx;
1048 git_reference *stash = NULL;
1049 git_reflog *reflog = NULL;
1050 size_t max;
1051 int error;
1052
1053 if ((error = git_transaction_new(&tx, repo)) < 0)
1054 return error;
1055
1056 if ((error = git_transaction_lock_ref(tx, GIT_REFS_STASH_FILE)) < 0)
1057 goto cleanup;
1058
1059 if ((error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE)) < 0)
1060 goto cleanup;
1061
1062 if ((error = git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE)) < 0)
1063 goto cleanup;
1064
1065 max = git_reflog_entrycount(reflog);
1066
1067 if (!max || index > max - 1) {
1068 error = GIT_ENOTFOUND;
1069 git_error_set(GIT_ERROR_STASH, "no stashed state at position %" PRIuZ, index);
1070 goto cleanup;
1071 }
1072
1073 if ((error = git_reflog_drop(reflog, index, true)) < 0)
1074 goto cleanup;
1075
1076 if ((error = git_transaction_set_reflog(tx, GIT_REFS_STASH_FILE, reflog)) < 0)
1077 goto cleanup;
1078
1079 if (max == 1) {
1080 if ((error = git_transaction_remove(tx, GIT_REFS_STASH_FILE)) < 0)
1081 goto cleanup;
1082 } else if (index == 0) {
1083 const git_reflog_entry *entry;
1084
1085 entry = git_reflog_entry_byindex(reflog, 0);
1086 if ((error = git_transaction_set_target(tx, GIT_REFS_STASH_FILE, &entry->oid_cur, NULL, NULL)) < 0)
1087 goto cleanup;
1088 }
1089
1090 error = git_transaction_commit(tx);
1091
1092 cleanup:
1093 git_reference_free(stash);
1094 git_transaction_free(tx);
1095 git_reflog_free(reflog);
1096 return error;
1097 }
1098
1099 int git_stash_pop(
1100 git_repository *repo,
1101 size_t index,
1102 const git_stash_apply_options *options)
1103 {
1104 int error;
1105
1106 if ((error = git_stash_apply(repo, index, options)) < 0)
1107 return error;
1108
1109 return git_stash_drop(repo, index);
1110 }