Skip to content

Commit 64a6dd8

Browse files
pks-tgitster
authored andcommitted
refs: implement removal of ref storages
We're about to introduce logic to migrate ref storages. One part of the migration will be to delete the files that are part of the old ref storage format. We don't yet have a way to delete such data generically across ref backends though. Implement a new `delete` callback and expose it via a new `ref_storage_delete()` function. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1339cb3 commit 64a6dd8

File tree

6 files changed

+146
-0
lines changed

6 files changed

+146
-0
lines changed

refs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,11 @@ int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *e
18611861
return refs->be->create_on_disk(refs, flags, err);
18621862
}
18631863

1864+
int ref_store_remove_on_disk(struct ref_store *refs, struct strbuf *err)
1865+
{
1866+
return refs->be->remove_on_disk(refs, err);
1867+
}
1868+
18641869
int repo_resolve_gitlink_ref(struct repository *r,
18651870
const char *submodule, const char *refname,
18661871
struct object_id *oid)

refs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *e
129129
*/
130130
void ref_store_release(struct ref_store *ref_store);
131131

132+
/*
133+
* Remove the ref store from disk. This deletes all associated data.
134+
*/
135+
int ref_store_remove_on_disk(struct ref_store *refs, struct strbuf *err);
136+
132137
/*
133138
* Return the peeled value of the oid currently being iterated via
134139
* for_each_ref(), etc. This is equivalent to calling:

refs/files-backend.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,11 +3342,73 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store,
33423342
return 0;
33433343
}
33443344

3345+
struct remove_one_root_ref_data {
3346+
const char *gitdir;
3347+
struct strbuf *err;
3348+
};
3349+
3350+
static int remove_one_root_ref(const char *refname,
3351+
void *cb_data)
3352+
{
3353+
struct remove_one_root_ref_data *data = cb_data;
3354+
struct strbuf buf = STRBUF_INIT;
3355+
int ret = 0;
3356+
3357+
strbuf_addf(&buf, "%s/%s", data->gitdir, refname);
3358+
3359+
ret = unlink(buf.buf);
3360+
if (ret < 0)
3361+
strbuf_addf(data->err, "could not delete %s: %s\n",
3362+
refname, strerror(errno));
3363+
3364+
strbuf_release(&buf);
3365+
return ret;
3366+
}
3367+
3368+
static int files_ref_store_remove_on_disk(struct ref_store *ref_store,
3369+
struct strbuf *err)
3370+
{
3371+
struct files_ref_store *refs =
3372+
files_downcast(ref_store, REF_STORE_WRITE, "remove");
3373+
struct remove_one_root_ref_data data = {
3374+
.gitdir = refs->base.gitdir,
3375+
.err = err,
3376+
};
3377+
struct strbuf sb = STRBUF_INIT;
3378+
int ret = 0;
3379+
3380+
strbuf_addf(&sb, "%s/refs", refs->base.gitdir);
3381+
if (remove_dir_recursively(&sb, 0) < 0) {
3382+
strbuf_addf(err, "could not delete refs: %s",
3383+
strerror(errno));
3384+
ret = -1;
3385+
}
3386+
strbuf_reset(&sb);
3387+
3388+
strbuf_addf(&sb, "%s/logs", refs->base.gitdir);
3389+
if (remove_dir_recursively(&sb, 0) < 0) {
3390+
strbuf_addf(err, "could not delete logs: %s",
3391+
strerror(errno));
3392+
ret = -1;
3393+
}
3394+
strbuf_reset(&sb);
3395+
3396+
if (for_each_root_ref(refs, remove_one_root_ref, &data) < 0)
3397+
ret = -1;
3398+
3399+
if (ref_store_remove_on_disk(refs->packed_ref_store, err) < 0)
3400+
ret = -1;
3401+
3402+
strbuf_release(&sb);
3403+
return ret;
3404+
}
3405+
33453406
struct ref_storage_be refs_be_files = {
33463407
.name = "files",
33473408
.init = files_ref_store_init,
33483409
.release = files_ref_store_release,
33493410
.create_on_disk = files_ref_store_create_on_disk,
3411+
.remove_on_disk = files_ref_store_remove_on_disk,
33503412

33513413
.transaction_prepare = files_transaction_prepare,
33523414
.transaction_finish = files_transaction_finish,

refs/packed-backend.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "../git-compat-util.h"
22
#include "../config.h"
3+
#include "../dir.h"
34
#include "../gettext.h"
45
#include "../hash.h"
56
#include "../hex.h"
@@ -1266,6 +1267,19 @@ static int packed_ref_store_create_on_disk(struct ref_store *ref_store UNUSED,
12661267
return 0;
12671268
}
12681269

1270+
static int packed_ref_store_remove_on_disk(struct ref_store *ref_store,
1271+
struct strbuf *err)
1272+
{
1273+
struct packed_ref_store *refs = packed_downcast(ref_store, 0, "remove");
1274+
1275+
if (remove_path(refs->path) < 0) {
1276+
strbuf_addstr(err, "could not delete packed-refs");
1277+
return -1;
1278+
}
1279+
1280+
return 0;
1281+
}
1282+
12691283
/*
12701284
* Write the packed refs from the current snapshot to the packed-refs
12711285
* tempfile, incorporating any changes from `updates`. `updates` must
@@ -1724,6 +1738,7 @@ struct ref_storage_be refs_be_packed = {
17241738
.init = packed_ref_store_init,
17251739
.release = packed_ref_store_release,
17261740
.create_on_disk = packed_ref_store_create_on_disk,
1741+
.remove_on_disk = packed_ref_store_remove_on_disk,
17271742

17281743
.transaction_prepare = packed_transaction_prepare,
17291744
.transaction_finish = packed_transaction_finish,

refs/refs-internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,12 @@ typedef int ref_store_create_on_disk_fn(struct ref_store *refs,
517517
int flags,
518518
struct strbuf *err);
519519

520+
/*
521+
* Remove the reference store from disk.
522+
*/
523+
typedef int ref_store_remove_on_disk_fn(struct ref_store *refs,
524+
struct strbuf *err);
525+
520526
typedef int ref_transaction_prepare_fn(struct ref_store *refs,
521527
struct ref_transaction *transaction,
522528
struct strbuf *err);
@@ -649,6 +655,7 @@ struct ref_storage_be {
649655
ref_store_init_fn *init;
650656
ref_store_release_fn *release;
651657
ref_store_create_on_disk_fn *create_on_disk;
658+
ref_store_remove_on_disk_fn *remove_on_disk;
652659

653660
ref_transaction_prepare_fn *transaction_prepare;
654661
ref_transaction_finish_fn *transaction_finish;

refs/reftable-backend.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "../git-compat-util.h"
22
#include "../abspath.h"
33
#include "../chdir-notify.h"
4+
#include "../dir.h"
45
#include "../environment.h"
56
#include "../gettext.h"
67
#include "../hash.h"
@@ -343,6 +344,56 @@ static int reftable_be_create_on_disk(struct ref_store *ref_store,
343344
return 0;
344345
}
345346

347+
static int reftable_be_remove_on_disk(struct ref_store *ref_store,
348+
struct strbuf *err)
349+
{
350+
struct reftable_ref_store *refs =
351+
reftable_be_downcast(ref_store, REF_STORE_WRITE, "remove");
352+
struct strbuf sb = STRBUF_INIT;
353+
int ret = 0;
354+
355+
/*
356+
* Release the ref store such that all stacks are closed. This is
357+
* required so that the "tables.list" file is not open anymore, which
358+
* would otherwise make it impossible to remove the file on Windows.
359+
*/
360+
reftable_be_release(ref_store);
361+
362+
strbuf_addf(&sb, "%s/reftable", refs->base.gitdir);
363+
if (remove_dir_recursively(&sb, 0) < 0) {
364+
strbuf_addf(err, "could not delete reftables: %s",
365+
strerror(errno));
366+
ret = -1;
367+
}
368+
strbuf_reset(&sb);
369+
370+
strbuf_addf(&sb, "%s/HEAD", refs->base.gitdir);
371+
if (unlink(sb.buf) < 0) {
372+
strbuf_addf(err, "could not delete stub HEAD: %s",
373+
strerror(errno));
374+
ret = -1;
375+
}
376+
strbuf_reset(&sb);
377+
378+
strbuf_addf(&sb, "%s/refs/heads", refs->base.gitdir);
379+
if (unlink(sb.buf) < 0) {
380+
strbuf_addf(err, "could not delete stub heads: %s",
381+
strerror(errno));
382+
ret = -1;
383+
}
384+
strbuf_reset(&sb);
385+
386+
strbuf_addf(&sb, "%s/refs", refs->base.gitdir);
387+
if (rmdir(sb.buf) < 0) {
388+
strbuf_addf(err, "could not delete refs directory: %s",
389+
strerror(errno));
390+
ret = -1;
391+
}
392+
393+
strbuf_release(&sb);
394+
return ret;
395+
}
396+
346397
struct reftable_ref_iterator {
347398
struct ref_iterator base;
348399
struct reftable_ref_store *refs;
@@ -2196,6 +2247,7 @@ struct ref_storage_be refs_be_reftable = {
21962247
.init = reftable_be_init,
21972248
.release = reftable_be_release,
21982249
.create_on_disk = reftable_be_create_on_disk,
2250+
.remove_on_disk = reftable_be_remove_on_disk,
21992251

22002252
.transaction_prepare = reftable_be_transaction_prepare,
22012253
.transaction_finish = reftable_be_transaction_finish,

0 commit comments

Comments
 (0)