2 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
9 #include "repository.h"
14 #include "git2/diff.h"
15 #include "git2/stash.h"
16 #include "git2/status.h"
17 #include "git2/checkout.h"
18 #include "git2/index.h"
19 #include "git2/transaction.h"
20 #include "git2/merge.h"
22 #include "signature.h"
27 static int create_error(int error
, const char *msg
)
29 giterr_set(GITERR_STASH
, "Cannot stash changes - %s", msg
);
33 static int retrieve_head(git_reference
**out
, git_repository
*repo
)
35 int error
= git_repository_head(out
, repo
);
37 if (error
== GIT_EUNBORNBRANCH
)
38 return create_error(error
, "You do not have the initial commit yet.");
43 static int append_abbreviated_oid(git_buf
*out
, const git_oid
*b_commit
)
47 formatted_oid
= git_oid_allocfmt(b_commit
);
48 GITERR_CHECK_ALLOC(formatted_oid
);
50 git_buf_put(out
, formatted_oid
, 7);
51 git__free(formatted_oid
);
53 return git_buf_oom(out
) ? -1 : 0;
56 static int append_commit_description(git_buf
*out
, git_commit
* commit
)
58 const char *summary
= git_commit_summary(commit
);
59 GITERR_CHECK_ALLOC(summary
);
61 if (append_abbreviated_oid(out
, git_commit_id(commit
)) < 0)
64 git_buf_putc(out
, ' ');
65 git_buf_puts(out
, summary
);
66 git_buf_putc(out
, '\n');
68 return git_buf_oom(out
) ? -1 : 0;
71 static int retrieve_base_commit_and_message(
72 git_commit
**b_commit
,
73 git_buf
*stash_message
,
76 git_reference
*head
= NULL
;
79 if ((error
= retrieve_head(&head
, repo
)) < 0)
82 if (strcmp("HEAD", git_reference_name(head
)) == 0)
83 error
= git_buf_puts(stash_message
, "(no branch): ");
85 error
= git_buf_printf(
88 git_reference_name(head
) + strlen(GIT_REFS_HEADS_DIR
));
92 if ((error
= git_commit_lookup(
93 b_commit
, repo
, git_reference_target(head
))) < 0)
96 if ((error
= append_commit_description(stash_message
, *b_commit
)) < 0)
100 git_reference_free(head
);
104 static int build_tree_from_index(git_tree
**out
, git_index
*index
)
109 if ((error
= git_index_write_tree(&i_tree_oid
, index
)) < 0)
112 return git_tree_lookup(out
, git_index_owner(index
), &i_tree_oid
);
115 static int commit_index(
116 git_commit
**i_commit
,
118 const git_signature
*stasher
,
120 const git_commit
*parent
)
122 git_tree
*i_tree
= NULL
;
123 git_oid i_commit_oid
;
124 git_buf msg
= GIT_BUF_INIT
;
127 if ((error
= build_tree_from_index(&i_tree
, index
)) < 0)
130 if ((error
= git_buf_printf(&msg
, "index on %s\n", message
)) < 0)
133 if ((error
= git_commit_create(
135 git_index_owner(index
),
146 error
= git_commit_lookup(i_commit
, git_index_owner(index
), &i_commit_oid
);
149 git_tree_free(i_tree
);
154 struct stash_update_rules
{
155 bool include_changed
;
156 bool include_untracked
;
157 bool include_ignored
;
160 static int stash_update_index_from_diff(
162 const git_diff
*diff
,
163 struct stash_update_rules
*data
)
166 size_t d
, max_d
= git_diff_num_deltas(diff
);
168 for (d
= 0; !error
&& d
< max_d
; ++d
) {
169 const char *add_path
= NULL
;
170 const git_diff_delta
*delta
= git_diff_get_delta(diff
, d
);
172 switch (delta
->status
) {
173 case GIT_DELTA_IGNORED
:
174 if (data
->include_ignored
)
175 add_path
= delta
->new_file
.path
;
178 case GIT_DELTA_UNTRACKED
:
179 if (data
->include_untracked
&&
180 delta
->new_file
.mode
!= GIT_FILEMODE_TREE
)
181 add_path
= delta
->new_file
.path
;
184 case GIT_DELTA_ADDED
:
185 case GIT_DELTA_MODIFIED
:
186 if (data
->include_changed
)
187 add_path
= delta
->new_file
.path
;
190 case GIT_DELTA_DELETED
:
191 if (data
->include_changed
&&
192 !git_index_find(NULL
, index
, delta
->old_file
.path
))
193 error
= git_index_remove(index
, delta
->old_file
.path
, 0);
200 "Cannot update index. Unimplemented status (%d)",
205 if (add_path
!= NULL
)
206 error
= git_index_add_bypath(index
, add_path
);
212 static int build_untracked_tree(
215 git_commit
*i_commit
,
218 git_tree
*i_tree
= NULL
;
219 git_diff
*diff
= NULL
;
220 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
221 struct stash_update_rules data
= {0};
224 git_index_clear(index
);
226 if (flags
& GIT_STASH_INCLUDE_UNTRACKED
) {
227 opts
.flags
|= GIT_DIFF_INCLUDE_UNTRACKED
|
228 GIT_DIFF_RECURSE_UNTRACKED_DIRS
;
229 data
.include_untracked
= true;
232 if (flags
& GIT_STASH_INCLUDE_IGNORED
) {
233 opts
.flags
|= GIT_DIFF_INCLUDE_IGNORED
|
234 GIT_DIFF_RECURSE_IGNORED_DIRS
;
235 data
.include_ignored
= true;
238 if ((error
= git_commit_tree(&i_tree
, i_commit
)) < 0)
241 if ((error
= git_diff_tree_to_workdir(
242 &diff
, git_index_owner(index
), i_tree
, &opts
)) < 0)
245 if ((error
= stash_update_index_from_diff(index
, diff
, &data
)) < 0)
248 error
= build_tree_from_index(tree_out
, index
);
252 git_tree_free(i_tree
);
256 static int commit_untracked(
257 git_commit
**u_commit
,
259 const git_signature
*stasher
,
261 git_commit
*i_commit
,
264 git_tree
*u_tree
= NULL
;
265 git_oid u_commit_oid
;
266 git_buf msg
= GIT_BUF_INIT
;
269 if ((error
= build_untracked_tree(&u_tree
, index
, i_commit
, flags
)) < 0)
272 if ((error
= git_buf_printf(&msg
, "untracked files on %s\n", message
)) < 0)
275 if ((error
= git_commit_create(
277 git_index_owner(index
),
288 error
= git_commit_lookup(u_commit
, git_index_owner(index
), &u_commit_oid
);
291 git_tree_free(u_tree
);
296 static git_diff_delta
*stash_delta_merge(
297 const git_diff_delta
*a
,
298 const git_diff_delta
*b
,
301 /* Special case for stash: if a file is deleted in the index, but exists
302 * in the working tree, we need to stash the workdir copy for the workdir.
304 if (a
->status
== GIT_DELTA_DELETED
&& b
->status
== GIT_DELTA_UNTRACKED
) {
305 git_diff_delta
*dup
= git_diff__delta_dup(b
, pool
);
308 dup
->status
= GIT_DELTA_MODIFIED
;
312 return git_diff__merge_like_cgit(a
, b
, pool
);
315 static int build_workdir_tree(
318 git_commit
*b_commit
)
320 git_repository
*repo
= git_index_owner(index
);
321 git_tree
*b_tree
= NULL
;
322 git_diff
*diff
= NULL
, *idx_to_wd
= NULL
;
323 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
324 struct stash_update_rules data
= {0};
327 opts
.flags
= GIT_DIFF_IGNORE_SUBMODULES
| GIT_DIFF_INCLUDE_UNTRACKED
;
329 if ((error
= git_commit_tree(&b_tree
, b_commit
)) < 0)
332 if ((error
= git_diff_tree_to_index(&diff
, repo
, b_tree
, index
, &opts
)) < 0 ||
333 (error
= git_diff_index_to_workdir(&idx_to_wd
, repo
, index
, &opts
)) < 0 ||
334 (error
= git_diff__merge(diff
, idx_to_wd
, stash_delta_merge
)) < 0)
337 data
.include_changed
= true;
339 if ((error
= stash_update_index_from_diff(index
, diff
, &data
)) < 0)
342 error
= build_tree_from_index(tree_out
, index
);
345 git_diff_free(idx_to_wd
);
347 git_tree_free(b_tree
);
352 static int commit_worktree(
353 git_oid
*w_commit_oid
,
355 const git_signature
*stasher
,
357 git_commit
*i_commit
,
358 git_commit
*b_commit
,
359 git_commit
*u_commit
)
362 git_tree
*w_tree
= NULL
, *i_tree
= NULL
;
363 const git_commit
*parents
[] = { NULL
, NULL
, NULL
};
365 parents
[0] = b_commit
;
366 parents
[1] = i_commit
;
367 parents
[2] = u_commit
;
369 if ((error
= git_commit_tree(&i_tree
, i_commit
)) < 0)
372 if ((error
= git_index_read_tree(index
, i_tree
)) < 0)
375 if ((error
= build_workdir_tree(&w_tree
, index
, b_commit
)) < 0)
378 error
= git_commit_create(
380 git_index_owner(index
),
391 git_tree_free(i_tree
);
392 git_tree_free(w_tree
);
396 static int prepare_worktree_commit_message(
398 const char *user_message
)
400 git_buf buf
= GIT_BUF_INIT
;
403 if ((error
= git_buf_set(&buf
, git_buf_cstr(msg
), git_buf_len(msg
))) < 0)
409 git_buf_printf(msg
, "WIP on %s", git_buf_cstr(&buf
));
413 if ((colon
= strchr(git_buf_cstr(&buf
), ':')) == NULL
)
416 git_buf_puts(msg
, "On ");
417 git_buf_put(msg
, git_buf_cstr(&buf
), colon
- buf
.ptr
);
418 git_buf_printf(msg
, ": %s\n", user_message
);
421 error
= (git_buf_oom(msg
) || git_buf_oom(&buf
)) ? -1 : 0;
429 static int update_reflog(
430 git_oid
*w_commit_oid
,
431 git_repository
*repo
,
434 git_reference
*stash
;
437 if ((error
= git_reference_ensure_log(repo
, GIT_REFS_STASH_FILE
)) < 0)
440 error
= git_reference_create(&stash
, repo
, GIT_REFS_STASH_FILE
, w_commit_oid
, 1, message
);
442 git_reference_free(stash
);
447 static int is_dirty_cb(const char *path
, unsigned int status
, void *payload
)
453 return GIT_PASSTHROUGH
;
456 static int ensure_there_are_changes_to_stash(
457 git_repository
*repo
,
458 bool include_untracked_files
,
459 bool include_ignored_files
)
462 git_status_options opts
= GIT_STATUS_OPTIONS_INIT
;
464 opts
.show
= GIT_STATUS_SHOW_INDEX_AND_WORKDIR
;
465 opts
.flags
= GIT_STATUS_OPT_EXCLUDE_SUBMODULES
;
467 if (include_untracked_files
)
468 opts
.flags
|= GIT_STATUS_OPT_INCLUDE_UNTRACKED
|
469 GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
;
471 if (include_ignored_files
)
472 opts
.flags
|= GIT_STATUS_OPT_INCLUDE_IGNORED
|
473 GIT_STATUS_OPT_RECURSE_IGNORED_DIRS
;
475 error
= git_status_foreach_ext(repo
, &opts
, is_dirty_cb
, NULL
);
477 if (error
== GIT_PASSTHROUGH
)
481 return create_error(GIT_ENOTFOUND
, "There is nothing to stash.");
486 static int reset_index_and_workdir(
487 git_repository
*repo
,
489 bool remove_untracked
,
492 git_checkout_options opts
= GIT_CHECKOUT_OPTIONS_INIT
;
494 opts
.checkout_strategy
= GIT_CHECKOUT_FORCE
;
496 if (remove_untracked
)
497 opts
.checkout_strategy
|= GIT_CHECKOUT_REMOVE_UNTRACKED
;
500 opts
.checkout_strategy
|= GIT_CHECKOUT_REMOVE_IGNORED
;
502 return git_checkout_tree(repo
, (git_object
*)commit
, &opts
);
507 git_repository
*repo
,
508 const git_signature
*stasher
,
512 git_index
*index
= NULL
;
513 git_commit
*b_commit
= NULL
, *i_commit
= NULL
, *u_commit
= NULL
;
514 git_buf msg
= GIT_BUF_INIT
;
517 assert(out
&& repo
&& stasher
);
519 if ((error
= git_repository__ensure_not_bare(repo
, "stash save")) < 0)
522 if ((error
= retrieve_base_commit_and_message(&b_commit
, &msg
, repo
)) < 0)
525 if ((error
= ensure_there_are_changes_to_stash(
527 (flags
& GIT_STASH_INCLUDE_UNTRACKED
) != 0,
528 (flags
& GIT_STASH_INCLUDE_IGNORED
) != 0)) < 0)
531 if ((error
= git_repository_index(&index
, repo
)) < 0)
534 if ((error
= commit_index(
535 &i_commit
, index
, stasher
, git_buf_cstr(&msg
), b_commit
)) < 0)
538 if ((flags
& (GIT_STASH_INCLUDE_UNTRACKED
| GIT_STASH_INCLUDE_IGNORED
)) &&
539 (error
= commit_untracked(
540 &u_commit
, index
, stasher
, git_buf_cstr(&msg
),
541 i_commit
, flags
)) < 0)
544 if ((error
= prepare_worktree_commit_message(&msg
, message
)) < 0)
547 if ((error
= commit_worktree(
548 out
, index
, stasher
, git_buf_cstr(&msg
),
549 i_commit
, b_commit
, u_commit
)) < 0)
554 if ((error
= update_reflog(out
, repo
, git_buf_cstr(&msg
))) < 0)
557 if ((error
= reset_index_and_workdir(
559 ((flags
& GIT_STASH_KEEP_INDEX
) != 0) ? i_commit
: b_commit
,
560 (flags
& GIT_STASH_INCLUDE_UNTRACKED
) != 0,
561 (flags
& GIT_STASH_INCLUDE_IGNORED
) != 0)) < 0)
567 git_commit_free(i_commit
);
568 git_commit_free(b_commit
);
569 git_commit_free(u_commit
);
570 git_index_free(index
);
575 static int retrieve_stash_commit(
577 git_repository
*repo
,
580 git_reference
*stash
= NULL
;
581 git_reflog
*reflog
= NULL
;
584 const git_reflog_entry
*entry
;
586 if ((error
= git_reference_lookup(&stash
, repo
, GIT_REFS_STASH_FILE
)) < 0)
589 if ((error
= git_reflog_read(&reflog
, repo
, GIT_REFS_STASH_FILE
)) < 0)
592 max
= git_reflog_entrycount(reflog
);
593 if (!max
|| index
> max
- 1) {
594 error
= GIT_ENOTFOUND
;
595 giterr_set(GITERR_STASH
, "No stashed state at position %" PRIuZ
, index
);
599 entry
= git_reflog_entry_byindex(reflog
, index
);
600 if ((error
= git_commit_lookup(commit
, repo
, git_reflog_entry_id_new(entry
))) < 0)
604 git_reference_free(stash
);
605 git_reflog_free(reflog
);
609 static int retrieve_stash_trees(
610 git_tree
**out_stash_tree
,
611 git_tree
**out_base_tree
,
612 git_tree
**out_index_tree
,
613 git_tree
**out_index_parent_tree
,
614 git_tree
**out_untracked_tree
,
615 git_commit
*stash_commit
)
617 git_tree
*stash_tree
= NULL
;
618 git_commit
*base_commit
= NULL
;
619 git_tree
*base_tree
= NULL
;
620 git_commit
*index_commit
= NULL
;
621 git_tree
*index_tree
= NULL
;
622 git_commit
*index_parent_commit
= NULL
;
623 git_tree
*index_parent_tree
= NULL
;
624 git_commit
*untracked_commit
= NULL
;
625 git_tree
*untracked_tree
= NULL
;
628 if ((error
= git_commit_tree(&stash_tree
, stash_commit
)) < 0)
631 if ((error
= git_commit_parent(&base_commit
, stash_commit
, 0)) < 0)
633 if ((error
= git_commit_tree(&base_tree
, base_commit
)) < 0)
636 if ((error
= git_commit_parent(&index_commit
, stash_commit
, 1)) < 0)
638 if ((error
= git_commit_tree(&index_tree
, index_commit
)) < 0)
641 if ((error
= git_commit_parent(&index_parent_commit
, index_commit
, 0)) < 0)
643 if ((error
= git_commit_tree(&index_parent_tree
, index_parent_commit
)) < 0)
646 if (git_commit_parentcount(stash_commit
) == 3) {
647 if ((error
= git_commit_parent(&untracked_commit
, stash_commit
, 2)) < 0)
649 if ((error
= git_commit_tree(&untracked_tree
, untracked_commit
)) < 0)
653 *out_stash_tree
= stash_tree
;
654 *out_base_tree
= base_tree
;
655 *out_index_tree
= index_tree
;
656 *out_index_parent_tree
= index_parent_tree
;
657 *out_untracked_tree
= untracked_tree
;
660 git_commit_free(untracked_commit
);
661 git_commit_free(index_parent_commit
);
662 git_commit_free(index_commit
);
663 git_commit_free(base_commit
);
665 git_tree_free(stash_tree
);
666 git_tree_free(base_tree
);
667 git_tree_free(index_tree
);
668 git_tree_free(index_parent_tree
);
669 git_tree_free(untracked_tree
);
674 static int merge_index_and_tree(
676 git_repository
*repo
,
677 git_tree
*ancestor_tree
,
678 git_index
*ours_index
,
679 git_tree
*theirs_tree
)
681 git_iterator
*ancestor
= NULL
, *ours
= NULL
, *theirs
= NULL
;
682 const git_iterator_flag_t flags
= GIT_ITERATOR_DONT_IGNORE_CASE
;
685 if ((error
= git_iterator_for_tree(&ancestor
, ancestor_tree
, flags
, NULL
, NULL
)) < 0 ||
686 (error
= git_iterator_for_index(&ours
, ours_index
, flags
, NULL
, NULL
)) < 0 ||
687 (error
= git_iterator_for_tree(&theirs
, theirs_tree
, flags
, NULL
, NULL
)) < 0)
690 error
= git_merge__iterators(out
, repo
, ancestor
, ours
, theirs
, NULL
);
693 git_iterator_free(ancestor
);
694 git_iterator_free(ours
);
695 git_iterator_free(theirs
);
699 static void normalize_apply_options(
700 git_stash_apply_options
*opts
,
701 const git_stash_apply_options
*given_apply_opts
)
703 if (given_apply_opts
!= NULL
) {
704 memcpy(opts
, given_apply_opts
, sizeof(git_stash_apply_options
));
706 git_stash_apply_options default_apply_opts
= GIT_STASH_APPLY_OPTIONS_INIT
;
707 memcpy(opts
, &default_apply_opts
, sizeof(git_stash_apply_options
));
710 if ((opts
->checkout_options
.checkout_strategy
& (GIT_CHECKOUT_SAFE
| GIT_CHECKOUT_FORCE
)) == 0)
711 opts
->checkout_options
.checkout_strategy
= GIT_CHECKOUT_SAFE
;
713 if (!opts
->checkout_options
.our_label
)
714 opts
->checkout_options
.our_label
= "Updated upstream";
716 if (!opts
->checkout_options
.their_label
)
717 opts
->checkout_options
.their_label
= "Stashed changes";
720 int git_stash_apply_init_options(git_stash_apply_options
*opts
, unsigned int version
)
722 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
723 opts
, version
, git_stash_apply_options
, GIT_STASH_APPLY_OPTIONS_INIT
);
727 #define NOTIFY_PROGRESS(opts, progress_type) \
729 if ((opts).progress_cb && \
730 (error = (opts).progress_cb((progress_type), (opts).progress_payload))) { \
731 error = (error < 0) ? error : -1; \
737 git_repository
*repo
,
739 const git_stash_apply_options
*given_opts
)
741 git_stash_apply_options opts
;
742 unsigned int checkout_strategy
;
743 git_commit
*stash_commit
= NULL
;
744 git_tree
*stash_tree
= NULL
;
745 git_tree
*stash_parent_tree
= NULL
;
746 git_tree
*index_tree
= NULL
;
747 git_tree
*index_parent_tree
= NULL
;
748 git_tree
*untracked_tree
= NULL
;
749 git_index
*repo_index
= NULL
;
750 git_index
*unstashed_index
= NULL
;
751 git_index
*modified_index
= NULL
;
752 git_index
*untracked_index
= NULL
;
755 GITERR_CHECK_VERSION(given_opts
, GIT_STASH_APPLY_OPTIONS_VERSION
, "git_stash_apply_options");
757 normalize_apply_options(&opts
, given_opts
);
758 checkout_strategy
= opts
.checkout_options
.checkout_strategy
;
760 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_LOADING_STASH
);
762 /* Retrieve commit corresponding to the given stash */
763 if ((error
= retrieve_stash_commit(&stash_commit
, repo
, index
)) < 0)
766 /* Retrieve all trees in the stash */
767 if ((error
= retrieve_stash_trees(
768 &stash_tree
, &stash_parent_tree
, &index_tree
,
769 &index_parent_tree
, &untracked_tree
, stash_commit
)) < 0)
772 /* Load repo index */
773 if ((error
= git_repository_index(&repo_index
, repo
)) < 0)
776 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX
);
778 /* Restore index if required */
779 if ((opts
.flags
& GIT_STASH_APPLY_REINSTATE_INDEX
) &&
780 git_oid_cmp(git_tree_id(stash_parent_tree
), git_tree_id(index_tree
))) {
782 if ((error
= merge_index_and_tree(
783 &unstashed_index
, repo
, index_parent_tree
, repo_index
, index_tree
)) < 0)
786 if (git_index_has_conflicts(unstashed_index
)) {
787 error
= GIT_ECONFLICT
;
792 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED
);
794 /* Restore modified files in workdir */
795 if ((error
= merge_index_and_tree(
796 &modified_index
, repo
, stash_parent_tree
, repo_index
, stash_tree
)) < 0)
799 /* If applicable, restore untracked / ignored files in workdir */
800 if (untracked_tree
) {
801 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED
);
803 if ((error
= merge_index_and_tree(&untracked_index
, repo
, NULL
, repo_index
, untracked_tree
)) < 0)
807 if (untracked_index
) {
808 opts
.checkout_options
.checkout_strategy
|= GIT_CHECKOUT_DONT_UPDATE_INDEX
;
810 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED
);
812 if ((error
= git_checkout_index(repo
, untracked_index
, &opts
.checkout_options
)) < 0)
815 opts
.checkout_options
.checkout_strategy
= checkout_strategy
;
819 /* If there are conflicts in the modified index, then we need to actually
820 * check that out as the repo's index. Otherwise, we don't update the
824 if (!git_index_has_conflicts(modified_index
))
825 opts
.checkout_options
.checkout_strategy
|= GIT_CHECKOUT_DONT_UPDATE_INDEX
;
827 /* Check out the modified index using the existing repo index as baseline,
828 * so that existing modifications in the index can be rewritten even when
829 * checking out safely.
831 opts
.checkout_options
.baseline_index
= repo_index
;
833 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED
);
835 if ((error
= git_checkout_index(repo
, modified_index
, &opts
.checkout_options
)) < 0)
838 if (unstashed_index
&& !git_index_has_conflicts(modified_index
)) {
839 if ((error
= git_index_read_index(repo_index
, unstashed_index
)) < 0)
843 NOTIFY_PROGRESS(opts
, GIT_STASH_APPLY_PROGRESS_DONE
);
845 error
= git_index_write(repo_index
);
848 git_index_free(untracked_index
);
849 git_index_free(modified_index
);
850 git_index_free(unstashed_index
);
851 git_index_free(repo_index
);
852 git_tree_free(untracked_tree
);
853 git_tree_free(index_parent_tree
);
854 git_tree_free(index_tree
);
855 git_tree_free(stash_parent_tree
);
856 git_tree_free(stash_tree
);
857 git_commit_free(stash_commit
);
861 int git_stash_foreach(
862 git_repository
*repo
,
863 git_stash_cb callback
,
866 git_reference
*stash
;
867 git_reflog
*reflog
= NULL
;
870 const git_reflog_entry
*entry
;
872 error
= git_reference_lookup(&stash
, repo
, GIT_REFS_STASH_FILE
);
873 if (error
== GIT_ENOTFOUND
) {
880 if ((error
= git_reflog_read(&reflog
, repo
, GIT_REFS_STASH_FILE
)) < 0)
883 max
= git_reflog_entrycount(reflog
);
884 for (i
= 0; i
< max
; i
++) {
885 entry
= git_reflog_entry_byindex(reflog
, i
);
888 git_reflog_entry_message(entry
),
889 git_reflog_entry_id_new(entry
),
893 giterr_set_after_callback(error
);
899 git_reference_free(stash
);
900 git_reflog_free(reflog
);
905 git_repository
*repo
,
909 git_reference
*stash
= NULL
;
910 git_reflog
*reflog
= NULL
;
914 if ((error
= git_transaction_new(&tx
, repo
)) < 0)
917 if ((error
= git_transaction_lock_ref(tx
, GIT_REFS_STASH_FILE
)) < 0)
920 if ((error
= git_reference_lookup(&stash
, repo
, GIT_REFS_STASH_FILE
)) < 0)
923 if ((error
= git_reflog_read(&reflog
, repo
, GIT_REFS_STASH_FILE
)) < 0)
926 max
= git_reflog_entrycount(reflog
);
928 if (!max
|| index
> max
- 1) {
929 error
= GIT_ENOTFOUND
;
930 giterr_set(GITERR_STASH
, "No stashed state at position %" PRIuZ
, index
);
934 if ((error
= git_reflog_drop(reflog
, index
, true)) < 0)
937 if ((error
= git_transaction_set_reflog(tx
, GIT_REFS_STASH_FILE
, reflog
)) < 0)
941 if ((error
= git_transaction_remove(tx
, GIT_REFS_STASH_FILE
)) < 0)
943 } else if (index
== 0) {
944 const git_reflog_entry
*entry
;
946 entry
= git_reflog_entry_byindex(reflog
, 0);
947 if ((error
= git_transaction_set_target(tx
, GIT_REFS_STASH_FILE
, &entry
->oid_cur
, NULL
, NULL
)) < 0)
951 error
= git_transaction_commit(tx
);
954 git_reference_free(stash
);
955 git_transaction_free(tx
);
956 git_reflog_free(reflog
);
961 git_repository
*repo
,
963 const git_stash_apply_options
*options
)
967 if ((error
= git_stash_apply(repo
, index
, options
)) < 0)
970 return git_stash_drop(repo
, index
);