From patchwork Thu Jan 7 13:51:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 12004227 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56263C433DB for ; Thu, 7 Jan 2021 13:52:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 258DC22B45 for ; Thu, 7 Jan 2021 13:52:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728551AbhAGNwe (ORCPT ); Thu, 7 Jan 2021 08:52:34 -0500 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:38075 "EHLO out2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728537AbhAGNwd (ORCPT ); Thu, 7 Jan 2021 08:52:33 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id B37575C0170 for ; Thu, 7 Jan 2021 08:51:41 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Thu, 07 Jan 2021 08:51:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; s=fm3; bh=dNLt0OW6KpyDsY6e8Tf2jmr5Zy1BhGqtQpoAyJN6 0hU=; b=YD9Guk3+x7E0pqkKBLa16c+Zw5DbrgcfEhP+MZ1E16OXRmm6nTmK+aaj 5X2Gw6sQOaA2I+qSxC1OQu5DKHj3DGBCUfqkgAxx4MugD+XuUf2VAw6TH86URddl LgGGOS8iOZmWtZsg/R7OtGVeq0qcf+u8J/IIuUivxh5iGnKpkOC9TH6UbQskjYMg +EpYOAoEgV2zut6wYI4bnR2leoOOrT4D4SPW73Bv05WXQY7gB3tHynMw/oGGVZxx FjU/xCxUfeaY1bymGfbEtYaFyU9tpsXh039RwqhpuyxhgOPJUjOWI9/AzdO5CLhs jMaRm6Gh2UB0Zf023+kpO0tBGhICTw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=dNLt0O W6KpyDsY6e8Tf2jmr5Zy1BhGqtQpoAyJN60hU=; b=LkG6ImHHpIAl2IX9y37BG8 GoHEld9gS57nsFid6fU0ZyoM/FaPeitJXuD4vEO455UDvB1WO4LWY5ZGU1y44bF5 TelaHMwwI4aJz+NboZMCBwk+9cE/tmnrdaFKanMCT/kPfZUGIF7TNg9IPKiucQRy VsLfC3IKyvBDRIascuJMDQxA2AC4UiCQP51RC+koCVqd2f3npKy+m8CcRclsSvBM pFiGY10RLCFLnw0//4e7dSDxlZ/BwvziSsSAajrAhaBrK3Hntr9vtgn9NmLqCSjF xA6pQ1uLFrsCmsthHDJnY/QbauHp7R91AA9osy2SKB4e1g36zSLtkydMzMS8s7Qg == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrvdegvddgheejucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpeffhffvuffkfhggtggujgesghdtre ertddtvdenucfhrhhomheprfgrthhrihgtkhcuufhtvghinhhhrghrughtuceophhssehp khhsrdhimheqnecuggftrfgrthhtvghrnhepheeghfdtfeeuffehkefgffduleffjedthf dvjeektdfhhedvlefgtefgvdettdfhnecukfhppeejjedrudefrdefgedrvdefvdenucev lhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesphhksh drihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-077-013-034-232.77.13.pool.telefonica.de [77.13.34.232]) by mail.messagingengine.com (Postfix) with ESMTPA id 329A0108005C for ; Thu, 7 Jan 2021 08:51:41 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id d5e6043f (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for ; Thu, 7 Jan 2021 13:51:40 +0000 (UTC) Date: Thu, 7 Jan 2021 14:51:39 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Subject: [PATCH 1/2] fetch: allow passing a transaction to `s_update_ref()` Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The handling of ref updates is completely handled by `s_update_ref()`, which will manage the complete lifecycle of the reference transaction. This is fine right now given that git-fetch(1) does not support atomic fetches, so each reference gets its own transaction. It is quite inflexible though, as `s_update_ref()` only knows about a single reference update at a time, so it doesn't allow us to alter the strategy. This commit prepares `s_update_ref()` and its only caller `update_local_ref()` to allow passing an external transaction. If none is given, then the existing behaviour is triggered which creates a new transaction and directly commits it. Otherwise, if the caller provides a transaction, then we only queue the update but don't commit it. This optionally allows the caller to manage when a transaction will be committed. Given that `update_local_ref()` is always called with a `NULL` transaction for now, no change in behaviour is expected from this change. Signed-off-by: Patrick Steinhardt --- builtin/fetch.c | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index ecf8537605..020a977bc7 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -583,13 +583,14 @@ static struct ref *get_ref_map(struct remote *remote, static int s_update_ref(const char *action, struct ref *ref, + struct ref_transaction *transaction, int check_old) { char *msg; char *rla = getenv("GIT_REFLOG_ACTION"); - struct ref_transaction *transaction; + struct ref_transaction *transaction_to_free = NULL; struct strbuf err = STRBUF_INIT; - int ret, df_conflict = 0; + int ret, df_conflict = 0, commit = 0; if (dry_run) return 0; @@ -597,26 +598,38 @@ static int s_update_ref(const char *action, rla = default_rla.buf; msg = xstrfmt("%s: %s", rla, action); - transaction = ref_transaction_begin(&err); - if (!transaction || - ref_transaction_update(transaction, ref->name, + /* + * If no transaction was passed to us, we manage the transaction + * ourselves. Otherwise, we trust the caller to handle the transaction + * lifecycle. + */ + if (!transaction) { + transaction = transaction_to_free = ref_transaction_begin(&err); + if (!transaction) + goto fail; + commit = 1; + } + + if (ref_transaction_update(transaction, ref->name, &ref->new_oid, check_old ? &ref->old_oid : NULL, 0, msg, &err)) goto fail; - ret = ref_transaction_commit(transaction, &err); - if (ret) { - df_conflict = (ret == TRANSACTION_NAME_CONFLICT); - goto fail; + if (commit) { + ret = ref_transaction_commit(transaction, &err); + if (ret) { + df_conflict = (ret == TRANSACTION_NAME_CONFLICT); + goto fail; + } } - ref_transaction_free(transaction); + ref_transaction_free(transaction_to_free); strbuf_release(&err); free(msg); return 0; fail: - ref_transaction_free(transaction); + ref_transaction_free(transaction_to_free); error("%s", err.buf); strbuf_release(&err); free(msg); @@ -759,6 +772,7 @@ static void format_display(struct strbuf *display, char code, } static int update_local_ref(struct ref *ref, + struct ref_transaction *transaction, const char *remote, const struct ref *remote_ref, struct strbuf *display, @@ -799,7 +813,7 @@ static int update_local_ref(struct ref *ref, starts_with(ref->name, "refs/tags/")) { if (force || ref->force) { int r; - r = s_update_ref("updating tag", ref, 0); + r = s_update_ref("updating tag", ref, transaction, 0); format_display(display, r ? '!' : 't', _("[tag update]"), r ? _("unable to update local ref") : NULL, remote, pretty_ref, summary_width); @@ -836,7 +850,7 @@ static int update_local_ref(struct ref *ref, what = _("[new ref]"); } - r = s_update_ref(msg, ref, 0); + r = s_update_ref(msg, ref, transaction, 0); format_display(display, r ? '!' : '*', what, r ? _("unable to update local ref") : NULL, remote, pretty_ref, summary_width); @@ -858,7 +872,7 @@ static int update_local_ref(struct ref *ref, strbuf_add_unique_abbrev(&quickref, ¤t->object.oid, DEFAULT_ABBREV); strbuf_addstr(&quickref, ".."); strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV); - r = s_update_ref("fast-forward", ref, 1); + r = s_update_ref("fast-forward", ref, transaction, 1); format_display(display, r ? '!' : ' ', quickref.buf, r ? _("unable to update local ref") : NULL, remote, pretty_ref, summary_width); @@ -870,7 +884,7 @@ static int update_local_ref(struct ref *ref, strbuf_add_unique_abbrev(&quickref, ¤t->object.oid, DEFAULT_ABBREV); strbuf_addstr(&quickref, "..."); strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV); - r = s_update_ref("forced-update", ref, 1); + r = s_update_ref("forced-update", ref, transaction, 1); format_display(display, r ? '!' : '+', quickref.buf, r ? _("unable to update local ref") : _("forced update"), remote, pretty_ref, summary_width); @@ -1034,8 +1048,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, strbuf_reset(¬e); if (ref) { - rc |= update_local_ref(ref, what, rm, ¬e, - summary_width); + rc |= update_local_ref(ref, NULL, what, + rm, ¬e, summary_width); free(ref); } else if (write_fetch_head || dry_run) { /*