{"thread":{"id":"54062","subject":"[PATCH 1/3] Make refs_ref_exists public","startedAt":"2020-08-18T12:18:06Z","lastAt":"2020-08-21T18:34:58Z","messageCount":23,"participants":["Han-Wen Nienhuys via GitGitGadget","Junio C Hamano","Han-Wen Nienhuys"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"403926","messageId":"5e29fa74dc70b5e36ace27ed6d83060cf0925681.1597753075.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.git.1597753075.gitgitgadget@gmail.com","subject":"[PATCH 1/3] Make refs_ref_exists public","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-18T12:17:53Z","receivedAt":"2020-08-18T12:18:06Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n refs.c | 2 +-\n refs.h | 2 ++\n 2 files changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/refs.c b/refs.c\nindex cf91711968..d46080f4b6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -313,7 +313,7 @@ int read_ref(const char *refname, struct object_id *oid)\n \treturn read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);\n }\n \n-static int refs_ref_exists(struct ref_store *refs, const char *refname)\n+int refs_ref_exists(struct ref_store *refs, const char *refname)\n {\n \treturn !!refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING, NULL, NULL);\n }\ndiff --git a/refs.h b/refs.h\nindex 29e28124cd..04bd25019f 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -105,6 +105,8 @@ int refs_verify_refname_available(struct ref_store *refs,\n \t\t\t\t  const struct string_list *skip,\n \t\t\t\t  struct strbuf *err);\n \n+int refs_ref_exists(struct ref_store *refs, const char *refname);\n+\n int ref_exists(const char *refname);\n \n int should_autocreate_reflog(const char *refname);\n-- \ngitgitgadget\n\n"},{"id":"403927","messageId":"06a8e8cbd1370ba3d4ea8a0a9f1e69d27b1d62c4.1597753075.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.git.1597753075.gitgitgadget@gmail.com","subject":"[PATCH 2/3] Treat CHERRY_PICK_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-18T12:17:54Z","receivedAt":"2020-08-18T12:18:11Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nCheck for existence and delete CHERRY_PICK_HEAD through ref functions.\nThis will help cherry-pick work with alternate ref storage backends.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n builtin/commit.c | 34 +++++++++++++++++++---------------\n builtin/merge.c  |  2 +-\n path.c           |  1 -\n path.h           |  7 ++++---\n sequencer.c      | 42 ++++++++++++++++++++++++++----------------\n wt-status.c      |  4 ++--\n 6 files changed, 52 insertions(+), 38 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 69ac78d5e5..619b71bcb4 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -847,21 +847,25 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\tif (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&\n \t\t\t\t!merge_contains_scissors)\n \t\t\t\twt_status_add_cut_line(s->fp);\n-\t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n-\t\t\t    whence == FROM_MERGE\n-\t\t\t\t? _(\"\\n\"\n-\t\t\t\t\t\"It looks like you may be committing a merge.\\n\"\n-\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n-\t\t\t\t\t\"\t%s\\n\"\n-\t\t\t\t\t\"and try again.\\n\")\n-\t\t\t\t: _(\"\\n\"\n-\t\t\t\t\t\"It looks like you may be committing a cherry-pick.\\n\"\n-\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n-\t\t\t\t\t\"\t%s\\n\"\n-\t\t\t\t\t\"and try again.\\n\"),\n-\t\t\t\twhence == FROM_MERGE ?\n-\t\t\t\t\tgit_path_merge_head(the_repository) :\n-\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n+\t\t\tif (whence == FROM_MERGE)\n+\t\t\t\tstatus_printf_ln(\n+\t\t\t\t\ts, GIT_COLOR_NORMAL,\n+\n+\t\t\t\t\t_(\"\\n\"\n+\t\t\t\t\t  \"It looks like you may be committing a merge.\\n\"\n+\t\t\t\t\t  \"If this is not correct, please remove the file\\n\"\n+\t\t\t\t\t  \"\t%s\\n\"\n+\t\t\t\t\t  \"and try again.\\n\"),\n+\t\t\t\t\tgit_path_merge_head(the_repository));\n+\t\t\telse\n+\t\t\t\tstatus_printf_ln(\n+\t\t\t\t\ts, GIT_COLOR_NORMAL,\n+\n+\t\t\t\t\t_(\"\\n\"\n+\t\t\t\t\t  \"It looks like you may be committing a cherry-pick.\\n\"\n+\t\t\t\t\t  \"If this is not correct, please run\\n\"\n+\t\t\t\t\t  \"\tgit cherry-pick --abort\\n\"\n+\t\t\t\t\t  \"and try again.\\n\"));\n \t\t}\n \n \t\tfprintf(s->fp, \"\\n\");\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 74829a838e..b9a89ba858 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1348,7 +1348,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\telse\n \t\t\tdie(_(\"You have not concluded your merge (MERGE_HEAD exists).\"));\n \t}\n-\tif (file_exists(git_path_cherry_pick_head(the_repository))) {\n+\tif (ref_exists(\"CHERRY_PICK_HEAD\")) {\n \t\tif (advice_resolve_conflict)\n \t\t\tdie(_(\"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\\n\"\n \t\t\t    \"Please, commit your changes before you merge.\"));\ndiff --git a/path.c b/path.c\nindex 8b2c753191..783cc2ae81 100644\n--- a/path.c\n+++ b/path.c\n@@ -1528,7 +1528,6 @@ char *xdg_cache_home(const char *filename)\n \treturn NULL;\n }\n \n-REPO_GIT_PATH_FUNC(cherry_pick_head, \"CHERRY_PICK_HEAD\")\n REPO_GIT_PATH_FUNC(revert_head, \"REVERT_HEAD\")\n REPO_GIT_PATH_FUNC(squash_msg, \"SQUASH_MSG\")\n REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\ndiff --git a/path.h b/path.h\nindex 1f1bf8f87a..8941c018a9 100644\n--- a/path.h\n+++ b/path.h\n@@ -170,7 +170,6 @@ void report_linked_checkout_garbage(void);\n \t}\n \n struct path_cache {\n-\tconst char *cherry_pick_head;\n \tconst char *revert_head;\n \tconst char *squash_msg;\n \tconst char *merge_msg;\n@@ -182,9 +181,11 @@ struct path_cache {\n \tconst char *shallow;\n };\n \n-#define PATH_CACHE_INIT { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }\n+#define PATH_CACHE_INIT                                              \\\n+\t{                                                            \\\n+\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n+\t}\n \n-const char *git_path_cherry_pick_head(struct repository *r);\n const char *git_path_revert_head(struct repository *r);\n const char *git_path_squash_msg(struct repository *r);\n const char *git_path_merge_msg(struct repository *r);\ndiff --git a/sequencer.c b/sequencer.c\nindex cc3f8fa88e..09e2ff659e 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -381,7 +381,8 @@ static void print_advice(struct repository *r, int show_hint,\n \t\t * (typically rebase --interactive) wants to take care\n \t\t * of the commit itself so remove CHERRY_PICK_HEAD\n \t\t */\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\treturn;\n \t}\n \n@@ -1455,7 +1456,8 @@ static int do_commit(struct repository *r,\n \t\t\t\t    author, opts, flags, &oid);\n \t\tstrbuf_release(&sb);\n \t\tif (!res) {\n-\t\t\tunlink(git_path_cherry_pick_head(r));\n+\t\t\trefs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t\t\"CHERRY_PICK_HEAD\", NULL, 0);\n \t\t\tunlink(git_path_merge_msg(r));\n \t\t\tif (!is_rebase_i(opts))\n \t\t\t\tprint_commit_summary(r, NULL, &oid,\n@@ -1966,7 +1968,8 @@ static int do_pick_commit(struct repository *r,\n \t\tflags |= ALLOW_EMPTY;\n \t} else if (allow == 2) {\n \t\tdrop_commit = 1;\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\tunlink(git_path_merge_msg(r));\n \t\tfprintf(stderr,\n \t\t\t_(\"dropping %s %s -- patch contents already upstream\\n\"),\n@@ -2305,8 +2308,10 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)\n \tstruct replay_opts opts = REPLAY_OPTS_INIT;\n \tint need_cleanup = 0;\n \n-\tif (file_exists(git_path_cherry_pick_head(r))) {\n-\t\tif (!unlink(git_path_cherry_pick_head(r)) && verbose)\n+\tif (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\")) {\n+\t\tif (!refs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t     \"CHERRY_PICK_HEAD\", NULL, 0) &&\n+\t\t    verbose)\n \t\t\twarning(_(\"cancelling a cherry picking in progress\"));\n \t\topts.action = REPLAY_PICK;\n \t\tneed_cleanup = 1;\n@@ -2671,8 +2676,9 @@ static int create_seq_dir(struct repository *r)\n \tenum replay_action action;\n \tconst char *in_progress_error = NULL;\n \tconst char *in_progress_advice = NULL;\n-\tunsigned int advise_skip = file_exists(git_path_revert_head(r)) ||\n-\t\t\t\tfile_exists(git_path_cherry_pick_head(r));\n+\tunsigned int advise_skip =\n+\t\tfile_exists(git_path_revert_head(r)) ||\n+\t\trefs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\");\n \n \tif (!sequencer_get_last_command(r, &action)) {\n \t\tswitch (action) {\n@@ -2771,7 +2777,7 @@ static int rollback_single_pick(struct repository *r)\n {\n \tstruct object_id head_oid;\n \n-\tif (!file_exists(git_path_cherry_pick_head(r)) &&\n+\tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n \t    !file_exists(git_path_revert_head(r)))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \tif (read_ref_full(\"HEAD\", 0, &head_oid, NULL))\n@@ -2874,7 +2880,8 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)\n \t\t}\n \t\tbreak;\n \tcase REPLAY_PICK:\n-\t\tif (!file_exists(git_path_cherry_pick_head(r))) {\n+\t\tif (!refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t     \"CHERRY_PICK_HEAD\")) {\n \t\t\tif (action != REPLAY_PICK)\n \t\t\t\treturn error(_(\"no cherry-pick in progress\"));\n \t\t\tif (!rollback_is_safe())\n@@ -3569,7 +3576,8 @@ static int do_merge(struct repository *r,\n \t\t\t\t    oid_to_hex(&j->item->object.oid));\n \n \t\tstrbuf_release(&ref_name);\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\trollback_lock_file(&lock);\n \n \t\trollback_lock_file(&lock);\n@@ -4201,7 +4209,7 @@ static int continue_single_pick(struct repository *r)\n {\n \tconst char *argv[] = { \"commit\", NULL };\n \n-\tif (!file_exists(git_path_cherry_pick_head(r)) &&\n+\tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n \t    !file_exists(git_path_revert_head(r)))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n@@ -4318,9 +4326,10 @@ static int commit_staged_changes(struct repository *r,\n \t}\n \n \tif (is_clean) {\n-\t\tconst char *cherry_pick_head = git_path_cherry_pick_head(r);\n-\n-\t\tif (file_exists(cherry_pick_head) && unlink(cherry_pick_head))\n+\t\tif (refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t    \"CHERRY_PICK_HEAD\") &&\n+\t\t    refs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t    \"CHERRY_PICK_HEAD\", NULL, 0))\n \t\t\treturn error(_(\"could not remove CHERRY_PICK_HEAD\"));\n \t\tif (!final_fixup)\n \t\t\treturn 0;\n@@ -4379,7 +4388,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \n \tif (!is_rebase_i(opts)) {\n \t\t/* Verify that the conflict has been resolved */\n-\t\tif (file_exists(git_path_cherry_pick_head(r)) ||\n+\t\tif (refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t    \"CHERRY_PICK_HEAD\") ||\n \t\t    file_exists(git_path_revert_head(r))) {\n \t\t\tres = continue_single_pick(r);\n \t\t\tif (res)\n@@ -5442,7 +5452,7 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)\n \n int sequencer_determine_whence(struct repository *r, enum commit_whence *whence)\n {\n-\tif (file_exists(git_path_cherry_pick_head(r))) {\n+\tif (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\")) {\n \t\tstruct object_id cherry_pick_head, rebase_head;\n \n \t\tif (file_exists(git_path_seq_dir()))\ndiff --git a/wt-status.c b/wt-status.c\nindex d75399085d..c6abf2f3ca 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1672,8 +1672,8 @@ void wt_status_get_state(struct repository *r,\n \t\tstate->merge_in_progress = 1;\n \t} else if (wt_status_check_rebase(NULL, state)) {\n \t\t;\t\t/* all set */\n-\t} else if (!stat(git_path_cherry_pick_head(r), &st) &&\n-\t\t\t!get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n+\t} else if (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n+\t\t   !get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n \t\tstate->cherry_pick_in_progress = 1;\n \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n \t}\n-- \ngitgitgadget\n\n"},{"id":"403928","messageId":"173d81dbb41c3a7f4ab5187c1a056da182c4f6e5.1597753075.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.git.1597753075.gitgitgadget@gmail.com","subject":"[PATCH 3/3] Treat REVERT_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-18T12:17:55Z","receivedAt":"2020-08-18T12:18:18Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n path.c      |  1 -\n path.h      |  8 +++-----\n sequencer.c | 16 +++++++++-------\n wt-status.c |  2 +-\n 4 files changed, 13 insertions(+), 14 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 783cc2ae81..7b385e5eb2 100644\n--- a/path.c\n+++ b/path.c\n@@ -1528,7 +1528,6 @@ char *xdg_cache_home(const char *filename)\n \treturn NULL;\n }\n \n-REPO_GIT_PATH_FUNC(revert_head, \"REVERT_HEAD\")\n REPO_GIT_PATH_FUNC(squash_msg, \"SQUASH_MSG\")\n REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\n REPO_GIT_PATH_FUNC(merge_rr, \"MERGE_RR\")\ndiff --git a/path.h b/path.h\nindex 8941c018a9..e7e77da6aa 100644\n--- a/path.h\n+++ b/path.h\n@@ -170,7 +170,6 @@ void report_linked_checkout_garbage(void);\n \t}\n \n struct path_cache {\n-\tconst char *revert_head;\n \tconst char *squash_msg;\n \tconst char *merge_msg;\n \tconst char *merge_rr;\n@@ -181,12 +180,11 @@ struct path_cache {\n \tconst char *shallow;\n };\n \n-#define PATH_CACHE_INIT                                              \\\n-\t{                                                            \\\n-\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n+#define PATH_CACHE_INIT                                        \\\n+\t{                                                      \\\n+\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n \t}\n \n-const char *git_path_revert_head(struct repository *r);\n const char *git_path_squash_msg(struct repository *r);\n const char *git_path_merge_msg(struct repository *r);\n const char *git_path_merge_rr(struct repository *r);\ndiff --git a/sequencer.c b/sequencer.c\nindex 09e2ff659e..d116ea69bd 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2317,8 +2317,10 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)\n \t\tneed_cleanup = 1;\n \t}\n \n-\tif (file_exists(git_path_revert_head(r))) {\n-\t\tif (!unlink(git_path_revert_head(r)) && verbose)\n+\tif (refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n+\t\tif (!refs_delete_ref(get_main_ref_store(r), \"\", \"REVERT_HEAD\",\n+\t\t\t\t     NULL, 0) &&\n+\t\t    verbose)\n \t\t\twarning(_(\"cancelling a revert in progress\"));\n \t\topts.action = REPLAY_REVERT;\n \t\tneed_cleanup = 1;\n@@ -2677,7 +2679,7 @@ static int create_seq_dir(struct repository *r)\n \tconst char *in_progress_error = NULL;\n \tconst char *in_progress_advice = NULL;\n \tunsigned int advise_skip =\n-\t\tfile_exists(git_path_revert_head(r)) ||\n+\t\trefs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\") ||\n \t\trefs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\");\n \n \tif (!sequencer_get_last_command(r, &action)) {\n@@ -2778,7 +2780,7 @@ static int rollback_single_pick(struct repository *r)\n \tstruct object_id head_oid;\n \n \tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n-\t    !file_exists(git_path_revert_head(r)))\n+\t    !refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\"))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \tif (read_ref_full(\"HEAD\", 0, &head_oid, NULL))\n \t\treturn error(_(\"cannot resolve HEAD\"));\n@@ -2872,7 +2874,7 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)\n \t */\n \tswitch (opts->action) {\n \tcase REPLAY_REVERT:\n-\t\tif (!file_exists(git_path_revert_head(r))) {\n+\t\tif (!refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n \t\t\tif (action != REPLAY_REVERT)\n \t\t\t\treturn error(_(\"no revert in progress\"));\n \t\t\tif (!rollback_is_safe())\n@@ -4210,7 +4212,7 @@ static int continue_single_pick(struct repository *r)\n \tconst char *argv[] = { \"commit\", NULL };\n \n \tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n-\t    !file_exists(git_path_revert_head(r)))\n+\t    !refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\"))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n }\n@@ -4390,7 +4392,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t/* Verify that the conflict has been resolved */\n \t\tif (refs_ref_exists(get_main_ref_store(r),\n \t\t\t\t    \"CHERRY_PICK_HEAD\") ||\n-\t\t    file_exists(git_path_revert_head(r))) {\n+\t\t    refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n \t\t\tres = continue_single_pick(r);\n \t\t\tif (res)\n \t\t\t\tgoto release_todo_list;\ndiff --git a/wt-status.c b/wt-status.c\nindex c6abf2f3ca..ecbe570e28 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1678,7 +1678,7 @@ void wt_status_get_state(struct repository *r,\n \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n \t}\n \twt_status_check_bisect(NULL, state);\n-\tif (!stat(git_path_revert_head(r), &st) &&\n+\tif (refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\") &&\n \t    !get_oid(\"REVERT_HEAD\", &oid)) {\n \t\tstate->revert_in_progress = 1;\n \t\toidcpy(&state->revert_head_oid, &oid);\n-- \ngitgitgadget\n"},{"id":"403929","messageId":"pull.706.git.1597753075.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":null,"subject":"[PATCH 0/3] Use refs API for handling sundry pseudorefs","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-18T12:17:52Z","receivedAt":"2020-08-18T12:18:19Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"This series changes the handling of CHERRY_PICK_HEAD and REVERT_HEAD to use\nthe refs API, as a preliminary refactor for reftable. \n\nNo functional changes.\n\nHan-Wen Nienhuys (3):\n  Make refs_ref_exists public\n  Treat CHERRY_PICK_HEAD as a pseudo ref\n  Treat REVERT_HEAD as a pseudo ref\n\n builtin/commit.c | 34 ++++++++++++++++-------------\n builtin/merge.c  |  2 +-\n path.c           |  2 --\n path.h           |  9 ++++----\n refs.c           |  2 +-\n refs.h           |  2 ++\n sequencer.c      | 56 +++++++++++++++++++++++++++++-------------------\n wt-status.c      |  6 +++---\n 8 files changed, 64 insertions(+), 49 deletions(-)\n\n\nbase-commit: 2befe97201e1f3175cce557866c5822793624b5a\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-706%2Fhanwen%2Fstray-pseudorefs-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-706/hanwen/stray-pseudorefs-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/706\n-- \ngitgitgadget\n"},{"id":"403972","messageId":"xmqq1rk3y9s0.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"pull.706.git.1597753075.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/3] Use refs API for handling sundry pseudorefs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-18T20:33:03Z","receivedAt":"2020-08-18T20:33:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> This series changes the handling of CHERRY_PICK_HEAD and REVERT_HEAD to use\n> the refs API, as a preliminary refactor for reftable. \n\nNice.\n"},{"id":"403973","messageId":"xmqqwo1vwuwx.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"5e29fa74dc70b5e36ace27ed6d83060cf0925681.1597753075.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/3] Make refs_ref_exists public","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-18T20:39:26Z","receivedAt":"2020-08-18T20:39:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Subject: Re: [PATCH 1/3] Make refs_ref_exists public\n\nDocumentation/SubmittingPatches[[describe-changes]]\n\nApplies to all three patches and probably other recent topics from\nyou.\n\n> From: Han-Wen Nienhuys <hanwen@google.com>\n>\n> Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n> ---\n>  refs.c | 2 +-\n>  refs.h | 2 ++\n>  2 files changed, 3 insertions(+), 1 deletion(-)\n>\n> diff --git a/refs.c b/refs.c\n> index cf91711968..d46080f4b6 100644\n> --- a/refs.c\n> +++ b/refs.c\n> @@ -313,7 +313,7 @@ int read_ref(const char *refname, struct object_id *oid)\n>  \treturn read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);\n>  }\n>  \n> -static int refs_ref_exists(struct ref_store *refs, const char *refname)\n> +int refs_ref_exists(struct ref_store *refs, const char *refname)\n>  {\n>  \treturn !!refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING, NULL, NULL);\n>  }\n> diff --git a/refs.h b/refs.h\n> index 29e28124cd..04bd25019f 100644\n> --- a/refs.h\n> +++ b/refs.h\n> @@ -105,6 +105,8 @@ int refs_verify_refname_available(struct ref_store *refs,\n>  \t\t\t\t  const struct string_list *skip,\n>  \t\t\t\t  struct strbuf *err);\n>  \n> +int refs_ref_exists(struct ref_store *refs, const char *refname);\n> +\n>  int ref_exists(const char *refname);\n>  \n>  int should_autocreate_reflog(const char *refname);\n"},{"id":"403974","messageId":"xmqqsgcjwtpv.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"06a8e8cbd1370ba3d4ea8a0a9f1e69d27b1d62c4.1597753075.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/3] Treat CHERRY_PICK_HEAD as a pseudo ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-18T21:05:16Z","receivedAt":"2020-08-18T21:05:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Han-Wen Nienhuys <hanwen@google.com>\n>\n> Check for existence and delete CHERRY_PICK_HEAD through ref functions.\n> This will help cherry-pick work with alternate ref storage backends.\n\nThese two sentences are true, but this patch does another thing that\nis not advertised here.  It stops recommending removal of\nCHERRY_PICK_HEAD from the filesystem with \"rm\" (or using \"git\nupdate-ref -d\" for that matter) as a way to avoid recording the\ncurrent commit as a cherry-pick.\n\nThe intent of the warning message touched by this patch, I think, is\nthat there is CHERRY_PICK_HEAD, but that might be a leftover one\nthat does not have to do anything to do with the commit the user is\nmaking, and continuing blindly may record the commit incorrectly\n(perhaps 'cherry-picked-from' trailer is added incorrectly?\nexisting notes data would be copied to the newly created commit?).\n\nTo recover from the situation, the user would want to abort the\ncommit while keeping the changes made to the working tree and to the\nindex to avoid the result recorded as a cherry-pick of an irrelevant\ncommit, get rid of CHERRY_PICK_HEAD and then attempt the \"git\ncommit\" again.\n\nDoes \"git cherry-pick --abort\" only remove CHERRY_PICK_HEAD without\ndoing any other damage to the working tree files and to the index?\n\n> Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n> ---\n>  builtin/commit.c | 34 +++++++++++++++++++---------------\n>  builtin/merge.c  |  2 +-\n>  path.c           |  1 -\n>  path.h           |  7 ++++---\n>  sequencer.c      | 42 ++++++++++++++++++++++++++----------------\n>  wt-status.c      |  4 ++--\n>  6 files changed, 52 insertions(+), 38 deletions(-)\n>\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 69ac78d5e5..619b71bcb4 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -847,21 +847,25 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n>  \t\t\tif (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&\n>  \t\t\t\t!merge_contains_scissors)\n>  \t\t\t\twt_status_add_cut_line(s->fp);\n> -\t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n> -\t\t\t    whence == FROM_MERGE\n> -\t\t\t\t? _(\"\\n\"\n> -\t\t\t\t\t\"It looks like you may be committing a merge.\\n\"\n> -\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n> -\t\t\t\t\t\"\t%s\\n\"\n> -\t\t\t\t\t\"and try again.\\n\")\n> -\t\t\t\t: _(\"\\n\"\n> -\t\t\t\t\t\"It looks like you may be committing a cherry-pick.\\n\"\n> -\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n> -\t\t\t\t\t\"\t%s\\n\"\n> -\t\t\t\t\t\"and try again.\\n\"),\n> -\t\t\t\twhence == FROM_MERGE ?\n> -\t\t\t\t\tgit_path_merge_head(the_repository) :\n> -\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n> +\t\t\tif (whence == FROM_MERGE)\n> +\t\t\t\tstatus_printf_ln(\n> +\t\t\t\t\ts, GIT_COLOR_NORMAL,\n> +\n> +\t\t\t\t\t_(\"\\n\"\n> +\t\t\t\t\t  \"It looks like you may be committing a merge.\\n\"\n> +\t\t\t\t\t  \"If this is not correct, please remove the file\\n\"\n> +\t\t\t\t\t  \"\t%s\\n\"\n> +\t\t\t\t\t  \"and try again.\\n\"),\n> +\t\t\t\t\tgit_path_merge_head(the_repository));\n> +\t\t\telse\n> +\t\t\t\tstatus_printf_ln(\n> +\t\t\t\t\ts, GIT_COLOR_NORMAL,\n> +\n> +\t\t\t\t\t_(\"\\n\"\n> +\t\t\t\t\t  \"It looks like you may be committing a cherry-pick.\\n\"\n> +\t\t\t\t\t  \"If this is not correct, please run\\n\"\n> +\t\t\t\t\t  \"\tgit cherry-pick --abort\\n\"\n> +\t\t\t\t\t  \"and try again.\\n\"));\n>  \t\t}\n\nI do not know about this change (see above).\n\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index 74829a838e..b9a89ba858 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -1348,7 +1348,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\telse\n>  \t\t\tdie(_(\"You have not concluded your merge (MERGE_HEAD exists).\"));\n>  \t}\n> -\tif (file_exists(git_path_cherry_pick_head(the_repository))) {\n> +\tif (ref_exists(\"CHERRY_PICK_HEAD\")) {\n\nThis, and all the rest, look quite sensible.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index d75399085d..c6abf2f3ca 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -1672,8 +1672,8 @@ void wt_status_get_state(struct repository *r,\n>  \t\tstate->merge_in_progress = 1;\n>  \t} else if (wt_status_check_rebase(NULL, state)) {\n>  \t\t;\t\t/* all set */\n> -\t} else if (!stat(git_path_cherry_pick_head(r), &st) &&\n> -\t\t\t!get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n> +\t} else if (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n> +\t\t   !get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n>  \t\tstate->cherry_pick_in_progress = 1;\n>  \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n>  \t}\n"},{"id":"403975","messageId":"xmqqo8n7wtne.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"173d81dbb41c3a7f4ab5187c1a056da182c4f6e5.1597753075.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 3/3] Treat REVERT_HEAD as a pseudo ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-18T21:06:45Z","receivedAt":"2020-08-18T21:06:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Han-Wen Nienhuys <hanwen@google.com>\n>\n> Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n> ---\n\nThis does what was advertised by the proposed log message in the\nprevious patch for REVERT_HEAD.  I see nothing questionable here.\n\nNice.\n"},{"id":"404017","messageId":"CAFQ2z_PYpP4WdUaaG4=fOQ_7RLLmGLjuBQaE2yQVA9=7j9XcuQ@mail.gmail.com","threadId":"54062","inReplyTo":"xmqqsgcjwtpv.fsf@gitster.c.googlers.com","subject":"Re: [PATCH 2/3] Treat CHERRY_PICK_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys","fromEmail":"hanwen@google.com","sentAt":"2020-08-19T15:04:22Z","receivedAt":"2020-08-19T15:04:57Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"On Tue, Aug 18, 2020 at 11:05 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> \"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n> > From: Han-Wen Nienhuys <hanwen@google.com>\n> >\n> > Check for existence and delete CHERRY_PICK_HEAD through ref functions.\n> > This will help cherry-pick work with alternate ref storage backends.\n>\n> These two sentences are true, but this patch does another thing that\n> is not advertised here.  It stops recommending removal of\n> CHERRY_PICK_HEAD from the filesystem with \"rm\" (or using \"git\n> update-ref -d\" for that matter) as a way to avoid recording the\n> current commit as a cherry-pick.\n..\n> Does \"git cherry-pick --abort\" only remove CHERRY_PICK_HEAD without\n> doing any other damage to the working tree files and to the index?\n\nGood catch. I just added cherry-pick --abort without much thinking. I\nreverted to update-ref -d which should be equivalent to what is\ncurrently recommended.\n\n-- \nHan-Wen Nienhuys - Google Munich\nI work 80%. Don't expect answers from me on Fridays.\n--\n\nGoogle Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich\n\nRegistergericht und -nummer: Hamburg, HRB 86891\n\nSitz der Gesellschaft: Hamburg\n\nGeschäftsführer: Paul Manicle, Halimah DeLaine Prado\n"},{"id":"404022","messageId":"pull.706.v2.git.1597850128.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.git.1597753075.gitgitgadget@gmail.com","subject":"[PATCH v2 0/4] Use refs API for handling sundry pseudorefs","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-19T15:15:23Z","receivedAt":"2020-08-19T15:15:40Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"This series changes the handling of CHERRY_PICK_HEAD and REVERT_HEAD to use\nthe refs API, as a preliminary refactor for reftable. \n\nNo functional changes.\n\nHan-Wen Nienhuys (4):\n  refs: make refs_ref_exists public\n  sequencer: treat CHERRY_PICK_HEAD as a pseudo ref\n  builtin/commit: suggest update-ref for pseudoref removal\n  sequencer: treat REVERT_HEAD as a pseudo ref\n\n builtin/commit.c | 30 +++++++++++++-------------\n builtin/merge.c  |  2 +-\n path.c           |  2 --\n path.h           |  9 ++++----\n refs.c           |  2 +-\n refs.h           |  2 ++\n sequencer.c      | 56 +++++++++++++++++++++++++++++-------------------\n wt-status.c      |  6 +++---\n 8 files changed, 60 insertions(+), 49 deletions(-)\n\n\nbase-commit: 2befe97201e1f3175cce557866c5822793624b5a\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-706%2Fhanwen%2Fstray-pseudorefs-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-706/hanwen/stray-pseudorefs-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/706\n\nRange-diff vs v1:\n\n 1:  5e29fa74dc ! 1:  a8467a0d66 Make refs_ref_exists public\n     @@ Metadata\n      Author: Han-Wen Nienhuys <hanwen@google.com>\n      \n       ## Commit message ##\n     -    Make refs_ref_exists public\n     +    refs: make refs_ref_exists public\n     +\n     +    This will be necessary to replace file existence checks for pseudorefs.\n      \n          Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n      \n 2:  06a8e8cbd1 ! 2:  2797e98446 Treat CHERRY_PICK_HEAD as a pseudo ref\n     @@ Metadata\n      Author: Han-Wen Nienhuys <hanwen@google.com>\n      \n       ## Commit message ##\n     -    Treat CHERRY_PICK_HEAD as a pseudo ref\n     +    sequencer: treat CHERRY_PICK_HEAD as a pseudo ref\n      \n          Check for existence and delete CHERRY_PICK_HEAD through ref functions.\n          This will help cherry-pick work with alternate ref storage backends.\n      \n          Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n      \n     - ## builtin/commit.c ##\n     -@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const char *prefix,\n     - \t\t\tif (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&\n     - \t\t\t\t!merge_contains_scissors)\n     - \t\t\t\twt_status_add_cut_line(s->fp);\n     --\t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n     --\t\t\t    whence == FROM_MERGE\n     --\t\t\t\t? _(\"\\n\"\n     --\t\t\t\t\t\"It looks like you may be committing a merge.\\n\"\n     --\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n     --\t\t\t\t\t\"\t%s\\n\"\n     --\t\t\t\t\t\"and try again.\\n\")\n     --\t\t\t\t: _(\"\\n\"\n     --\t\t\t\t\t\"It looks like you may be committing a cherry-pick.\\n\"\n     --\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n     --\t\t\t\t\t\"\t%s\\n\"\n     --\t\t\t\t\t\"and try again.\\n\"),\n     --\t\t\t\twhence == FROM_MERGE ?\n     --\t\t\t\t\tgit_path_merge_head(the_repository) :\n     --\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n     -+\t\t\tif (whence == FROM_MERGE)\n     -+\t\t\t\tstatus_printf_ln(\n     -+\t\t\t\t\ts, GIT_COLOR_NORMAL,\n     -+\n     -+\t\t\t\t\t_(\"\\n\"\n     -+\t\t\t\t\t  \"It looks like you may be committing a merge.\\n\"\n     -+\t\t\t\t\t  \"If this is not correct, please remove the file\\n\"\n     -+\t\t\t\t\t  \"\t%s\\n\"\n     -+\t\t\t\t\t  \"and try again.\\n\"),\n     -+\t\t\t\t\tgit_path_merge_head(the_repository));\n     -+\t\t\telse\n     -+\t\t\t\tstatus_printf_ln(\n     -+\t\t\t\t\ts, GIT_COLOR_NORMAL,\n     -+\n     -+\t\t\t\t\t_(\"\\n\"\n     -+\t\t\t\t\t  \"It looks like you may be committing a cherry-pick.\\n\"\n     -+\t\t\t\t\t  \"If this is not correct, please run\\n\"\n     -+\t\t\t\t\t  \"\tgit cherry-pick --abort\\n\"\n     -+\t\t\t\t\t  \"and try again.\\n\"));\n     - \t\t}\n     - \n     - \t\tfprintf(s->fp, \"\\n\");\n     -\n       ## builtin/merge.c ##\n      @@ builtin/merge.c: int cmd_merge(int argc, const char **argv, const char *prefix)\n       \t\telse\n -:  ---------- > 3:  2681638651 builtin/commit: suggest update-ref for pseudoref removal\n 3:  173d81dbb4 ! 4:  9dcc10f807 Treat REVERT_HEAD as a pseudo ref\n     @@ Metadata\n      Author: Han-Wen Nienhuys <hanwen@google.com>\n      \n       ## Commit message ##\n     -    Treat REVERT_HEAD as a pseudo ref\n     +    sequencer: treat REVERT_HEAD as a pseudo ref\n      \n          Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n      \n\n-- \ngitgitgadget\n"},{"id":"404023","messageId":"a8467a0d66d1291970a182f4dcad77dca1a0f196.1597850128.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v2.git.1597850128.gitgitgadget@gmail.com","subject":"[PATCH v2 1/4] refs: make refs_ref_exists public","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-19T15:15:24Z","receivedAt":"2020-08-19T15:15:40Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nThis will be necessary to replace file existence checks for pseudorefs.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n refs.c | 2 +-\n refs.h | 2 ++\n 2 files changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/refs.c b/refs.c\nindex cf91711968..d46080f4b6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -313,7 +313,7 @@ int read_ref(const char *refname, struct object_id *oid)\n \treturn read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);\n }\n \n-static int refs_ref_exists(struct ref_store *refs, const char *refname)\n+int refs_ref_exists(struct ref_store *refs, const char *refname)\n {\n \treturn !!refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING, NULL, NULL);\n }\ndiff --git a/refs.h b/refs.h\nindex 29e28124cd..04bd25019f 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -105,6 +105,8 @@ int refs_verify_refname_available(struct ref_store *refs,\n \t\t\t\t  const struct string_list *skip,\n \t\t\t\t  struct strbuf *err);\n \n+int refs_ref_exists(struct ref_store *refs, const char *refname);\n+\n int ref_exists(const char *refname);\n \n int should_autocreate_reflog(const char *refname);\n-- \ngitgitgadget\n\n"},{"id":"404024","messageId":"2797e98446deba2756eb8433141514253a54a604.1597850128.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v2.git.1597850128.gitgitgadget@gmail.com","subject":"[PATCH v2 2/4] sequencer: treat CHERRY_PICK_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-19T15:15:25Z","receivedAt":"2020-08-19T15:15:51Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nCheck for existence and delete CHERRY_PICK_HEAD through ref functions.\nThis will help cherry-pick work with alternate ref storage backends.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n builtin/merge.c |  2 +-\n path.c          |  1 -\n path.h          |  7 ++++---\n sequencer.c     | 42 ++++++++++++++++++++++++++----------------\n wt-status.c     |  4 ++--\n 5 files changed, 33 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 74829a838e..b9a89ba858 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1348,7 +1348,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\telse\n \t\t\tdie(_(\"You have not concluded your merge (MERGE_HEAD exists).\"));\n \t}\n-\tif (file_exists(git_path_cherry_pick_head(the_repository))) {\n+\tif (ref_exists(\"CHERRY_PICK_HEAD\")) {\n \t\tif (advice_resolve_conflict)\n \t\t\tdie(_(\"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\\n\"\n \t\t\t    \"Please, commit your changes before you merge.\"));\ndiff --git a/path.c b/path.c\nindex 8b2c753191..783cc2ae81 100644\n--- a/path.c\n+++ b/path.c\n@@ -1528,7 +1528,6 @@ char *xdg_cache_home(const char *filename)\n \treturn NULL;\n }\n \n-REPO_GIT_PATH_FUNC(cherry_pick_head, \"CHERRY_PICK_HEAD\")\n REPO_GIT_PATH_FUNC(revert_head, \"REVERT_HEAD\")\n REPO_GIT_PATH_FUNC(squash_msg, \"SQUASH_MSG\")\n REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\ndiff --git a/path.h b/path.h\nindex 1f1bf8f87a..8941c018a9 100644\n--- a/path.h\n+++ b/path.h\n@@ -170,7 +170,6 @@ void report_linked_checkout_garbage(void);\n \t}\n \n struct path_cache {\n-\tconst char *cherry_pick_head;\n \tconst char *revert_head;\n \tconst char *squash_msg;\n \tconst char *merge_msg;\n@@ -182,9 +181,11 @@ struct path_cache {\n \tconst char *shallow;\n };\n \n-#define PATH_CACHE_INIT { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }\n+#define PATH_CACHE_INIT                                              \\\n+\t{                                                            \\\n+\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n+\t}\n \n-const char *git_path_cherry_pick_head(struct repository *r);\n const char *git_path_revert_head(struct repository *r);\n const char *git_path_squash_msg(struct repository *r);\n const char *git_path_merge_msg(struct repository *r);\ndiff --git a/sequencer.c b/sequencer.c\nindex cc3f8fa88e..09e2ff659e 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -381,7 +381,8 @@ static void print_advice(struct repository *r, int show_hint,\n \t\t * (typically rebase --interactive) wants to take care\n \t\t * of the commit itself so remove CHERRY_PICK_HEAD\n \t\t */\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\treturn;\n \t}\n \n@@ -1455,7 +1456,8 @@ static int do_commit(struct repository *r,\n \t\t\t\t    author, opts, flags, &oid);\n \t\tstrbuf_release(&sb);\n \t\tif (!res) {\n-\t\t\tunlink(git_path_cherry_pick_head(r));\n+\t\t\trefs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t\t\"CHERRY_PICK_HEAD\", NULL, 0);\n \t\t\tunlink(git_path_merge_msg(r));\n \t\t\tif (!is_rebase_i(opts))\n \t\t\t\tprint_commit_summary(r, NULL, &oid,\n@@ -1966,7 +1968,8 @@ static int do_pick_commit(struct repository *r,\n \t\tflags |= ALLOW_EMPTY;\n \t} else if (allow == 2) {\n \t\tdrop_commit = 1;\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\tunlink(git_path_merge_msg(r));\n \t\tfprintf(stderr,\n \t\t\t_(\"dropping %s %s -- patch contents already upstream\\n\"),\n@@ -2305,8 +2308,10 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)\n \tstruct replay_opts opts = REPLAY_OPTS_INIT;\n \tint need_cleanup = 0;\n \n-\tif (file_exists(git_path_cherry_pick_head(r))) {\n-\t\tif (!unlink(git_path_cherry_pick_head(r)) && verbose)\n+\tif (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\")) {\n+\t\tif (!refs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t     \"CHERRY_PICK_HEAD\", NULL, 0) &&\n+\t\t    verbose)\n \t\t\twarning(_(\"cancelling a cherry picking in progress\"));\n \t\topts.action = REPLAY_PICK;\n \t\tneed_cleanup = 1;\n@@ -2671,8 +2676,9 @@ static int create_seq_dir(struct repository *r)\n \tenum replay_action action;\n \tconst char *in_progress_error = NULL;\n \tconst char *in_progress_advice = NULL;\n-\tunsigned int advise_skip = file_exists(git_path_revert_head(r)) ||\n-\t\t\t\tfile_exists(git_path_cherry_pick_head(r));\n+\tunsigned int advise_skip =\n+\t\tfile_exists(git_path_revert_head(r)) ||\n+\t\trefs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\");\n \n \tif (!sequencer_get_last_command(r, &action)) {\n \t\tswitch (action) {\n@@ -2771,7 +2777,7 @@ static int rollback_single_pick(struct repository *r)\n {\n \tstruct object_id head_oid;\n \n-\tif (!file_exists(git_path_cherry_pick_head(r)) &&\n+\tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n \t    !file_exists(git_path_revert_head(r)))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \tif (read_ref_full(\"HEAD\", 0, &head_oid, NULL))\n@@ -2874,7 +2880,8 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)\n \t\t}\n \t\tbreak;\n \tcase REPLAY_PICK:\n-\t\tif (!file_exists(git_path_cherry_pick_head(r))) {\n+\t\tif (!refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t     \"CHERRY_PICK_HEAD\")) {\n \t\t\tif (action != REPLAY_PICK)\n \t\t\t\treturn error(_(\"no cherry-pick in progress\"));\n \t\t\tif (!rollback_is_safe())\n@@ -3569,7 +3576,8 @@ static int do_merge(struct repository *r,\n \t\t\t\t    oid_to_hex(&j->item->object.oid));\n \n \t\tstrbuf_release(&ref_name);\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\trollback_lock_file(&lock);\n \n \t\trollback_lock_file(&lock);\n@@ -4201,7 +4209,7 @@ static int continue_single_pick(struct repository *r)\n {\n \tconst char *argv[] = { \"commit\", NULL };\n \n-\tif (!file_exists(git_path_cherry_pick_head(r)) &&\n+\tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n \t    !file_exists(git_path_revert_head(r)))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n@@ -4318,9 +4326,10 @@ static int commit_staged_changes(struct repository *r,\n \t}\n \n \tif (is_clean) {\n-\t\tconst char *cherry_pick_head = git_path_cherry_pick_head(r);\n-\n-\t\tif (file_exists(cherry_pick_head) && unlink(cherry_pick_head))\n+\t\tif (refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t    \"CHERRY_PICK_HEAD\") &&\n+\t\t    refs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t    \"CHERRY_PICK_HEAD\", NULL, 0))\n \t\t\treturn error(_(\"could not remove CHERRY_PICK_HEAD\"));\n \t\tif (!final_fixup)\n \t\t\treturn 0;\n@@ -4379,7 +4388,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \n \tif (!is_rebase_i(opts)) {\n \t\t/* Verify that the conflict has been resolved */\n-\t\tif (file_exists(git_path_cherry_pick_head(r)) ||\n+\t\tif (refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t    \"CHERRY_PICK_HEAD\") ||\n \t\t    file_exists(git_path_revert_head(r))) {\n \t\t\tres = continue_single_pick(r);\n \t\t\tif (res)\n@@ -5442,7 +5452,7 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)\n \n int sequencer_determine_whence(struct repository *r, enum commit_whence *whence)\n {\n-\tif (file_exists(git_path_cherry_pick_head(r))) {\n+\tif (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\")) {\n \t\tstruct object_id cherry_pick_head, rebase_head;\n \n \t\tif (file_exists(git_path_seq_dir()))\ndiff --git a/wt-status.c b/wt-status.c\nindex d75399085d..c6abf2f3ca 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1672,8 +1672,8 @@ void wt_status_get_state(struct repository *r,\n \t\tstate->merge_in_progress = 1;\n \t} else if (wt_status_check_rebase(NULL, state)) {\n \t\t;\t\t/* all set */\n-\t} else if (!stat(git_path_cherry_pick_head(r), &st) &&\n-\t\t\t!get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n+\t} else if (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n+\t\t   !get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n \t\tstate->cherry_pick_in_progress = 1;\n \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n \t}\n-- \ngitgitgadget\n\n"},{"id":"404025","messageId":"2681638651debf267bbe7e45e41decca5852808b.1597850128.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v2.git.1597850128.gitgitgadget@gmail.com","subject":"[PATCH v2 3/4] builtin/commit: suggest update-ref for pseudoref removal","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-19T15:15:26Z","receivedAt":"2020-08-19T15:15:55Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nWhen pseudorefs move to a different ref storage mechanism, pseudorefs no longer\ncan be removed with 'rm'. Instead, suggest a \"update-ref -d\" command, which will\nwork regardless of ref storage backend.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n builtin/commit.c | 30 +++++++++++++++---------------\n 1 file changed, 15 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 69ac78d5e5..a4e5e395ba 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -844,24 +844,24 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\tstruct ident_split ci, ai;\n \n \t\tif (whence != FROM_COMMIT) {\n+\t\t\tconst char *pseudoref = (whence == FROM_MERGE) ?\n+\t\t\t\t\t\t\t      \"MERGE_HEAD\" :\n+\t\t\t\t\t\t\t      \"CHERRY_PICK_HEAD\";\n+\t\t\tconst char *what = (whence == FROM_MERGE) ?\n+\t\t\t\t\t\t\t \"merge\" :\n+\t\t\t\t\t\t\t \"cherry-pick\";\n+\n \t\t\tif (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&\n \t\t\t\t!merge_contains_scissors)\n \t\t\t\twt_status_add_cut_line(s->fp);\n-\t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n-\t\t\t    whence == FROM_MERGE\n-\t\t\t\t? _(\"\\n\"\n-\t\t\t\t\t\"It looks like you may be committing a merge.\\n\"\n-\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n-\t\t\t\t\t\"\t%s\\n\"\n-\t\t\t\t\t\"and try again.\\n\")\n-\t\t\t\t: _(\"\\n\"\n-\t\t\t\t\t\"It looks like you may be committing a cherry-pick.\\n\"\n-\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n-\t\t\t\t\t\"\t%s\\n\"\n-\t\t\t\t\t\"and try again.\\n\"),\n-\t\t\t\twhence == FROM_MERGE ?\n-\t\t\t\t\tgit_path_merge_head(the_repository) :\n-\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n+\t\t\tstatus_printf_ln(\n+\t\t\t\ts, GIT_COLOR_NORMAL,\n+\t\t\t\t_(\"\\n\"\n+\t\t\t\t  \"It looks like you may be committing a %s.\\n\"\n+\t\t\t\t  \"If this is not correct, please remove %s with\\n\"\n+\t\t\t\t  \"\tgit update-ref -d %s\\n\"\n+\t\t\t\t  \"and try again.\\n\"),\n+\t\t\t\twhat, pseudoref, pseudoref);\n \t\t}\n \n \t\tfprintf(s->fp, \"\\n\");\n-- \ngitgitgadget\n\n"},{"id":"404026","messageId":"9dcc10f80702754ace48f6aa1915ee7afe5b506e.1597850128.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v2.git.1597850128.gitgitgadget@gmail.com","subject":"[PATCH v2 4/4] sequencer: treat REVERT_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-19T15:15:27Z","receivedAt":"2020-08-19T15:15:59Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n path.c      |  1 -\n path.h      |  8 +++-----\n sequencer.c | 16 +++++++++-------\n wt-status.c |  2 +-\n 4 files changed, 13 insertions(+), 14 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 783cc2ae81..7b385e5eb2 100644\n--- a/path.c\n+++ b/path.c\n@@ -1528,7 +1528,6 @@ char *xdg_cache_home(const char *filename)\n \treturn NULL;\n }\n \n-REPO_GIT_PATH_FUNC(revert_head, \"REVERT_HEAD\")\n REPO_GIT_PATH_FUNC(squash_msg, \"SQUASH_MSG\")\n REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\n REPO_GIT_PATH_FUNC(merge_rr, \"MERGE_RR\")\ndiff --git a/path.h b/path.h\nindex 8941c018a9..e7e77da6aa 100644\n--- a/path.h\n+++ b/path.h\n@@ -170,7 +170,6 @@ void report_linked_checkout_garbage(void);\n \t}\n \n struct path_cache {\n-\tconst char *revert_head;\n \tconst char *squash_msg;\n \tconst char *merge_msg;\n \tconst char *merge_rr;\n@@ -181,12 +180,11 @@ struct path_cache {\n \tconst char *shallow;\n };\n \n-#define PATH_CACHE_INIT                                              \\\n-\t{                                                            \\\n-\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n+#define PATH_CACHE_INIT                                        \\\n+\t{                                                      \\\n+\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n \t}\n \n-const char *git_path_revert_head(struct repository *r);\n const char *git_path_squash_msg(struct repository *r);\n const char *git_path_merge_msg(struct repository *r);\n const char *git_path_merge_rr(struct repository *r);\ndiff --git a/sequencer.c b/sequencer.c\nindex 09e2ff659e..d116ea69bd 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2317,8 +2317,10 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)\n \t\tneed_cleanup = 1;\n \t}\n \n-\tif (file_exists(git_path_revert_head(r))) {\n-\t\tif (!unlink(git_path_revert_head(r)) && verbose)\n+\tif (refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n+\t\tif (!refs_delete_ref(get_main_ref_store(r), \"\", \"REVERT_HEAD\",\n+\t\t\t\t     NULL, 0) &&\n+\t\t    verbose)\n \t\t\twarning(_(\"cancelling a revert in progress\"));\n \t\topts.action = REPLAY_REVERT;\n \t\tneed_cleanup = 1;\n@@ -2677,7 +2679,7 @@ static int create_seq_dir(struct repository *r)\n \tconst char *in_progress_error = NULL;\n \tconst char *in_progress_advice = NULL;\n \tunsigned int advise_skip =\n-\t\tfile_exists(git_path_revert_head(r)) ||\n+\t\trefs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\") ||\n \t\trefs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\");\n \n \tif (!sequencer_get_last_command(r, &action)) {\n@@ -2778,7 +2780,7 @@ static int rollback_single_pick(struct repository *r)\n \tstruct object_id head_oid;\n \n \tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n-\t    !file_exists(git_path_revert_head(r)))\n+\t    !refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\"))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \tif (read_ref_full(\"HEAD\", 0, &head_oid, NULL))\n \t\treturn error(_(\"cannot resolve HEAD\"));\n@@ -2872,7 +2874,7 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)\n \t */\n \tswitch (opts->action) {\n \tcase REPLAY_REVERT:\n-\t\tif (!file_exists(git_path_revert_head(r))) {\n+\t\tif (!refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n \t\t\tif (action != REPLAY_REVERT)\n \t\t\t\treturn error(_(\"no revert in progress\"));\n \t\t\tif (!rollback_is_safe())\n@@ -4210,7 +4212,7 @@ static int continue_single_pick(struct repository *r)\n \tconst char *argv[] = { \"commit\", NULL };\n \n \tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n-\t    !file_exists(git_path_revert_head(r)))\n+\t    !refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\"))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n }\n@@ -4390,7 +4392,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t/* Verify that the conflict has been resolved */\n \t\tif (refs_ref_exists(get_main_ref_store(r),\n \t\t\t\t    \"CHERRY_PICK_HEAD\") ||\n-\t\t    file_exists(git_path_revert_head(r))) {\n+\t\t    refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n \t\t\tres = continue_single_pick(r);\n \t\t\tif (res)\n \t\t\t\tgoto release_todo_list;\ndiff --git a/wt-status.c b/wt-status.c\nindex c6abf2f3ca..ecbe570e28 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1678,7 +1678,7 @@ void wt_status_get_state(struct repository *r,\n \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n \t}\n \twt_status_check_bisect(NULL, state);\n-\tif (!stat(git_path_revert_head(r), &st) &&\n+\tif (refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\") &&\n \t    !get_oid(\"REVERT_HEAD\", &oid)) {\n \t\tstate->revert_in_progress = 1;\n \t\toidcpy(&state->revert_head_oid, &oid);\n-- \ngitgitgadget\n"},{"id":"404032","messageId":"xmqqa6yqvcik.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"CAFQ2z_PYpP4WdUaaG4=fOQ_7RLLmGLjuBQaE2yQVA9=7j9XcuQ@mail.gmail.com","subject":"Re: [PATCH 2/3] Treat CHERRY_PICK_HEAD as a pseudo ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-19T16:14:27Z","receivedAt":"2020-08-19T16:14:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Han-Wen Nienhuys <hanwen@google.com> writes:\n\n>> Does \"git cherry-pick --abort\" only remove CHERRY_PICK_HEAD without\n>> doing any other damage to the working tree files and to the index?\n>\n> Good catch. I just added cherry-pick --abort without much thinking. I\n> reverted to update-ref -d which should be equivalent to what is\n> currently recommended.\n\nI think that is a good change, although it is unfortunate that the\ncommand line completion considers \"git update-ref -d CHERRY_P<TAB>\"\nsomething it should help the user with.\n\nI tried \"cherry-pick --abort\" to see what happens after\n\n    $ edit A B\n    $ git add A\n    $ git rev-parse HEAD~200 >.git/CHERRY_PICK_HEAD\n    $ git commit\n\nand aborting the last \"git commit\" step.  As \"cherry-pick --abort\"\ninvolves running \"git reset --merge\" internally, of course some\nstates the user wanted to commit were wiped out and lost.\n\nThanks.\n\n"},{"id":"404068","messageId":"xmqqwo1us506.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"2681638651debf267bbe7e45e41decca5852808b.1597850128.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 3/4] builtin/commit: suggest update-ref for pseudoref removal","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-19T21:24:57Z","receivedAt":"2020-08-19T21:25:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Han-Wen Nienhuys <hanwen@google.com>\n>\n> When pseudorefs move to a different ref storage mechanism, pseudorefs no longer\n> can be removed with 'rm'. Instead, suggest a \"update-ref -d\" command, which will\n> work regardless of ref storage backend.\n>\n> Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>\n> ---\n>  builtin/commit.c | 30 +++++++++++++++---------------\n>  1 file changed, 15 insertions(+), 15 deletions(-)\n\nThe spirit is good, but the execution of this patch hurts i18n by\nconsolidating messages that have been deliberately split and\nduplicated to avoid sentence lego.  Limiting the scope of the change\nto doing\n\n    -please remove the file\n    -    %s\n    +please remove %s with\n    +    git update-ref -d '%s'\n\ntwice may be (unfortunately) more preferrable.\n\nAs we'd be repeating the same pseudoref variable twice, introduction\nof an extra variable pseudoref may be a good idea.\n\nOr would it work better to use %1$s twice, e.g.\n\n    status_printf_ln(...\n\t\t     _(...\n\t\t\t\"... please remove %1$s with\\n\"\n\t\t\t\"    git update-ref -d '%1$s'\\n\"\n\t\t\t\"and try again.\\n\"), pseudoref);\n\nI dunno.\n"},{"id":"404141","messageId":"CAFQ2z_O52ymKhkmWQpKSq1cMoxXBf=93HDN1YPzmQ4Kt-d2JYw@mail.gmail.com","threadId":"54062","inReplyTo":"xmqqwo1us506.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 3/4] builtin/commit: suggest update-ref for pseudoref removal","fromName":"Han-Wen Nienhuys","fromEmail":"hanwen@google.com","sentAt":"2020-08-21T14:57:21Z","receivedAt":"2020-08-21T14:57:40Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"On Wed, Aug 19, 2020 at 11:25 PM Junio C Hamano <gitster@pobox.com> wrote:\n> The spirit is good, but the execution of this patch hurts i18n by\n> consolidating messages that have been deliberately split and\n> duplicated to avoid sentence lego.  Limiting the scope of the change\n> to doing\n\nFair enough. I've just written out the complete command in the next version.\n\n-- \nHan-Wen Nienhuys - Google Munich\nI work 80%. Don't expect answers from me on Fridays.\n--\n\nGoogle Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich\n\nRegistergericht und -nummer: Hamburg, HRB 86891\n\nSitz der Gesellschaft: Hamburg\n\nGeschäftsführer: Paul Manicle, Halimah DeLaine Prado\n"},{"id":"404152","messageId":"9ba013664584087edcc3bc7101ef0d207b1f8b7d.1598029177.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v3.git.1598029177.gitgitgadget@gmail.com","subject":"[PATCH v3 4/4] sequencer: treat REVERT_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-21T16:59:37Z","receivedAt":"2020-08-21T17:00:54Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n path.c      |  1 -\n path.h      |  8 +++-----\n sequencer.c | 16 +++++++++-------\n wt-status.c |  2 +-\n 4 files changed, 13 insertions(+), 14 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 783cc2ae81..7b385e5eb2 100644\n--- a/path.c\n+++ b/path.c\n@@ -1528,7 +1528,6 @@ char *xdg_cache_home(const char *filename)\n \treturn NULL;\n }\n \n-REPO_GIT_PATH_FUNC(revert_head, \"REVERT_HEAD\")\n REPO_GIT_PATH_FUNC(squash_msg, \"SQUASH_MSG\")\n REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\n REPO_GIT_PATH_FUNC(merge_rr, \"MERGE_RR\")\ndiff --git a/path.h b/path.h\nindex 8941c018a9..e7e77da6aa 100644\n--- a/path.h\n+++ b/path.h\n@@ -170,7 +170,6 @@ void report_linked_checkout_garbage(void);\n \t}\n \n struct path_cache {\n-\tconst char *revert_head;\n \tconst char *squash_msg;\n \tconst char *merge_msg;\n \tconst char *merge_rr;\n@@ -181,12 +180,11 @@ struct path_cache {\n \tconst char *shallow;\n };\n \n-#define PATH_CACHE_INIT                                              \\\n-\t{                                                            \\\n-\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n+#define PATH_CACHE_INIT                                        \\\n+\t{                                                      \\\n+\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n \t}\n \n-const char *git_path_revert_head(struct repository *r);\n const char *git_path_squash_msg(struct repository *r);\n const char *git_path_merge_msg(struct repository *r);\n const char *git_path_merge_rr(struct repository *r);\ndiff --git a/sequencer.c b/sequencer.c\nindex 3f538a0851..d7db076715 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2317,8 +2317,10 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)\n \t\tneed_cleanup = 1;\n \t}\n \n-\tif (file_exists(git_path_revert_head(r))) {\n-\t\tif (!unlink(git_path_revert_head(r)) && verbose)\n+\tif (refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n+\t\tif (!refs_delete_ref(get_main_ref_store(r), \"\", \"REVERT_HEAD\",\n+\t\t\t\t     NULL, 0) &&\n+\t\t    verbose)\n \t\t\twarning(_(\"cancelling a revert in progress\"));\n \t\topts.action = REPLAY_REVERT;\n \t\tneed_cleanup = 1;\n@@ -2677,7 +2679,7 @@ static int create_seq_dir(struct repository *r)\n \tconst char *in_progress_error = NULL;\n \tconst char *in_progress_advice = NULL;\n \tunsigned int advise_skip =\n-\t\tfile_exists(git_path_revert_head(r)) ||\n+\t\trefs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\") ||\n \t\trefs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\");\n \n \tif (!sequencer_get_last_command(r, &action)) {\n@@ -2778,7 +2780,7 @@ static int rollback_single_pick(struct repository *r)\n \tstruct object_id head_oid;\n \n \tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n-\t    !file_exists(git_path_revert_head(r)))\n+\t    !refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\"))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \tif (read_ref_full(\"HEAD\", 0, &head_oid, NULL))\n \t\treturn error(_(\"cannot resolve HEAD\"));\n@@ -2872,7 +2874,7 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)\n \t */\n \tswitch (opts->action) {\n \tcase REPLAY_REVERT:\n-\t\tif (!file_exists(git_path_revert_head(r))) {\n+\t\tif (!refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n \t\t\tif (action != REPLAY_REVERT)\n \t\t\t\treturn error(_(\"no revert in progress\"));\n \t\t\tif (!rollback_is_safe())\n@@ -4210,7 +4212,7 @@ static int continue_single_pick(struct repository *r)\n \tconst char *argv[] = { \"commit\", NULL };\n \n \tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n-\t    !file_exists(git_path_revert_head(r)))\n+\t    !refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\"))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n }\n@@ -4390,7 +4392,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t/* Verify that the conflict has been resolved */\n \t\tif (refs_ref_exists(get_main_ref_store(r),\n \t\t\t\t    \"CHERRY_PICK_HEAD\") ||\n-\t\t    file_exists(git_path_revert_head(r))) {\n+\t\t    refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\")) {\n \t\t\tres = continue_single_pick(r);\n \t\t\tif (res)\n \t\t\t\tgoto release_todo_list;\ndiff --git a/wt-status.c b/wt-status.c\nindex c6abf2f3ca..ecbe570e28 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1678,7 +1678,7 @@ void wt_status_get_state(struct repository *r,\n \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n \t}\n \twt_status_check_bisect(NULL, state);\n-\tif (!stat(git_path_revert_head(r), &st) &&\n+\tif (refs_ref_exists(get_main_ref_store(r), \"REVERT_HEAD\") &&\n \t    !get_oid(\"REVERT_HEAD\", &oid)) {\n \t\tstate->revert_in_progress = 1;\n \t\toidcpy(&state->revert_head_oid, &oid);\n-- \ngitgitgadget\n"},{"id":"404158","messageId":"5ff5d2c6636ff7ef0c41bae4ce53923925979f0a.1598029177.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v3.git.1598029177.gitgitgadget@gmail.com","subject":"[PATCH v3 2/4] sequencer: treat CHERRY_PICK_HEAD as a pseudo ref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-21T16:59:35Z","receivedAt":"2020-08-21T17:04:34Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nCheck for existence and delete CHERRY_PICK_HEAD through ref functions.\nThis will help cherry-pick work with alternate ref storage backends.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n builtin/merge.c |  2 +-\n path.c          |  1 -\n path.h          |  7 ++++---\n sequencer.c     | 42 ++++++++++++++++++++++++++----------------\n wt-status.c     |  4 ++--\n 5 files changed, 33 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 74829a838e..b9a89ba858 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1348,7 +1348,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\telse\n \t\t\tdie(_(\"You have not concluded your merge (MERGE_HEAD exists).\"));\n \t}\n-\tif (file_exists(git_path_cherry_pick_head(the_repository))) {\n+\tif (ref_exists(\"CHERRY_PICK_HEAD\")) {\n \t\tif (advice_resolve_conflict)\n \t\t\tdie(_(\"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\\n\"\n \t\t\t    \"Please, commit your changes before you merge.\"));\ndiff --git a/path.c b/path.c\nindex 8b2c753191..783cc2ae81 100644\n--- a/path.c\n+++ b/path.c\n@@ -1528,7 +1528,6 @@ char *xdg_cache_home(const char *filename)\n \treturn NULL;\n }\n \n-REPO_GIT_PATH_FUNC(cherry_pick_head, \"CHERRY_PICK_HEAD\")\n REPO_GIT_PATH_FUNC(revert_head, \"REVERT_HEAD\")\n REPO_GIT_PATH_FUNC(squash_msg, \"SQUASH_MSG\")\n REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\ndiff --git a/path.h b/path.h\nindex 1f1bf8f87a..8941c018a9 100644\n--- a/path.h\n+++ b/path.h\n@@ -170,7 +170,6 @@ void report_linked_checkout_garbage(void);\n \t}\n \n struct path_cache {\n-\tconst char *cherry_pick_head;\n \tconst char *revert_head;\n \tconst char *squash_msg;\n \tconst char *merge_msg;\n@@ -182,9 +181,11 @@ struct path_cache {\n \tconst char *shallow;\n };\n \n-#define PATH_CACHE_INIT { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }\n+#define PATH_CACHE_INIT                                              \\\n+\t{                                                            \\\n+\t\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL \\\n+\t}\n \n-const char *git_path_cherry_pick_head(struct repository *r);\n const char *git_path_revert_head(struct repository *r);\n const char *git_path_squash_msg(struct repository *r);\n const char *git_path_merge_msg(struct repository *r);\ndiff --git a/sequencer.c b/sequencer.c\nindex 2425896911..3f538a0851 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -381,7 +381,8 @@ static void print_advice(struct repository *r, int show_hint,\n \t\t * (typically rebase --interactive) wants to take care\n \t\t * of the commit itself so remove CHERRY_PICK_HEAD\n \t\t */\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\treturn;\n \t}\n \n@@ -1455,7 +1456,8 @@ static int do_commit(struct repository *r,\n \t\t\t\t    author, opts, flags, &oid);\n \t\tstrbuf_release(&sb);\n \t\tif (!res) {\n-\t\t\tunlink(git_path_cherry_pick_head(r));\n+\t\t\trefs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t\t\"CHERRY_PICK_HEAD\", NULL, 0);\n \t\t\tunlink(git_path_merge_msg(r));\n \t\t\tif (!is_rebase_i(opts))\n \t\t\t\tprint_commit_summary(r, NULL, &oid,\n@@ -1966,7 +1968,8 @@ static int do_pick_commit(struct repository *r,\n \t\tflags |= ALLOW_EMPTY;\n \t} else if (allow == 2) {\n \t\tdrop_commit = 1;\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\tunlink(git_path_merge_msg(r));\n \t\tfprintf(stderr,\n \t\t\t_(\"dropping %s %s -- patch contents already upstream\\n\"),\n@@ -2305,8 +2308,10 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose)\n \tstruct replay_opts opts = REPLAY_OPTS_INIT;\n \tint need_cleanup = 0;\n \n-\tif (file_exists(git_path_cherry_pick_head(r))) {\n-\t\tif (!unlink(git_path_cherry_pick_head(r)) && verbose)\n+\tif (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\")) {\n+\t\tif (!refs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t     \"CHERRY_PICK_HEAD\", NULL, 0) &&\n+\t\t    verbose)\n \t\t\twarning(_(\"cancelling a cherry picking in progress\"));\n \t\topts.action = REPLAY_PICK;\n \t\tneed_cleanup = 1;\n@@ -2671,8 +2676,9 @@ static int create_seq_dir(struct repository *r)\n \tenum replay_action action;\n \tconst char *in_progress_error = NULL;\n \tconst char *in_progress_advice = NULL;\n-\tunsigned int advise_skip = file_exists(git_path_revert_head(r)) ||\n-\t\t\t\tfile_exists(git_path_cherry_pick_head(r));\n+\tunsigned int advise_skip =\n+\t\tfile_exists(git_path_revert_head(r)) ||\n+\t\trefs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\");\n \n \tif (!sequencer_get_last_command(r, &action)) {\n \t\tswitch (action) {\n@@ -2771,7 +2777,7 @@ static int rollback_single_pick(struct repository *r)\n {\n \tstruct object_id head_oid;\n \n-\tif (!file_exists(git_path_cherry_pick_head(r)) &&\n+\tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n \t    !file_exists(git_path_revert_head(r)))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \tif (read_ref_full(\"HEAD\", 0, &head_oid, NULL))\n@@ -2874,7 +2880,8 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts)\n \t\t}\n \t\tbreak;\n \tcase REPLAY_PICK:\n-\t\tif (!file_exists(git_path_cherry_pick_head(r))) {\n+\t\tif (!refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t     \"CHERRY_PICK_HEAD\")) {\n \t\t\tif (action != REPLAY_PICK)\n \t\t\t\treturn error(_(\"no cherry-pick in progress\"));\n \t\t\tif (!rollback_is_safe())\n@@ -3569,7 +3576,8 @@ static int do_merge(struct repository *r,\n \t\t\t\t    oid_to_hex(&j->item->object.oid));\n \n \t\tstrbuf_release(&ref_name);\n-\t\tunlink(git_path_cherry_pick_head(r));\n+\t\trefs_delete_ref(get_main_ref_store(r), \"\", \"CHERRY_PICK_HEAD\",\n+\t\t\t\tNULL, 0);\n \t\trollback_lock_file(&lock);\n \n \t\trollback_lock_file(&lock);\n@@ -4201,7 +4209,7 @@ static int continue_single_pick(struct repository *r)\n {\n \tconst char *argv[] = { \"commit\", NULL };\n \n-\tif (!file_exists(git_path_cherry_pick_head(r)) &&\n+\tif (!refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n \t    !file_exists(git_path_revert_head(r)))\n \t\treturn error(_(\"no cherry-pick or revert in progress\"));\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n@@ -4318,9 +4326,10 @@ static int commit_staged_changes(struct repository *r,\n \t}\n \n \tif (is_clean) {\n-\t\tconst char *cherry_pick_head = git_path_cherry_pick_head(r);\n-\n-\t\tif (file_exists(cherry_pick_head) && unlink(cherry_pick_head))\n+\t\tif (refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t    \"CHERRY_PICK_HEAD\") &&\n+\t\t    refs_delete_ref(get_main_ref_store(r), \"\",\n+\t\t\t\t    \"CHERRY_PICK_HEAD\", NULL, 0))\n \t\t\treturn error(_(\"could not remove CHERRY_PICK_HEAD\"));\n \t\tif (!final_fixup)\n \t\t\treturn 0;\n@@ -4379,7 +4388,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \n \tif (!is_rebase_i(opts)) {\n \t\t/* Verify that the conflict has been resolved */\n-\t\tif (file_exists(git_path_cherry_pick_head(r)) ||\n+\t\tif (refs_ref_exists(get_main_ref_store(r),\n+\t\t\t\t    \"CHERRY_PICK_HEAD\") ||\n \t\t    file_exists(git_path_revert_head(r))) {\n \t\t\tres = continue_single_pick(r);\n \t\t\tif (res)\n@@ -5443,7 +5453,7 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)\n \n int sequencer_determine_whence(struct repository *r, enum commit_whence *whence)\n {\n-\tif (file_exists(git_path_cherry_pick_head(r))) {\n+\tif (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\")) {\n \t\tstruct object_id cherry_pick_head, rebase_head;\n \n \t\tif (file_exists(git_path_seq_dir()))\ndiff --git a/wt-status.c b/wt-status.c\nindex d75399085d..c6abf2f3ca 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1672,8 +1672,8 @@ void wt_status_get_state(struct repository *r,\n \t\tstate->merge_in_progress = 1;\n \t} else if (wt_status_check_rebase(NULL, state)) {\n \t\t;\t\t/* all set */\n-\t} else if (!stat(git_path_cherry_pick_head(r), &st) &&\n-\t\t\t!get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n+\t} else if (refs_ref_exists(get_main_ref_store(r), \"CHERRY_PICK_HEAD\") &&\n+\t\t   !get_oid(\"CHERRY_PICK_HEAD\", &oid)) {\n \t\tstate->cherry_pick_in_progress = 1;\n \t\toidcpy(&state->cherry_pick_head_oid, &oid);\n \t}\n-- \ngitgitgadget\n\n"},{"id":"404159","messageId":"pull.706.v3.git.1598029177.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v2.git.1597850128.gitgitgadget@gmail.com","subject":"[PATCH v3 0/4] Use refs API for handling sundry pseudorefs","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-21T16:59:33Z","receivedAt":"2020-08-21T17:04:35Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"This series changes the handling of CHERRY_PICK_HEAD and REVERT_HEAD to use\nthe refs API, as a preliminary refactor for reftable. \n\nNo functional changes.\n\nHan-Wen Nienhuys (4):\n  refs: make refs_ref_exists public\n  sequencer: treat CHERRY_PICK_HEAD as a pseudo ref\n  builtin/commit: suggest update-ref for pseudoref removal\n  sequencer: treat REVERT_HEAD as a pseudo ref\n\n builtin/commit.c | 26 +++++++++++-----------\n builtin/merge.c  |  2 +-\n path.c           |  2 --\n path.h           |  9 ++++----\n refs.c           |  2 +-\n refs.h           |  2 ++\n sequencer.c      | 56 +++++++++++++++++++++++++++++-------------------\n wt-status.c      |  6 +++---\n 8 files changed, 57 insertions(+), 48 deletions(-)\n\n\nbase-commit: 675a4aaf3b226c0089108221b96559e0baae5de9\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-706%2Fhanwen%2Fstray-pseudorefs-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-706/hanwen/stray-pseudorefs-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/706\n\nRange-diff vs v2:\n\n 1:  a8467a0d66 = 1:  bfea176682 refs: make refs_ref_exists public\n 2:  2797e98446 = 2:  5ff5d2c663 sequencer: treat CHERRY_PICK_HEAD as a pseudo ref\n 3:  2681638651 ! 3:  8aacde69c8 builtin/commit: suggest update-ref for pseudoref removal\n     @@ Commit message\n      \n       ## builtin/commit.c ##\n      @@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const char *prefix,\n     - \t\tstruct ident_split ci, ai;\n     - \n     - \t\tif (whence != FROM_COMMIT) {\n     -+\t\t\tconst char *pseudoref = (whence == FROM_MERGE) ?\n     -+\t\t\t\t\t\t\t      \"MERGE_HEAD\" :\n     -+\t\t\t\t\t\t\t      \"CHERRY_PICK_HEAD\";\n     -+\t\t\tconst char *what = (whence == FROM_MERGE) ?\n     -+\t\t\t\t\t\t\t \"merge\" :\n     -+\t\t\t\t\t\t\t \"cherry-pick\";\n     -+\n       \t\t\tif (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&\n       \t\t\t\t!merge_contains_scissors)\n       \t\t\t\twt_status_add_cut_line(s->fp);\n     @@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha\n      -\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n      -\t\t\t\t\t\"\t%s\\n\"\n      -\t\t\t\t\t\"and try again.\\n\"),\n     --\t\t\t\twhence == FROM_MERGE ?\n     --\t\t\t\t\tgit_path_merge_head(the_repository) :\n     --\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n      +\t\t\tstatus_printf_ln(\n      +\t\t\t\ts, GIT_COLOR_NORMAL,\n     -+\t\t\t\t_(\"\\n\"\n     -+\t\t\t\t  \"It looks like you may be committing a %s.\\n\"\n     -+\t\t\t\t  \"If this is not correct, please remove %s with\\n\"\n     -+\t\t\t\t  \"\tgit update-ref -d %s\\n\"\n     -+\t\t\t\t  \"and try again.\\n\"),\n     -+\t\t\t\twhat, pseudoref, pseudoref);\n     + \t\t\t\twhence == FROM_MERGE ?\n     +-\t\t\t\t\tgit_path_merge_head(the_repository) :\n     +-\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n     ++\t\t\t\t\t      _(\"\\n\"\n     ++\t\t\t\t\t  \"It looks like you may be committing a merge.\\n\"\n     ++\t\t\t\t\t  \"If this is not correct, please run\\n\"\n     ++\t\t\t\t\t  \"\tgit update-ref -d MERGE_HEAD\\n\"\n     ++\t\t\t\t\t  \"and try again.\\n\") :\n     ++\t\t\t\t\t      _(\"\\n\"\n     ++\t\t\t\t\t  \"It looks like you may be committing a cherry-pick.\\n\"\n     ++\t\t\t\t\t  \"If this is not correct, please run\\n\"\n     ++\t\t\t\t\t  \"\tgit update-ref -d CHERRY_PICK_HEAD\\n\"\n     ++\t\t\t\t\t  \"and try again.\\n\"));\n       \t\t}\n       \n       \t\tfprintf(s->fp, \"\\n\");\n 4:  9dcc10f807 = 4:  9ba0136645 sequencer: treat REVERT_HEAD as a pseudo ref\n\n-- \ngitgitgadget\n"},{"id":"404160","messageId":"bfea176682f271588577be38ecd84b87cfcbd942.1598029177.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v3.git.1598029177.gitgitgadget@gmail.com","subject":"[PATCH v3 1/4] refs: make refs_ref_exists public","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-21T16:59:34Z","receivedAt":"2020-08-21T17:04:41Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nThis will be necessary to replace file existence checks for pseudorefs.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n refs.c | 2 +-\n refs.h | 2 ++\n 2 files changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/refs.c b/refs.c\nindex cf91711968..d46080f4b6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -313,7 +313,7 @@ int read_ref(const char *refname, struct object_id *oid)\n \treturn read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);\n }\n \n-static int refs_ref_exists(struct ref_store *refs, const char *refname)\n+int refs_ref_exists(struct ref_store *refs, const char *refname)\n {\n \treturn !!refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING, NULL, NULL);\n }\ndiff --git a/refs.h b/refs.h\nindex 29e28124cd..04bd25019f 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -105,6 +105,8 @@ int refs_verify_refname_available(struct ref_store *refs,\n \t\t\t\t  const struct string_list *skip,\n \t\t\t\t  struct strbuf *err);\n \n+int refs_ref_exists(struct ref_store *refs, const char *refname);\n+\n int ref_exists(const char *refname);\n \n int should_autocreate_reflog(const char *refname);\n-- \ngitgitgadget\n\n"},{"id":"404161","messageId":"8aacde69c8c4689b6b68f11a310a308595ed49ad.1598029177.git.gitgitgadget@gmail.com","threadId":"54062","inReplyTo":"pull.706.v3.git.1598029177.gitgitgadget@gmail.com","subject":"[PATCH v3 3/4] builtin/commit: suggest update-ref for pseudoref removal","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-08-21T16:59:36Z","receivedAt":"2020-08-21T17:04:46Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"From: Han-Wen Nienhuys <hanwen@google.com>\n\nWhen pseudorefs move to a different ref storage mechanism, pseudorefs no longer\ncan be removed with 'rm'. Instead, suggest a \"update-ref -d\" command, which will\nwork regardless of ref storage backend.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n builtin/commit.c | 26 ++++++++++++--------------\n 1 file changed, 12 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 69ac78d5e5..671721c385 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -847,21 +847,19 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\tif (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&\n \t\t\t\t!merge_contains_scissors)\n \t\t\t\twt_status_add_cut_line(s->fp);\n-\t\t\tstatus_printf_ln(s, GIT_COLOR_NORMAL,\n-\t\t\t    whence == FROM_MERGE\n-\t\t\t\t? _(\"\\n\"\n-\t\t\t\t\t\"It looks like you may be committing a merge.\\n\"\n-\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n-\t\t\t\t\t\"\t%s\\n\"\n-\t\t\t\t\t\"and try again.\\n\")\n-\t\t\t\t: _(\"\\n\"\n-\t\t\t\t\t\"It looks like you may be committing a cherry-pick.\\n\"\n-\t\t\t\t\t\"If this is not correct, please remove the file\\n\"\n-\t\t\t\t\t\"\t%s\\n\"\n-\t\t\t\t\t\"and try again.\\n\"),\n+\t\t\tstatus_printf_ln(\n+\t\t\t\ts, GIT_COLOR_NORMAL,\n \t\t\t\twhence == FROM_MERGE ?\n-\t\t\t\t\tgit_path_merge_head(the_repository) :\n-\t\t\t\t\tgit_path_cherry_pick_head(the_repository));\n+\t\t\t\t\t      _(\"\\n\"\n+\t\t\t\t\t  \"It looks like you may be committing a merge.\\n\"\n+\t\t\t\t\t  \"If this is not correct, please run\\n\"\n+\t\t\t\t\t  \"\tgit update-ref -d MERGE_HEAD\\n\"\n+\t\t\t\t\t  \"and try again.\\n\") :\n+\t\t\t\t\t      _(\"\\n\"\n+\t\t\t\t\t  \"It looks like you may be committing a cherry-pick.\\n\"\n+\t\t\t\t\t  \"If this is not correct, please run\\n\"\n+\t\t\t\t\t  \"\tgit update-ref -d CHERRY_PICK_HEAD\\n\"\n+\t\t\t\t\t  \"and try again.\\n\"));\n \t\t}\n \n \t\tfprintf(s->fp, \"\\n\");\n-- \ngitgitgadget\n\n"},{"id":"404178","messageId":"xmqq1rjzalva.fsf@gitster.c.googlers.com","threadId":"54062","inReplyTo":"pull.706.v3.git.1598029177.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 0/4] Use refs API for handling sundry pseudorefs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-21T18:34:49Z","receivedAt":"2020-08-21T18:34:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Han-Wen Nienhuys via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> This series changes the handling of CHERRY_PICK_HEAD and REVERT_HEAD to use\n> the refs API, as a preliminary refactor for reftable. \n>\n> No functional changes.\n>\n> Han-Wen Nienhuys (4):\n>   refs: make refs_ref_exists public\n>   sequencer: treat CHERRY_PICK_HEAD as a pseudo ref\n>   builtin/commit: suggest update-ref for pseudoref removal\n>   sequencer: treat REVERT_HEAD as a pseudo ref\n\nThanks.\n"}]}