{"thread":{"id":"57385","subject":"[PATCH 0/2] Prepare (auto)stash for reftable","startedAt":"2022-02-08T22:25:21Z","lastAt":"2022-02-08T22:25:45Z","messageCount":3,"participants":["Han-Wen Nienhuys via GitGitGadget"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"448004","messageId":"pull.1214.git.git.1644350985.gitgitgadget@gmail.com","threadId":"57385","inReplyTo":null,"subject":"[PATCH 0/2] Prepare (auto)stash for reftable","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-08T20:09:43Z","receivedAt":"2022-02-08T22:25:21Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"Stashes are stored as hex OIDs in files under .git/ but are accessed as\nrefs.\n\nThis series consistently treats stashes (AUTOMERGE_STASH,\nrebase-merge/autostash etc.) as refs.\n\nHan-Wen Nienhuys (2):\n  t3420: prepare for reftable\n  Treat MERGE_AUTOSTASH and friends as a pseudoref\n\n branch.c                    |  2 +-\n builtin/commit.c            |  2 +-\n builtin/merge.c             | 29 +++++++++++------------\n builtin/rebase.c            | 34 ++++++++++++++++++++++-----\n path.c                      |  1 -\n path.h                      |  3 +--\n sequencer.c                 | 46 +++++++++++++++++--------------------\n t/t3420-rebase-autostash.sh | 31 +++++++++++++------------\n 8 files changed, 82 insertions(+), 66 deletions(-)\n\n\nbase-commit: a9cd6a0c5981a7d3c9865cf1966243c82f93e58e\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1214%2Fhanwen%2Freftable-stash-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1214/hanwen/reftable-stash-v1\nPull-Request: https://github.com/git/git/pull/1214\n-- \ngitgitgadget\n"},{"id":"448005","messageId":"fc1bd0621085f331b804c83df7a03cb1d4872fcd.1644350985.git.gitgitgadget@gmail.com","threadId":"57385","inReplyTo":"pull.1214.git.git.1644350985.gitgitgadget@gmail.com","subject":"[PATCH 1/2] t3420: prepare for reftable","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-08T20:09:44Z","receivedAt":"2022-02-08T22:25:25Z","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 autostash existence using rev-parse; remove the autostash\nusing test-tool.\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n t/t3420-rebase-autostash.sh | 31 ++++++++++++++++---------------\n 1 file changed, 16 insertions(+), 15 deletions(-)\n\ndiff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh\nindex 43fcb68f27e..e6466290e03 100755\n--- a/t/t3420-rebase-autostash.sh\n+++ b/t/t3420-rebase-autostash.sh\n@@ -79,7 +79,7 @@ create_expected_failure_merge () {\n \n testrebase () {\n \ttype=$1\n-\tdotest=$2\n+\ttest_type=$2\n \n \ttest_expect_success \"rebase$type: dirty worktree, --no-autostash\" '\n \t\ttest_config rebase.autostash true &&\n@@ -133,9 +133,10 @@ testrebase () {\n \t\ttest_when_finished git branch -D rebased-feature-branch &&\n \t\techo dirty >>file3 &&\n \t\ttest_must_fail git rebase$type related-onto-branch &&\n-\t\ttest_path_is_file $dotest/autostash &&\n+\t\tgit rev-parse $test_type/autostash &&\n \t\ttest_path_is_missing file3 &&\n-\t\trm -rf $dotest &&\n+\t\ttest-tool ref-store main delete-refs REF_SKIP_REFNAME_VERIFICATION msg $test_type/autostash &&\n+\t\trm -rf .git/$test_type &&\n \t\tgit reset --hard &&\n \t\tgit checkout feature-branch\n \t'\n@@ -147,12 +148,12 @@ testrebase () {\n \t\ttest_when_finished git branch -D rebased-feature-branch &&\n \t\techo dirty >>file3 &&\n \t\ttest_must_fail git rebase$type related-onto-branch &&\n-\t\ttest_path_is_file $dotest/autostash &&\n+\t\tgit rev-parse $test_type/autostash &&\n \t\ttest_path_is_missing file3 &&\n \t\techo \"conflicting-plus-goodbye\" >file2 &&\n \t\tgit add file2 &&\n \t\tgit rebase --continue &&\n-\t\ttest_path_is_missing $dotest/autostash &&\n+\t\ttest_must_fail git rev-parse $test_type/autostash &&\n \t\tgrep dirty file3 &&\n \t\tgit checkout feature-branch\n \t'\n@@ -164,10 +165,10 @@ testrebase () {\n \t\ttest_when_finished git branch -D rebased-feature-branch &&\n \t\techo dirty >>file3 &&\n \t\ttest_must_fail git rebase$type related-onto-branch &&\n-\t\ttest_path_is_file $dotest/autostash &&\n+\t\tgit rev-parse $test_type/autostash &&\n \t\ttest_path_is_missing file3 &&\n \t\tgit rebase --skip &&\n-\t\ttest_path_is_missing $dotest/autostash &&\n+\t\ttest_must_fail git rev-parse $test_type/autostash &&\n \t\tgrep dirty file3 &&\n \t\tgit checkout feature-branch\n \t'\n@@ -179,10 +180,10 @@ testrebase () {\n \t\ttest_when_finished git branch -D rebased-feature-branch &&\n \t\techo dirty >>file3 &&\n \t\ttest_must_fail git rebase$type related-onto-branch &&\n-\t\ttest_path_is_file $dotest/autostash &&\n+\t\tgit rev-parse $test_type/autostash &&\n \t\ttest_path_is_missing file3 &&\n \t\tgit rebase --abort &&\n-\t\ttest_path_is_missing $dotest/autostash &&\n+\t\ttest_must_fail git rev-parse $test_type/autostash &&\n \t\tgrep dirty file3 &&\n \t\tgit checkout feature-branch\n \t'\n@@ -195,11 +196,11 @@ testrebase () {\n \t\techo dirty >>file3 &&\n \t\tgit diff >expect &&\n \t\ttest_must_fail git rebase$type related-onto-branch &&\n-\t\ttest_path_is_file $dotest/autostash &&\n+\t\tgit rev-parse $test_type/autostash &&\n \t\ttest_path_is_missing file3 &&\n \t\tgit rebase --quit &&\n \t\ttest_when_finished git stash drop &&\n-\t\ttest_path_is_missing $dotest/autostash &&\n+\t\ttest_must_fail git rev-parse $test_type/autostash &&\n \t\t! grep dirty file3 &&\n \t\tgit stash show -p >actual &&\n \t\ttest_cmp expect actual &&\n@@ -214,7 +215,7 @@ testrebase () {\n \t\techo dirty >file4 &&\n \t\tgit add file4 &&\n \t\tgit rebase$type unrelated-onto-branch >actual 2>&1 &&\n-\t\ttest_path_is_missing $dotest &&\n+\t\ttest_must_fail git rev-parse $test_type/autostash &&\n \t\tgit reset --hard &&\n \t\tgrep unrelated file4 &&\n \t\t! grep dirty file4 &&\n@@ -257,9 +258,9 @@ test_expect_success \"rebase: noop rebase\" '\n \tgit checkout feature-branch\n '\n \n-testrebase \" --apply\" .git/rebase-apply\n-testrebase \" --merge\" .git/rebase-merge\n-testrebase \" --interactive\" .git/rebase-merge\n+testrebase \" --apply\" rebase-apply\n+testrebase \" --merge\" rebase-merge\n+testrebase \" --interactive\" rebase-merge\n \n test_expect_success 'abort rebase -i with --autostash' '\n \ttest_when_finished \"git reset --hard\" &&\n-- \ngitgitgadget\n\n"},{"id":"448008","messageId":"395baf11c9f7f9a54de24ab99c2242933b3c25a7.1644350985.git.gitgitgadget@gmail.com","threadId":"57385","inReplyTo":"pull.1214.git.git.1644350985.gitgitgadget@gmail.com","subject":"[PATCH 2/2] Treat MERGE_AUTOSTASH and friends as a pseudoref","fromName":"Han-Wen Nienhuys via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-08T20:09:45Z","receivedAt":"2022-02-08T22:25:45Z","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\nIn t7600-merge.sh, we can see\n\n        git stash show -p MERGE_AUTOSTASH\n\nwhich yields\n\n        error: MERGE_AUTOSTASH is not a valid reference\n\nin reftable. stash.c further confirms the stash should be treated as a\nrevision, by calling setup_revisions() on the first argument to\nshow_stash()\n\nSigned-off-by: Han-Wen Nienhuys <hanwen@google.com>\n---\n branch.c         |  2 +-\n builtin/commit.c |  2 +-\n builtin/merge.c  | 29 ++++++++++++++---------------\n builtin/rebase.c | 34 ++++++++++++++++++++++++++++------\n path.c           |  1 -\n path.h           |  3 +--\n sequencer.c      | 46 +++++++++++++++++++++-------------------------\n 7 files changed, 66 insertions(+), 51 deletions(-)\n\ndiff --git a/branch.c b/branch.c\nindex 6b31df539a5..f506f56de09 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -637,7 +637,7 @@ void remove_merge_branch_state(struct repository *r)\n \tunlink(git_path_merge_msg(r));\n \tunlink(git_path_merge_mode(r));\n \tunlink(git_path_auto_merge(r));\n-\tsave_autostash(git_path_merge_autostash(r));\n+\tsave_autostash(MERGE_AUTOSTASH);\n }\n \n void remove_branch_state(struct repository *r, int verbose)\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 33ca9e99c80..ef05ecf39df 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1855,7 +1855,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\t\t\t     &oid, flags);\n \t}\n \n-\tapply_autostash(git_path_merge_autostash(the_repository));\n+\tapply_autostash(MERGE_AUTOSTASH);\n \n \tUNLEAK(err);\n \tUNLEAK(sb);\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex a94a03384ae..81f4fa83c24 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -492,7 +492,7 @@ static void finish(struct commit *head_commit,\n \t/* Run a post-merge hook */\n \trun_hooks_l(\"post-merge\", squash ? \"1\" : \"0\", NULL);\n \n-\tapply_autostash(git_path_merge_autostash(the_repository));\n+\tapply_autostash(MERGE_AUTOSTASH);\n \tstrbuf_release(&reflog_message);\n }\n \n@@ -1318,8 +1318,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \tif (abort_current_merge) {\n \t\tint nargc = 2;\n \t\tconst char *nargv[] = {\"reset\", \"--merge\", NULL};\n-\t\tstruct strbuf stash_oid = STRBUF_INIT;\n-\n+\t\tstruct object_id stash_oid;\n+\t\tchar hex[GIT_MAX_HEXSZ + 1] = { 0 };\n \t\tif (orig_argc != 2)\n \t\t\tusage_msg_opt(_(\"--abort expects no arguments\"),\n \t\t\t      builtin_merge_usage, builtin_merge_options);\n@@ -1327,17 +1327,17 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\tif (!file_exists(git_path_merge_head(the_repository)))\n \t\t\tdie(_(\"There is no merge to abort (MERGE_HEAD missing).\"));\n \n-\t\tif (read_oneliner(&stash_oid, git_path_merge_autostash(the_repository),\n-\t\t    READ_ONELINER_SKIP_IF_EMPTY))\n-\t\t\tunlink(git_path_merge_autostash(the_repository));\n+\t\tif (!read_ref(MERGE_AUTOSTASH, &stash_oid)) {\n+\t\t\toid_to_hex_r(hex, &stash_oid);\n+\t\t\tdelete_ref(\"merge --abort\", MERGE_AUTOSTASH, NULL, 0);\n+\t\t}\n \n \t\t/* Invoke 'git reset --merge' */\n \t\tret = cmd_reset(nargc, nargv, prefix);\n \n-\t\tif (stash_oid.len)\n-\t\t\tapply_autostash_oid(stash_oid.buf);\n+\t\tif (hex[0])\n+\t\t\tapply_autostash_oid(hex);\n \n-\t\tstrbuf_release(&stash_oid);\n \t\tgoto done;\n \t}\n \n@@ -1567,13 +1567,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t}\n \n \t\tif (autostash)\n-\t\t\tcreate_autostash(the_repository,\n-\t\t\t\t\t git_path_merge_autostash(the_repository));\n+\t\t\tcreate_autostash(the_repository, MERGE_AUTOSTASH);\n \t\tif (checkout_fast_forward(the_repository,\n \t\t\t\t\t  &head_commit->object.oid,\n \t\t\t\t\t  &commit->object.oid,\n \t\t\t\t\t  overwrite_ignore)) {\n-\t\t\tapply_autostash(git_path_merge_autostash(the_repository));\n+\t\t\tapply_autostash(MERGE_AUTOSTASH);\n+\n \t\t\tret = 1;\n \t\t\tgoto done;\n \t\t}\n@@ -1638,8 +1638,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\tdie_ff_impossible();\n \n \tif (autostash)\n-\t\tcreate_autostash(the_repository,\n-\t\t\t\t git_path_merge_autostash(the_repository));\n+\t\tcreate_autostash(the_repository, MERGE_AUTOSTASH);\n \n \t/* We are going to make a new commit. */\n \tgit_committer_info(IDENT_STRICT);\n@@ -1722,7 +1721,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\telse\n \t\t\tfprintf(stderr, _(\"Merge with strategy %s failed.\\n\"),\n \t\t\t\tuse_strategies[0]->name);\n-\t\tapply_autostash(git_path_merge_autostash(the_repository));\n+\t\tapply_autostash(MERGE_AUTOSTASH);\n \t\tret = 2;\n \t\tgoto done;\n \t} else if (best_strategy == wt_strategy)\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex b29ad2b65e7..e84c21ab8fc 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -414,6 +414,17 @@ static const char *state_dir_path(const char *filename, struct rebase_options *o\n \treturn path.buf;\n }\n \n+static const char *state_pseudoref(const char *suffix,\n+\t\t\t\t   struct rebase_options *opts)\n+{\n+\tstatic struct strbuf pseudo_ref = STRBUF_INIT;\n+\tstrbuf_reset(&pseudo_ref);\n+\tstrbuf_addstr(&pseudo_ref, strrchr(opts->state_dir, '/') + 1);\n+\tstrbuf_addstr(&pseudo_ref, \"/\");\n+\tstrbuf_addstr(&pseudo_ref, suffix);\n+\treturn pseudo_ref.buf;\n+}\n+\n /* Initialize the rebase options from the state directory. */\n static int read_basic_state(struct rebase_options *opts)\n {\n@@ -544,10 +555,11 @@ static int finish_rebase(struct rebase_options *opts)\n {\n \tstruct strbuf dir = STRBUF_INIT;\n \tint ret = 0;\n+\tconst char *autostash_ref = state_pseudoref(\"autostash\", opts);\n \n \tdelete_ref(NULL, \"REBASE_HEAD\", NULL, REF_NO_DEREF);\n \tunlink(git_path_auto_merge(the_repository));\n-\tapply_autostash(state_dir_path(\"autostash\", opts));\n+\tapply_autostash(autostash_ref);\n \t/*\n \t * We ignore errors in 'git maintenance run --auto', since the\n \t * user should see them.\n@@ -559,6 +571,9 @@ static int finish_rebase(struct rebase_options *opts)\n \t\treplay.action = REPLAY_INTERACTIVE_REBASE;\n \t\tret = sequencer_remove_state(&replay);\n \t} else {\n+\t\tif (delete_ref(\"cleanup autostash\", autostash_ref, NULL,\n+\t\t\t       REF_SKIP_REFNAME_VERIFICATION))\n+\t\t\tdie(\"failed cleaning up autostash ref\");\n \t\tstrbuf_addstr(&dir, opts->state_dir);\n \t\tif (remove_dir_recursively(&dir, 0))\n \t\t\tret = error(_(\"could not remove '%s'\"),\n@@ -760,8 +775,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t\tfinish_rebase(opts);\n \t} else if (status == 2) {\n \t\tstruct strbuf dir = STRBUF_INIT;\n-\n-\t\tapply_autostash(state_dir_path(\"autostash\", opts));\n+\t\tconst char *autostash_ref = state_pseudoref(\"autostash\", opts);\n+\t\tapply_autostash(autostash_ref);\n+\t\tif (delete_ref(\"cleanup autostash\", autostash_ref, NULL,\n+\t\t\t       REF_SKIP_REFNAME_VERIFICATION))\n+\t\t\tdie(\"failed cleaning up autostash ref\");\n \t\tstrbuf_addstr(&dir, opts->state_dir);\n \t\tremove_dir_recursively(&dir, 0);\n \t\tstrbuf_release(&dir);\n@@ -1310,13 +1328,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tgoto cleanup;\n \t}\n \tcase ACTION_QUIT: {\n-\t\tsave_autostash(state_dir_path(\"autostash\", &options));\n+\t\tconst char *autostash_ref =\n+\t\t\tstate_pseudoref(\"autostash\", &options);\n+\t\tsave_autostash(autostash_ref);\n \t\tif (options.type == REBASE_MERGE) {\n \t\t\tstruct replay_opts replay = REPLAY_OPTS_INIT;\n \n \t\t\treplay.action = REPLAY_INTERACTIVE_REBASE;\n \t\t\tret = sequencer_remove_state(&replay);\n \t\t} else {\n+\t\t\tif (delete_ref(\"deleted autostash_ref\", autostash_ref,\n+\t\t\t\t       NULL, REF_SKIP_REFNAME_VERIFICATION))\n+\t\t\t\tdie(\"failed to cleanup autostash ref\");\n \t\t\tstrbuf_reset(&buf);\n \t\t\tstrbuf_addstr(&buf, options.state_dir);\n \t\t\tret = remove_dir_recursively(&buf, 0);\n@@ -1670,8 +1693,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \n \tif (options.autostash)\n \t\tcreate_autostash(the_repository,\n-\t\t\t\t state_dir_path(\"autostash\", &options));\n-\n+\t\t\t\t state_pseudoref(\"autostash\", &options));\n \n \tif (require_clean_work_tree(the_repository, \"rebase\",\n \t\t\t\t    _(\"Please commit or stash them.\"), 1, 1)) {\ndiff --git a/path.c b/path.c\nindex 2c895471d90..f69a912a279 100644\n--- a/path.c\n+++ b/path.c\n@@ -1552,7 +1552,6 @@ REPO_GIT_PATH_FUNC(merge_msg, \"MERGE_MSG\")\n REPO_GIT_PATH_FUNC(merge_rr, \"MERGE_RR\")\n REPO_GIT_PATH_FUNC(merge_mode, \"MERGE_MODE\")\n REPO_GIT_PATH_FUNC(merge_head, \"MERGE_HEAD\")\n-REPO_GIT_PATH_FUNC(merge_autostash, \"MERGE_AUTOSTASH\")\n REPO_GIT_PATH_FUNC(auto_merge, \"AUTO_MERGE\")\n REPO_GIT_PATH_FUNC(fetch_head, \"FETCH_HEAD\")\n REPO_GIT_PATH_FUNC(shallow, \"shallow\")\ndiff --git a/path.h b/path.h\nindex b68691a86b8..e1cf1db98ba 100644\n--- a/path.h\n+++ b/path.h\n@@ -175,7 +175,6 @@ struct path_cache {\n \tconst char *merge_rr;\n \tconst char *merge_mode;\n \tconst char *merge_head;\n-\tconst char *merge_autostash;\n \tconst char *auto_merge;\n \tconst char *fetch_head;\n \tconst char *shallow;\n@@ -188,11 +187,11 @@ const char *git_path_merge_msg(struct repository *r);\n const char *git_path_merge_rr(struct repository *r);\n const char *git_path_merge_mode(struct repository *r);\n const char *git_path_merge_head(struct repository *r);\n-const char *git_path_merge_autostash(struct repository *r);\n const char *git_path_auto_merge(struct repository *r);\n const char *git_path_fetch_head(struct repository *r);\n const char *git_path_shallow(struct repository *r);\n \n+#define MERGE_AUTOSTASH \"MERGE_AUTOSTASH\"\n \n int ends_with_path_components(const char *path, const char *components);\n \ndiff --git a/sequencer.c b/sequencer.c\nindex 35006c0cea6..d61ad1e215d 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -160,7 +160,6 @@ static GIT_PATH_FUNC(rebase_path_quiet, \"rebase-merge/quiet\")\n static GIT_PATH_FUNC(rebase_path_signoff, \"rebase-merge/signoff\")\n static GIT_PATH_FUNC(rebase_path_head_name, \"rebase-merge/head-name\")\n static GIT_PATH_FUNC(rebase_path_onto, \"rebase-merge/onto\")\n-static GIT_PATH_FUNC(rebase_path_autostash, \"rebase-merge/autostash\")\n static GIT_PATH_FUNC(rebase_path_strategy, \"rebase-merge/strategy\")\n static GIT_PATH_FUNC(rebase_path_strategy_opts, \"rebase-merge/strategy_opts\")\n static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, \"rebase-merge/allow_rerere_autoupdate\")\n@@ -4085,7 +4084,7 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)\n \treturn -1;\n }\n \n-void create_autostash(struct repository *r, const char *path)\n+void create_autostash(struct repository *r, const char *pseudoref)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct lock_file lock_file = LOCK_INIT;\n@@ -4117,10 +4116,10 @@ void create_autostash(struct repository *r, const char *path)\n \t\tstrbuf_reset(&buf);\n \t\tstrbuf_add_unique_abbrev(&buf, &oid, DEFAULT_ABBREV);\n \n-\t\tif (safe_create_leading_directories_const(path))\n-\t\t\tdie(_(\"Could not create directory for '%s'\"),\n-\t\t\t    path);\n-\t\twrite_file(path, \"%s\", oid_to_hex(&oid));\n+\t\trefs_update_ref(get_main_ref_store(r), \"create_autostash\",\n+\t\t\t\tpseudoref, &oid, null_oid(), 0,\n+\t\t\t\tUPDATE_REFS_DIE_ON_ERR);\n+\n \t\tprintf(_(\"Created autostash: %s\\n\"), buf.buf);\n \t\tif (reset_head(r, &ropts) < 0)\n \t\t\tdie(_(\"could not reset --hard\"));\n@@ -4174,33 +4173,30 @@ static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply)\n \treturn ret;\n }\n \n-static int apply_save_autostash(const char *path, int attempt_apply)\n+static int apply_save_autostash(const char *pseudoref, int attempt_apply)\n {\n-\tstruct strbuf stash_oid = STRBUF_INIT;\n+\tstruct object_id oid;\n+\tchar hex[GIT_MAX_HEXSZ + 1] = { 0 };\n \tint ret = 0;\n \n-\tif (!read_oneliner(&stash_oid, path,\n-\t\t\t   READ_ONELINER_SKIP_IF_EMPTY)) {\n-\t\tstrbuf_release(&stash_oid);\n+\tif (read_ref(pseudoref, &oid))\n \t\treturn 0;\n-\t}\n-\tstrbuf_trim(&stash_oid);\n \n-\tret = apply_save_autostash_oid(stash_oid.buf, attempt_apply);\n+\tret = apply_save_autostash_oid(oid_to_hex_r(hex, &oid), attempt_apply);\n \n-\tunlink(path);\n-\tstrbuf_release(&stash_oid);\n+\tdelete_ref(\"save autostash\", pseudoref, NULL,\n+\t\t   REF_SKIP_REFNAME_VERIFICATION);\n \treturn ret;\n }\n \n-int save_autostash(const char *path)\n+int save_autostash(const char *pseudoref)\n {\n-\treturn apply_save_autostash(path, 0);\n+\treturn apply_save_autostash(pseudoref, 0);\n }\n \n-int apply_autostash(const char *path)\n+int apply_autostash(const char *pseudoref)\n {\n-\treturn apply_save_autostash(path, 1);\n+\treturn apply_save_autostash(pseudoref, 1);\n }\n \n int apply_autostash_oid(const char *stash_oid)\n@@ -4222,7 +4218,7 @@ static int checkout_onto(struct repository *r, struct replay_opts *opts,\n \t\t.default_reflog_action = \"rebase\"\n \t};\n \tif (reset_head(r, &ropts)) {\n-\t\tapply_autostash(rebase_path_autostash());\n+\t\tapply_autostash(\"rebase-merge/autostash\");\n \t\tsequencer_remove_state(opts);\n \t\treturn error(_(\"could not detach HEAD\"));\n \t}\n@@ -4556,7 +4552,7 @@ cleanup_head_ref:\n \t\t\t\trun_command(&hook);\n \t\t\t}\n \t\t}\n-\t\tapply_autostash(rebase_path_autostash());\n+\t\tapply_autostash(\"rebase-merge/autostash\");\n \n \t\tif (!opts->quiet) {\n \t\t\tif (!opts->verbose)\n@@ -5635,7 +5631,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla\n \t\ttodo_list_add_exec_commands(todo_list, commands);\n \n \tif (count_commands(todo_list) == 0) {\n-\t\tapply_autostash(rebase_path_autostash());\n+\t\tapply_autostash(\"rebase-merge/autostash\");\n \t\tsequencer_remove_state(opts);\n \n \t\treturn error(_(\"nothing to do\"));\n@@ -5646,12 +5642,12 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla\n \tif (res == -1)\n \t\treturn -1;\n \telse if (res == -2) {\n-\t\tapply_autostash(rebase_path_autostash());\n+\t\tapply_autostash(\"rebase-merge/autostash\");\n \t\tsequencer_remove_state(opts);\n \n \t\treturn -1;\n \t} else if (res == -3) {\n-\t\tapply_autostash(rebase_path_autostash());\n+\t\tapply_autostash(\"rebase-merge/autostash\");\n \t\tsequencer_remove_state(opts);\n \t\ttodo_list_release(&new_todo);\n \n-- \ngitgitgadget\n"}]}