@matheusbsbs / matheus-bagliano / commits / b309a97108
Fork 0

reset: extract reset_head() from rebase

Continue the process of lib-ifying the autostash code. In a future commit, this will be used to implement `--autostash` in other builtins. This patch is best viewed with `--color-moved`. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Denton Liu committed Apr 7, 2020 at 10:28 UTC b309a9710899dab2f76455526f573a90fad5d13c
4 files changed +162 -138
Makefile
+1
@@ -970,6 +970,7 @@ LIB_OBJS += replace-object.o
970 LIB_OBJS += repo-settings.o
971 LIB_OBJS += repository.o
972 LIB_OBJS += rerere.o
973 +LIB_OBJS += reset.o
974 LIB_OBJS += resolve-undo.o
975 LIB_OBJS += revision.o
976 LIB_OBJS += run-command.o
builtin/rebase.c
+1 -138
@@ -27,6 +27,7 @@
27 #include "branch.h"
28 #include "sequencer.h"
29 #include "rebase-interactive.h"
30 +#include "reset.h"
31
32 #define DEFAULT_REFLOG_ACTION "rebase"
33
@@ -766,144 +767,6 @@ static void add_var(struct strbuf *buf, const char *name, const char *value)
767 }
768 }
769
769 -#define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
770 -
771 -#define RESET_HEAD_DETACH (1<<0)
772 -#define RESET_HEAD_HARD (1<<1)
773 -#define RESET_HEAD_RUN_POST_CHECKOUT_HOOK (1<<2)
774 -#define RESET_HEAD_REFS_ONLY (1<<3)
775 -#define RESET_ORIG_HEAD (1<<4)
776 -
777 -static int reset_head(struct repository *r, struct object_id *oid, const char *action,
778 - const char *switch_to_branch, unsigned flags,
779 - const char *reflog_orig_head, const char *reflog_head,
780 - const char *default_reflog_action)
781 -{
782 - unsigned detach_head = flags & RESET_HEAD_DETACH;
783 - unsigned reset_hard = flags & RESET_HEAD_HARD;
784 - unsigned run_hook = flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
785 - unsigned refs_only = flags & RESET_HEAD_REFS_ONLY;
786 - unsigned update_orig_head = flags & RESET_ORIG_HEAD;
787 - struct object_id head_oid;
788 - struct tree_desc desc[2] = { { NULL }, { NULL } };
789 - struct lock_file lock = LOCK_INIT;
790 - struct unpack_trees_options unpack_tree_opts;
791 - struct tree *tree;
792 - const char *reflog_action;
793 - struct strbuf msg = STRBUF_INIT;
794 - size_t prefix_len;
795 - struct object_id *orig = NULL, oid_orig,
796 - *old_orig = NULL, oid_old_orig;
797 - int ret = 0, nr = 0;
798 -
799 - if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
800 - BUG("Not a fully qualified branch: '%s'", switch_to_branch);
801 -
802 - if (!refs_only && repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {
803 - ret = -1;
804 - goto leave_reset_head;
805 - }
806 -
807 - if ((!oid || !reset_hard) && get_oid("HEAD", &head_oid)) {
808 - ret = error(_("could not determine HEAD revision"));
809 - goto leave_reset_head;
810 - }
811 -
812 - if (!oid)
813 - oid = &head_oid;
814 -
815 - if (refs_only)
816 - goto reset_head_refs;
817 -
818 - memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
819 - setup_unpack_trees_porcelain(&unpack_tree_opts, action);
820 - unpack_tree_opts.head_idx = 1;
821 - unpack_tree_opts.src_index = r->index;
822 - unpack_tree_opts.dst_index = r->index;
823 - unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
824 - unpack_tree_opts.update = 1;
825 - unpack_tree_opts.merge = 1;
826 - if (!detach_head)
827 - unpack_tree_opts.reset = 1;
828 -
829 - if (repo_read_index_unmerged(r) < 0) {
830 - ret = error(_("could not read index"));
831 - goto leave_reset_head;
832 - }
833 -
834 - if (!reset_hard && !fill_tree_descriptor(r, &desc[nr++], &head_oid)) {
835 - ret = error(_("failed to find tree of %s"),
836 - oid_to_hex(&head_oid));
837 - goto leave_reset_head;
838 - }
839 -
840 - if (!fill_tree_descriptor(r, &desc[nr++], oid)) {
841 - ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
842 - goto leave_reset_head;
843 - }
844 -
845 - if (unpack_trees(nr, desc, &unpack_tree_opts)) {
846 - ret = -1;
847 - goto leave_reset_head;
848 - }
849 -
850 - tree = parse_tree_indirect(oid);
851 - prime_cache_tree(r, r->index, tree);
852 -
853 - if (write_locked_index(r->index, &lock, COMMIT_LOCK) < 0) {
854 - ret = error(_("could not write index"));
855 - goto leave_reset_head;
856 - }
857 -
858 -reset_head_refs:
859 - reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
860 - strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : default_reflog_action);
861 - prefix_len = msg.len;
862 -
863 - if (update_orig_head) {
864 - if (!get_oid("ORIG_HEAD", &oid_old_orig))
865 - old_orig = &oid_old_orig;
866 - if (!get_oid("HEAD", &oid_orig)) {
867 - orig = &oid_orig;
868 - if (!reflog_orig_head) {
869 - strbuf_addstr(&msg, "updating ORIG_HEAD");
870 - reflog_orig_head = msg.buf;
871 - }
872 - update_ref(reflog_orig_head, "ORIG_HEAD", orig,
873 - old_orig, 0, UPDATE_REFS_MSG_ON_ERR);
874 - } else if (old_orig)
875 - delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
876 - }
877 -
878 - if (!reflog_head) {
879 - strbuf_setlen(&msg, prefix_len);
880 - strbuf_addstr(&msg, "updating HEAD");
881 - reflog_head = msg.buf;
882 - }
883 - if (!switch_to_branch)
884 - ret = update_ref(reflog_head, "HEAD", oid, orig,
885 - detach_head ? REF_NO_DEREF : 0,
886 - UPDATE_REFS_MSG_ON_ERR);
887 - else {
888 - ret = update_ref(reflog_head, switch_to_branch, oid,
889 - NULL, 0, UPDATE_REFS_MSG_ON_ERR);
890 - if (!ret)
891 - ret = create_symref("HEAD", switch_to_branch,
892 - reflog_head);
893 - }
894 - if (run_hook)
895 - run_hook_le(NULL, "post-checkout",
896 - oid_to_hex(orig ? orig : &null_oid),
897 - oid_to_hex(oid), "1", NULL);
898 -
899 -leave_reset_head:
900 - strbuf_release(&msg);
901 - rollback_lock_file(&lock);
902 - while (nr)
903 - free((void *)desc[--nr].buffer);
904 - return ret;
905 -}
906 -
770 static int move_to_original_branch(struct rebase_options *opts)
771 {
772 struct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
reset.c new
+140
@@ -0,0 +1,140 @@
1 +#include "git-compat-util.h"
2 +#include "cache-tree.h"
3 +#include "lockfile.h"
4 +#include "refs.h"
5 +#include "reset.h"
6 +#include "run-command.h"
7 +#include "tree-walk.h"
8 +#include "tree.h"
9 +#include "unpack-trees.h"
10 +
11 +int reset_head(struct repository *r, struct object_id *oid, const char *action,
12 + const char *switch_to_branch, unsigned flags,
13 + const char *reflog_orig_head, const char *reflog_head,
14 + const char *default_reflog_action)
15 +{
16 + unsigned detach_head = flags & RESET_HEAD_DETACH;
17 + unsigned reset_hard = flags & RESET_HEAD_HARD;
18 + unsigned run_hook = flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
19 + unsigned refs_only = flags & RESET_HEAD_REFS_ONLY;
20 + unsigned update_orig_head = flags & RESET_ORIG_HEAD;
21 + struct object_id head_oid;
22 + struct tree_desc desc[2] = { { NULL }, { NULL } };
23 + struct lock_file lock = LOCK_INIT;
24 + struct unpack_trees_options unpack_tree_opts;
25 + struct tree *tree;
26 + const char *reflog_action;
27 + struct strbuf msg = STRBUF_INIT;
28 + size_t prefix_len;
29 + struct object_id *orig = NULL, oid_orig,
30 + *old_orig = NULL, oid_old_orig;
31 + int ret = 0, nr = 0;
32 +
33 + if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
34 + BUG("Not a fully qualified branch: '%s'", switch_to_branch);
35 +
36 + if (!refs_only && repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {
37 + ret = -1;
38 + goto leave_reset_head;
39 + }
40 +
41 + if ((!oid || !reset_hard) && get_oid("HEAD", &head_oid)) {
42 + ret = error(_("could not determine HEAD revision"));
43 + goto leave_reset_head;
44 + }
45 +
46 + if (!oid)
47 + oid = &head_oid;
48 +
49 + if (refs_only)
50 + goto reset_head_refs;
51 +
52 + memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
53 + setup_unpack_trees_porcelain(&unpack_tree_opts, action);
54 + unpack_tree_opts.head_idx = 1;
55 + unpack_tree_opts.src_index = r->index;
56 + unpack_tree_opts.dst_index = r->index;
57 + unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
58 + unpack_tree_opts.update = 1;
59 + unpack_tree_opts.merge = 1;
60 + if (!detach_head)
61 + unpack_tree_opts.reset = 1;
62 +
63 + if (repo_read_index_unmerged(r) < 0) {
64 + ret = error(_("could not read index"));
65 + goto leave_reset_head;
66 + }
67 +
68 + if (!reset_hard && !fill_tree_descriptor(r, &desc[nr++], &head_oid)) {
69 + ret = error(_("failed to find tree of %s"),
70 + oid_to_hex(&head_oid));
71 + goto leave_reset_head;
72 + }
73 +
74 + if (!fill_tree_descriptor(r, &desc[nr++], oid)) {
75 + ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
76 + goto leave_reset_head;
77 + }
78 +
79 + if (unpack_trees(nr, desc, &unpack_tree_opts)) {
80 + ret = -1;
81 + goto leave_reset_head;
82 + }
83 +
84 + tree = parse_tree_indirect(oid);
85 + prime_cache_tree(r, r->index, tree);
86 +
87 + if (write_locked_index(r->index, &lock, COMMIT_LOCK) < 0) {
88 + ret = error(_("could not write index"));
89 + goto leave_reset_head;
90 + }
91 +
92 +reset_head_refs:
93 + reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
94 + strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : default_reflog_action);
95 + prefix_len = msg.len;
96 +
97 + if (update_orig_head) {
98 + if (!get_oid("ORIG_HEAD", &oid_old_orig))
99 + old_orig = &oid_old_orig;
100 + if (!get_oid("HEAD", &oid_orig)) {
101 + orig = &oid_orig;
102 + if (!reflog_orig_head) {
103 + strbuf_addstr(&msg, "updating ORIG_HEAD");
104 + reflog_orig_head = msg.buf;
105 + }
106 + update_ref(reflog_orig_head, "ORIG_HEAD", orig,
107 + old_orig, 0, UPDATE_REFS_MSG_ON_ERR);
108 + } else if (old_orig)
109 + delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
110 + }
111 +
112 + if (!reflog_head) {
113 + strbuf_setlen(&msg, prefix_len);
114 + strbuf_addstr(&msg, "updating HEAD");
115 + reflog_head = msg.buf;
116 + }
117 + if (!switch_to_branch)
118 + ret = update_ref(reflog_head, "HEAD", oid, orig,
119 + detach_head ? REF_NO_DEREF : 0,
120 + UPDATE_REFS_MSG_ON_ERR);
121 + else {
122 + ret = update_ref(reflog_head, switch_to_branch, oid,
123 + NULL, 0, UPDATE_REFS_MSG_ON_ERR);
124 + if (!ret)
125 + ret = create_symref("HEAD", switch_to_branch,
126 + reflog_head);
127 + }
128 + if (run_hook)
129 + run_hook_le(NULL, "post-checkout",
130 + oid_to_hex(orig ? orig : &null_oid),
131 + oid_to_hex(oid), "1", NULL);
132 +
133 +leave_reset_head:
134 + strbuf_release(&msg);
135 + rollback_lock_file(&lock);
136 + while (nr)
137 + free((void *)desc[--nr].buffer);
138 + return ret;
139 +
140 +}
reset.h new
+20
@@ -0,0 +1,20 @@
1 +#ifndef RESET_H
2 +#define RESET_H
3 +
4 +#include "hash.h"
5 +#include "repository.h"
6 +
7 +#define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
8 +
9 +#define RESET_HEAD_DETACH (1<<0)
10 +#define RESET_HEAD_HARD (1<<1)
11 +#define RESET_HEAD_RUN_POST_CHECKOUT_HOOK (1<<2)
12 +#define RESET_HEAD_REFS_ONLY (1<<3)
13 +#define RESET_ORIG_HEAD (1<<4)
14 +
15 +int reset_head(struct repository *r, struct object_id *oid, const char *action,
16 + const char *switch_to_branch, unsigned flags,
17 + const char *reflog_orig_head, const char *reflog_head,
18 + const char *default_reflog_action);
19 +
20 +#endif