From patchwork Tue May 7 06:00:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656282 Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com [209.85.167.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6151E6BFA6 for ; Tue, 7 May 2024 06:00:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061648; cv=none; b=elzv/ztz5cmNd7kti24Crqo6DFaAy8+bq3qOkUpOJwGsQIVDcxujWhqaBAwhvBxzTAHZWf2DcFVU5SlbXCHcyOsq7FYKCyMeAQIqjB6pxsgoul9+cJEqE3Qt5sBh8n4KH4iDPrWuYXgYlrldv/DY7y6ihRxHCdJvtlFCDYPHAKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061648; c=relaxed/simple; bh=zQxDD9fY2hqKoLtyTsKLx5rm4COwe0VQzHfvY0VLlPQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GlLZtSF/93HMDDNgqX88NH7m3AJ6MQkDqym2b6zS3mecQHAsLTGUsrA03B1kilcedAuTPTEoM4XDkAjCndfj8T+R3QgMyxoUv1YEukkRfoNfUfAhfB62+Mzi6hYKscEg/ggY7XPnLT6n87E9vYjRFSBcnAzeR4cKQoMEsnpe59U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XxQgmfJ/; arc=none smtp.client-ip=209.85.167.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XxQgmfJ/" Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-51f1b378ca5so4639305e87.1 for ; Mon, 06 May 2024 23:00:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061644; x=1715666444; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4SM3sxWp3ptbNyMoTOMjN0vGJxRLhxiA+TANcGco65w=; b=XxQgmfJ/SjJa+dIP9qBMF3RxuyMug+oPYF7fqd9+Wmh4gP9uXSxVPs2BxEEr/IT8r0 209j14Qll9mZ7dElq/FARjqGGN1Ck68pXxRetlIEoo7hMQY5S08B3v+PxZVOsR/tRiJ5 J+inMc1aFXyv5e30IxzYPP3P6p0KsNmoYunS81Mii/XTQzxZoPXJ1hCW0P5gy6oyZJOF MUC9wsYzx4Ppkh/4jAl1ar7LuPphsI70S5eVJv3VgET8ElA7AZ7lNaMshlv4Pt8arciD if7rrUboSiLuqLvu8VmpVG7xYzxnU2VoJvCKCdFqDdaabuDT1fPucEUvV9Gn7rAXA/Mx qamQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061644; x=1715666444; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4SM3sxWp3ptbNyMoTOMjN0vGJxRLhxiA+TANcGco65w=; b=k2X7agPyRtMc2XJmjududlhQ/DVJXT6YZYByhhcwZTDgKAryNbfUctOl69vtDeVmOR alTkbUclHfyqLYRrXtRJ2O1SqLkVLzEZ7xc5XGfdqC2xWYiDShjSWrWY7NZbTUwy9Ud/ h8HJev8i6QeIo9fEIIZ2kONutyy6Nat8D4Idt9Gmk91eQNCBihEx4RMT4VMKrjXlgMaO US1Q9iA2At9Q/YjaRhCHXYgPuISRcoOfzswxbV4ukJbBdjudvOrqFdboka+6FBPQZABF UQinBs8DE9lY8ykT5oAoZMUBwt6LMiPfdDyQK2D9TLLmZimoenb3G1vZFwxNqE1NZYUB N/Nw== X-Forwarded-Encrypted: i=1; AJvYcCWvsRRH3AHr5HlUoVHmSAO6V9kwk8KHzAoVPcbojWcb/9mCSH8WBaBcGju04ZbeCpvsd2GO8BNJGa4FBw0mrp7Jw73H X-Gm-Message-State: AOJu0Yzmqpr0MttlubIBYzlTO3Vbsvfyz+bfy/ek0MGVR+CQmgXzrM9v tIdlftk2orWT/iU67iPXse+eMAtlKw+gjbLzbOzYstw4R2QoHQ+W X-Google-Smtp-Source: AGHT+IHc0hn+xHIO2rlPJXs6QueR4xQRHO6jUhwa5584W1hyaIhHWJq0dG3Rz5siDueay0+n/fJaOw== X-Received: by 2002:ac2:58d9:0:b0:519:166a:d217 with SMTP id u25-20020ac258d9000000b00519166ad217mr8625265lfo.32.1715061643964; Mon, 06 May 2024 23:00:43 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:43 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 1/8] refs: accept symref values in `ref_transaction_update()` Date: Tue, 7 May 2024 08:00:28 +0200 Message-ID: <20240507060035.28602-2-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The function `ref_transaction_update()` obtains ref information and flags to create a `ref_update` and add them to the transaction at hand. To extend symref support in transactions, we need to also accept the old and new ref targets and process it. This commit adds the required parameters to the function and modifies all call sites. The two parameters added are `new_target` and `old_target`. The `new_target` is used to denote what the reference should point to when the transaction is applied. Some functions allow this parameter to be NULL, meaning that the reference is not changed. The `old_target` denotes the value the reference must have before the update. Some functions allow this parameter to be NULL, meaning that the old value of the reference is not checked. We also update the internal function `ref_transaction_add_update()` similarly to take the two new parameters. Signed-off-by: Karthik Nayak --- branch.c | 2 +- builtin/fast-import.c | 5 +++-- builtin/fetch.c | 2 +- builtin/receive-pack.c | 1 + builtin/replace.c | 2 +- builtin/tag.c | 1 + builtin/update-ref.c | 1 + refs.c | 22 +++++++++++++++++----- refs.h | 18 +++++++++++++++++- refs/files-backend.c | 12 ++++++------ refs/refs-internal.h | 14 ++++++++++++++ refs/reftable-backend.c | 4 ++-- sequencer.c | 9 +++++---- walker.c | 2 +- 14 files changed, 71 insertions(+), 24 deletions(-) diff --git a/branch.c b/branch.c index e4a738fc7b..48af4c3ceb 100644 --- a/branch.c +++ b/branch.c @@ -627,7 +627,7 @@ void create_branch(struct repository *r, if (!transaction || ref_transaction_update(transaction, ref.buf, &oid, forcing ? NULL : null_oid(), - 0, msg, &err) || + NULL, NULL, 0, msg, &err) || ref_transaction_commit(transaction, &err)) die("%s", err.buf); ref_transaction_free(transaction); diff --git a/builtin/fast-import.c b/builtin/fast-import.c index dc5a9d32dd..297dfb91a1 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -1634,7 +1634,7 @@ static int update_branch(struct branch *b) transaction = ref_transaction_begin(&err); if (!transaction || ref_transaction_update(transaction, b->name, &b->oid, &old_oid, - 0, msg, &err) || + NULL, NULL, 0, msg, &err) || ref_transaction_commit(transaction, &err)) { ref_transaction_free(transaction); error("%s", err.buf); @@ -1675,7 +1675,8 @@ static void dump_tags(void) strbuf_addf(&ref_name, "refs/tags/%s", t->name); if (ref_transaction_update(transaction, ref_name.buf, - &t->oid, NULL, 0, msg, &err)) { + &t->oid, NULL, NULL, NULL, + 0, msg, &err)) { failure |= error("%s", err.buf); goto cleanup; } diff --git a/builtin/fetch.c b/builtin/fetch.c index 5857d860db..66840b7c5b 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -668,7 +668,7 @@ static int s_update_ref(const char *action, ret = ref_transaction_update(transaction, ref->name, &ref->new_oid, check_old ? &ref->old_oid : NULL, - 0, msg, &err); + NULL, NULL, 0, msg, &err); if (ret) { ret = STORE_REF_ERROR_OTHER; goto out; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index e8d7df14b6..b150ef39a8 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1595,6 +1595,7 @@ static const char *update(struct command *cmd, struct shallow_info *si) if (ref_transaction_update(transaction, namespaced_name, new_oid, old_oid, + NULL, NULL, 0, "push", &err)) { rp_error("%s", err.buf); diff --git a/builtin/replace.c b/builtin/replace.c index da59600ad2..7690687b0e 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -201,7 +201,7 @@ static int replace_object_oid(const char *object_ref, transaction = ref_transaction_begin(&err); if (!transaction || ref_transaction_update(transaction, ref.buf, repl, &prev, - 0, NULL, &err) || + NULL, NULL, 0, NULL, &err) || ref_transaction_commit(transaction, &err)) res = error("%s", err.buf); diff --git a/builtin/tag.c b/builtin/tag.c index 9a33cb50b4..40a65fdebc 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -660,6 +660,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) transaction = ref_transaction_begin(&err); if (!transaction || ref_transaction_update(transaction, ref.buf, &object, &prev, + NULL, NULL, create_reflog ? REF_FORCE_CREATE_REFLOG : 0, reflog_msg.buf, &err) || ref_transaction_commit(transaction, &err)) { diff --git a/builtin/update-ref.c b/builtin/update-ref.c index e46afbc46d..21fdbf6ac8 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -204,6 +204,7 @@ static void parse_cmd_update(struct ref_transaction *transaction, if (ref_transaction_update(transaction, refname, &new_oid, have_old ? &old_oid : NULL, + NULL, NULL, update_flags | create_reflog_flag, msg, &err)) die("%s", err.buf); diff --git a/refs.c b/refs.c index 7c3c7465a4..d7df137904 100644 --- a/refs.c +++ b/refs.c @@ -1268,6 +1268,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) { struct ref_update *update; @@ -1275,6 +1276,11 @@ struct ref_update *ref_transaction_add_update( if (transaction->state != REF_TRANSACTION_OPEN) BUG("update called for transaction that is not open"); + if (old_oid && old_target) + BUG("only one of old_oid and old_target should be non NULL"); + if (new_oid && new_target) + BUG("only one of new_oid and new_target should be non NULL"); + FLEX_ALLOC_STR(update, refname, refname); ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc); transaction->updates[transaction->nr++] = update; @@ -1293,6 +1299,8 @@ int ref_transaction_update(struct ref_transaction *transaction, const char *refname, const struct object_id *new_oid, const struct object_id *old_oid, + const char *new_target, + const char *old_target, unsigned int flags, const char *msg, struct strbuf *err) { @@ -1327,7 +1335,8 @@ int ref_transaction_update(struct ref_transaction *transaction, flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0); ref_transaction_add_update(transaction, refname, flags, - new_oid, old_oid, msg); + new_oid, old_oid, new_target, + old_target, msg); return 0; } @@ -1342,7 +1351,8 @@ int ref_transaction_create(struct ref_transaction *transaction, return 1; } return ref_transaction_update(transaction, refname, new_oid, - null_oid(), flags, msg, err); + null_oid(), NULL, NULL, flags, + msg, err); } int ref_transaction_delete(struct ref_transaction *transaction, @@ -1355,7 +1365,8 @@ int ref_transaction_delete(struct ref_transaction *transaction, BUG("delete called with old_oid set to zeros"); return ref_transaction_update(transaction, refname, null_oid(), old_oid, - flags, msg, err); + NULL, NULL, flags, + msg, err); } int ref_transaction_verify(struct ref_transaction *transaction, @@ -1368,6 +1379,7 @@ int ref_transaction_verify(struct ref_transaction *transaction, BUG("verify called with old_oid set to NULL"); return ref_transaction_update(transaction, refname, NULL, old_oid, + NULL, NULL, flags, NULL, err); } @@ -1382,8 +1394,8 @@ int refs_update_ref(struct ref_store *refs, const char *msg, t = ref_store_transaction_begin(refs, &err); if (!t || - ref_transaction_update(t, refname, new_oid, old_oid, flags, msg, - &err) || + ref_transaction_update(t, refname, new_oid, old_oid, NULL, NULL, + flags, msg, &err) || ref_transaction_commit(t, &err)) { ret = 1; ref_transaction_free(t); diff --git a/refs.h b/refs.h index 8255989e7e..9abbfd35a2 100644 --- a/refs.h +++ b/refs.h @@ -648,6 +648,16 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err); * before the update. A copy of this value is made in the * transaction. * + * new_target -- the target reference that the reference will be + * updated to point to. If the reference is a regular reference, + * it will be converted to a symbolic reference. Cannot be set + * together with `new_oid`. A copy of this value is made in the + * transaction. + * + * old_target -- the reference that the reference must be pointing to. + * Canont be set together with `old_oid`. A copy of this value is + * made in the transaction. + * * flags -- flags affecting the update, passed to * update_ref_lock(). Possible flags: REF_NO_DEREF, * REF_FORCE_CREATE_REFLOG. See those constants for more @@ -713,7 +723,11 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err); * beforehand. The old value is checked after the lock is taken to * prevent races. If the old value doesn't agree with old_oid, the * whole transaction fails. If old_oid is NULL, then the previous - * value is not checked. + * value is not checked. If `old_target` is not NULL, treat the reference + * as a symbolic ref and validate that its target before the update is + * `old_target`. If the `new_target` is not NULL, then the reference + * will be updated to a symbolic ref which targets `new_target`. + * Together, these allow us to update between regular refs and symrefs. * * See the above comment "Reference transaction updates" for more * information. @@ -722,6 +736,8 @@ int ref_transaction_update(struct ref_transaction *transaction, const char *refname, const struct object_id *new_oid, const struct object_id *old_oid, + const char *new_target, + const char *old_target, unsigned int flags, const char *msg, struct strbuf *err); diff --git a/refs/files-backend.c b/refs/files-backend.c index ea927c516d..7e432cf026 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1197,7 +1197,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; @@ -1291,7 +1291,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); @@ -2308,7 +2308,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,7 +2371,7 @@ 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); + NULL, NULL, update->msg); new_update->parent_update = update; @@ -2762,7 +2762,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); } } @@ -3047,7 +3047,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)) { diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 56641aa57a..108f4ec419 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -124,6 +124,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); /* diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 10ee92e1f7..f48ab5ad22 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -870,7 +870,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); } @@ -949,7 +949,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, */ new_update = ref_transaction_add_update( transaction, referent.buf, new_flags, - &u->new_oid, &u->old_oid, u->msg); + &u->new_oid, &u->old_oid, NULL, NULL, u->msg); new_update->parent_update = u; /* diff --git a/sequencer.c b/sequencer.c index 88de4dc20f..61e007d85f 100644 --- a/sequencer.c +++ b/sequencer.c @@ -665,7 +665,7 @@ static int fast_forward_to(struct repository *r, if (!transaction || ref_transaction_update(transaction, "HEAD", to, unborn && !is_rebase_i(opts) ? - null_oid() : from, + null_oid() : from, NULL, NULL, 0, sb.buf, &err) || ref_transaction_commit(transaction, &err)) { ref_transaction_free(transaction); @@ -1298,7 +1298,7 @@ int update_head_with_reflog(const struct commit *old_head, if (!transaction || ref_transaction_update(transaction, "HEAD", new_head, old_head ? &old_head->object.oid : null_oid(), - 0, sb.buf, err) || + NULL, NULL, 0, sb.buf, err) || ref_transaction_commit(transaction, err)) { ret = -1; } @@ -3832,8 +3832,9 @@ static int do_label(struct repository *r, const char *name, int len) } else if (repo_get_oid(r, "HEAD", &head_oid)) { error(_("could not read HEAD")); ret = -1; - } else if (ref_transaction_update(transaction, ref_name.buf, &head_oid, - NULL, 0, msg.buf, &err) < 0 || + } else if (ref_transaction_update(transaction, ref_name.buf, + &head_oid, NULL, NULL, NULL, + 0, msg.buf, &err) < 0 || ref_transaction_commit(transaction, &err)) { error("%s", err.buf); ret = -1; diff --git a/walker.c b/walker.c index c0fd632d92..1b3df43906 100644 --- a/walker.c +++ b/walker.c @@ -324,7 +324,7 @@ int walker_fetch(struct walker *walker, int targets, char **target, strbuf_reset(&refname); strbuf_addf(&refname, "refs/%s", write_ref[i]); if (ref_transaction_update(transaction, refname.buf, - oids + i, NULL, 0, + oids + i, NULL, NULL, NULL, 0, msg ? msg : "fetch (unknown)", &err)) { error("%s", err.buf); From patchwork Tue May 7 06:00:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656283 Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A95E96E61E for ; Tue, 7 May 2024 06:00:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061649; cv=none; b=tBy7agTZB5yqXdeBLqTd3DRNnUod1RkOTNtf9/OSAGfTebskjSyMQZ5KxCPLvesaJodFNBqyAMvcDpmKMWfyManpEFzfASgmWW9TmxbYi59LbWhI7ORfO4fglEsyGTIPifb4QNFPb67Hi40V8LkYP9Wa8DeF8Flsu53fZP7CG7o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061649; c=relaxed/simple; bh=VkRW+ZBkxA/CvtLiP78ty+3rxW9ryHbybS89zYiqGv0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oM3p+9f/CcmuTCAExHPtf2Yiu7sQUDvub4G/u8dQ5bahodU/yZoN0TtGGIU8IbAkhj4jlgW1MbrB7aJ4nB0BZ01qDvlIQ59AxBynaFPwEQHuy5pPfAP3zWu777ekVjkxYZOq+1YXcHr2J1Nbl6QnEhhLPj2DjV0So2hZh6e/3qk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DPGbUu5/; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DPGbUu5/" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-51ffff16400so3792131e87.2 for ; Mon, 06 May 2024 23:00:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061646; x=1715666446; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Cgxw0fHacZoNXQLo7BaHZtOt/IT1F3iuSKCHI1fQRM0=; b=DPGbUu5/jy2KAJhfmWORe6/uCwDuf5Rbo2jM/VivCp9pOQIVItOSb5/EIGSiOKCQel H4aozabD+VrtW6mkv7Z6uRXIvon+EomH6UbpGEiVSmeYZ8OfZ62kg9I65N6ATmZEtRJD EzI2AtP+WWUrw975hl31caiincBnBQX05wKyZxUsIrQBu27Lvc930O2qhXN0Njd7BFjw xAazd0bg2wtMgc6z+LQjzYlMZJjb17f8n1GxrOw1Sq0NQWkeud2ghtQqYoUzHsj+PDxH t1iVTOhaav0pBOILSix5RgonRZxjpCgmy9a4tBjpMiPpkiyI7kpauh9li0VCJA/cdqGi WJBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061646; x=1715666446; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Cgxw0fHacZoNXQLo7BaHZtOt/IT1F3iuSKCHI1fQRM0=; b=E9HRxB+9f2ODEfLGSaSbE/QdDbKPESafqLDPWGV2hBAc/xaerXLyekvZIaft/Oi7co jDbOQzpQC2a1ZtW+GYUgQJsIx8mVhL1DOaFZKpQuNiuW5GwOpagJTgl40/WfXhkBcxCF yXTzIKGP+zbLAJ9dXulu2G/hAVdPsuhm7ePKXqOGfD1P/P8zpUYZFoJTni2kvGsu/5OY hgOFQePdjagXwI41ZItWWgyxBq6Egov9EmRnk/eY5N0GBJZ7EIGBDUX2Lm0llZ2rED5C dhdFePY/JwRemnKbNgdnQb9YbuTuQx0n876+N6Qo39z6V55ywzgIM1oHBNPCH0JaSd7V USxw== X-Forwarded-Encrypted: i=1; AJvYcCXGJvVCITNej5kg9b352K4dV4/m8qCK4cqg7uZ5me0KgmaQP1U5YrqN+t2d1XK5SCZWN6WGjby1+xHcZzJIkuHLSHRr X-Gm-Message-State: AOJu0YwFVm7wzYkLaLb4nGUNNfWOZ0Yq0tnnfsc+tjDkvz+8c/olLDqj A6fUVu/l3LY8hiUQW8D6ZasOtH7OJeWSAUUSADWeF09rD8xedP+/ X-Google-Smtp-Source: AGHT+IFe9AndMfdvzCACSZgwvnfNMR/BysLf6Ld0A4bYKB0asf5/h+n2Zk7KtGNmnrZ3mgGYSRsTVw== X-Received: by 2002:a05:6512:36cf:b0:51d:4c8a:bbdb with SMTP id e15-20020a05651236cf00b0051d4c8abbdbmr8844644lfs.3.1715061645625; Mon, 06 May 2024 23:00:45 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:44 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 2/8] files-backend: extract out `create_symref_lock()` Date: Tue, 7 May 2024 08:00:29 +0200 Message-ID: <20240507060035.28602-3-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The function `create_symref_locked()` creates a symref by creating a '.lock' file and then committing the symref lock, which creates the final symref. Extract the early half of `create_symref_locked()` into a new helper function `create_symref_lock()`. Because the name of the new function is too similar to the original, rename the original to `create_and_commit_symref()` to avoid confusion. The new function `create_symref_locked()` can be used to create the symref lock in a separate step from that of committing it. This allows to add transactional support for symrefs, where the lock would be created in the preparation step and the lock would be committed in the finish step. Signed-off-by: Karthik Nayak --- refs/files-backend.c | 51 ++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 7e432cf026..40cc715ea7 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1919,27 +1919,49 @@ static void update_symref_reflog(struct files_ref_store *refs, } } -static int create_symref_locked(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) { + 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 (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)); + return -1; + } + + return 0; +} + +static int create_and_commit_symref(struct files_ref_store *refs, + struct ref_lock *lock, const char *refname, + const char *target, const char *logmsg) +{ + struct strbuf err = STRBUF_INIT; + int ret; + 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")) - return error("unable to fdopen %s: %s", - get_lock_file_path(&lock->lk), strerror(errno)); + ret = create_symref_lock(refs, lock, refname, target, &err); + if (!ret) { + update_symref_reflog(refs, lock, refname, target, logmsg); - update_symref_reflog(refs, lock, refname, target, logmsg); + if (commit_ref(lock) < 0) + return error("unable to write symref for %s: %s", refname, + strerror(errno)); + } else { + return error("%s", err.buf); + } - /* 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; + return ret; } static int files_create_symref(struct ref_store *ref_store, @@ -1959,7 +1981,8 @@ static int files_create_symref(struct ref_store *ref_store, return -1; } - ret = create_symref_locked(refs, lock, refname, target, logmsg); + ret = create_and_commit_symref(refs, lock, refname, target, logmsg); + unlock_ref(lock); return ret; } From patchwork Tue May 7 06:00:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656284 Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62B5E6EB7A for ; Tue, 7 May 2024 06:00:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061650; cv=none; b=etvc1tYFBaUhkAT85+NuxFgThUtPAUmu+usmVL7I5C4j7FcD7IJvPtqGmlva1Mbc0CzyZ/73ufElwhdYWh7/y1v2Ig58OaKzv/R4j+ycJul6j1e+4lKn0nczUe8uTlqEN1N8YH7qlFmoUnBVewfKzMDjc6mmDQPsPNmitkMwfaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061650; c=relaxed/simple; bh=7Pf1fx0P4z980EmQ+ovkbhphpSd8ZE2uzC7W9ZQebKg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eDCA+VVj3BfEpEy4+uQb3/9MQe3uVS95TXNSJJieYazX6i1lAByr1CDRJ5xijz8uJzXbxfmfqBiEP5ADat+XVpVsKhBMp8xUC9arj/eHeFFjdCv8ScKXlM05ULVqO6ylrGpeo4EyCPnT+uL4d0bTN8GYAGoSUHm85ZNcUzqQyc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=A309qOWK; arc=none smtp.client-ip=209.85.218.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A309qOWK" Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-a59ece5e18bso65185966b.2 for ; Mon, 06 May 2024 23:00:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061647; x=1715666447; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=P02ZmJE6RNT/N2lLFf2c/XtYHhmAMQqkNxwNabNxb/g=; b=A309qOWKMb0fZ9TuHTvGuMCEHPULt9MCrYukF1Om5H8tvV7XFV0aRgUqhHuhkz5hbJ OAUjQEGT2+N2cT4Zpm3wzG0A0X/+ZK+j6Bgp6r7YsmeZ0PJ8G053jNZDZ8hEuO6CHBRZ fWDOi7vI73ClaNsjKRuscCuJMZuzRhimEHp1tnaock8PC52r36f/k3dmxcLKfXTWUoLH Kzho1F8M95UQf7irCnju1KvQWZvshxlCk9Q5aOlpWURJx+jTF3S9fRIkHD4wfgqy2mUG cpzK3JZjjjjeqL5M4xoqoneeExiheitinkOOBmi+wQ5nIfdLiOB0MXZALBi3AvVIBb8y Rrqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061647; x=1715666447; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P02ZmJE6RNT/N2lLFf2c/XtYHhmAMQqkNxwNabNxb/g=; b=CN9BkB7nhODy1tilJPBFfYnmixmbEKBAAvRHVUplDXDtzrf/VTCoUV/QGYm1MTJXsD I5tQTxq86FfOM4so9oEwtxzqRCZp2Sfm5BardojK3E7yXPHxjkH4eyAwcBlKKSL5R5zr 0h4SAUylhjVmIKGTCba3CzKoQ5OmoxxmhKo2zh/XojVUkVxUOfc+YxJPQs9L4PkR6j2Y 004y43XcooBYIGI21ts8jA/ULmwid939o/yvqhnHW36VTJb9n+r7hy3mTmuHpawokaAm pJs5wCio9m/q+stidT3MMvlXd/gYC+NdtgV+uwD9hHf1z5lRmnuDpEe6muReWxYLT1he 6KwQ== X-Forwarded-Encrypted: i=1; AJvYcCVrO6jSwcd3NpzujFECfixcGRS7lxkT3SYNJ7xqgBatXNymctSnkdN+xmdS5+ECGoqcIL9dasTV4NfIpi3ASR4SJADf X-Gm-Message-State: AOJu0YwixEJ1Wun0l7rRHwrmnFFPwxEOAtjO6QO0bP79AxQf6B2VsFI8 MiGONB8trIWUT5piKHy5e6uYVy58HudIhp18+eSzPVL8YunH8NtF X-Google-Smtp-Source: AGHT+IE0MzIbUSGMhN9zqcmXjDTeGJfapTNVCAA61CpgqQLc65Pk/tW7NBHI7DDOI2mqZjWR0INmmA== X-Received: by 2002:a17:906:3cf:b0:a59:efff:e795 with SMTP id c15-20020a17090603cf00b00a59efffe795mr761621eja.59.1715061646730; Mon, 06 May 2024 23:00:46 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:46 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 3/8] refs: support symrefs in 'reference-transaction' hook Date: Tue, 7 May 2024 08:00:30 +0200 Message-ID: <20240507060035.28602-4-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The 'reference-transaction' hook runs whenever a reference update is made to the system. In a previous commit, we added the `old_target` and `new_target` fields to the `reference_transaction_update()`. In following commits we'll also add the code to handle symref's in the reference backends. Support symrefs also in the 'reference-transaction' hook, by modifying the current format: SP SP LF to be be: SP SP LF where for regular refs the output would not change and remain the same. But when either 'old-value' or 'new-value' is a symref, we print the ref as 'ref:'. This does break backward compatibility, but the 'reference-transaction' hook's documentation always stated that support for symbolic references may be added in the future. We do not add any tests in this commit since there is no git command which activates this flow, in an upcoming commit, we'll start using transaction based symref updates as the default, we'll add tests there for the hook too. Signed-off-by: Karthik Nayak --- Documentation/githooks.txt | 14 +++++++++----- refs.c | 20 ++++++++++++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index ee9b92c90d..06e997131b 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -486,7 +486,7 @@ reference-transaction This hook is invoked by any Git command that performs reference updates. It executes whenever a reference transaction is prepared, committed or aborted and may thus get called multiple times. The hook -does not cover symbolic references (but that may change in the future). +also supports symbolic reference updates. The hook takes exactly one argument, which is the current state the given reference transaction is in: @@ -503,16 +503,20 @@ given reference transaction is in: For each reference update that was added to the transaction, the hook receives on standard input a line of the format: - SP SP LF + SP SP LF -where `` is the old object name passed into the reference -transaction, `` is the new object name to be stored in the +where `` is the old object name passed into the reference +transaction, `` is the new object name to be stored in the ref and `` is the full name of the ref. When force updating the reference regardless of its current value or when the reference is -to be created anew, `` is the all-zeroes object name. To +to be created anew, `` is the all-zeroes object name. To distinguish these cases, you can inspect the current value of `` via `git rev-parse`. +For symbolic reference updates the `` and `` +fields could denote references instead of objects. A reference will be +denoted with a 'ref:' prefix, like `ref:`. + The exit status of the hook is ignored for any state except for the "prepared" state. In the "prepared" state, a non-zero exit status will cause the transaction to be aborted. The hook will not be called with diff --git a/refs.c b/refs.c index d7df137904..2bb3e09425 100644 --- a/refs.c +++ b/refs.c @@ -2366,10 +2366,22 @@ static int run_transaction_hook(struct ref_transaction *transaction, struct ref_update *update = transaction->updates[i]; strbuf_reset(&buf); - strbuf_addf(&buf, "%s %s %s\n", - oid_to_hex(&update->old_oid), - oid_to_hex(&update->new_oid), - update->refname); + + if (!(update->flags & REF_HAVE_OLD)) + strbuf_addf(&buf, "%s ", oid_to_hex(null_oid())); + else if (update->old_target) + strbuf_addf(&buf, "ref:%s ", update->old_target); + else + strbuf_addf(&buf, "%s ", oid_to_hex(&update->old_oid)); + + if (!(update->flags & REF_HAVE_NEW)) + strbuf_addf(&buf, "%s ", oid_to_hex(null_oid())); + else if (update->new_target) + strbuf_addf(&buf, "ref:%s ", update->new_target); + else + strbuf_addf(&buf, "%s ", oid_to_hex(&update->new_oid)); + + strbuf_addf(&buf, "%s\n", update->refname); if (write_in_full(proc.in, buf.buf, buf.len) < 0) { if (errno != EPIPE) { From patchwork Tue May 7 06:00:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656285 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D2006F505 for ; Tue, 7 May 2024 06:00:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061652; cv=none; b=KBA1ZI4DPOHh5rcLxyLhlXb71Puiwxt6d7WdeHL0ajFrkV0jhEmgauZ7EKSQPSbZaifuq+f7dv7CRngfkYXJKKuv3SmZArUn8yU2B4oyZH0T6/qizHM7Gx/b2CD+nMtT1FEWfcyRh/dsWKZtEXcLfrY9exjOknUq7oMWDkDyzb0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061652; c=relaxed/simple; bh=oZFWb+3aaNcg/2ca6eKEJMk7EIU6qgKjI84Y2Ec/j00=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZbNWYxbCOfYvqY8pZFMfT/mQQ3Fyh1Vj4c/1a6ATK6TaJRFGEIjWZZN+/RGJIYT40993HOkgd9yD8JhTVTobTlQmv5LCiCwewZ13kxFi865+4fJWeCTDrvyE2O8L7o5Rr2HHQ+acJq3QrnoN9335uepty1mjCCTW68lo5ogXuWY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=I6EJBiS+; arc=none smtp.client-ip=209.85.218.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="I6EJBiS+" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-a59b178b75bso438632066b.0 for ; Mon, 06 May 2024 23:00:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061648; x=1715666448; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZflLsbLD4lKmVHQqEfTTNP8o7RKt7jjLEZ5EL2rALYg=; b=I6EJBiS+0UiK8wItHlpFt1ifiQRb/5dlnhRrjpjEjfN8jsf8nKI7Q54OXWyWkNOHh8 q13pFkZdCTLRYDyxdWq2u1JOJ+aEMoLIlml959knrslH20qpeMh5VvXBWavW712e+nlv YadXuXIh9wf1nLAii6rt9A6eu71RWbrYHzw9saRm1eWvYKQR6Br0TfTsnDYUiZXNX7ub SJzJvHwNJPYLESLD9VWTqRpbMWW0L2cN55B7BT830TKTRZve4bXqg6jhkDQTGiLE9yJ4 5Rz2HFV+O0cpwwuqEL+W45nLkZ4eAMSJSEHdrcCK10BjOgbBpInoApoFt9NxWTMOEmC/ Ja4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061648; x=1715666448; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZflLsbLD4lKmVHQqEfTTNP8o7RKt7jjLEZ5EL2rALYg=; b=iULMRahxs5MNKM5c/HUinFrY1WkRmlM5akMPrAYweVDUK/woUk23jPznAf2jv1VUGa Ea8AeTq9ChqzINSbf5zR+M+HZ05dh3L4FF3NWNTWWrtQq4nnYPK7ikFnFgeWyxFszUWZ 3Xu28wn9lMkcGKMGmdnq8dzKopoiM3PfyI046TAhzvINPpUSxi0EqwgnKk+zKAX/CebU 8qbyzHtYB+4Nw05vTdmWYqPFnNx6Pdw3jLpOvvtQ2JSbnGdvnm32Fratn6plXptIsvDN VyHEF7mv+zpsbjaqDagOq1Rz5OoI34sXIEOT+cOgQW/oGzcfpuOyOZGhWv9fPmtZ+q8G DHBQ== X-Forwarded-Encrypted: i=1; AJvYcCX6415Ci71CLazERmgKluLBO+oiRIjQeu1ze/q7DH0hv6J93xe+/8ErF95/fSguEDgFGmmSIsuYHxIGF5SBda9jcs/z X-Gm-Message-State: AOJu0YzmTAET9tFHp0ocJVcpvwwXl4giE44/JleE/InR0cADMSprvCnW 7aHiZdgbZXfEJIewvJPELpEMEw2M14MZYAd+0BU/0IPzoyAwkNgz X-Google-Smtp-Source: AGHT+IGDMVKQ+BukINj8sjufJAXbgTmW3bPtufSaSk7AwBWHc/e+lUhaq289uH3XpMKfV98hWtOyFg== X-Received: by 2002:a17:906:358b:b0:a59:a8a4:a5a7 with SMTP id o11-20020a170906358b00b00a59a8a4a5a7mr5414137ejb.30.1715061647774; Mon, 06 May 2024 23:00:47 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:47 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 4/8] refs: move `original_update_refname` to 'refs.c' Date: Tue, 7 May 2024 08:00:31 +0200 Message-ID: <20240507060035.28602-5-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The files backend and the reftable backend implement `original_update_refname` to obtain the original refname of the update. Move it out to 'refs.c' and only expose it internally to the refs library. This will be used in an upcoming commit to also introduce another common functionality for the two backends. We also rename the function to `ref_update_original_update_refname` to keep it consistent with the upcoming other 'ref_update_*' functions that'll be introduced. Signed-off-by: Karthik Nayak --- refs.c | 9 +++++++++ refs/files-backend.c | 21 +++++---------------- refs/refs-internal.h | 5 +++++ refs/reftable-backend.c | 24 +++++++----------------- 4 files changed, 26 insertions(+), 33 deletions(-) diff --git a/refs.c b/refs.c index 2bb3e09425..d65e4cc41e 100644 --- a/refs.c +++ b/refs.c @@ -2830,3 +2830,12 @@ int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg { return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg); } + +const char *ref_update_original_update_refname(struct ref_update *update) +{ + while (update->parent_update) + update = update->parent_update; + + return update->refname; +} + diff --git a/refs/files-backend.c b/refs/files-backend.c index 40cc715ea7..64d2a50e97 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2422,17 +2422,6 @@ static int split_symref_update(struct ref_update *update, return 0; } -/* - * 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 @@ -2449,16 +2438,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)); @@ -2512,7 +2501,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; } @@ -2532,7 +2521,7 @@ 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; } diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 108f4ec419..617b93a6c8 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -749,4 +749,9 @@ 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); + #endif /* REFS_REFS_INTERNAL_H */ diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index f48ab5ad22..0988f59ed4 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -622,16 +622,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; @@ -910,7 +900,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; } @@ -982,17 +972,17 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, 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; From patchwork Tue May 7 06:00:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656286 Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0F217173C for ; Tue, 7 May 2024 06:00:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061652; cv=none; b=M7u18wZ7MQY6dW6mAkiHCrOyNvO6Vvc9o38o25wR9kAaEScCeQhAFnZtnnXsbIz77ckbeTTKS9/tr+7YVIWK4tAI75uMswFKE/3XL3yQ1gckcAx0ut9zWuD1eW+0F6JkPXGGxXCyNV7GEEAX9RnZmKNJkh6n4wDOpGYFTh4FbMg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061652; c=relaxed/simple; bh=7cJsSwyMkKuXm1xzPHJYuZTWvnNfnS1CSRaFMBaIqWs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FRjl9DJLESdsKW3NK8WjjK7Li6jz1u0jnk9U/Az4T0esh93iPCoZOMSXFLwV64LbOuULgl5qOtWPO+QYkhtuXPl3+tkQUqTKUSUbWAGBgFXEP0z5vv1v/U2wCsMHjYTtgBEAZkj7HTFEZJE+44gx9bVzVh58nZORR1pwp0E1eZI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jKG/9aNP; arc=none smtp.client-ip=209.85.218.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jKG/9aNP" Received: by mail-ej1-f44.google.com with SMTP id a640c23a62f3a-a59b49162aeso544870266b.3 for ; Mon, 06 May 2024 23:00:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061649; x=1715666449; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aLFqoNvj9+ALOinCqHFXtGzqODaIuuOrMT33qZrfTDw=; b=jKG/9aNPck5bbuQ+YMRC1FJiYCAyQp922tJY+yHxhHfppY5jMhrTSWomhh5GIg3WcD +OMbPgwzhVz/IumJpsJy5Kt9GTJUPslaxVrBHLFUJXELT3kvonegU+c3AjmodltfQ++j jNyg+a9O1EeYtr8WGseMZxk/Jf4/m/iZcCD57Vfu4Umc4pT1sGSw5X8iWq4lpbr7sL14 ak3qqHgAWXaLhgnkbd+SRHeSssdQ2fLHUyzb/9ytiZPCBM9OY/IgbmPLTdP7WxVbAgmO 2DWqUCgt8vsaxA/3tTv1PEivV5KRpqJ6gAq/xOeYgsm+fxsMPOjNvpO6XDhQ32peHj9F NAnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061649; x=1715666449; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aLFqoNvj9+ALOinCqHFXtGzqODaIuuOrMT33qZrfTDw=; b=txYaN70Iy4xyqXCfeYRWfEgT3Y37kJCJl5F37+3r/DH84qigRaG/E/cMT+kjjXn/50 ad9NIRCc4VH0yZnvl7wpbbTJEQDD/BcUJjrk0TOaFcQi1w+Or4oU9mGP3UuQST1ykvJO g28H/xrNFfuTXWC3bsMYtNA39i8kVPcfoCMAoBYzNmgSlJWglHZ6KrK9h9Pnx4MTx65/ a6Bx3prk5hvosT9rgJ89ym0V029vzU545gZwfAau1AfuxezendYG3Qn6BXXtMdCn4BKp GVormpAKQ+sLcpfFR0U5Dl835OXCMWSQUtAY8QkZbM+nyMbbQBGSvV0gpwVmIHevLfGZ B6sw== X-Forwarded-Encrypted: i=1; AJvYcCWg70dDnZOexj4IYHCv2BDA6atxXP3t1Znofa650kDnAE5xKgElxwmo2BDUiEbX3bHuq5TQVv3K8M4vewroMiMzwZAO X-Gm-Message-State: AOJu0YxADQXR05moWg9Ix04od0rsmKxD7Z5frhhu6lnmdLDIxH8v0ztV +Lh5gR4ZLT5S418+MjA+rhbKIQwkbNcBSgtU2SdGttbymx1QkIWo X-Google-Smtp-Source: AGHT+IGd9nqIjTQegPCpy4TQFj0ksuZtSjTR6KK0iyWYjiSv8kWK2VDUzBOXAe9GxEF57ramuyChKw== X-Received: by 2002:a17:907:7e8c:b0:a59:ad15:6133 with SMTP id qb12-20020a1709077e8c00b00a59ad156133mr5646021ejc.71.1715061648857; Mon, 06 May 2024 23:00:48 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:48 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 5/8] refs: add support for transactional symref updates Date: Tue, 7 May 2024 08:00:32 +0200 Message-ID: <20240507060035.28602-6-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The reference backends currently support transactional reference updates. While this is exposed to users via 'git-update-ref' and its '--stdin' mode, it is also used internally within various commands. However, we do not support transactional updates of symrefs. This commit adds support for symrefs in both the 'files' and the 'reftable' backend. Here, we add and use `ref_update_has_null_new_value()`, a helper function which is used to check if there is a new_value in a reference update. The new value could either be a symref target `new_target` or a OID `new_oid`. We also add another common function `ref_update_check_old_target` which will be used to check if the update's old_target corresponds to a reference's current target. Now transactional updates (verify, create, delete, update) can be used for: - regular refs - symbolic refs - conversion of regular to symbolic refs and vice versa This also allows us to expose this to users via new commands in 'git-update-ref' in the future. Note that a dangling symref update does not record a new reflog entry, which is unchanged before and after this commit. Signed-off-by: Karthik Nayak --- refs.c | 36 ++++++++++++- refs/files-backend.c | 113 ++++++++++++++++++++++++++++++++-------- refs/refs-internal.h | 16 ++++++ refs/reftable-backend.c | 71 +++++++++++++++++++------ 4 files changed, 196 insertions(+), 40 deletions(-) diff --git a/refs.c b/refs.c index d65e4cc41e..f3d6b3b8e3 100644 --- a/refs.c +++ b/refs.c @@ -1257,6 +1257,8 @@ void ref_transaction_free(struct ref_transaction *transaction) for (i = 0; i < transaction->nr; i++) { free(transaction->updates[i]->msg); + free((char *)transaction->updates[i]->new_target); + free((char *)transaction->updates[i]->old_target); free(transaction->updates[i]); } free(transaction->updates); @@ -1287,10 +1289,13 @@ struct ref_update *ref_transaction_add_update( update->flags = flags; - if (flags & REF_HAVE_NEW) + update->new_target = xstrdup_or_null(new_target); + update->old_target = xstrdup_or_null(old_target); + if ((flags & REF_HAVE_NEW) && new_oid) oidcpy(&update->new_oid, new_oid); - if (flags & REF_HAVE_OLD) + if ((flags & REF_HAVE_OLD) && old_oid) oidcpy(&update->old_oid, old_oid); + update->msg = normalize_reflog_message(msg); return update; } @@ -1333,6 +1338,7 @@ int ref_transaction_update(struct ref_transaction *transaction, flags &= REF_TRANSACTION_UPDATE_ALLOWED_FLAGS; flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0); + flags |= (new_target ? REF_HAVE_NEW : 0) | (old_target ? REF_HAVE_OLD : 0); ref_transaction_add_update(transaction, refname, flags, new_oid, old_oid, new_target, @@ -2839,3 +2845,29 @@ const char *ref_update_original_update_refname(struct ref_update *update) return update->refname; } +int ref_update_has_null_new_value(struct ref_update *update) +{ + return !update->new_target && is_null_oid(&update->new_oid); +} + +int ref_update_check_old_target(const char *referent, struct ref_update *update, + struct strbuf *err) +{ + if (!update->old_target) + BUG("called without old_target set"); + + if (!strcmp(referent, update->old_target)) + return 0; + + if (!strcmp(referent, "")) + strbuf_addf(err, "verifying symref target: '%s': " + "reference is missing but expected %s", + ref_update_original_update_refname(update), + update->old_target); + else + strbuf_addf(err, "verifying symref target: '%s': " + "is at %s but expected %s", + ref_update_original_update_refname(update), + referent, update->old_target); + return -1; +} diff --git a/refs/files-backend.c b/refs/files-backend.c index 64d2a50e97..1d4650b7cb 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2393,8 +2393,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, - NULL, NULL, 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; @@ -2482,7 +2483,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) { @@ -2525,7 +2526,14 @@ static int lock_ref_for_update(struct files_ref_store *refs, 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; } @@ -2546,7 +2554,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; } @@ -2564,9 +2582,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)) { /* @@ -2829,6 +2866,43 @@ static int files_transaction_prepare(struct ref_store *ref_store, 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) @@ -2859,23 +2933,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)) { diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 617b93a6c8..819157256e 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -754,4 +754,20 @@ struct ref_store *maybe_debug_wrap_ref_store(const char *gitdir, struct ref_stor */ 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 0988f59ed4..4817dc2f0b 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -887,7 +887,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) @@ -938,8 +938,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, NULL, NULL, 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; /* @@ -969,7 +971,12 @@ 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"), @@ -1080,7 +1087,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}; @@ -1121,24 +1130,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, From patchwork Tue May 7 06:00:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656287 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B4D0C6EB7A for ; Tue, 7 May 2024 06:00:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061653; cv=none; b=T2PD3CIbrcqx9XXHhOXH0nIzJjYAfPjWyV5dmWoGFixcZUUqWtSMyB6NNVR4SpMwQlsjdRPIC+B1Bd0PoZ2YldH2n1M7LXlXgAW/hbj4KLAUaEy4k/ViJp0KwCCDiDBLBe/7E1UZu45bck71zVQsfmcmNkdgGe+YLehrHtil2Z8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061653; c=relaxed/simple; bh=e9imN1I21socGEjEcAjlHGmjZLgxzFHZIDkHaN/esAM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OYpT596i5C2nicJKBwQvnT7kGXjV79KBFhBPyycQOnf0Ff3c88b4ZFthfQxd5tNuZiFNY+PIumq7dIWh4QBjlwIMHqSDgWCXvspDkag3IIvrPaiq9q7Le9LqfZ0z6NUfy6bjDeCF1UzCNbo0GO/kszM58hqZSMyQ5SYipZUflQg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=U4no6GPq; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="U4no6GPq" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-a59a387fbc9so649056566b.1 for ; Mon, 06 May 2024 23:00:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061650; x=1715666450; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZOH5pbanK7ZQ02ZKP5sH5tnEdm44NkeP8GauV+D5Fhc=; b=U4no6GPqdQe6df4psBG4vRoX/CTKXI5Qi6WNYpeQrEXDIHV+yfJDL+2tzo+uUGv6t1 l9psNIviMIseMVES0a0hDzi4AIKuIXh/PpIQ1WKHMEy0NCMiZw4CzBgGEahU8ciz3iCP MX/1zTi6D8Xh5q1Hh05u+cgK8+osVZ3/eTDlnK6oueODFosCTziP19ieG+VDqOftUJ0e ao+GnxrtExqo7cfnij6cnc0/qRLTwFx5FouUObOyMS3K5NAx6icWM0qaoUX5JimOjj17 EmSrCMnewnks/IgcWxI+g/GmEXU+K3x67x+0ETWOoUtlvOq5WB3A6lE21ZMulSG1I678 cXzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061650; x=1715666450; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZOH5pbanK7ZQ02ZKP5sH5tnEdm44NkeP8GauV+D5Fhc=; b=m3gXxTgUkrdHVN74m/zr7wfbHvyvwlYSD9eXkaOrzVGwcLjRGi6Z1GaCmvyiznbK+D WodB+LLB3MkWY2REglq8AOZJ1fc78FG2tPv4nT9cynhiRyiKE79K3hIetCO+E0QPUPjE Oxg3X7/xK/xbkpPQQZHLFOiYvMX44yp1u4NG/BWZmlAM4WZ07+Cw6KFw7PMqNVjOQAq4 47UUp6l7PrMqUB9mAv+UZqEiIv10BZU3qI+i73VqllFBCgMqkImIPqVByb7TD1vzC2m2 ue9yX3Ij2+v1wapHDMerl1SyToirpAFEOJwxoDwT+ehzJJ8OVHG5Jn+k044DZVzxRuIC 4ZHg== X-Forwarded-Encrypted: i=1; AJvYcCVigOlPFuPInjbbIefmsdsUPoKOlkf7TtM9Wt6D7EaIyoJoUIasJMKJG52Ck1UvkOtKBP+wH+oqgDu9Ef2mHVse0bmC X-Gm-Message-State: AOJu0Yz2vrARFq8rbZMOqOzdZ5Kr7L9LqGbhUMc95ezTU2FwLKrLxMp6 MitG1bRULF+AukvSNM6ylIiXE2Z/4/qepd/EgeINZMxNrvJzZeGt X-Google-Smtp-Source: AGHT+IFsZBKIU0251MIqCgUSOGUQei8M3nPU5wXr9IvIjL6kMOPcwPw3ExHd9DiP3L13Y/2SUI3rWA== X-Received: by 2002:a17:907:6d10:b0:a59:bd5b:a0f3 with SMTP id sa16-20020a1709076d1000b00a59bd5ba0f3mr4907006ejc.38.1715061649928; Mon, 06 May 2024 23:00:49 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:49 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 6/8] refs: use transaction in `refs_create_symref()` Date: Tue, 7 May 2024 08:00:33 +0200 Message-ID: <20240507060035.28602-7-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The `refs_create_symref()` function updates a symref to a given new target. To do this, it uses a ref-backend specific function `create_symref()`. In the previous commits, we introduced symref support in transactions. This means we can now use transactions to perform symref updates and don't have to resort to `create_symref()`. Doing this allows us to remove and cleanup `create_symref()`, which we will do in the following commit. Modify the expected error message for a test in 't/t0610-reftable-basics.sh', since the error is now thrown from 'refs.c'. This is because in transactional updates, F/D conflicts are caught before we're in the reference backend. Signed-off-by: Karthik Nayak --- refs.c | 24 +++++++++++++++++------- t/t1416-ref-transaction-hooks.sh | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/refs.c b/refs.c index f3d6b3b8e3..7a693dbcfb 100644 --- a/refs.c +++ b/refs.c @@ -2305,14 +2305,24 @@ int refs_create_symref(struct ref_store *refs, const char *refs_heads_master, const char *logmsg) { - char *msg; - int retval; + struct ref_transaction *transaction; + struct strbuf err = STRBUF_INIT; + int ret = 0; - msg = normalize_reflog_message(logmsg); - retval = refs->be->create_symref(refs, ref_target, refs_heads_master, - msg); - free(msg); - return retval; + transaction = ref_store_transaction_begin(refs, &err); + if (!transaction || + ref_transaction_update(transaction, ref_target, NULL, NULL, + refs_heads_master, NULL, REF_NO_DEREF, + logmsg, &err) || + ref_transaction_commit(transaction, &err)) { + ret = error("%s", err.buf); + } + + strbuf_release(&err); + if (transaction) + ref_transaction_free(transaction); + + return ret; } int create_symref(const char *ref_target, const char *refs_heads_master, diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh index 2092488090..067fd57290 100755 --- a/t/t1416-ref-transaction-hooks.sh +++ b/t/t1416-ref-transaction-hooks.sh @@ -134,4 +134,27 @@ test_expect_success 'interleaving hook calls succeed' ' test_cmp expect target-repo.git/actual ' +test_expect_success 'hook captures git-symbolic-ref updates' ' + test_when_finished "rm actual" && + + test_hook reference-transaction <<-\EOF && + echo "$*" >>actual + while read -r line + do + printf "%s\n" "$line" + done >>actual + EOF + + git symbolic-ref refs/heads/symref refs/heads/main && + + cat >expect <<-EOF && + prepared + $ZERO_OID ref:refs/heads/main refs/heads/symref + committed + $ZERO_OID ref:refs/heads/main refs/heads/symref + EOF + + test_cmp expect actual +' + test_done From patchwork Tue May 7 06:00:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656288 Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C42D46E602 for ; Tue, 7 May 2024 06:00:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061654; cv=none; b=uTbaedFPoskIMOAxSFrQ9X4DnlxS0N7osD3/wKFx8sEm5ykaxg1HmDaydZAxZE+MvMggpj7CcLiXy2IelYnR/0Mh9g/d6d6ZaqcxQRlZnKkLOZ7ijzozwpPIMbOW25GDuXHyK3kWr5Jg96zgPrDMH7Eizr+x+VfmuHajgfm+c0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061654; c=relaxed/simple; bh=3i+z22tQX0RBr2pB4FYZcAHrbEHQnK24jJl96zwKs8c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q35APmGc+6ij3ZGrGDRBaCgpCwHxDMoBnAFZsRiFYvx6vRk2aBqO5eOoCTwvxpuMHyN3tn3EblD3KtxSDPBxY25YwTztSGYPFOKKP02XCA5V+OXR06sjc6lDXDVXMKXFCixpNhUs0EALdEPHPCFaVoLevO0jlLrShz0ZXMIxrKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lqD6e3e/; arc=none smtp.client-ip=209.85.218.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lqD6e3e/" Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-a4702457ccbso675083666b.3 for ; Mon, 06 May 2024 23:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061651; x=1715666451; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JzjnaJrDthg0F1Wv35QQl2XaWNLJzwznwprWuLwXgeM=; b=lqD6e3e/P7kbZB2SrNvstLwHeVVRBcjaG6RG2TLwKQYF62SDT122gUX+xQwiTIt5iI KUQhBeWvVdOICQpqcJ5VLiA5DmsbCVQHS6pYWaJ7J8igZiK/AaEvOVtdNTSxM482t7Kw jPJZ5yXSo9gOsTXbPeOU9aAXjEeCcr5ha57UldyNApTPyr/yzNgrrTG29ZfceKkhx+24 6zKNwwIdtFI/xXeLa/yT4LyfKb6dT7sYHc3tHr9fKNoN6aQSiuN2yYyhJXSxnU7W6fcZ 5TAvecSrC55j7kA/6wyr3YdhAEtzbVfvK6finu4p8+eShpTyerPPN2HKmdsygDRghGN1 QHWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061651; x=1715666451; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JzjnaJrDthg0F1Wv35QQl2XaWNLJzwznwprWuLwXgeM=; b=NRL0mSkbeDM/AuDZt/5PXukNr/LVnEprVuzIp8nEXxPGmW9sYCFE9jwCovCpZ9Hb1l xYGTFRjFrSiEokPkrhlEy/iH35HqIlui8zz8uB1mMNFSlKxXJgKBJasi/8OcYmNq9BGy 7t0oB+2ou/4iNJKmdAhUBf94wES3e0Fab63Sbi6EjtpH/7rqeU2u5wp2kHZrc9Zp4qWS AUEddK5F/8UtDvk4ahwxGAHGiK8KBEhUwmw74OcmRC9qIoXukriqJLa7RFiF+Asx0Op4 xsNaTj7DrDwqg9fGB7IvbDHy2hA4iWoeXF5+afWZvxZ2sYoRbRjrJGPBWxAZTclxBHpR In+Q== X-Forwarded-Encrypted: i=1; AJvYcCXedSgvGnAtXS+uDPUqBEXcr0VgZ1P+4yTKV4LyTap7zyujZmn/lt2I7Kir9CHyvrWUQVDzHmCAhZ4KJYeSDV9SEfHU X-Gm-Message-State: AOJu0YxN9mpL9p/iQ82OWSLjEhJ6J0jPtWgnPqUwL2dObH7dAvk0Gvw1 dFCl6XiUz/wJ7FBNyMkWIk2b5B01GTNOtFQfHtC565KPFajFAj7K X-Google-Smtp-Source: AGHT+IGgQVw8W1tny20B6z71uQEILr0lgB0FW5X+YcieveRaNP6QbpHOeRtQ7h/rvtT2KdaI9PGW8A== X-Received: by 2002:a17:906:730d:b0:a59:c52b:9937 with SMTP id di13-20020a170906730d00b00a59c52b9937mr4208011ejc.4.1715061650964; Mon, 06 May 2024 23:00:50 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:50 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 7/8] refs: rename `refs_create_symref()` to `refs_update_symref()` Date: Tue, 7 May 2024 08:00:34 +0200 Message-ID: <20240507060035.28602-8-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak The `refs_create_symref()` function is used to update/create a symref. But it doesn't check the old target of the symref, if existing. It force updates the symref. In this regard, the name `refs_create_symref()` is a bit misleading. So let's rename it to `refs_update_symref()`. This is akin to how 'git-update-ref(1)' also allows us to create apart from update. While we're here, rename the arguments in the function to clarify what they actually signify and reduce confusion. Signed-off-by: Karthik Nayak --- builtin/branch.c | 2 +- builtin/worktree.c | 2 +- refs.c | 12 +++++------- refs.h | 2 +- t/helper/test-ref-store.c | 2 +- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index dd3e3a7dc0..4491f7a20c 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -555,7 +555,7 @@ static int replace_each_worktree_head_symref(struct worktree **worktrees, continue; refs = get_worktree_ref_store(worktrees[i]); - if (refs_create_symref(refs, "HEAD", newref, logmsg)) + if (refs_update_symref(refs, "HEAD", newref, logmsg)) ret = error(_("HEAD of working tree %s is not updated"), worktrees[i]->path); } diff --git a/builtin/worktree.c b/builtin/worktree.c index 7c6c72536b..480202c517 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -517,7 +517,7 @@ static int add_worktree(const char *path, const char *refname, ret = refs_update_ref(wt_refs, NULL, "HEAD", &commit->object.oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR); else - ret = refs_create_symref(wt_refs, "HEAD", symref.buf, NULL); + ret = refs_update_symref(wt_refs, "HEAD", symref.buf, NULL); if (ret) goto done; diff --git a/refs.c b/refs.c index 7a693dbcfb..85f53a2cbe 100644 --- a/refs.c +++ b/refs.c @@ -2300,10 +2300,8 @@ int peel_iterated_oid(const struct object_id *base, struct object_id *peeled) return peel_object(base, peeled) ? -1 : 0; } -int refs_create_symref(struct ref_store *refs, - const char *ref_target, - const char *refs_heads_master, - const char *logmsg) +int refs_update_symref(struct ref_store *refs, const char *ref, + const char *target, const char *logmsg) { struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; @@ -2311,8 +2309,8 @@ int refs_create_symref(struct ref_store *refs, transaction = ref_store_transaction_begin(refs, &err); if (!transaction || - ref_transaction_update(transaction, ref_target, NULL, NULL, - refs_heads_master, NULL, REF_NO_DEREF, + ref_transaction_update(transaction, ref, NULL, NULL, + target, NULL, REF_NO_DEREF, logmsg, &err) || ref_transaction_commit(transaction, &err)) { ret = error("%s", err.buf); @@ -2328,7 +2326,7 @@ int refs_create_symref(struct ref_store *refs, int create_symref(const char *ref_target, const char *refs_heads_master, const char *logmsg) { - return refs_create_symref(get_main_ref_store(the_repository), ref_target, + return refs_update_symref(get_main_ref_store(the_repository), ref_target, refs_heads_master, logmsg); } diff --git a/refs.h b/refs.h index 9abbfd35a2..7c69e8cc0d 100644 --- a/refs.h +++ b/refs.h @@ -606,7 +606,7 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg); -int refs_create_symref(struct ref_store *refs, const char *refname, +int refs_update_symref(struct ref_store *refs, const char *refname, const char *target, const char *logmsg); int create_symref(const char *refname, const char *target, const char *logmsg); diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 82bbf6e2e6..4651e4ced7 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -118,7 +118,7 @@ static int cmd_create_symref(struct ref_store *refs, const char **argv) const char *target = notnull(*argv++, "target"); const char *logmsg = *argv++; - return refs_create_symref(refs, refname, target, logmsg); + return refs_update_symref(refs, refname, target, logmsg); } static struct flag_definition transaction_flags[] = { From patchwork Tue May 7 06:00:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthik Nayak X-Patchwork-Id: 13656289 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5C1873165 for ; Tue, 7 May 2024 06:00:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061655; cv=none; b=Rce1SrLLweQ5Xp8VTM4+Du1JDrR2iiVZn71jJd//x8PLMTFlpuEcnwIwkR7leiOAWdhkSm/o10jm4/6juqqaUNRCCO4QFelZkwADe7bo8l7C2d5O8Njg5PisAw0xM48PXKOya3TZSBSc00eh6Mst9ZFEjLO9uqRnNk3lpXvM72Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061655; c=relaxed/simple; bh=kF+EDh/ryZI6KxNn7WkG5luCKI0VXXDuErCCT0/1lu4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dLM6tuKKnBKEKx+A8KeOfNWNBC/wSltTUAtwq6V4vp/HCkiTyT3wG50zN9aUwnoKg1UqQU+5bcB3DG0iOR+7qHaEuOA6H1lbfODMh2VKIAB/OH7s5a3RCO6JfApyTQf+V+ENb5gdeDppn4wtHrtmMNbzj53TNIczc7/qKKw7XJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nLTSG9ba; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nLTSG9ba" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-a59c04839caso531265466b.2 for ; Mon, 06 May 2024 23:00:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061652; x=1715666452; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GVEG99y8fAy6cbpfsABy9hc4SGIvYaKu4M0X0/D2PmY=; b=nLTSG9baUB+WrWKdz6gXE0KQ3JnnnU2AT0haz5Nsj28NnLhIYGkePJfEGUsU/tG5we Y/QhwIXau44JYQaNJ3z/XmVlABEGD2D+RBeTUOpa6leS8vTFPgsJnrwIavmxkPmQCktl FZpZFHMKbyVtuIcQsl9QTt7qJ+e9GYDAjzwn/+iWjSjMNo7d/A2lT6sasWRZHr9Iqa88 LE/weWZXx9k6q7OB//YLLG+cCJm36AtFCqvV8/SNrIweAP4zk5fQlgblXBlwIpJ2CbIj ptyaQ+dVGevPXob4V48JHrdiUlbnzMWPhRAazDNclg0y4qc7LVKmFgIadohcyGuu9BQ4 jcFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061652; x=1715666452; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GVEG99y8fAy6cbpfsABy9hc4SGIvYaKu4M0X0/D2PmY=; b=mIiz0p950QWcWwenlpKEqcnEowyXSh6c5Z9MvPhHMD8DxQyDx5B6gqIt+whV/4pNh9 9RAVdM5CluS+wu6vUF9n2e+y6+0kp/Nae9j/LWIa25e55hgVD56cBExzS+K4eeAKseTv uRfR1yoxo/1x3UO240N6+C1yPp3s5cqzR9rRDlHENA6/yuOlMJE1dV4V0wquPHPesrUh F4Im65+HuZzRUDbw2iLF6UykXbsPTU2EohkPr0oern/PczScZIjyqcm16rQhunzJGZAm v9OfOWJPSamxQcOeTBGq6A89nbXqV8kpwKWCSPddztbaOUmbR44z1P1vzkEH+6V1x5C1 l5FQ== X-Forwarded-Encrypted: i=1; AJvYcCV1HJEOhN42T6z4eazu0df952+D/BHCvWxua1k0CVQNqEpNipEU4bvLe65HcNJoWltLHfVzhArIAFLV2tBhkgPOT9Oq X-Gm-Message-State: AOJu0Yw9Sq8qUtLnSSW6USNmtc9H7NfBtSjRxGt+DovhPbhJo6QOy5xi xf21LdnEUAiWFXXAByKdB2WhvooprFoHdvzubFuwWI4o6AV1bkno X-Google-Smtp-Source: AGHT+IGPRwypuVTBAJ4rGvzSrLijpb3Q/SOl8yXyRtJIpmcVBWKpkWoMkXDLiVMyq5DiEPcwjq9eXQ== X-Received: by 2002:a17:907:7203:b0:a59:c31a:91be with SMTP id dr3-20020a170907720300b00a59c31a91bemr3810033ejc.16.1715061651873; Mon, 06 May 2024 23:00:51 -0700 (PDT) Received: from laptop.fritz.box ([2a02:2455:826e:4900:1aa1:adf2:4cd1:ebdc]) by smtp.gmail.com with ESMTPSA id y27-20020a1709060a9b00b00a59baca79basm3066691ejf.60.2024.05.06.23.00.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 23:00:51 -0700 (PDT) From: Karthik Nayak X-Google-Original-From: Karthik Nayak To: karthik.188@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, ps@pks.im, phillip.wood123@gmail.com Subject: [PATCH v7 8/8] refs: remove `create_symref` and associated dead code Date: Tue, 7 May 2024 08:00:35 +0200 Message-ID: <20240507060035.28602-9-knayak@gitlab.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240507060035.28602-1-knayak@gitlab.com> References: <20240503124115.252413-1-knayak@gitlab.com> <20240507060035.28602-1-knayak@gitlab.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Karthik Nayak In the previous commits, we converted `refs_create_symref()` to utilize transactions to perform symref updates. Earlier `refs_create_symref()` used `create_symref()` to do the same. We can now remove `create_symref()` and any code associated with it which is no longer used. We remove `create_symref()` code from all the reference backends and also remove it entirely from the `ref_storage_be` struct. Signed-off-by: Karthik Nayak --- refs/debug.c | 13 ----- refs/files-backend.c | 67 ------------------------- refs/packed-backend.c | 1 - refs/refs-internal.h | 5 -- refs/reftable-backend.c | 105 ---------------------------------------- 5 files changed, 191 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 1d4650b7cb..dc0490f0db 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1902,23 +1902,6 @@ 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) -{ - 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_lock(struct files_ref_store *refs, struct ref_lock *lock, const char *refname, const char *target, struct strbuf *err) @@ -1938,55 +1921,6 @@ static int create_symref_lock(struct files_ref_store *refs, return 0; } -static int create_and_commit_symref(struct files_ref_store *refs, - struct ref_lock *lock, const char *refname, - const char *target, const char *logmsg) -{ - struct strbuf err = STRBUF_INIT; - int ret; - - if (prefer_symlink_refs && !create_ref_symlink(lock, target)) { - update_symref_reflog(refs, lock, refname, target, logmsg); - return 0; - } - - ret = create_symref_lock(refs, lock, refname, target, &err); - if (!ret) { - update_symref_reflog(refs, lock, refname, target, logmsg); - - if (commit_ref(lock) < 0) - return error("unable to write symref for %s: %s", refname, - strerror(errno)); - } else { - return error("%s", err.buf); - } - - return ret; -} - -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_and_commit_symref(refs, lock, refname, target, logmsg); - - unlock_ref(lock); - return ret; -} - static int files_reflog_exists(struct ref_store *ref_store, const char *refname) { @@ -3373,7 +3307,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 819157256e..53a6c5d842 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -566,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); @@ -690,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; diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 4817dc2f0b..d8e06767a4 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1307,110 +1307,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; @@ -2325,7 +2221,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,