diff options
Diffstat (limited to 'refs')
| -rw-r--r-- | refs/debug.c | 13 | ||||
| -rw-r--r-- | refs/files-backend.c | 212 | ||||
| -rw-r--r-- | refs/packed-backend.c | 1 | ||||
| -rw-r--r-- | refs/refs-internal.h | 40 | ||||
| -rw-r--r-- | refs/reftable-backend.c | 202 |
5 files changed, 212 insertions, 256 deletions
diff --git a/refs/debug.c b/refs/debug.c index c7531b17f0..8be316bb67 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -131,18 +131,6 @@ static int debug_pack_refs(struct ref_store *ref_store, struct pack_refs_opts *o return res; } -static int debug_create_symref(struct ref_store *ref_store, - const char *ref_name, const char *target, - const char *logmsg) -{ - struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; - int res = drefs->refs->be->create_symref(drefs->refs, ref_name, target, - logmsg); - trace_printf_key(&trace_refs, "create_symref: %s -> %s \"%s\": %d\n", ref_name, - target, logmsg, res); - return res; -} - static int debug_rename_ref(struct ref_store *ref_store, const char *oldref, const char *newref, const char *logmsg) { @@ -441,7 +429,6 @@ struct ref_storage_be refs_be_debug = { .initial_transaction_commit = debug_initial_transaction_commit, .pack_refs = debug_pack_refs, - .create_symref = debug_create_symref, .rename_ref = debug_rename_ref, .copy_ref = debug_copy_ref, diff --git a/refs/files-backend.c b/refs/files-backend.c index a098d14ea0..3dce0c2a34 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -794,8 +794,10 @@ retry: */ if (refs_verify_refname_available( refs->packed_ref_store, refname, - extras, NULL, err)) + extras, NULL, err)) { + ret = TRANSACTION_NAME_CONFLICT; goto error_return; + } } ret = 0; @@ -1198,7 +1200,7 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r) ref_transaction_add_update( transaction, r->name, REF_NO_DEREF | REF_HAVE_NEW | REF_HAVE_OLD | REF_IS_PRUNING, - null_oid(), &r->oid, NULL); + null_oid(), &r->oid, NULL, NULL, NULL); if (ref_transaction_commit(transaction, &err)) goto cleanup; @@ -1292,7 +1294,7 @@ static int files_pack_refs(struct ref_store *ref_store, * packed-refs transaction: */ if (ref_transaction_update(transaction, iter->refname, - iter->oid, NULL, + iter->oid, NULL, NULL, NULL, REF_NO_DEREF, NULL, &err)) die("failure preparing to create packed reference %s: %s", iter->refname, err.buf); @@ -1903,66 +1905,23 @@ static int create_ref_symlink(struct ref_lock *lock, const char *target) return ret; } -static void update_symref_reflog(struct files_ref_store *refs, - struct ref_lock *lock, const char *refname, - const char *target, const char *logmsg) +static int create_symref_lock(struct files_ref_store *refs, + struct ref_lock *lock, const char *refname, + const char *target, struct strbuf *err) { - struct strbuf err = STRBUF_INIT; - struct object_id new_oid; - - if (logmsg && - refs_resolve_ref_unsafe(&refs->base, target, - RESOLVE_REF_READING, &new_oid, NULL) && - files_log_ref_write(refs, refname, &lock->old_oid, - &new_oid, logmsg, 0, &err)) { - error("%s", err.buf); - strbuf_release(&err); - } -} - -static int create_symref_locked(struct files_ref_store *refs, - struct ref_lock *lock, const char *refname, - const char *target, const char *logmsg) -{ - if (prefer_symlink_refs && !create_ref_symlink(lock, target)) { - update_symref_reflog(refs, lock, refname, target, logmsg); - return 0; + if (!fdopen_lock_file(&lock->lk, "w")) { + strbuf_addf(err, "unable to fdopen %s: %s", + get_lock_file_path(&lock->lk), strerror(errno)); + return -1; } - if (!fdopen_lock_file(&lock->lk, "w")) - return error("unable to fdopen %s: %s", + if (fprintf(get_lock_file_fp(&lock->lk), "ref: %s\n", target) < 0) { + strbuf_addf(err, "unable to write to %s: %s", get_lock_file_path(&lock->lk), strerror(errno)); - - update_symref_reflog(refs, lock, refname, target, logmsg); - - /* no error check; commit_ref will check ferror */ - fprintf(get_lock_file_fp(&lock->lk), "ref: %s\n", target); - if (commit_ref(lock) < 0) - return error("unable to write symref for %s: %s", refname, - strerror(errno)); - return 0; -} - -static int files_create_symref(struct ref_store *ref_store, - const char *refname, const char *target, - const char *logmsg) -{ - struct files_ref_store *refs = - files_downcast(ref_store, REF_STORE_WRITE, "create_symref"); - struct strbuf err = STRBUF_INIT; - struct ref_lock *lock; - int ret; - - lock = lock_ref_oid_basic(refs, refname, &err); - if (!lock) { - error("%s", err.buf); - strbuf_release(&err); return -1; } - ret = create_symref_locked(refs, lock, refname, target, logmsg); - unlock_ref(lock); - return ret; + return 0; } static int files_reflog_exists(struct ref_store *ref_store, @@ -2309,7 +2268,7 @@ static int split_head_update(struct ref_update *update, transaction, "HEAD", update->flags | REF_LOG_ONLY | REF_NO_DEREF, &update->new_oid, &update->old_oid, - update->msg); + NULL, NULL, update->msg); /* * Add "HEAD". This insertion is O(N) in the transaction @@ -2371,8 +2330,9 @@ static int split_symref_update(struct ref_update *update, new_update = ref_transaction_add_update( transaction, referent, new_flags, - &update->new_oid, &update->old_oid, - update->msg); + update->new_target ? NULL : &update->new_oid, + update->old_target ? NULL : &update->old_oid, + update->new_target, update->old_target, update->msg); new_update->parent_update = update; @@ -2401,17 +2361,6 @@ static int split_symref_update(struct ref_update *update, } /* - * Return the refname under which update was originally requested. - */ -static const char *original_update_refname(struct ref_update *update) -{ - while (update->parent_update) - update = update->parent_update; - - return update->refname; -} - -/* * Check whether the REF_HAVE_OLD and old_oid values stored in update * are consistent with oid, which is the reference's current value. If * everything is OK, return 0; otherwise, write an error message to @@ -2427,16 +2376,16 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid, if (is_null_oid(&update->old_oid)) strbuf_addf(err, "cannot lock ref '%s': " "reference already exists", - original_update_refname(update)); + ref_update_original_update_refname(update)); else if (is_null_oid(oid)) strbuf_addf(err, "cannot lock ref '%s': " "reference is missing but expected %s", - original_update_refname(update), + ref_update_original_update_refname(update), oid_to_hex(&update->old_oid)); else strbuf_addf(err, "cannot lock ref '%s': " "is at %s but expected %s", - original_update_refname(update), + ref_update_original_update_refname(update), oid_to_hex(oid), oid_to_hex(&update->old_oid)); @@ -2471,7 +2420,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, files_assert_main_repository(refs, "lock_ref_for_update"); - if ((update->flags & REF_HAVE_NEW) && is_null_oid(&update->new_oid)) + if ((update->flags & REF_HAVE_NEW) && ref_update_has_null_new_value(update)) update->flags |= REF_DELETING; if (head_ref) { @@ -2490,7 +2439,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, reason = strbuf_detach(err, NULL); strbuf_addf(err, "cannot lock ref '%s': %s", - original_update_refname(update), reason); + ref_update_original_update_refname(update), reason); free(reason); goto out; } @@ -2510,11 +2459,18 @@ static int lock_ref_for_update(struct files_ref_store *refs, if (update->flags & REF_HAVE_OLD) { strbuf_addf(err, "cannot lock ref '%s': " "error reading reference", - original_update_refname(update)); + ref_update_original_update_refname(update)); ret = TRANSACTION_GENERIC_ERROR; goto out; } - } else if (check_old_oid(update, &lock->old_oid, err)) { + } + + if (update->old_target) { + if (ref_update_check_old_target(referent.buf, update, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto out; + } + } else if (check_old_oid(update, &lock->old_oid, err)) { ret = TRANSACTION_GENERIC_ERROR; goto out; } @@ -2535,7 +2491,17 @@ static int lock_ref_for_update(struct files_ref_store *refs, } else { struct ref_update *parent_update; - if (check_old_oid(update, &lock->old_oid, err)) { + /* + * Even if the ref is a regular ref, if `old_target` is set, we + * check the referent value. Ideally `old_target` should only + * be set for symrefs, but we're strict about its usage. + */ + if (update->old_target) { + if (ref_update_check_old_target(referent.buf, update, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto out; + } + } else if (check_old_oid(update, &lock->old_oid, err)) { ret = TRANSACTION_GENERIC_ERROR; goto out; } @@ -2553,9 +2519,28 @@ static int lock_ref_for_update(struct files_ref_store *refs, } } - if ((update->flags & REF_HAVE_NEW) && - !(update->flags & REF_DELETING) && - !(update->flags & REF_LOG_ONLY)) { + if (update->new_target && !(update->flags & REF_LOG_ONLY)) { + if (create_symref_lock(refs, lock, update->refname, + update->new_target, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto out; + } + + if (close_ref_gently(lock)) { + strbuf_addf(err, "couldn't close '%s.lock'", + update->refname); + ret = TRANSACTION_GENERIC_ERROR; + goto out; + } + + /* + * Once we have created the symref lock, the commit + * phase of the transaction only needs to commit the lock. + */ + update->flags |= REF_NEEDS_COMMIT; + } else if ((update->flags & REF_HAVE_NEW) && + !(update->flags & REF_DELETING) && + !(update->flags & REF_LOG_ONLY)) { if (!(update->type & REF_ISSYMREF) && oideq(&lock->old_oid, &update->new_oid)) { /* @@ -2763,7 +2748,7 @@ static int files_transaction_prepare(struct ref_store *ref_store, packed_transaction, update->refname, REF_HAVE_NEW | REF_NO_DEREF, &update->new_oid, NULL, - NULL); + NULL, NULL, NULL); } } @@ -2818,6 +2803,43 @@ cleanup: return ret; } +static int parse_and_write_reflog(struct files_ref_store *refs, + struct ref_update *update, + struct ref_lock *lock, + struct strbuf *err) +{ + if (update->new_target) { + /* + * We want to get the resolved OID for the target, to ensure + * that the correct value is added to the reflog. + */ + if (!refs_resolve_ref_unsafe(&refs->base, update->new_target, + RESOLVE_REF_READING, + &update->new_oid, NULL)) { + /* + * TODO: currently we skip creating reflogs for dangling + * symref updates. It would be nice to capture this as + * zero oid updates however. + */ + return 0; + } + } + + if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, + &update->new_oid, update->msg, update->flags, err)) { + char *old_msg = strbuf_detach(err, NULL); + + strbuf_addf(err, "cannot update the ref '%s': %s", + lock->ref_name, old_msg); + free(old_msg); + unlock_ref(lock); + update->backend_data = NULL; + return -1; + } + + return 0; +} + static int files_transaction_finish(struct ref_store *ref_store, struct ref_transaction *transaction, struct strbuf *err) @@ -2848,23 +2870,20 @@ static int files_transaction_finish(struct ref_store *ref_store, if (update->flags & REF_NEEDS_COMMIT || update->flags & REF_LOG_ONLY) { - if (files_log_ref_write(refs, - lock->ref_name, - &lock->old_oid, - &update->new_oid, - update->msg, update->flags, - err)) { - char *old_msg = strbuf_detach(err, NULL); - - strbuf_addf(err, "cannot update the ref '%s': %s", - lock->ref_name, old_msg); - free(old_msg); - unlock_ref(lock); - update->backend_data = NULL; + if (parse_and_write_reflog(refs, update, lock, err)) { ret = TRANSACTION_GENERIC_ERROR; goto cleanup; } } + + /* + * We try creating a symlink, if that succeeds we continue to the + * next update. If not, we try and create a regular symref. + */ + if (update->new_target && prefer_symlink_refs) + if (!create_ref_symlink(lock, update->new_target)) + continue; + if (update->flags & REF_NEEDS_COMMIT) { clear_loose_ref_cache(refs); if (commit_ref(lock)) { @@ -3048,7 +3067,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store, ref_transaction_add_update(packed_transaction, update->refname, update->flags & ~REF_HAVE_OLD, &update->new_oid, &update->old_oid, - NULL); + NULL, NULL, NULL); } if (packed_refs_lock(refs->packed_ref_store, 0, err)) { @@ -3291,7 +3310,6 @@ struct ref_storage_be refs_be_files = { .initial_transaction_commit = files_initial_transaction_commit, .pack_refs = files_pack_refs, - .create_symref = files_create_symref, .rename_ref = files_rename_ref, .copy_ref = files_copy_ref, diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 4e826c05ff..a937e7dbfc 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1714,7 +1714,6 @@ struct ref_storage_be refs_be_packed = { .initial_transaction_commit = packed_initial_transaction_commit, .pack_refs = packed_pack_refs, - .create_symref = NULL, .rename_ref = NULL, .copy_ref = NULL, diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 56641aa57a..53a6c5d842 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -125,6 +125,19 @@ struct ref_update { struct object_id old_oid; /* + * If set, point the reference to this value. This can also be + * used to convert regular references to become symbolic refs. + * Cannot be set together with `new_oid`. + */ + const char *new_target; + + /* + * If set, check that the reference previously pointed to this + * value. Cannot be set together with `old_oid`. + */ + const char *old_target; + + /* * One or more of REF_NO_DEREF, REF_FORCE_CREATE_REFLOG, * REF_HAVE_NEW, REF_HAVE_OLD, or backend-specific flags. */ @@ -173,6 +186,7 @@ struct ref_update *ref_transaction_add_update( const char *refname, unsigned int flags, const struct object_id *new_oid, const struct object_id *old_oid, + const char *new_target, const char *old_target, const char *msg); /* @@ -552,10 +566,6 @@ typedef int ref_transaction_commit_fn(struct ref_store *refs, typedef int pack_refs_fn(struct ref_store *ref_store, struct pack_refs_opts *opts); -typedef int create_symref_fn(struct ref_store *ref_store, - const char *ref_target, - const char *refs_heads_master, - const char *logmsg); typedef int rename_ref_fn(struct ref_store *ref_store, const char *oldref, const char *newref, const char *logmsg); @@ -676,7 +686,6 @@ struct ref_storage_be { ref_transaction_commit_fn *initial_transaction_commit; pack_refs_fn *pack_refs; - create_symref_fn *create_symref; rename_ref_fn *rename_ref; copy_ref_fn *copy_ref; @@ -735,4 +744,25 @@ void base_ref_store_init(struct ref_store *refs, struct repository *repo, */ struct ref_store *maybe_debug_wrap_ref_store(const char *gitdir, struct ref_store *store); +/* + * Return the refname under which update was originally requested. + */ +const char *ref_update_original_update_refname(struct ref_update *update); + +/* + * Helper function to check if the new value is null, this + * takes into consideration that the update could be a regular + * ref or a symbolic ref. + */ +int ref_update_has_null_new_value(struct ref_update *update); + +/* + * Check whether the old_target values stored in update are consistent + * with the referent, which is the symbolic reference's current value. + * If everything is OK, return 0; otherwise, write an error message to + * err and return -1. + */ +int ref_update_check_old_target(const char *referent, struct ref_update *update, + struct strbuf *err); + #endif /* REFS_REFS_INTERNAL_H */ diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 010ef811b6..98cebbcf39 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -579,16 +579,6 @@ static int reftable_be_read_symbolic_ref(struct ref_store *ref_store, return ret; } -/* - * Return the refname under which update was originally requested. - */ -static const char *original_update_refname(struct ref_update *update) -{ - while (update->parent_update) - update = update->parent_update; - return update->refname; -} - struct reftable_transaction_update { struct ref_update *update; struct object_id current_oid; @@ -827,7 +817,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, new_update = ref_transaction_add_update( transaction, "HEAD", u->flags | REF_LOG_ONLY | REF_NO_DEREF, - &u->new_oid, &u->old_oid, u->msg); + &u->new_oid, &u->old_oid, NULL, NULL, u->msg); string_list_insert(&affected_refnames, new_update->refname); } @@ -854,7 +844,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, * There is no need to write the reference deletion * when the reference in question doesn't exist. */ - if (u->flags & REF_HAVE_NEW && !is_null_oid(&u->new_oid)) { + if ((u->flags & REF_HAVE_NEW) && !ref_update_has_null_new_value(u)) { ret = queue_transaction_update(refs, tx_data, u, ¤t_oid, err); if (ret) @@ -867,7 +857,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, /* The reference does not exist, but we expected it to. */ strbuf_addf(err, _("cannot lock ref '%s': " "unable to resolve reference '%s'"), - original_update_refname(u), u->refname); + ref_update_original_update_refname(u), u->refname); ret = -1; goto done; } @@ -905,8 +895,10 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, * intertwined with the locking in files-backend.c. */ new_update = ref_transaction_add_update( - transaction, referent.buf, new_flags, - &u->new_oid, &u->old_oid, u->msg); + transaction, referent.buf, new_flags, + &u->new_oid, &u->old_oid, u->new_target, + u->old_target, u->msg); + new_update->parent_update = u; /* @@ -936,20 +928,25 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, * individual refs. But the error messages match what the files * backend returns, which keeps our tests happy. */ - if (u->flags & REF_HAVE_OLD && !oideq(¤t_oid, &u->old_oid)) { + if (u->old_target) { + if (ref_update_check_old_target(referent.buf, u, err)) { + ret = -1; + goto done; + } + } else if ((u->flags & REF_HAVE_OLD) && !oideq(¤t_oid, &u->old_oid)) { if (is_null_oid(&u->old_oid)) strbuf_addf(err, _("cannot lock ref '%s': " - "reference already exists"), - original_update_refname(u)); + "reference already exists"), + ref_update_original_update_refname(u)); else if (is_null_oid(¤t_oid)) strbuf_addf(err, _("cannot lock ref '%s': " - "reference is missing but expected %s"), - original_update_refname(u), + "reference is missing but expected %s"), + ref_update_original_update_refname(u), oid_to_hex(&u->old_oid)); else strbuf_addf(err, _("cannot lock ref '%s': " - "is at %s but expected %s"), - original_update_refname(u), + "is at %s but expected %s"), + ref_update_original_update_refname(u), oid_to_hex(¤t_oid), oid_to_hex(&u->old_oid)); ret = -1; @@ -1047,7 +1044,9 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data * - `core.logAllRefUpdates` tells us to create the reflog for * the given ref. */ - if (u->flags & REF_HAVE_NEW && !(u->type & REF_ISSYMREF) && is_null_oid(&u->new_oid)) { + if ((u->flags & REF_HAVE_NEW) && + !(u->type & REF_ISSYMREF) && + ref_update_has_null_new_value(u)) { struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; @@ -1088,24 +1087,52 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data (u->flags & REF_FORCE_CREATE_REFLOG || should_write_log(&arg->refs->base, u->refname))) { struct reftable_log_record *log; + int create_reflog = 1; + + if (u->new_target) { + if (!refs_resolve_ref_unsafe(&arg->refs->base, u->new_target, + RESOLVE_REF_READING, &u->new_oid, NULL)) { + /* + * TODO: currently we skip creating reflogs for dangling + * symref updates. It would be nice to capture this as + * zero oid updates however. + */ + create_reflog = 0; + } + } - ALLOC_GROW(logs, logs_nr + 1, logs_alloc); - log = &logs[logs_nr++]; - memset(log, 0, sizeof(*log)); - - fill_reftable_log_record(log, &committer_ident); - log->update_index = ts; - log->refname = xstrdup(u->refname); - memcpy(log->value.update.new_hash, u->new_oid.hash, GIT_MAX_RAWSZ); - memcpy(log->value.update.old_hash, tx_update->current_oid.hash, GIT_MAX_RAWSZ); - log->value.update.message = - xstrndup(u->msg, arg->refs->write_options.block_size / 2); + if (create_reflog) { + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + log = &logs[logs_nr++]; + memset(log, 0, sizeof(*log)); + + fill_reftable_log_record(log, &committer_ident); + log->update_index = ts; + log->refname = xstrdup(u->refname); + memcpy(log->value.update.new_hash, + u->new_oid.hash, GIT_MAX_RAWSZ); + memcpy(log->value.update.old_hash, + tx_update->current_oid.hash, GIT_MAX_RAWSZ); + log->value.update.message = + xstrndup(u->msg, arg->refs->write_options.block_size / 2); + } } if (u->flags & REF_LOG_ONLY) continue; - if (u->flags & REF_HAVE_NEW && is_null_oid(&u->new_oid)) { + if (u->new_target) { + struct reftable_ref_record ref = { + .refname = (char *)u->refname, + .value_type = REFTABLE_REF_SYMREF, + .value.symref = (char *)u->new_target, + .update_index = ts, + }; + + ret = reftable_writer_add_ref(writer, &ref); + if (ret < 0) + goto done; + } else if ((u->flags & REF_HAVE_NEW) && ref_update_has_null_new_value(u)) { struct reftable_ref_record ref = { .refname = (char *)u->refname, .update_index = ts, @@ -1237,110 +1264,6 @@ struct write_create_symref_arg { const char *logmsg; }; -static int write_create_symref_table(struct reftable_writer *writer, void *cb_data) -{ - struct write_create_symref_arg *create = cb_data; - uint64_t ts = reftable_stack_next_update_index(create->stack); - struct reftable_ref_record ref = { - .refname = (char *)create->refname, - .value_type = REFTABLE_REF_SYMREF, - .value.symref = (char *)create->target, - .update_index = ts, - }; - struct ident_split committer_ident = {0}; - struct reftable_log_record log = {0}; - struct object_id new_oid; - struct object_id old_oid; - const char *committer_info; - int ret; - - reftable_writer_set_limits(writer, ts, ts); - - ret = refs_verify_refname_available(&create->refs->base, create->refname, - NULL, NULL, create->err); - if (ret < 0) - return ret; - - ret = reftable_writer_add_ref(writer, &ref); - if (ret) - return ret; - - /* - * Note that it is important to try and resolve the reference before we - * write the log entry. This is because `should_write_log()` will munge - * `core.logAllRefUpdates`, which is undesirable when we create a new - * repository because it would be written into the config. As HEAD will - * not resolve for new repositories this ordering will ensure that this - * never happens. - */ - if (!create->logmsg || - !refs_resolve_ref_unsafe(&create->refs->base, create->target, - RESOLVE_REF_READING, &new_oid, NULL) || - !should_write_log(&create->refs->base, create->refname)) - return 0; - - committer_info = git_committer_info(0); - if (split_ident_line(&committer_ident, committer_info, strlen(committer_info))) - BUG("failed splitting committer info"); - - fill_reftable_log_record(&log, &committer_ident); - log.refname = xstrdup(create->refname); - log.update_index = ts; - log.value.update.message = xstrndup(create->logmsg, - create->refs->write_options.block_size / 2); - memcpy(log.value.update.new_hash, new_oid.hash, GIT_MAX_RAWSZ); - if (refs_resolve_ref_unsafe(&create->refs->base, create->refname, - RESOLVE_REF_READING, &old_oid, NULL)) - memcpy(log.value.update.old_hash, old_oid.hash, GIT_MAX_RAWSZ); - - ret = reftable_writer_add_log(writer, &log); - reftable_log_record_release(&log); - return ret; -} - -static int reftable_be_create_symref(struct ref_store *ref_store, - const char *refname, - const char *target, - const char *logmsg) -{ - struct reftable_ref_store *refs = - reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_symref"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); - struct strbuf err = STRBUF_INIT; - struct write_create_symref_arg arg = { - .refs = refs, - .stack = stack, - .refname = refname, - .target = target, - .logmsg = logmsg, - .err = &err, - }; - int ret; - - ret = refs->err; - if (ret < 0) - goto done; - - ret = reftable_stack_reload(stack); - if (ret) - goto done; - - ret = reftable_stack_add(stack, &write_create_symref_table, &arg); - -done: - assert(ret != REFTABLE_API_ERROR); - if (ret) { - if (err.len) - error("%s", err.buf); - else - error("unable to write symref for %s: %s", refname, - reftable_error_str(ret)); - } - - strbuf_release(&err); - return ret; -} - struct write_copy_arg { struct reftable_ref_store *refs; struct reftable_stack *stack; @@ -2255,7 +2178,6 @@ struct ref_storage_be refs_be_reftable = { .initial_transaction_commit = reftable_be_initial_transaction_commit, .pack_refs = reftable_be_pack_refs, - .create_symref = reftable_be_create_symref, .rename_ref = reftable_be_rename_ref, .copy_ref = reftable_be_copy_ref, |
