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"
21 #include "signature.h"
23 static int create_error(int error
, const char *msg
)
25 giterr_set(GITERR_STASH
, "Cannot stash changes - %s", msg
);
29 static int retrieve_head(git_reference
**out
, git_repository
*repo
)
31 int error
= git_repository_head(out
, repo
);
33 if (error
== GIT_EUNBORNBRANCH
)
34 return create_error(error
, "You do not have the initial commit yet.");
39 static int append_abbreviated_oid(git_buf
*out
, const git_oid
*b_commit
)
43 formatted_oid
= git_oid_allocfmt(b_commit
);
44 GITERR_CHECK_ALLOC(formatted_oid
);
46 git_buf_put(out
, formatted_oid
, 7);
47 git__free(formatted_oid
);
49 return git_buf_oom(out
) ? -1 : 0;
52 static int append_commit_description(git_buf
*out
, git_commit
* commit
)
54 const char *summary
= git_commit_summary(commit
);
55 GITERR_CHECK_ALLOC(summary
);
57 if (append_abbreviated_oid(out
, git_commit_id(commit
)) < 0)
60 git_buf_putc(out
, ' ');
61 git_buf_puts(out
, summary
);
62 git_buf_putc(out
, '\n');
64 return git_buf_oom(out
) ? -1 : 0;
67 static int retrieve_base_commit_and_message(
68 git_commit
**b_commit
,
69 git_buf
*stash_message
,
72 git_reference
*head
= NULL
;
75 if ((error
= retrieve_head(&head
, repo
)) < 0)
78 if (strcmp("HEAD", git_reference_name(head
)) == 0)
79 error
= git_buf_puts(stash_message
, "(no branch): ");
81 error
= git_buf_printf(
84 git_reference_name(head
) + strlen(GIT_REFS_HEADS_DIR
));
88 if ((error
= git_commit_lookup(
89 b_commit
, repo
, git_reference_target(head
))) < 0)
92 if ((error
= append_commit_description(stash_message
, *b_commit
)) < 0)
96 git_reference_free(head
);
100 static int build_tree_from_index(git_tree
**out
, git_index
*index
)
105 if ((error
= git_index_write_tree(&i_tree_oid
, index
)) < 0)
108 return git_tree_lookup(out
, git_index_owner(index
), &i_tree_oid
);
111 static int commit_index(
112 git_commit
**i_commit
,
114 const git_signature
*stasher
,
116 const git_commit
*parent
)
118 git_tree
*i_tree
= NULL
;
119 git_oid i_commit_oid
;
120 git_buf msg
= GIT_BUF_INIT
;
123 if ((error
= build_tree_from_index(&i_tree
, index
)) < 0)
126 if ((error
= git_buf_printf(&msg
, "index on %s\n", message
)) < 0)
129 if ((error
= git_commit_create(
131 git_index_owner(index
),
142 error
= git_commit_lookup(i_commit
, git_index_owner(index
), &i_commit_oid
);
145 git_tree_free(i_tree
);
150 struct stash_update_rules
{
151 bool include_changed
;
152 bool include_untracked
;
153 bool include_ignored
;
156 static int stash_update_index_from_diff(
158 const git_diff
*diff
,
159 struct stash_update_rules
*data
)
162 size_t d
, max_d
= git_diff_num_deltas(diff
);
164 for (d
= 0; !error
&& d
< max_d
; ++d
) {
165 const char *add_path
= NULL
;
166 const git_diff_delta
*delta
= git_diff_get_delta(diff
, d
);
168 switch (delta
->status
) {
169 case GIT_DELTA_IGNORED
:
170 if (data
->include_ignored
)
171 add_path
= delta
->new_file
.path
;
174 case GIT_DELTA_UNTRACKED
:
175 if (data
->include_untracked
&&
176 delta
->new_file
.mode
!= GIT_FILEMODE_TREE
)
177 add_path
= delta
->new_file
.path
;
180 case GIT_DELTA_ADDED
:
181 case GIT_DELTA_MODIFIED
:
182 if (data
->include_changed
)
183 add_path
= delta
->new_file
.path
;
186 case GIT_DELTA_DELETED
:
187 if (data
->include_changed
&&
188 !git_index_find(NULL
, index
, delta
->old_file
.path
))
189 error
= git_index_remove(index
, delta
->old_file
.path
, 0);
196 "Cannot update index. Unimplemented status (%d)",
201 if (add_path
!= NULL
)
202 error
= git_index_add_bypath(index
, add_path
);
208 static int build_untracked_tree(
211 git_commit
*i_commit
,
214 git_tree
*i_tree
= NULL
;
215 git_diff
*diff
= NULL
;
216 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
217 struct stash_update_rules data
= {0};
220 git_index_clear(index
);
222 if (flags
& GIT_STASH_INCLUDE_UNTRACKED
) {
223 opts
.flags
|= GIT_DIFF_INCLUDE_UNTRACKED
|
224 GIT_DIFF_RECURSE_UNTRACKED_DIRS
;
225 data
.include_untracked
= true;
228 if (flags
& GIT_STASH_INCLUDE_IGNORED
) {
229 opts
.flags
|= GIT_DIFF_INCLUDE_IGNORED
|
230 GIT_DIFF_RECURSE_IGNORED_DIRS
;
231 data
.include_ignored
= true;
234 if ((error
= git_commit_tree(&i_tree
, i_commit
)) < 0)
237 if ((error
= git_diff_tree_to_workdir(
238 &diff
, git_index_owner(index
), i_tree
, &opts
)) < 0)
241 if ((error
= stash_update_index_from_diff(index
, diff
, &data
)) < 0)
244 error
= build_tree_from_index(tree_out
, index
);
248 git_tree_free(i_tree
);
252 static int commit_untracked(
253 git_commit
**u_commit
,
255 const git_signature
*stasher
,
257 git_commit
*i_commit
,
260 git_tree
*u_tree
= NULL
;
261 git_oid u_commit_oid
;
262 git_buf msg
= GIT_BUF_INIT
;
265 if ((error
= build_untracked_tree(&u_tree
, index
, i_commit
, flags
)) < 0)
268 if ((error
= git_buf_printf(&msg
, "untracked files on %s\n", message
)) < 0)
271 if ((error
= git_commit_create(
273 git_index_owner(index
),
284 error
= git_commit_lookup(u_commit
, git_index_owner(index
), &u_commit_oid
);
287 git_tree_free(u_tree
);
292 static int build_workdir_tree(
295 git_commit
*b_commit
)
297 git_repository
*repo
= git_index_owner(index
);
298 git_tree
*b_tree
= NULL
;
299 git_diff
*diff
= NULL
;
300 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
301 struct stash_update_rules data
= {0};
304 opts
.flags
= GIT_DIFF_IGNORE_SUBMODULES
;
306 if ((error
= git_commit_tree(&b_tree
, b_commit
)) < 0)
309 if ((error
= git_diff_tree_to_workdir(&diff
, repo
, b_tree
, &opts
)) < 0)
312 data
.include_changed
= true;
314 if ((error
= stash_update_index_from_diff(index
, diff
, &data
)) < 0)
317 error
= build_tree_from_index(tree_out
, index
);
321 git_tree_free(b_tree
);
326 static int commit_worktree(
327 git_oid
*w_commit_oid
,
329 const git_signature
*stasher
,
331 git_commit
*i_commit
,
332 git_commit
*b_commit
,
333 git_commit
*u_commit
)
336 git_tree
*w_tree
= NULL
, *i_tree
= NULL
;
337 const git_commit
*parents
[] = { NULL
, NULL
, NULL
};
339 parents
[0] = b_commit
;
340 parents
[1] = i_commit
;
341 parents
[2] = u_commit
;
343 if ((error
= git_commit_tree(&i_tree
, i_commit
)) < 0)
346 if ((error
= git_index_read_tree(index
, i_tree
)) < 0)
349 if ((error
= build_workdir_tree(&w_tree
, index
, b_commit
)) < 0)
352 error
= git_commit_create(
354 git_index_owner(index
),
365 git_tree_free(i_tree
);
366 git_tree_free(w_tree
);
370 static int prepare_worktree_commit_message(
372 const char *user_message
)
374 git_buf buf
= GIT_BUF_INIT
;
377 if ((error
= git_buf_set(&buf
, git_buf_cstr(msg
), git_buf_len(msg
))) < 0)
383 git_buf_printf(msg
, "WIP on %s", git_buf_cstr(&buf
));
387 if ((colon
= strchr(git_buf_cstr(&buf
), ':')) == NULL
)
390 git_buf_puts(msg
, "On ");
391 git_buf_put(msg
, git_buf_cstr(&buf
), colon
- buf
.ptr
);
392 git_buf_printf(msg
, ": %s\n", user_message
);
395 error
= (git_buf_oom(msg
) || git_buf_oom(&buf
)) ? -1 : 0;
403 static int update_reflog(
404 git_oid
*w_commit_oid
,
405 git_repository
*repo
,
408 git_reference
*stash
;
411 if ((error
= git_reference_ensure_log(repo
, GIT_REFS_STASH_FILE
)) < 0)
414 error
= git_reference_create(&stash
, repo
, GIT_REFS_STASH_FILE
, w_commit_oid
, 1, message
);
416 git_reference_free(stash
);
421 static int is_dirty_cb(const char *path
, unsigned int status
, void *payload
)
427 return GIT_PASSTHROUGH
;
430 static int ensure_there_are_changes_to_stash(
431 git_repository
*repo
,
432 bool include_untracked_files
,
433 bool include_ignored_files
)
436 git_status_options opts
= GIT_STATUS_OPTIONS_INIT
;
438 opts
.show
= GIT_STATUS_SHOW_INDEX_AND_WORKDIR
;
439 opts
.flags
= GIT_STATUS_OPT_EXCLUDE_SUBMODULES
;
441 if (include_untracked_files
)
442 opts
.flags
|= GIT_STATUS_OPT_INCLUDE_UNTRACKED
|
443 GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
;
445 if (include_ignored_files
)
446 opts
.flags
|= GIT_STATUS_OPT_INCLUDE_IGNORED
|
447 GIT_STATUS_OPT_RECURSE_IGNORED_DIRS
;
449 error
= git_status_foreach_ext(repo
, &opts
, is_dirty_cb
, NULL
);
451 if (error
== GIT_PASSTHROUGH
)
455 return create_error(GIT_ENOTFOUND
, "There is nothing to stash.");
460 static int reset_index_and_workdir(
461 git_repository
*repo
,
463 bool remove_untracked
,
466 git_checkout_options opts
= GIT_CHECKOUT_OPTIONS_INIT
;
468 opts
.checkout_strategy
= GIT_CHECKOUT_FORCE
;
470 if (remove_untracked
)
471 opts
.checkout_strategy
|= GIT_CHECKOUT_REMOVE_UNTRACKED
;
474 opts
.checkout_strategy
|= GIT_CHECKOUT_REMOVE_IGNORED
;
476 return git_checkout_tree(repo
, (git_object
*)commit
, &opts
);
481 git_repository
*repo
,
482 const git_signature
*stasher
,
486 git_index
*index
= NULL
;
487 git_commit
*b_commit
= NULL
, *i_commit
= NULL
, *u_commit
= NULL
;
488 git_buf msg
= GIT_BUF_INIT
;
491 assert(out
&& repo
&& stasher
);
493 if ((error
= git_repository__ensure_not_bare(repo
, "stash save")) < 0)
496 if ((error
= retrieve_base_commit_and_message(&b_commit
, &msg
, repo
)) < 0)
499 if ((error
= ensure_there_are_changes_to_stash(
501 (flags
& GIT_STASH_INCLUDE_UNTRACKED
) != 0,
502 (flags
& GIT_STASH_INCLUDE_IGNORED
) != 0)) < 0)
505 if ((error
= git_repository_index(&index
, repo
)) < 0)
508 if ((error
= commit_index(
509 &i_commit
, index
, stasher
, git_buf_cstr(&msg
), b_commit
)) < 0)
512 if ((flags
& (GIT_STASH_INCLUDE_UNTRACKED
| GIT_STASH_INCLUDE_IGNORED
)) &&
513 (error
= commit_untracked(
514 &u_commit
, index
, stasher
, git_buf_cstr(&msg
),
515 i_commit
, flags
)) < 0)
518 if ((error
= prepare_worktree_commit_message(&msg
, message
)) < 0)
521 if ((error
= commit_worktree(
522 out
, index
, stasher
, git_buf_cstr(&msg
),
523 i_commit
, b_commit
, u_commit
)) < 0)
528 if ((error
= update_reflog(out
, repo
, git_buf_cstr(&msg
))) < 0)
531 if ((error
= reset_index_and_workdir(
533 ((flags
& GIT_STASH_KEEP_INDEX
) != 0) ? i_commit
: b_commit
,
534 (flags
& GIT_STASH_INCLUDE_UNTRACKED
) != 0,
535 (flags
& GIT_STASH_INCLUDE_IGNORED
) != 0)) < 0)
541 git_commit_free(i_commit
);
542 git_commit_free(b_commit
);
543 git_commit_free(u_commit
);
544 git_index_free(index
);
549 static int retrieve_stash_commit(
551 git_repository
*repo
,
554 git_reference
*stash
= NULL
;
555 git_reflog
*reflog
= NULL
;
558 const git_reflog_entry
*entry
;
560 if ((error
= git_reference_lookup(&stash
, repo
, GIT_REFS_STASH_FILE
)) < 0)
563 if ((error
= git_reflog_read(&reflog
, repo
, GIT_REFS_STASH_FILE
)) < 0)
566 max
= git_reflog_entrycount(reflog
);
567 if (!max
|| index
> max
- 1) {
568 error
= GIT_ENOTFOUND
;
569 giterr_set(GITERR_STASH
, "No stashed state at position %" PRIuZ
, index
);
573 entry
= git_reflog_entry_byindex(reflog
, index
);
574 if ((error
= git_commit_lookup(commit
, repo
, git_reflog_entry_id_new(entry
))) < 0)
578 git_reference_free(stash
);
579 git_reflog_free(reflog
);
583 static int retrieve_stash_trees(
584 git_tree
**out_stash_tree
,
585 git_tree
**out_base_tree
,
586 git_tree
**out_index_tree
,
587 git_tree
**out_index_parent_tree
,
588 git_tree
**out_untracked_tree
,
589 git_commit
*stash_commit
)
591 git_tree
*stash_tree
= NULL
;
592 git_commit
*base_commit
= NULL
;
593 git_tree
*base_tree
= NULL
;
594 git_commit
*index_commit
= NULL
;
595 git_tree
*index_tree
= NULL
;
596 git_commit
*index_parent_commit
= NULL
;
597 git_tree
*index_parent_tree
= NULL
;
598 git_commit
*untracked_commit
= NULL
;
599 git_tree
*untracked_tree
= NULL
;
602 if ((error
= git_commit_tree(&stash_tree
, stash_commit
)) < 0)
605 if ((error
= git_commit_parent(&base_commit
, stash_commit
, 0)) < 0)
607 if ((error
= git_commit_tree(&base_tree
, base_commit
)) < 0)
610 if ((error
= git_commit_parent(&index_commit
, stash_commit
, 1)) < 0)
612 if ((error
= git_commit_tree(&index_tree
, index_commit
)) < 0)
615 if ((error
= git_commit_parent(&index_parent_commit
, index_commit
, 0)) < 0)
617 if ((error
= git_commit_tree(&index_parent_tree
, index_parent_commit
)) < 0)
620 if (git_commit_parentcount(stash_commit
) == 3) {
621 if ((error
= git_commit_parent(&untracked_commit
, stash_commit
, 2)) < 0)
623 if ((error
= git_commit_tree(&untracked_tree
, untracked_commit
)) < 0)
627 *out_stash_tree
= stash_tree
;
628 *out_base_tree
= base_tree
;
629 *out_index_tree
= index_tree
;
630 *out_index_parent_tree
= index_parent_tree
;
631 *out_untracked_tree
= untracked_tree
;
634 git_commit_free(untracked_commit
);
635 git_commit_free(index_parent_commit
);
636 git_commit_free(index_commit
);
637 git_commit_free(base_commit
);
639 git_tree_free(stash_tree
);
640 git_tree_free(base_tree
);
641 git_tree_free(index_tree
);
642 git_tree_free(index_parent_tree
);
643 git_tree_free(untracked_tree
);
648 static int apply_index(
649 git_tree
**unstashed_tree
,
650 git_repository
*repo
,
651 git_tree
*start_index_tree
,
652 git_tree
*index_parent_tree
,
653 git_tree
*index_tree
)
655 git_index
*unstashed_index
= NULL
;
656 git_merge_options options
= GIT_MERGE_OPTIONS_INIT
;
660 if ((error
= git_merge_trees(
661 &unstashed_index
, repo
, index_parent_tree
,
662 start_index_tree
, index_tree
, &options
)) < 0)
665 if ((error
= git_index_write_tree_to(&oid
, unstashed_index
, repo
)) < 0)
668 if ((error
= git_tree_lookup(unstashed_tree
, repo
, &oid
)) < 0)
672 git_index_free(unstashed_index
);
676 static int apply_untracked(
677 git_repository
*repo
,
678 git_tree
*start_index_tree
,
679 git_tree
*untracked_tree
)
681 git_checkout_options options
= GIT_CHECKOUT_OPTIONS_INIT
;
682 git_index
*merged_index
= NULL
;
685 options
.checkout_strategy
=
686 GIT_CHECKOUT_SAFE
| GIT_CHECKOUT_DONT_UPDATE_INDEX
;
688 if ((error
= git_merge_trees(&merged_index
,
689 repo
, NULL
, start_index_tree
, untracked_tree
, NULL
)) == 0)
690 error
= git_checkout_index(repo
, merged_index
, &options
);
692 git_index_free(merged_index
);
696 static int checkout_modified_notify_callback(
697 git_checkout_notify_t why
,
699 const git_diff_file
*baseline
,
700 const git_diff_file
*target
,
701 const git_diff_file
*workdir
,
708 GIT_UNUSED(baseline
);
712 if ((error
= git_status_file(&status
, payload
, path
)) < 0)
715 if (status
& GIT_STATUS_WT_MODIFIED
) {
716 giterr_set(GITERR_STASH
, "Local changes to '%s' would be overwritten", path
);
717 return GIT_EMERGECONFLICT
;
723 static int apply_modified(
725 git_repository
*repo
,
727 git_tree
*start_index_tree
,
728 git_tree
*stash_tree
,
731 git_index
*index
= NULL
;
732 git_merge_options merge_options
= GIT_MERGE_OPTIONS_INIT
;
733 git_checkout_options checkout_options
= GIT_CHECKOUT_OPTIONS_INIT
;
736 if ((error
= git_merge_trees(
737 &index
, repo
, base_tree
,
738 start_index_tree
, stash_tree
, &merge_options
)) < 0)
741 checkout_options
.checkout_strategy
= GIT_CHECKOUT_SAFE
| GIT_CHECKOUT_ALLOW_CONFLICTS
;
742 if ((flags
& GIT_APPLY_REINSTATE_INDEX
) && !git_index_has_conflicts(index
)) {
743 /* No need to update the index if it will be overridden later on */
744 checkout_options
.checkout_strategy
|= GIT_CHECKOUT_DONT_UPDATE_INDEX
;
746 checkout_options
.notify_flags
= GIT_CHECKOUT_NOTIFY_CONFLICT
;
747 checkout_options
.notify_cb
= checkout_modified_notify_callback
;
748 checkout_options
.notify_payload
= repo
;
749 checkout_options
.our_label
= "Updated upstream";
750 checkout_options
.their_label
= "Stashed changes";
751 if ((error
= git_checkout_index(repo
, index
, &checkout_options
)) < 0)
754 *has_conflicts
= git_index_has_conflicts(index
);
757 git_index_free(index
);
761 static int unstage_modified_files(
762 git_repository
*repo
,
763 git_index
*repo_index
,
764 git_tree
*unstashed_tree
,
765 git_tree
*start_index_tree
)
767 git_diff
*diff
= NULL
;
768 git_diff_options options
= GIT_DIFF_OPTIONS_INIT
;
772 if (unstashed_tree
) {
773 if ((error
= git_index_read_tree(repo_index
, unstashed_tree
)) < 0)
776 options
.flags
= GIT_DIFF_FORCE_BINARY
;
777 if ((error
= git_diff_tree_to_index(&diff
, repo
, start_index_tree
,
778 repo_index
, &options
)) < 0)
782 This behavior is not 100% similar to "git stash apply" as the latter uses
783 "git-read-tree --reset {treeish}" which preserves the stat()s from the
784 index instead of replacing them with the tree ones for identical files.
787 if ((error
= git_index_read_tree(repo_index
, start_index_tree
)) < 0)
790 for (i
= 0, count
= git_diff_num_deltas(diff
); i
< count
; ++i
) {
791 const git_diff_delta
* delta
= git_diff_get_delta(diff
, i
);
792 if (delta
->status
== GIT_DELTA_ADDED
) {
793 if ((error
= git_index_add_bypath(
794 repo_index
, delta
->new_file
.path
)) < 0)
806 git_repository
*repo
,
810 git_commit
*stash_commit
= NULL
;
811 git_tree
*stash_tree
= NULL
;
812 git_tree
*base_tree
= NULL
;
813 git_tree
*index_tree
= NULL
;
814 git_tree
*index_parent_tree
= NULL
;
815 git_tree
*untracked_tree
= NULL
;
816 git_index
*repo_index
= NULL
;
817 git_tree
*start_index_tree
= NULL
;
818 git_tree
*unstashed_tree
= NULL
;
822 /* Retrieve commit corresponding to the given stash */
823 if ((error
= retrieve_stash_commit(&stash_commit
, repo
, index
)) < 0)
826 /* Retrieve all trees in the stash */
827 if ((error
= retrieve_stash_trees(
828 &stash_tree
, &base_tree
, &index_tree
,
829 &index_parent_tree
, &untracked_tree
, stash_commit
)) < 0)
832 /* Load repo index */
833 if ((error
= git_repository_index(&repo_index
, repo
)) < 0)
836 /* Create tree from index */
837 if ((error
= build_tree_from_index(&start_index_tree
, repo_index
)) < 0)
840 /* Restore index if required */
841 if ((flags
& GIT_APPLY_REINSTATE_INDEX
) &&
842 git_oid_cmp(git_tree_id(base_tree
), git_tree_id(index_tree
)) &&
843 git_oid_cmp(git_tree_id(start_index_tree
), git_tree_id(index_tree
))) {
845 if ((error
= apply_index(
846 &unstashed_tree
, repo
, start_index_tree
,
847 index_parent_tree
, index_tree
)) < 0)
851 /* If applicable, restore untracked / ignored files in workdir */
852 if (untracked_tree
) {
853 if ((error
= apply_untracked(repo
, start_index_tree
, untracked_tree
)) < 0)
857 /* Restore modified files in workdir */
858 if ((error
= apply_modified(
859 &has_conflicts
, repo
, base_tree
, start_index_tree
,
860 stash_tree
, flags
)) < 0)
863 /* Unstage modified files from index unless there were merge conflicts */
864 if (!has_conflicts
&& (error
= unstage_modified_files(
865 repo
, repo_index
, unstashed_tree
, start_index_tree
)) < 0)
868 /* Write updated index */
869 if ((error
= git_index_write(repo_index
)) < 0)
873 git_tree_free(unstashed_tree
);
874 git_tree_free(start_index_tree
);
875 git_index_free(repo_index
);
876 git_tree_free(untracked_tree
);
877 git_tree_free(index_parent_tree
);
878 git_tree_free(index_tree
);
879 git_tree_free(base_tree
);
880 git_tree_free(stash_tree
);
881 git_commit_free(stash_commit
);
885 int git_stash_foreach(
886 git_repository
*repo
,
887 git_stash_cb callback
,
890 git_reference
*stash
;
891 git_reflog
*reflog
= NULL
;
894 const git_reflog_entry
*entry
;
896 error
= git_reference_lookup(&stash
, repo
, GIT_REFS_STASH_FILE
);
897 if (error
== GIT_ENOTFOUND
) {
904 if ((error
= git_reflog_read(&reflog
, repo
, GIT_REFS_STASH_FILE
)) < 0)
907 max
= git_reflog_entrycount(reflog
);
908 for (i
= 0; i
< max
; i
++) {
909 entry
= git_reflog_entry_byindex(reflog
, i
);
912 git_reflog_entry_message(entry
),
913 git_reflog_entry_id_new(entry
),
917 giterr_set_after_callback(error
);
923 git_reference_free(stash
);
924 git_reflog_free(reflog
);
929 git_repository
*repo
,
933 git_reference
*stash
= NULL
;
934 git_reflog
*reflog
= NULL
;
938 if ((error
= git_transaction_new(&tx
, repo
)) < 0)
941 if ((error
= git_transaction_lock_ref(tx
, GIT_REFS_STASH_FILE
)) < 0)
944 if ((error
= git_reference_lookup(&stash
, repo
, GIT_REFS_STASH_FILE
)) < 0)
947 if ((error
= git_reflog_read(&reflog
, repo
, GIT_REFS_STASH_FILE
)) < 0)
950 max
= git_reflog_entrycount(reflog
);
952 if (!max
|| index
> max
- 1) {
953 error
= GIT_ENOTFOUND
;
954 giterr_set(GITERR_STASH
, "No stashed state at position %" PRIuZ
, index
);
958 if ((error
= git_reflog_drop(reflog
, index
, true)) < 0)
961 if ((error
= git_transaction_set_reflog(tx
, GIT_REFS_STASH_FILE
, reflog
)) < 0)
965 if ((error
= git_transaction_remove(tx
, GIT_REFS_STASH_FILE
)) < 0)
967 } else if (index
== 0) {
968 const git_reflog_entry
*entry
;
970 entry
= git_reflog_entry_byindex(reflog
, 0);
971 if ((error
= git_transaction_set_target(tx
, GIT_REFS_STASH_FILE
, &entry
->oid_cur
, NULL
, NULL
)) < 0)
975 error
= git_transaction_commit(tx
);
978 git_reference_free(stash
);
979 git_transaction_free(tx
);
980 git_reflog_free(reflog
);
985 git_repository
*repo
,
991 if ((error
= git_stash_apply(repo
, index
, flags
)) < 0)
994 return git_stash_drop(repo
, index
);