reset_head(): factor out ref updates

In the next commit we will stop trying to update HEAD when we are removing uncommitted changes from the working tree. Move the code that updates the refs to its own function in preparation for that. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Jan 26, 2022 at 13:05 UTC d6a9f5ea8e97dd9435e5fa02cc129c1b241934f2
1 file changed +62 -48
reset.c
+62 -48
@@ -8,25 +8,75 @@
8 #include "tree.h"
9 #include "unpack-trees.h"
10
11 +static int update_refs(const struct object_id *oid, const char *switch_to_branch,
12 + const struct object_id *head, const char *reflog_head,
13 + const char *reflog_orig_head,
14 + const char *default_reflog_action, unsigned flags)
15 +{
16 + unsigned detach_head = flags & RESET_HEAD_DETACH;
17 + unsigned run_hook = flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
18 + unsigned update_orig_head = flags & RESET_ORIG_HEAD;
19 + struct object_id *old_orig = NULL, oid_old_orig;
20 + struct strbuf msg = STRBUF_INIT;
21 + const char *reflog_action;
22 + size_t prefix_len;
23 + int ret;
24 +
25 + reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
26 + strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : default_reflog_action);
27 + prefix_len = msg.len;
28 +
29 + if (update_orig_head) {
30 + if (!get_oid("ORIG_HEAD", &oid_old_orig))
31 + old_orig = &oid_old_orig;
32 + if (head) {
33 + if (!reflog_orig_head) {
34 + strbuf_addstr(&msg, "updating ORIG_HEAD");
35 + reflog_orig_head = msg.buf;
36 + }
37 + update_ref(reflog_orig_head, "ORIG_HEAD", head,
38 + old_orig, 0, UPDATE_REFS_MSG_ON_ERR);
39 + } else if (old_orig)
40 + delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
41 + }
42 +
43 + if (!reflog_head) {
44 + strbuf_setlen(&msg, prefix_len);
45 + strbuf_addstr(&msg, "updating HEAD");
46 + reflog_head = msg.buf;
47 + }
48 + if (!switch_to_branch)
49 + ret = update_ref(reflog_head, "HEAD", oid, head,
50 + detach_head ? REF_NO_DEREF : 0,
51 + UPDATE_REFS_MSG_ON_ERR);
52 + else {
53 + ret = update_ref(reflog_head, switch_to_branch, oid,
54 + NULL, 0, UPDATE_REFS_MSG_ON_ERR);
55 + if (!ret)
56 + ret = create_symref("HEAD", switch_to_branch,
57 + reflog_head);
58 + }
59 + if (!ret && run_hook)
60 + run_hook_le(NULL, "post-checkout",
61 + oid_to_hex(head ? head : null_oid()),
62 + oid_to_hex(oid), "1", NULL);
63 + strbuf_release(&msg);
64 + return ret;
65 +}
66 +
67 int reset_head(struct repository *r, struct object_id *oid,
68 const char *switch_to_branch, unsigned flags,
69 const char *reflog_orig_head, const char *reflog_head,
70 const char *default_reflog_action)
71 {
16 - unsigned detach_head = flags & RESET_HEAD_DETACH;
72 unsigned reset_hard = flags & RESET_HEAD_HARD;
18 - unsigned run_hook = flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
73 unsigned refs_only = flags & RESET_HEAD_REFS_ONLY;
20 - unsigned update_orig_head = flags & RESET_ORIG_HEAD;
74 struct object_id *head = NULL, head_oid;
75 struct tree_desc desc[2] = { { NULL }, { NULL } };
76 struct lock_file lock = LOCK_INIT;
77 struct unpack_trees_options unpack_tree_opts = { 0 };
78 struct tree *tree;
26 - const char *action, *reflog_action;
27 - struct strbuf msg = STRBUF_INIT;
28 - size_t prefix_len;
29 - struct object_id *old_orig = NULL, oid_old_orig;
79 + const char *action;
80 int ret = 0, nr = 0;
81
82 if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
@@ -48,7 +98,9 @@ int reset_head(struct repository *r, struct object_id *oid,
98 oid = &head_oid;
99
100 if (refs_only)
51 - goto reset_head_refs;
101 + return update_refs(oid, switch_to_branch, head, reflog_head,
102 + reflog_orig_head, default_reflog_action,
103 + flags);
104
105 action = reset_hard ? "reset" : "checkout";
106 setup_unpack_trees_porcelain(&unpack_tree_opts, action);
@@ -92,48 +144,10 @@ int reset_head(struct repository *r, struct object_id *oid,
144 goto leave_reset_head;
145 }
146
95 -reset_head_refs:
96 - reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
97 - strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : default_reflog_action);
98 - prefix_len = msg.len;
99 -
100 - if (update_orig_head) {
101 - if (!get_oid("ORIG_HEAD", &oid_old_orig))
102 - old_orig = &oid_old_orig;
103 - if (head) {
104 - if (!reflog_orig_head) {
105 - strbuf_addstr(&msg, "updating ORIG_HEAD");
106 - reflog_orig_head = msg.buf;
107 - }
108 - update_ref(reflog_orig_head, "ORIG_HEAD", head,
109 - old_orig, 0, UPDATE_REFS_MSG_ON_ERR);
110 - } else if (old_orig)
111 - delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
112 - }
113 -
114 - if (!reflog_head) {
115 - strbuf_setlen(&msg, prefix_len);
116 - strbuf_addstr(&msg, "updating HEAD");
117 - reflog_head = msg.buf;
118 - }
119 - if (!switch_to_branch)
120 - ret = update_ref(reflog_head, "HEAD", oid, head,
121 - detach_head ? REF_NO_DEREF : 0,
122 - UPDATE_REFS_MSG_ON_ERR);
123 - else {
124 - ret = update_ref(reflog_head, switch_to_branch, oid,
125 - NULL, 0, UPDATE_REFS_MSG_ON_ERR);
126 - if (!ret)
127 - ret = create_symref("HEAD", switch_to_branch,
128 - reflog_head);
129 - }
130 - if (!ret && run_hook)
131 - run_hook_le(NULL, "post-checkout",
132 - oid_to_hex(head ? head : null_oid()),
133 - oid_to_hex(oid), "1", NULL);
147 + ret = update_refs(oid, switch_to_branch, head, reflog_head,
148 + reflog_orig_head, default_reflog_action, flags);
149
150 leave_reset_head:
136 - strbuf_release(&msg);
151 rollback_lock_file(&lock);
152 clear_unpack_trees_porcelain(&unpack_tree_opts);
153 while (nr)