sequencer: introduce functions to handle autostashes via refs
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jan 19, 2024 at 11:40 UTC
35122daebc8030ccc42f54fe4f08272091e4aa94
2 files changed
+64
-5
sequencer.c
+61
-5
@@ -4463,12 +4463,17 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)
4463
return -1;
4464
}
4465
4466
-void create_autostash(struct repository *r, const char *path)
4466
+static void create_autostash_internal(struct repository *r,
4467
+ const char *path,
4468
+ const char *refname)
4469
{
4470
struct strbuf buf = STRBUF_INIT;
4471
struct lock_file lock_file = LOCK_INIT;
4472
int fd;
4473
4474
+ if (path && refname)
4475
+ BUG("can only pass path or refname");
4476
+
4477
fd = repo_hold_locked_index(r, &lock_file, 0);
4478
refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
4479
if (0 <= fd)
@@ -4495,10 +4500,16 @@ void create_autostash(struct repository *r, const char *path)
4500
strbuf_reset(&buf);
4501
strbuf_add_unique_abbrev(&buf, &oid, DEFAULT_ABBREV);
4502
4498
- if (safe_create_leading_directories_const(path))
4499
- die(_("Could not create directory for '%s'"),
4500
- path);
4501
- write_file(path, "%s", oid_to_hex(&oid));
4503
+ if (path) {
4504
+ if (safe_create_leading_directories_const(path))
4505
+ die(_("Could not create directory for '%s'"),
4506
+ path);
4507
+ write_file(path, "%s", oid_to_hex(&oid));
4508
+ } else {
4509
+ refs_update_ref(get_main_ref_store(r), "", refname,
4510
+ &oid, null_oid(), 0, UPDATE_REFS_DIE_ON_ERR);
4511
+ }
4512
+
4513
printf(_("Created autostash: %s\n"), buf.buf);
4514
if (reset_head(r, &ropts) < 0)
4515
die(_("could not reset --hard"));
@@ -4509,6 +4520,16 @@ void create_autostash(struct repository *r, const char *path)
4520
strbuf_release(&buf);
4521
}
4522
4523
+void create_autostash(struct repository *r, const char *path)
4524
+{
4525
+ create_autostash_internal(r, path, NULL);
4526
+}
4527
+
4528
+void create_autostash_ref(struct repository *r, const char *refname)
4529
+{
4530
+ create_autostash_internal(r, NULL, refname);
4531
+}
4532
+
4533
static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply)
4534
{
4535
struct child_process child = CHILD_PROCESS_INIT;
@@ -4586,6 +4607,41 @@ int apply_autostash_oid(const char *stash_oid)
4607
return apply_save_autostash_oid(stash_oid, 1);
4608
}
4609
4610
+static int apply_save_autostash_ref(struct repository *r, const char *refname,
4611
+ int attempt_apply)
4612
+{
4613
+ struct object_id stash_oid;
4614
+ char stash_oid_hex[GIT_MAX_HEXSZ + 1];
4615
+ int flag, ret;
4616
+
4617
+ if (!refs_ref_exists(get_main_ref_store(r), refname))
4618
+ return 0;
4619
+
4620
+ if (!refs_resolve_ref_unsafe(get_main_ref_store(r), refname,
4621
+ RESOLVE_REF_READING, &stash_oid, &flag))
4622
+ return -1;
4623
+ if (flag & REF_ISSYMREF)
4624
+ return error(_("autostash reference is a symref"));
4625
+
4626
+ oid_to_hex_r(stash_oid_hex, &stash_oid);
4627
+ ret = apply_save_autostash_oid(stash_oid_hex, attempt_apply);
4628
+
4629
+ refs_delete_ref(get_main_ref_store(r), "", refname,
4630
+ &stash_oid, REF_NO_DEREF);
4631
+
4632
+ return ret;
4633
+}
4634
+
4635
+int save_autostash_ref(struct repository *r, const char *refname)
4636
+{
4637
+ return apply_save_autostash_ref(r, refname, 0);
4638
+}
4639
+
4640
+int apply_autostash_ref(struct repository *r, const char *refname)
4641
+{
4642
+ return apply_save_autostash_ref(r, refname, 1);
4643
+}
4644
+
4645
static int checkout_onto(struct repository *r, struct replay_opts *opts,
4646
const char *onto_name, const struct object_id *onto,
4647
const struct object_id *orig_head)
sequencer.h
+3
@@ -225,9 +225,12 @@ void commit_post_rewrite(struct repository *r,
225
const struct object_id *new_head);
226
227
void create_autostash(struct repository *r, const char *path);
228
+void create_autostash_ref(struct repository *r, const char *refname);
229
int save_autostash(const char *path);
230
+int save_autostash_ref(struct repository *r, const char *refname);
231
int apply_autostash(const char *path);
232
int apply_autostash_oid(const char *stash_oid);
233
+int apply_autostash_ref(struct repository *r, const char *refname);
234
235
#define SUMMARY_INITIAL_COMMIT (1 << 0)
236
#define SUMMARY_SHOW_AUTHOR_DATE (1 << 1)