git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/7] sequencer: introduce functions to handle autostashes via refs

From
Patrick Steinhardt <ps@pks.im>
Date
Jan 19, 2024, 10:40 UTC
Message-ID
<abcf1f5cf428072d19639dc4209e0c1554f3eb53.1705659748.git.ps@pks.im>
In-Reply-To
<cover.1705659748.git.ps@pks.im>

We're about to convert the MERGE_AUTOSTASH ref to become non-special, using the refs API instead of direct filesystem access to both read and write the ref. The current interfaces to write autostashes is entirely path-based though, so we need to extend them to also support writes via the refs API instead.

Ideally, we would be able to fully replace the old set of path-based interfaces. But the sequencer will continue to write state into "rebase-merge/autostash". This path is not considered to be a ref at all and will thus stay is-is for now, which requires us to keep both path- and refs-based interfaces to handle autostashes.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 sequencer.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++----
 sequencer.h |  3 +++
 2 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 47c8d17cbb..91de546b32 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -4463,12 +4463,17 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)
 	return -1;
 }
 
-void create_autostash(struct repository *r, const char *path)
+static void create_autostash_internal(struct repository *r,
+				      const char *path,
+				      const char *refname)
 {
 	struct strbuf buf = STRBUF_INIT;
 	struct lock_file lock_file = LOCK_INIT;
 	int fd;
 
+	if (path && refname)
+		BUG("can only pass path or refname");
+
 	fd = repo_hold_locked_index(r, &lock_file, 0);
 	refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
 	if (0 <= fd)
@@ -4495,10 +4500,16 @@ void create_autostash(struct repository *r, const char *path)
 		strbuf_reset(&buf);
 		strbuf_add_unique_abbrev(&buf, &oid, DEFAULT_ABBREV);
 
-		if (safe_create_leading_directories_const(path))
-			die(_("Could not create directory for '%s'"),
-			    path);
-		write_file(path, "%s", oid_to_hex(&oid));
+		if (path) {
+			if (safe_create_leading_directories_const(path))
+				die(_("Could not create directory for '%s'"),
+				    path);
+			write_file(path, "%s", oid_to_hex(&oid));
+		} else {
+			refs_update_ref(get_main_ref_store(r), "", refname,
+					&oid, null_oid(), 0, UPDATE_REFS_DIE_ON_ERR);
+		}
+
 		printf(_("Created autostash: %s\n"), buf.buf);
 		if (reset_head(r, &ropts) < 0)
 			die(_("could not reset --hard"));
@@ -4509,6 +4520,16 @@ void create_autostash(struct repository *r, const char *path)
 	strbuf_release(&buf);
 }
 
+void create_autostash(struct repository *r, const char *path)
+{
+	create_autostash_internal(r, path, NULL);
+}
+
+void create_autostash_ref(struct repository *r, const char *refname)
+{
+	create_autostash_internal(r, NULL, refname);
+}
+
 static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply)
 {
 	struct child_process child = CHILD_PROCESS_INIT;
@@ -4586,6 +4607,41 @@ int apply_autostash_oid(const char *stash_oid)
 	return apply_save_autostash_oid(stash_oid, 1);
 }
 
+static int apply_save_autostash_ref(struct repository *r, const char *refname,
+				    int attempt_apply)
+{
+	struct object_id stash_oid;
+	char stash_oid_hex[GIT_MAX_HEXSZ + 1];
+	int flag, ret;
+
+	if (!refs_ref_exists(get_main_ref_store(r), refname))
+		return 0;
+
+	if (!refs_resolve_ref_unsafe(get_main_ref_store(r), refname,
+				     RESOLVE_REF_READING, &stash_oid, &flag))
+		return -1;
+	if (flag & REF_ISSYMREF)
+		return error(_("autostash reference is a symref"));
+
+	oid_to_hex_r(stash_oid_hex, &stash_oid);
+	ret = apply_save_autostash_oid(stash_oid_hex, attempt_apply);
+
+	refs_delete_ref(get_main_ref_store(r), "", refname,
+			&stash_oid, REF_NO_DEREF);
+
+	return ret;
+}
+
+int save_autostash_ref(struct repository *r, const char *refname)
+{
+	return apply_save_autostash_ref(r, refname, 0);
+}
+
+int apply_autostash_ref(struct repository *r, const char *refname)
+{
+	return apply_save_autostash_ref(r, refname, 1);
+}
+
 static int checkout_onto(struct repository *r, struct replay_opts *opts,
 			 const char *onto_name, const struct object_id *onto,
 			 const struct object_id *orig_head)
diff --git a/sequencer.h b/sequencer.h
index 913a0f652d..dcef7bb99c 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -225,9 +225,12 @@ void commit_post_rewrite(struct repository *r,
 			 const struct object_id *new_head);
 
 void create_autostash(struct repository *r, const char *path);
+void create_autostash_ref(struct repository *r, const char *refname);
 int save_autostash(const char *path);
+int save_autostash_ref(struct repository *r, const char *refname);
 int apply_autostash(const char *path);
 int apply_autostash_oid(const char *stash_oid);
+int apply_autostash_ref(struct repository *r, const char *refname);
 
 #define SUMMARY_INITIAL_COMMIT   (1 << 0)
 #define SUMMARY_SHOW_AUTHOR_DATE (1 << 1)
-- 
2.43.GIT
Previous: Karthik NayakNext: Junio C Hamano
Message 13 of 23 in “refs: convert special refs to become normal pseudo-refs”
  1. 0/7 refs: convert special refs to become normal pseudo-refsPatrick Steinhardt, Jan 19, 2024
  2. 1/7 sequencer: clean up pseudo refs with REF_NO_DEREFPatrick Steinhardt, Jan 19, 2024
  3. Junio C HamanoJan 19, 2024
  4. Patrick SteinhardtJan 22, 2024
  5. Karthik NayakJan 22, 2024
  6. Patrick SteinhardtJan 22, 2024
  7. 2/7 sequencer: delete REBASE_HEAD in correct repo when picking commitsPatrick Steinhardt, Jan 19, 2024
  8. 3/7 refs: convert AUTO_MERGE to become a normal pseudo-refPatrick Steinhardt, Jan 19, 2024
  9. Junio C HamanoJan 19, 2024
  10. Patrick SteinhardtJan 22, 2024
  11. Elijah NewrenJan 24, 2024
  12. Karthik NayakJan 22, 2024
  13. 4/7 sequencer: introduce functions to handle autostashes via refsPatrick Steinhardt, Jan 19, 2024
  14. Junio C HamanoJan 19, 2024
  15. Patrick SteinhardtJan 22, 2024
  16. Phillip WoodJan 22, 2024
  17. Junio C HamanoJan 22, 2024
  18. 5/7 refs: convert MERGE_AUTOSTASH to become a normal pseudo-refPatrick Steinhardt, Jan 19, 2024
  19. 6/7 refs: redefine special refsPatrick Steinhardt, Jan 19, 2024
  20. Junio C HamanoJan 19, 2024
  21. 7/7 Documentation: add "special refs" to the glossaryPatrick Steinhardt, Jan 19, 2024
  22. Phillip WoodJan 23, 2024
  23. Patrick SteinhardtJan 24, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.