refs: convert AUTO_MERGE to become a normal pseudo-ref

In 70c70de616 (refs: complete list of special refs, 2023-12-14) we have inrtoduced a new `is_special_ref()` function that classifies some refs as being special. The rule is that special refs are exclusively read and written via the filesystem directly, whereas normal refs exclucsively go via the refs API. The intent of that commit was to record the status quo so that we know to route reads of such special refs consistently. Eventually, the list should be reduced to its bare minimum of refs which really are special, namely FETCH_HEAD and MERGE_HEAD. Follow up on this promise and convert the AUTO_MERGE ref to become a normal pseudo-ref by using the refs API to both read and write it instead of accessing the filesystem directly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 19, 2024 at 11:40 UTC fd7c6ffa9e118cdf18a3752ec456070ed0a22e3b
9 files changed +23 -18
branch.c
+2 -1
@@ -817,7 +817,8 @@ void remove_merge_branch_state(struct repository *r)
817 unlink(git_path_merge_rr(r));
818 unlink(git_path_merge_msg(r));
819 unlink(git_path_merge_mode(r));
820 - unlink(git_path_auto_merge(r));
820 + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
821 + NULL, REF_NO_DEREF);
822 save_autostash(git_path_merge_autostash(r));
823 }
824
builtin/rebase.c
+1 -1
@@ -515,7 +515,7 @@ static int finish_rebase(struct rebase_options *opts)
515 int ret = 0;
516
517 delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
518 - unlink(git_path_auto_merge(the_repository));
518 + delete_ref(NULL, "AUTO_MERGE", NULL, REF_NO_DEREF);
519 apply_autostash(state_dir_path("autostash", opts));
520 /*
521 * We ignore errors in 'git maintenance run --auto', since the
merge-ort.c
+12 -7
@@ -38,6 +38,7 @@
38 #include "path.h"
39 #include "promisor-remote.h"
40 #include "read-cache-ll.h"
41 +#include "refs.h"
42 #include "revision.h"
43 #include "sparse-index.h"
44 #include "strmap.h"
@@ -4659,9 +4660,6 @@ void merge_switch_to_result(struct merge_options *opt,
4660 {
4661 assert(opt->priv == NULL);
4662 if (result->clean >= 0 && update_worktree_and_index) {
4662 - const char *filename;
4663 - FILE *fp;
4664 -
4663 trace2_region_enter("merge", "checkout", opt->repo);
4664 if (checkout(opt, head, result->tree)) {
4665 /* failure to function */
@@ -4687,10 +4685,17 @@ void merge_switch_to_result(struct merge_options *opt,
4685 trace2_region_leave("merge", "record_conflicted", opt->repo);
4686
4687 trace2_region_enter("merge", "write_auto_merge", opt->repo);
4690 - filename = git_path_auto_merge(opt->repo);
4691 - fp = xfopen(filename, "w");
4692 - fprintf(fp, "%s\n", oid_to_hex(&result->tree->object.oid));
4693 - fclose(fp);
4688 + if (refs_update_ref(get_main_ref_store(opt->repo), "", "AUTO_MERGE",
4689 + &result->tree->object.oid, NULL, REF_NO_DEREF,
4690 + UPDATE_REFS_MSG_ON_ERR)) {
4691 + /* failure to function */
4692 + opt->priv = NULL;
4693 + result->clean = -1;
4694 + merge_finalize(opt, result);
4695 + trace2_region_leave("merge", "write_auto_merge",
4696 + opt->repo);
4697 + return;
4698 + }
4699 trace2_region_leave("merge", "write_auto_merge", opt->repo);
4700 }
4701 if (display_update_msgs)
path.c
-1
@@ -1589,6 +1589,5 @@ REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR")
1589 REPO_GIT_PATH_FUNC(merge_mode, "MERGE_MODE")
1590 REPO_GIT_PATH_FUNC(merge_head, "MERGE_HEAD")
1591 REPO_GIT_PATH_FUNC(merge_autostash, "MERGE_AUTOSTASH")
1592 -REPO_GIT_PATH_FUNC(auto_merge, "AUTO_MERGE")
1592 REPO_GIT_PATH_FUNC(fetch_head, "FETCH_HEAD")
1593 REPO_GIT_PATH_FUNC(shallow, "shallow")
path.h
-1
@@ -176,7 +176,6 @@ const char *git_path_merge_rr(struct repository *r);
176 const char *git_path_merge_mode(struct repository *r);
177 const char *git_path_merge_head(struct repository *r);
178 const char *git_path_merge_autostash(struct repository *r);
179 -const char *git_path_auto_merge(struct repository *r);
179 const char *git_path_fetch_head(struct repository *r);
180 const char *git_path_shallow(struct repository *r);
181
refs.c
-1
@@ -1874,7 +1874,6 @@ static int is_special_ref(const char *refname)
1874 * (normal ones).
1875 */
1876 static const char * const special_refs[] = {
1877 - "AUTO_MERGE",
1877 "FETCH_HEAD",
1878 "MERGE_AUTOSTASH",
1879 "MERGE_HEAD",
repository.c
-1
@@ -263,7 +263,6 @@ static void repo_clear_path_cache(struct repo_path_cache *cache)
263 FREE_AND_NULL(cache->merge_mode);
264 FREE_AND_NULL(cache->merge_head);
265 FREE_AND_NULL(cache->merge_autostash);
266 - FREE_AND_NULL(cache->auto_merge);
266 FREE_AND_NULL(cache->fetch_head);
267 FREE_AND_NULL(cache->shallow);
268 }
repository.h
-1
@@ -68,7 +68,6 @@ struct repo_path_cache {
68 char *merge_mode;
69 char *merge_head;
70 char *merge_autostash;
71 - char *auto_merge;
71 char *fetch_head;
72 char *shallow;
73 };
sequencer.c
+8 -4
@@ -2408,7 +2408,8 @@ static int do_pick_commit(struct repository *r,
2408 refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD",
2409 NULL, REF_NO_DEREF);
2410 unlink(git_path_merge_msg(r));
2411 - unlink(git_path_auto_merge(r));
2411 + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
2412 + NULL, REF_NO_DEREF);
2413 fprintf(stderr,
2414 _("dropping %s %s -- patch contents already upstream\n"),
2415 oid_to_hex(&commit->object.oid), msg.subject);
@@ -2818,7 +2819,8 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)
2819 need_cleanup = 1;
2820 }
2821
2821 - unlink(git_path_auto_merge(r));
2822 + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
2823 + NULL, REF_NO_DEREF);
2824
2825 if (!need_cleanup)
2826 return;
@@ -4766,7 +4768,8 @@ static int pick_commits(struct repository *r,
4768 }
4769 unlink(rebase_path_author_script());
4770 unlink(git_path_merge_head(r));
4769 - unlink(git_path_auto_merge(r));
4771 + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
4772 + NULL, REF_NO_DEREF);
4773 refs_delete_ref(get_main_ref_store(r), "", "REBASE_HEAD",
4774 NULL, REF_NO_DEREF);
4775
@@ -5123,7 +5126,8 @@ static int commit_staged_changes(struct repository *r,
5126 return error(_("could not commit staged changes."));
5127 unlink(rebase_path_amend());
5128 unlink(git_path_merge_head(r));
5126 - unlink(git_path_auto_merge(r));
5129 + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
5130 + NULL, REF_NO_DEREF);
5131 if (final_fixup) {
5132 unlink(rebase_path_fixup_msg());
5133 unlink(rebase_path_squash_msg());