From: Derrick Stolee <derrickstolee@xxxxxxxxxx> Signed-off-by: Derrick Stolee <derrickstolee@xxxxxxxxxx> --- Makefile | 1 + refs/packed-backend.c | 75 +++++++++++++++++++++++++++++++++++------ refs/packed-backend.h | 7 ++++ refs/packed-format-v2.c | 38 +++++++++++++++++++++ 4 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 refs/packed-format-v2.c diff --git a/Makefile b/Makefile index 3dc887941d4..16cd245e0ad 100644 --- a/Makefile +++ b/Makefile @@ -1058,6 +1058,7 @@ LIB_OBJS += refs/files-backend.o LIB_OBJS += refs/iterator.o LIB_OBJS += refs/packed-backend.o LIB_OBJS += refs/packed-format-v1.o +LIB_OBJS += refs/packed-format-v2.o LIB_OBJS += refs/ref-cache.o LIB_OBJS += refspec.o LIB_OBJS += remote.o diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 655aab939be..09f7b74584f 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -692,6 +692,45 @@ error: return ok; } +static int write_with_updates_v1(struct packed_ref_store *refs, + struct string_list *updates, + struct strbuf *err) +{ + FILE *out; + + out = fdopen_tempfile(refs->tempfile, "w"); + if (!out) { + strbuf_addf(err, "unable to fdopen packed-refs tempfile: %s", + strerror(errno)); + goto error; + } + + if (write_packed_file_header_v1(out) < 0) { + add_write_error(refs, err); + goto error; + } + + return merge_iterator_and_updates(refs, updates, err, + write_packed_entry_v1, out); + +error: + return -1; +} + +static int write_with_updates_v2(struct packed_ref_store *refs, + struct string_list *updates, + struct strbuf *err) +{ + struct write_packed_refs_v2_context *ctx = create_v2_context(refs, updates, err); + int ok = -1; + + if ((ok = write_packed_refs_v2(ctx)) < 0) + add_write_error(refs, err); + + free_v2_context(ctx); + return ok; +} + /* * Write the packed refs from the current snapshot to the packed-refs * tempfile, incorporating any changes from `updates`. `updates` must @@ -707,9 +746,9 @@ static int write_with_updates(struct packed_ref_store *refs, struct strbuf *err) { int ok; - FILE *out; struct strbuf sb = STRBUF_INIT; char *packed_refs_path; + int version; if (!is_lock_file_locked(&refs->lock)) BUG("write_with_updates() called while unlocked"); @@ -731,21 +770,35 @@ static int write_with_updates(struct packed_ref_store *refs, } strbuf_release(&sb); - out = fdopen_tempfile(refs->tempfile, "w"); - if (!out) { - strbuf_addf(err, "unable to fdopen packed-refs tempfile: %s", - strerror(errno)); - goto error; + if (git_config_get_int("refs.packedrefsversion", &version)) { + /* + * Set the default depending on the current extension + * list. Default to version 1 if available, but allow a + * default of 2 if only "packed-v2" exists. + */ + if (refs->store_flags & REF_STORE_FORMAT_PACKED) + version = 1; + else if (refs->store_flags & REF_STORE_FORMAT_PACKED_V2) + version = 2; + else + BUG("writing a packed-refs file without an extension"); } - if (write_packed_file_header_v1(out) < 0) { - add_write_error(refs, err); + switch (version) { + case 1: + ok = write_with_updates_v1(refs, updates, err); + break; + + case 2: + ok = write_with_updates_v2(refs, updates, err); + break; + + default: + strbuf_addf(err, "unknown packed-refs version: %d", + version); goto error; } - ok = merge_iterator_and_updates(refs, updates, err, - write_packed_entry_v1, out); - if (ok != ITER_DONE) { strbuf_addstr(err, "unable to write packed-refs file: " "error iterating over old contents"); diff --git a/refs/packed-backend.h b/refs/packed-backend.h index b6908bb002c..e76f26bfc46 100644 --- a/refs/packed-backend.h +++ b/refs/packed-backend.h @@ -243,4 +243,11 @@ int write_packed_entry_v1(const char *refname, const struct object_id *peeled, void *write_data); +struct write_packed_refs_v2_context; +struct write_packed_refs_v2_context *create_v2_context(struct packed_ref_store *refs, + struct string_list *updates, + struct strbuf *err); +int write_packed_refs_v2(struct write_packed_refs_v2_context *ctx); +void free_v2_context(struct write_packed_refs_v2_context *ctx); + #endif /* REFS_PACKED_BACKEND_H */ diff --git a/refs/packed-format-v2.c b/refs/packed-format-v2.c new file mode 100644 index 00000000000..ecf3cc93694 --- /dev/null +++ b/refs/packed-format-v2.c @@ -0,0 +1,38 @@ +#include "../cache.h" +#include "../config.h" +#include "../refs.h" +#include "refs-internal.h" +#include "packed-backend.h" +#include "../iterator.h" +#include "../lockfile.h" +#include "../chdir-notify.h" + +struct write_packed_refs_v2_context { + struct packed_ref_store *refs; + struct string_list *updates; + struct strbuf *err; +}; + +struct write_packed_refs_v2_context *create_v2_context(struct packed_ref_store *refs, + struct string_list *updates, + struct strbuf *err) +{ + struct write_packed_refs_v2_context *ctx; + CALLOC_ARRAY(ctx, 1); + + ctx->refs = refs; + ctx->updates = updates; + ctx->err = err; + + return ctx; +} + +int write_packed_refs_v2(struct write_packed_refs_v2_context *ctx) +{ + return 0; +} + +void free_v2_context(struct write_packed_refs_v2_context *ctx) +{ + free(ctx); +} -- gitgitgadget