From patchwork Tue Oct 22 19:45:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846121 Received: from aib29agh124.zrh1.oracleemaildelivery.com (aib29agh124.zrh1.oracleemaildelivery.com [192.29.178.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 644DE81AB6 for ; Tue, 22 Oct 2024 19:48:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626520; cv=none; b=r0DOuBqDhst1HHnBDGAd12gZx5fDPR4UxM9mew3Dv+XMmKNy9aYSVMO7gYqfcTZW5IwtjC8J9UV9k3oH54LTY2W8mAcZw4odOPPwSTnrHtoBACfTTgfSrozQIMV8upGOU7ask0D8/2Le8LJXujJ7XKV3vpvkYM+WUbmh+Wdnaos= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626520; c=relaxed/simple; bh=rvPztX5aQWf2chtjN8De06WmRBbYFEfID8lOD2ibqpQ=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=GdN0mZPIWGqOcYunF+JassXpWC7z/HpaBl1MX8PPxNu+71Aqh+dYNsViJAS4Fp8Rip5pptZ+IC9oz9vjEsn5eNVS5XRGCEmEALBr187u3Uo8bre8CeHnemB2ZLDF0fEgtwGS/IXd20OhrFFE1Nttpsn0rS1tJ6BJ/aGmBljV0fY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=JQnz2vsW; arc=none smtp.client-ip=192.29.178.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="JQnz2vsW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=TXXtbDI74iAl2tPoNVSzGF/3Uco31X4Pq7No/jAywlw=; b=JQnz2vsWjR/t0W2VfVxPR3tYOSBhnNHQvf8LF49cBv2riH9pnpqpcc3Y95UbzTcL1WrNdEncYy/4 5T8uBtvK+a0SyzXf2wrZTT94YOK5TeFDpYI7Im11EmMKqUPCBjuduJt3cH0z4g0fEST9OKhEXqqF 1Zn1KZd7sbFKXKXN5jjp/RCZqqIXRUTCU4iac7UlJJtMiyuW0iMJzHcYZHQI76shGsLY4LNmdjv+ ah4lBEFsmf5Y3p+yqK1gvrq8lkResLkmNFParF8p16X9LotCIyO42TSS81gbTtfcMe/EdsaCni5D G5anjZdso029maWTTXDEjz2urL37bR0TjFtzng== Received: by omta-ad1-fd2-401-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR00K0RWCXSY00@omta-ad1-fd2-401-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:48:33 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 1/8] t/t5505-remote: set default branch to main Date: Tue, 22 Oct 2024 21:45:38 +0200 Message-id: <20241022194710.3743691-2-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAGHA9QqAs6nny66Lrx6h0046xxLuoR2vVLgBl9cs5sCtwXDGDNe9lEtO3nRGarE jTONO6aB3lLZZxuthdVmFUcv6ZVsrs5ix59FZEZPG2UgIo2FjYi0dJAUV2Q5Pv9/ 1A0L3ScRBpv0Nf2OM87/gD2ezDOGzmSQGRaTCETuGWwO8mPELPn9D7PL8qNlwIGO ADtoPHMJp85Pr+CZvKNJ6XQYxcHSof2XDFU5Uls6LiG9JNS9NBNiCAjHAfqbVmDB e3vOysrtdmzngfPEQBnNYl5Kw1/MdosQUdu/5PFud8j36mvtuGBQUxlnLoiLPU+N ZAFoc9FmIMa1lhVvl3ULs0U2CUb/mbk7kkxYgW2QmqfSiR6+83bzyNYSSgKu/hFs BMRDs7g2hPM8FikKF9HGZgRPjl8m4IvXcxX/D+arVDm7Dzv0McaWyG/Uy0938ZYZ Pmrz9m10+35XJTZ35OgN5s4RpPKUs7l4OfVBzplfUNJL5OJ6WlzM8wU= Consider the bare repository called "mirror" in the test. Running `git remote add --mirror -f origin ../one` will not change HEAD, consequently if init.defaultBranch is not the same as what HEAD in the remote ("one"), HEAD in "mirror" will be pointing to a non-existent reference. Hence if "mirror" is used as a remote by yet another repository, ls-remote will not show HEAD. On the other hand, if init.defaultBranch happens to match HEAD in "one", then ls-remote will show HEAD. Since the CI globally exports GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main, there's a drift between how the test repositories are set up in the CI and during local testing. This issue does not manifest currently, as the test does not do any remote HEAD manipulation where this would come up, but should such things be added, a locally passing test would break the CI vice-versa. Set GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main in the test to be consistent with the CI. --- Notes: v9: - new patch - a bandaid for the CI issue noticed by Taylor (cf: https://lore.kernel.org/git/Zw8IKyPkG0Hr6%2F5t@nand.local/), but see https://lore.kernel.org/git/D4ZAELFWJMKN.S88LJ6YK31LZ@ferdinandy.com/ for the root cause in detail v10: no change v11: no change t/t5505-remote.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 532035933f..9b50276646 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -2,6 +2,9 @@ test_description='git remote porcelain-ish' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh From patchwork Tue Oct 22 19:45:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846122 Received: from aib29agh126.zrh1.oracleemaildelivery.com (aib29agh126.zrh1.oracleemaildelivery.com [192.29.178.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 749A11CB328 for ; Tue, 22 Oct 2024 19:48:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.126 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626525; cv=none; b=b7pHjDJgPVjpI67xYTw+jIY7Cw+V2+gpiTb4He/9Xgu33DGsrxtpqcPR+4Lk8e7FXXu9BLLp08zKvH6tWQoN+uUuYpuHM35WGqUhOs0uXQ5ZyQVNJFGMoFgnW0BfZjYjP1X1dsuIdHyfrvt42lEPlBdgz9lNotaZFA6v2aXYd9A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626525; c=relaxed/simple; bh=VTygttXscxWFz7ZWLZTX0/AbSUWJswHu7dHLPY6K9fQ=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=OKNpnkgcO9KukwBbjZfebxXJ+ZzfVm3YFG+gHYqbxgHKLjU0kup0AX/CNaIfn+MzssEwz3NbisB2x7p9OXAk3ocWY61sFE9d5ZTn6E4jonoYHn0tcbFCX6mjta8JT37XTTkMqX/DoYK+ydRtJLTZgbSbylXup1DBLaCTS5tY1OM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=bGl6MAXq; arc=none smtp.client-ip=192.29.178.126 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="bGl6MAXq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=Jc+LeolyUGuhhyqYfKhY2crtD6ChCc9pWY10P8TLfRc=; b=bGl6MAXqUKNUy8lizR/0j/rB2LJuQmRv5UkrduQuYIo95KLtGvVL4zhSJlOBhHzcDaCil2KiR6ie wa+n5mSfKwc58+yS0F6xNdpjl92zb3aFZcILCUw5Rsg6Oje0ledEDXsAW7PQ48qDjwwsbzE4OB17 zu2AbK37459nSIFiXNWe2TqD8aohxZwqG/EW4b4/JK/VDm9qpKLy8JyTDZlMeSEQb5jDLYP/f19c gNgjYnwU44MrSBMRUg5+6rM1PFasQh8sD8cGWb3wxkM3KFvkAVUs0ypyq3JuhMDSVTHGwTZ7qgwN CqH0/lFkoxX6wlQ78tWyjqNthfhgAHt58woWNQ== Received: by omta-ad1-fd3-401-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR00K1GWD46930@omta-ad1-fd3-401-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:48:40 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 2/8] refs: atomically record overwritten ref in update_symref Date: Tue, 22 Oct 2024 21:45:39 +0200 Message-id: <20241022194710.3743691-3-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAG656Mgg8rkdVTkhA9mTB/tlXmcC2Vv9h4yPU9dKJPc5HdMkMGX4ZKUOB6YvE+z l01DlZftdJvDV31NUU8L4CQpbNnTHNWvBZg7iNIQOO66hrz7MgiaY3u70agZch96 a/XDj/1D+Nm2j8IDVM4SV1Zbtsnzc6IinnQxHgS4hCg/YAcnEZMJnxoUTiFqX9kl Y1/bJgOaqJTiL02cjkhxATga4sssrIflLgDsuH9lTZDUsrTIiRoEpkRWzNYarcqW bMMI/jtuNXS8xr+tZ7GPO7klEaxpTk9pu2OXK1LM/otXh+8l/ZrU4XvIDZiwzjqM 6/gzhIaSRDxpLlVEvQBMWNHxPsw2I+aAlMrB7UBqiOYP4ZQB+MYn6YZvnKVYF8rd xfcMxsgnWcgo6ybnJ4RLq/72pei5/g7GPB/1/FGDWw9+pq+4n1dKkKx9ZtOrByif kOoqOHhaZlIdI0A7+HWPe297k0eJH4gJ4x3Bh17dxEGAuBaOA2TRdRos When updating a symref with update_symref it's currently not possible to know for sure what was the previous value that was overwritten. Extend refs_update_symref under a new function name, to record the value after the ref has been locked if the caller of refs_update_symref_extended requests it via a new variable in the function call. Keep the original refs_update_symref function with the same signature, but now as a wrapper around refs_update_symref_extended. Signed-off-by: Bence Ferdinandy --- Notes: v4: new patch v5: - added before_target to reftables backend - added an extra safety check for transaction's existence in refs.c v6: - no change v7: - remove the whole before_target concept from the backends and handle checking it in refs.c instead (thanks Karthik) - rename the before_target to referent which is how the same concept is called in the backends - change commit prefix to be more in line with project standards v8: no change v9: - instead of adding parameters to refs_update_symref, rename what was in v8 as refs_update_symref_extended and make refs_update_symref a wrapper for that. This significantly reduces the number of files that need to be touched, and avoids adding a lot of dummy NULL-s in unrelated places. v10: no change v11: no change refs.c | 19 ++++++++++++++++--- refs.h | 4 ++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/refs.c b/refs.c index 5f729ed412..24a4172cd2 100644 --- a/refs.c +++ b/refs.c @@ -2115,6 +2115,13 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct int refs_update_symref(struct ref_store *refs, const char *ref, const char *target, const char *logmsg) +{ + return refs_update_symref_extended(refs, ref, target, logmsg, NULL); +} + +int refs_update_symref_extended(struct ref_store *refs, const char *ref, + const char *target, const char *logmsg, + struct strbuf *referent) { struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; @@ -2122,13 +2129,20 @@ int refs_update_symref(struct ref_store *refs, const char *ref, transaction = ref_store_transaction_begin(refs, &err); if (!transaction || - ref_transaction_update(transaction, ref, NULL, NULL, + ref_transaction_update(transaction, ref, NULL, NULL, target, NULL, REF_NO_DEREF, logmsg, &err) || - ref_transaction_commit(transaction, &err)) { + ref_transaction_prepare(transaction, &err)) { ret = error("%s", err.buf); + goto cleanup; } + if (referent) + refs_read_symbolic_ref(refs, ref, referent); + if (ref_transaction_commit(transaction, &err)) + ret = error("%s", err.buf); + +cleanup: strbuf_release(&err); if (transaction) ref_transaction_free(transaction); @@ -2948,4 +2962,3 @@ int ref_update_expects_existing_old_ref(struct ref_update *update) return (update->flags & REF_HAVE_OLD) && (!is_null_oid(&update->old_oid) || update->old_target); } - diff --git a/refs.h b/refs.h index 108dfc93b3..259191a485 100644 --- a/refs.h +++ b/refs.h @@ -573,6 +573,10 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, int refs_update_symref(struct ref_store *refs, const char *refname, const char *target, const char *logmsg); +int refs_update_symref_extended(struct ref_store *refs, const char *refname, + const char *target, const char *logmsg, + struct strbuf *referent); + enum action_on_err { UPDATE_REFS_MSG_ON_ERR, UPDATE_REFS_DIE_ON_ERR, From patchwork Tue Oct 22 19:45:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846129 Received: from aib29agh127.zrh1.oracleemaildelivery.com (aib29agh127.zrh1.oracleemaildelivery.com [192.29.178.127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6B4514EC55 for ; Tue, 22 Oct 2024 19:49:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.127 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626586; cv=none; b=FnSHhTIefwgzKbEgA6VGu/DulNrjwp2Ql2jtac7DRNbI2DBXp5y1jwmJ4uyOWhhTT2slnN6B80IV7yfbDiCavSlsHH0Oma3Szx0dWejr9b+uhCNfjrILWCXLXV/BfNjDJc6g68qxnBb3nfO/P4LAFiPGbQ8WI7jw7XI+S19XA0o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626586; c=relaxed/simple; bh=rAoegY0N8I1GgIYsvlRpjR4+uot64LI0uDAvvDfU53U=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=Bdzl55fqyOtrjh7HbhB16F2bYC9FI85KhhQY1k3ILivo1cDB6UNDfvbb38LpBSE0DCgaYEN/Fl0Q6lfpwvRC1AwK0gwZABwQWFJ+A7scbNznQ45dGeT8eLQHOYxohFW6efy4KpVLW0Ug4enYveaok2xrxVPo/YVpcJESlNKZcrM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=IHjZ12+L; arc=none smtp.client-ip=192.29.178.127 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="IHjZ12+L" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=m4CrtxU9BBiXcF0zLhzLpmvg6VEP6ojE1ZctA+SPDR8=; b=IHjZ12+LXfsMaQM1+jFJr54qB7vPGJ0104hKpD+WKJF79YoqUtnZOcSEPazgrQsZjn2OCR6/bZQ2 PpVFLgapz/MCuw09NC90xZbSKM8mH/kEa35isYWWgXCSBAF8lg3OkuudZQvGFhstm4/OkD2Pd5EX qP4GOaXreNxHktHv0zqGBfg4cwwrKiuNmihzOiOkDU9MeHO4zoEMGXA4hzXqW6RuhieNOcFtghCH kSoLTDRoZeNWto2SRogCZ5nM+gvmDYkCn4KgyVO9csx+C/npoDalgat0FmNrtmLVwbJeApGR9RTc 92iuuSfC48+dysFW6n4Y7IZHHzUrX5zTMqNAHQ== Received: by omta-ad1-fd3-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR006PZWEOGZ90@omta-ad1-fd3-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:49:36 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 3/8] remote set-head: refactor for readability Date: Tue, 22 Oct 2024 21:45:40 +0200 Message-id: <20241022194710.3743691-4-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAEaY43CsX4NS5gnX13mxeflHPj4BoTX7uiPTxCe+2EPNdQOKX973DeBaZxpBN4U b0AA7+5xFQF/if8asuoVYmPxeYf7X5xNvraYr1yGdgXU6EPwMwYfYQhiQUtGmawW kdUJ8wUrEZNwCuK2ad0/ZBcgQrf9kY3KGshYSewvI1eZFKXGNuG7RjX29Y2vtnXi IiAJikPbfoYa5jXnuZ6LqUGR+E9k8IGGiz7j5zP4bWBULjx7VkcAFNNVDlJyUkMv wIPGYccRDlqj1/BbeZ4K/nQJrSmSx4jBdWVMpulMh9ejmtLc9FdAp8EUtnSWA4M2 wFa5D/yamLNOmQtKPONOCWVpNtS223c5b2iURlGDmorlyzWoATlzG9BMbTy6/WJY qAvTx74xMWxH+fKkVWyUm65RapZ8ApEN4OK7v/7OyJLbNWmrjZ6250+2+ntpW454 ZO0AneUVNAPgGPl8+an9e4L3V4FyFUgQxETm/5FxA/TfHUGe4lMbkJoY Rename buf and buf2 to something more explanatory. Instead of calling get_main_ref_store(the_repository) multiple times, call it once and store in a new refs variable. Although this change probably offers some performance benefits, the main purpose is to shorten the line lengths of function calls using this variable. Signed-off-by: Bence Ferdinandy --- Notes: v5: new patch (split from the next patch as a preparatory step) v6: no change v7: - change commit prefix to be more in line with project standards v8: no change v9: - further improve readability by renaming buf, and buf2 consistently with how patch 6 was already done v10: no change v11: no change builtin/remote.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index 76670ddd8b..1d68c5b2ba 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1402,8 +1402,9 @@ static int show(int argc, const char **argv, const char *prefix) static int set_head(int argc, const char **argv, const char *prefix) { int i, opt_a = 0, opt_d = 0, result = 0; - struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT; + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT; char *head_name = NULL; + struct ref_store *refs = get_main_ref_store(the_repository); struct option options[] = { OPT_BOOL('a', "auto", &opt_a, @@ -1415,7 +1416,7 @@ static int set_head(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, builtin_remote_sethead_usage, 0); if (argc) - strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]); + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]); if (!opt_a && !opt_d && argc == 2) { head_name = xstrdup(argv[1]); @@ -1434,25 +1435,25 @@ static int set_head(int argc, const char **argv, const char *prefix) head_name = xstrdup(states.heads.items[0].string); free_remote_ref_states(&states); } else if (opt_d && !opt_a && argc == 1) { - if (refs_delete_ref(get_main_ref_store(the_repository), NULL, buf.buf, NULL, REF_NO_DEREF)) - result |= error(_("Could not delete %s"), buf.buf); + if (refs_delete_ref(refs, NULL, b_head.buf, NULL, REF_NO_DEREF)) + result |= error(_("Could not delete %s"), b_head.buf); } else usage_with_options(builtin_remote_sethead_usage, options); if (head_name) { - strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", argv[0], head_name); /* make sure it's valid */ - if (!refs_ref_exists(get_main_ref_store(the_repository), buf2.buf)) - result |= error(_("Not a valid ref: %s"), buf2.buf); - else if (refs_update_symref(get_main_ref_store(the_repository), buf.buf, buf2.buf, "remote set-head")) - result |= error(_("Could not setup %s"), buf.buf); + if (!refs_ref_exists(refs, b_remote_head.buf)) + result |= error(_("Not a valid ref: %s"), b_remote_head.buf); + else if (refs_update_symref(refs, b_head.buf, b_remote_head.buf, "remote set-head")) + result |= error(_("Could not setup %s"), b_head.buf); else if (opt_a) printf("%s/HEAD set to %s\n", argv[0], head_name); free(head_name); } - strbuf_release(&buf); - strbuf_release(&buf2); + strbuf_release(&b_head); + strbuf_release(&b_remote_head); return result; } From patchwork Tue Oct 22 19:45:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846124 Received: from aib29agh123.zrh1.oracleemaildelivery.com (aib29agh123.zrh1.oracleemaildelivery.com [192.29.178.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2A81148314 for ; Tue, 22 Oct 2024 19:48:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626538; cv=none; b=N3u8uDWN8UYoAVhvvkL12AVkZh2FqXyTzr+1ppcJ5Ik3Iy/sV2F5Y6g0BVZ/7zpjxQAtKR1cQK8bSxWa5jm2o9eVnmeilS69N53k7OOk0tRMgX27s3GUpAscEn9MxhRFKSNSkZ5I9j9XU8UEfCXoifNtfPg0TcQQZQfhZCQg8OQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626538; c=relaxed/simple; bh=m5IR2sGZVdSxGtVaXsgC9Irua5yK9B3lPHEGUww0nS4=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=aD85KexhRiEa1kpq3+WwwFn/6Vjq16FPFNQ1gqjg2kjRTZt9+rZPeaXp22Z2A8ud+NsEczyXRDQKUVzHFryaqrK+qArbwP9njDwOjYDW/gGfP65ANYigZxo9T6WSBt3nPpUJZ6myzEvK3Km12HsoSQI3Wh4tryMEg0zFNZGcYZU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=mJBFZk3R; arc=none smtp.client-ip=192.29.178.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="mJBFZk3R" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=F8WcGegBOMKKeToAND2We+IfdouYgMXF699aM93/Yi8=; b=mJBFZk3RT6Al+S1R8o6Hc8BILxbIWTlsn2nB6lMQ2aVJMB5H1ZELhVRYYO0SGruvfdEQvFf7wjt8 q92714c1kNsXaw4MAUIaV7l/u3waE54CAH+/vFGManvbKCXMd9V+mZM2eB8TSfCNu5PlBh0dQSIM Wnf39L3LnUZjNaHLNFAqV18Ibi9RepUHe9voi/yj2/M8O0ih4TPGHIDheHpMT4kfPk7ZdSe9Hg4b kS9MJmuQhEV1m7iR/fuEqSztW6KgveAcCHAqcEUtqobEOU30mRs/V32mdBgXonR1u4enm2hMnrLg bEYGXlzEWWev9fIsvf0sNi3JCYeBM/mPByTTtw== Received: by omta-ad1-fd1-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR00ISKWDC9OF0@omta-ad1-fd1-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:48:49 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 4/8] remote set-head: better output for --auto Date: Tue, 22 Oct 2024 21:45:41 +0200 Message-id: <20241022194710.3743691-5-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAG656Mgg8rkdVTkhA9mTB/tlXmcC2Vv9h4yPU9dKJPc5HdMkMGX4ZKUOB6YvE+z l01DlZftdJvDV31NUU8Z4CQpbNnTHNWvBZj9xoS8VIK1EedgbPiA1MboHjlW+s4N L7xF8v8K+5fNa+SvfLAJ5l1uhG1irkXGFZuftVL92EO7HUbcflr3RNtN0ZiU/Sjq 3xe2ivJ3MpsZy+fqKpwodZr4aZBOUzv1DeaRdgMAokhigNCw4jtXtlVWCEp7iniu nMVQLSjVqSmsLiFtcXRhfuq57NutS+uFx9i05hKMNylBY4N45fIhxBEJBB3HCez0 flD7aHebAZuaQpd94vue4Zy1QbU/F+Zb6/veKBDpC/AkShfugrlRpEUQGAfULwqc NI/d6ThrYoSkUSZfRYRW4fIgqEoOQErLz4cj+eZtfrTrjoybkFcwcQF3Ln5R7BD5 /TJd3XWMugqDlKfzwKvGO2A6OrSEukB1GxEFSjbEzHNqs6VrKryneVKJ Currently, set-head --auto will print a message saying "remote/HEAD set to branch", which implies something was changed. Change the output of --auto, so the output actually reflects what was done: a) set a previously unset HEAD, b) change HEAD because remote changed or c) no updates. As a fourth output, if HEAD is changed from a previous value that was not a remote branch, explicitly call attention to this fact. Signed-off-by: Bence Ferdinandy --- Notes: v1-v2: was RFC in https://lore.kernel.org/git/20240910203835.2288291-1-bence@ferdinandy.com/ v3: This patch was originally sent along when I thought set-head was going to be invoked by fetch, but the discussion on the RFC concluded that it should be not. This opened the possibility to make it more explicit. Note: although I feel both things the patch does are really just cosmetic, an argument could be made for breaking it into two, one for the no-op part and one for the --auto print update. Was sent in: https://lore.kernel.org/git/20240915221055.904107-1-bence@ferdinandy.com/ v4: - changes are now handled atomically via the ref update transaction - outputs have changed along the lines of Junio's suggestion - minor refactor to set_head for improved legibility v5: - the minor refactor has been split out into its own patch v6: - fixed uninitialized prev_head - fixed case of unusual previous target - fixed a test that would have been actually broken at this patch (the output was only correct with the later update to fetch) - added 4 tests for the 4 output cases v7: - change commit prefix to be more in line with project standards - fixed tests to also work with the reftable backend - renamed report function, fixed style issue with checking buf len - fixed not releasing an strbuf v8: no change v9: - mark output strings in report_set_head_auto as translatable - rename buf_prev to b_local_head for consistency - use ${SQ} in tests instead of '\'' v10: no change v11: no change builtin/remote.c | 33 +++++++++++++++++++++++++++--- t/t5505-remote.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index 1d68c5b2ba..108f1271d3 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1399,10 +1399,35 @@ static int show(int argc, const char **argv, const char *prefix) return result; } +static void report_set_head_auto(const char *remote, const char *head_name, + struct strbuf *b_local_head) { + struct strbuf buf_prefix = STRBUF_INIT; + const char *prev_head = NULL; + + strbuf_addf(&buf_prefix, "refs/remotes/%s/", remote); + skip_prefix(b_local_head->buf, buf_prefix.buf, &prev_head); + + if (prev_head && !strcmp(prev_head, head_name)) + printf(_("'%s/HEAD' is unchanged and points to '%s'\n"), + remote, head_name); + else if (prev_head) + printf(_("'%s/HEAD' has changed from '%s' and now points to '%s'\n"), + remote, prev_head, head_name); + else if (!b_local_head->len) + printf(_("'%s/HEAD' is now created and points to '%s'\n"), + remote, head_name); + else + printf(_("'%s/HEAD' used to point to '%s' " + "(which is not a remote branch), but now points to '%s'\n"), + remote, b_local_head->buf, head_name); + strbuf_release(&buf_prefix); +} + static int set_head(int argc, const char **argv, const char *prefix) { int i, opt_a = 0, opt_d = 0, result = 0; - struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT; + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, + b_local_head = STRBUF_INIT; char *head_name = NULL; struct ref_store *refs = get_main_ref_store(the_repository); @@ -1445,15 +1470,17 @@ static int set_head(int argc, const char **argv, const char *prefix) /* make sure it's valid */ if (!refs_ref_exists(refs, b_remote_head.buf)) result |= error(_("Not a valid ref: %s"), b_remote_head.buf); - else if (refs_update_symref(refs, b_head.buf, b_remote_head.buf, "remote set-head")) + else if (refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf, + "remote set-head", &b_local_head)) result |= error(_("Could not setup %s"), b_head.buf); else if (opt_a) - printf("%s/HEAD set to %s\n", argv[0], head_name); + report_set_head_auto(argv[0], head_name, &b_local_head); free(head_name); } strbuf_release(&b_head); strbuf_release(&b_remote_head); + strbuf_release(&b_local_head); return result; } diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 9b50276646..0ea86d51a4 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -432,12 +432,51 @@ test_expect_success 'set-head --auto' ' ) ' +test_expect_success 'set-head --auto detects creation' ' + ( + cd test && + git symbolic-ref -d refs/remotes/origin/HEAD && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} is now created and points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects no change' ' + ( + cd test && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects change' ' + ( + cd test && + git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/ahead && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} has changed from ${SQ}ahead${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects strange ref' ' + ( + cd test && + git symbolic-ref refs/remotes/origin/HEAD refs/heads/main && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} used to point to ${SQ}refs/heads/main${SQ} (which is not a remote branch), but now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + test_expect_success 'set-head --auto has no problem w/multiple HEADs' ' ( cd test && git fetch two "refs/heads/*:refs/remotes/two/*" && git remote set-head --auto two >output 2>&1 && - echo "two/HEAD set to main" >expect && + echo "${SQ}two/HEAD${SQ} is now created and points to ${SQ}main${SQ}" >expect && test_cmp expect output ) ' @@ -456,6 +495,16 @@ test_expect_success 'set-head explicit' ' ) ' +test_expect_success 'set-head --auto reports change' ' + ( + cd test && + git remote set-head origin side2 && + git remote set-head --auto origin >output 2>&1 && + echo "${SQ}origin/HEAD${SQ} has changed from ${SQ}side2${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + cat >test/expect < X-Patchwork-Id: 13846125 Received: from aib29agh123.zrh1.oracleemaildelivery.com (aib29agh123.zrh1.oracleemaildelivery.com [192.29.178.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DDFDA1C9ED4 for ; Tue, 22 Oct 2024 19:48:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626541; cv=none; b=ejPmXQGbb4KYKIcf+GLRRhpD/SbSjusoZ1AhGVviRpc29mCbqGB+mpiBsaug0oyAvshxUGEqrcLk/1+IN6uYRVCTnk0LN2TJIHO9Fa6JtFtJf9go9lbu4BWW9QRrgqbV0ht5lCCGszxeVixpwUqIH4CWgGvtm5djP2+xA0X7d60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626541; c=relaxed/simple; bh=A/uM8XwdG/ozIj5gNcO5ACe3q2Aa0lSrj7nFxHl7NR0=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=Kb/Pe/RXc/7e25j79twJMbDdkUY7FAr7GdFl0o2ERE0ko6P6PqUZh2loOrEE65TyT5uV01CPmOToXnFH+xVqgGIvBI2CK5VEb+iOwVflnGeYptyqhGBvCdwk2N8Ctfgvndlg4sTyQb3Dq/2ntuWmfPaHBoHUj5V1ij4rCi/7saY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=pxqB17iY; arc=none smtp.client-ip=192.29.178.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="pxqB17iY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=bUjQjLMJNaMxDsTDlGSC9kY/bdIWliZ9BmqijzU64QE=; b=pxqB17iYELgf9GbUKtYm1aU6n7EJ1dEM7W8ziG6Q56CQjTXQL/ZHUB42CPwIbhSb6WmvSQNPwPEH uH63y5QS9DACLSeVDt9SdSJoHeVOQArVNaN309isrg/SAHnuOxtBqYUDE7TiHwjXFGZ3XTLdvldC uRJjXlQD0N7BD/2p8x4NOYBexpS4TYiaNSMbSCaKnCYxw5Nd2uRQz80kxnj8HIvMiXcHIy/+y4vY s6Bml3Nvz54zWbl97QV52DfDD4swyP9EI4KN0PCBivc3QhbZ23Zvfud934OrY9vyWH4AdEZAZJO2 WzjokgoNuVUH+6Y+n1ZFH9wr6J/OziO70+4mOw== Received: by omta-ad1-fd1-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR00ISYWDI9OF0@omta-ad1-fd1-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:48:54 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 5/8] refs: add TRANSACTION_CREATE_EXISTS error Date: Tue, 22 Oct 2024 21:45:42 +0200 Message-id: <20241022194710.3743691-6-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAG656Mgg8rkdVTkhA9mTB/tlXmcC2Vv9h4yPU9dKJPc5HdMkMGX4ZKUOB6YvE+z l01DlZftdJvDV31NUU8i4CQpbNnTHNWvBZhePg+II47A36KaDeNqxsLWXYyLaD4+ 6xMENLpLxZFO6P7YoDhuo38yAZl/654RSpyh48wRvyV8BCABSkIw8JMiN1q6D+57 9hDeRCid0xcPJ+e0wXuRFDK6kO/32Ot4BQhJOPzlm/RCIvdVpTqE0ZUQvaznvGMQ 2oH9U4mSGOm94Gy5ZWumZX9poQKij188eGjflSy+9LM55lLSsIAUNDPVZpoh8avv MFCpHTjvAcGk+fNYlPjCx1MMNlnbVS+t0SbX2CM24OQ4joA9h3Vk5BJZ2UpwJOla TSYoEyFdRYcMJMa8sNDmf/rmODk/TpZRyK7cE7b1fh5bMTVK0Zvzt+zzhDjZQoCW Sr9wtwcXn/Y4z5rMzhuXEpJK12zxN3FyXnAiR7HRwG36p9yus7xCkvE= Currently there is only one special error for transaction, for when there is a naming conflict, all other errors are dumped under a generic error. Add a new special error case for when the caller requests the reference to be updated only when it does not yet exist and the reference actually does exist. Signed-off-by: Bence Ferdinandy --- Notes: v4: new patch v5: no change v6: no change v7: - change commit prefix to be more in line with project standards - changed error checking to Karthik's suggestion v8: no change v9: - no change v10: no change v11: no change refs.h | 4 +++- refs/files-backend.c | 24 ++++++++++++++++-------- refs/reftable-backend.c | 6 ++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/refs.h b/refs.h index 259191a485..a5bc25442b 100644 --- a/refs.h +++ b/refs.h @@ -762,8 +762,10 @@ int ref_transaction_verify(struct ref_transaction *transaction, /* Naming conflict (for example, the ref names A and A/B conflict). */ #define TRANSACTION_NAME_CONFLICT -1 +/* When only creation was requested, but the ref already exists. */ +#define TRANSACTION_CREATE_EXISTS -2 /* All other errors. */ -#define TRANSACTION_GENERIC_ERROR -2 +#define TRANSACTION_GENERIC_ERROR -3 /* * Perform the preparatory stages of committing `transaction`. Acquire diff --git a/refs/files-backend.c b/refs/files-backend.c index 0824c0b8a9..e743ec44b5 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2502,14 +2502,18 @@ static int split_symref_update(struct ref_update *update, static int check_old_oid(struct ref_update *update, struct object_id *oid, struct strbuf *err) { + int ret = TRANSACTION_GENERIC_ERROR; + if (!(update->flags & REF_HAVE_OLD) || oideq(oid, &update->old_oid)) return 0; - if (is_null_oid(&update->old_oid)) + if (is_null_oid(&update->old_oid)) { strbuf_addf(err, "cannot lock ref '%s': " "reference already exists", ref_update_original_update_refname(update)); + ret = TRANSACTION_CREATE_EXISTS; + } else if (is_null_oid(oid)) strbuf_addf(err, "cannot lock ref '%s': " "reference is missing but expected %s", @@ -2522,7 +2526,7 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid, oid_to_hex(oid), oid_to_hex(&update->old_oid)); - return -1; + return ret; } /* @@ -2602,9 +2606,11 @@ 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)) { - ret = TRANSACTION_GENERIC_ERROR; - goto out; + } else { + ret = check_old_oid(update, &lock->old_oid, err); + if (ret) { + goto out; + } } } else { /* @@ -2635,9 +2641,11 @@ static int lock_ref_for_update(struct files_ref_store *refs, update->old_target); ret = TRANSACTION_GENERIC_ERROR; goto out; - } else if (check_old_oid(update, &lock->old_oid, err)) { - ret = TRANSACTION_GENERIC_ERROR; - goto out; + } else { + ret = check_old_oid(update, &lock->old_oid, err); + if (ret) { + goto out; + } } /* diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 3c6107c7ce..b3b5ce77dd 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1206,10 +1206,13 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, goto done; } } else if ((u->flags & REF_HAVE_OLD) && !oideq(¤t_oid, &u->old_oid)) { - if (is_null_oid(&u->old_oid)) + ret = TRANSACTION_NAME_CONFLICT; + if (is_null_oid(&u->old_oid)) { strbuf_addf(err, _("cannot lock ref '%s': " "reference already exists"), ref_update_original_update_refname(u)); + ret = TRANSACTION_CREATE_EXISTS; + } else if (is_null_oid(¤t_oid)) strbuf_addf(err, _("cannot lock ref '%s': " "reference is missing but expected %s"), @@ -1221,7 +1224,6 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, ref_update_original_update_refname(u), oid_to_hex(¤t_oid), oid_to_hex(&u->old_oid)); - ret = -1; goto done; } From patchwork Tue Oct 22 19:45:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846126 Received: from aib29agh126.zrh1.oracleemaildelivery.com (aib29agh126.zrh1.oracleemaildelivery.com [192.29.178.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 216AD81AB6 for ; Tue, 22 Oct 2024 19:49:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.126 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626545; cv=none; b=iFMY8tsSInC1+TO/kYAyWwhuSYFLmVoghph4ILFciy82KlNPTKI4TlPxpkSR9NQ4ueV7BElMqlZ6gURN0YaAwJxppuzKcgJJhRHkv+74wMoRtGIJ8DxfcU9ihAOIuclkBBprA5BqOnI0w36p7jh1UzaUQlrHNu8ZzSo2q7khaBU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626545; c=relaxed/simple; bh=zMNzg2CJa3X4BrWf3X1nyNKvz2AOc/y+0ue+iOZLXno=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=k1MbEjGpCarlnhkm8vYOglA6pbGL1djQvYS78ifpBkV1kDBhCXmS48XHkeiOhB9jOOnLADeQXmqnTKWDcu1qNSMShnY9d9zeq+5F1ZKJnu0WADv/77IwpxBlZbJNt8noZAVxxUmmfTYX+uFiil7fyRZazKEmm2nK/hpkuYFr53c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=RPH1YjfC; arc=none smtp.client-ip=192.29.178.126 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="RPH1YjfC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=/GoyyFXCFrh8IJ5Vv8oStZBynWNL3tgZxKrVDVEmXTk=; b=RPH1YjfCT1HTCN3/eZM20QtdKAwTwjNzkNaIQwNed9SOo4RZJjndyih2o6zd1fvGS2tEttUUk03P IcpWzuzOftOriPHOc2yyrjrbZC1kORDXgfFmoPtpjqJpyNOYyZMI+Lx0WuZF076MkRMAhp2u3Yn4 t0MpH3/WLDP2W4yHsUdtynJaOS9AhsRgMbw3xA/Y0pjbmPo1nu96+TfZSrU18TK1BkGkGF+p9kpB rXP6FNKreY3znLKoUnPGF6O3Eonl501sOnctNIQBxnJkFoaLMOlSTP1R7u6tJ1dUA/MjngBSwswj DVwupGEQ10hiL/gsRNm993MtBzxkz7TKT77+jQ== Received: by omta-ad1-fd3-401-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR00I5GWDQ2330@omta-ad1-fd3-401-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:49:02 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 6/8] refs: add create_only option to refs_update_symref_extended Date: Tue, 22 Oct 2024 21:45:43 +0200 Message-id: <20241022194710.3743691-7-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAEaY43CsX4NS5gnX13mxeflHPj4BoTX7uiPTxCe+2EPNdQOKX973DeBaZxpBN4U b0AA7+5xFQF/if8asurBYWPxeYf7X5xNvraMBAtqLoFWlNurCrUhXZwVUBUBHItn ZgYwuFN5t2fOnlJfZqK3e1PD2vG7/5lhqQIhNxVZsY+/9uG1S0af6HlEqNZDZ1D1 +IgdpmY1Mcxg44NdA/U69Fjnm1muSqLDc36QjuX1qu7fK7iBHOuDMc7jbD0EY6k8 N1ECbuhhqlvIlVs0rJ7beXyToqdExKMzMB4w2ArYZZPkV3SEPLGJ2aJJGDLWpW45 lqM7oQAMQYyF5SSx2rqXN88BNiOSf/eBakN243XXMlEcH2hjegVSuTFfZUxHwBQW V+antl0teyMrtlpeXDOfEjgEWKA6evkY3MbCwkWfeK32npeYNEngCh47RMg5CdTt SJ4DWjzsv/zTJYj1onA4pfyzA/CMzo+3HkhZa1augG8wdr1CLKQXDgvF Allow the caller to specify that it only wants to update the symref if it does not already exist. Silently ignore the error from the transaction API if the symref already exists. Signed-off-by: Bence Ferdinandy --- Notes: v4: new patch v5: no change v6: - switched from bool to int for create_only - refactored logic in refs_update_symref with goto as layed out by Junio v7: - change commit prefix to be more in line with project standards - refactored code to accommodate changes in the first patch, but otherwise no change v8: no change v9: - no change (except for following through the refs_update_symref_extended refactoring) v10: no change v11: no change builtin/remote.c | 2 +- refs.c | 32 +++++++++++++++++++++++--------- refs.h | 2 +- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index 108f1271d3..b1eba75a2b 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1471,7 +1471,7 @@ static int set_head(int argc, const char **argv, const char *prefix) if (!refs_ref_exists(refs, b_remote_head.buf)) result |= error(_("Not a valid ref: %s"), b_remote_head.buf); else if (refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf, - "remote set-head", &b_local_head)) + "remote set-head", &b_local_head, 0)) result |= error(_("Could not setup %s"), b_head.buf); else if (opt_a) report_set_head_auto(argv[0], head_name, &b_local_head); diff --git a/refs.c b/refs.c index 24a4172cd2..093ee11ab0 100644 --- a/refs.c +++ b/refs.c @@ -2116,31 +2116,45 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct int refs_update_symref(struct ref_store *refs, const char *ref, const char *target, const char *logmsg) { - return refs_update_symref_extended(refs, ref, target, logmsg, NULL); + return refs_update_symref_extended(refs, ref, target, logmsg, NULL, 0); } int refs_update_symref_extended(struct ref_store *refs, const char *ref, const char *target, const char *logmsg, - struct strbuf *referent) + struct strbuf *referent, int create_only) { struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; - int ret = 0; + int ret = 0, prepret = 0; transaction = ref_store_transaction_begin(refs, &err); - if (!transaction || - ref_transaction_update(transaction, ref, NULL, NULL, - target, NULL, REF_NO_DEREF, - logmsg, &err) || - ref_transaction_prepare(transaction, &err)) { + if (!transaction) { + error_return: ret = error("%s", err.buf); goto cleanup; } + if (create_only) { + if (ref_transaction_create(transaction, ref, NULL, target, + REF_NO_DEREF, logmsg, &err)) + goto error_return; + prepret = ref_transaction_prepare(transaction, &err); + if (prepret && prepret != TRANSACTION_CREATE_EXISTS) + goto error_return; + } else { + if (ref_transaction_update(transaction, ref, NULL, NULL, + target, NULL, REF_NO_DEREF, + logmsg, &err) || + ref_transaction_prepare(transaction, &err)) + goto error_return; + } + if (referent) refs_read_symbolic_ref(refs, ref, referent); + if (prepret == TRANSACTION_CREATE_EXISTS) + goto cleanup; if (ref_transaction_commit(transaction, &err)) - ret = error("%s", err.buf); + goto error_return; cleanup: strbuf_release(&err); diff --git a/refs.h b/refs.h index a5bc25442b..458582ebcf 100644 --- a/refs.h +++ b/refs.h @@ -575,7 +575,7 @@ int refs_update_symref(struct ref_store *refs, const char *refname, int refs_update_symref_extended(struct ref_store *refs, const char *refname, const char *target, const char *logmsg, - struct strbuf *referent); + struct strbuf *referent, int create_only); enum action_on_err { UPDATE_REFS_MSG_ON_ERR, From patchwork Tue Oct 22 19:45:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846127 Received: from aib29agh127.zrh1.oracleemaildelivery.com (aib29agh127.zrh1.oracleemaildelivery.com [192.29.178.127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3483617C98 for ; Tue, 22 Oct 2024 19:49:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.127 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626579; cv=none; b=H3Jn+k8EKYWjbDio1hjnEkJGQvtcAeTz51BH9HalVLVatuPsSbTvk1oZYXw/0WUNSJJD42nAbwbUwv7GahVWfLNcXbZYKEzspWlY17M2YYsKJJbcGve9ZwRZHbz2Zwf7OCvPHBpBDtdV2uph9QfrhX7iwPO+QonVdQSrroMtFFI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626579; c=relaxed/simple; bh=jKZLFosNK8PFBB9XpTR6NArpkIxB+/D0yt2KM0NddNQ=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=d3xQLzXUsXFkFF/WOja/dUUox//FC4HAFd+tRDAQtv+ZsLSb3cIR0FGWGplbYnzRAGvJXYB2lMnGBiYjicfV9QMQxZ5MqHWxAiQr57kD69EA+Jx+JEq+iDU5tEs0MXm7G6mbbPaJUOb+qm7VMEXaP25KXTaDo0M6vatk3KJTrn0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=XHKNbnBb; arc=none smtp.client-ip=192.29.178.127 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="XHKNbnBb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=5wzOczvqqs85KZBSo/2ufu/06oe8wcIMK6m0+ASYmL4=; b=XHKNbnBbqZvAiLO7GBdko+qyjCIKr0q9+fK32ydczk0aJ/jhOkK7wxv0ZDb5dJ9fJ2DUNOPNlWaQ jUHpL6ICJvQjA5ESiXmZPDQNBQ6jz/Jcuvmns6H5REkKZeZBMo++NqFghErROmlBbYKYXPSYArkl DNABsnA3gnfdeD1wM+xMi30KhboXb+n7qKaSIvIKv7Q2fggk4YiO845lkGzei5r2o6sK5eoE8e8i wlQQ0YT9DqXa7soH5LzD+19CjpfREO0Z2z8Sc0WdPXVVQuLCmBuqi+kL+NU6Jq4YRZXith59V5Tu rWqxiL4PfoEA+t7hQ9mca1pUUgson4INP8+dNA== Received: by omta-ad1-fd3-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR00HHOWEGV940@omta-ad1-fd3-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:49:28 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 7/8] fetch: set remote/HEAD if it does not exist Date: Tue, 22 Oct 2024 21:45:44 +0200 Message-id: <20241022194710.3743691-8-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAEaY43CsX4NS5gnX13mxeflHPj4BoTX7uiPTxCe+2EPNdQOKX973DeBaZxpBN4U b0AA7+5xFQF/if8asuoNYmPxeYf7X5xNvra26tShnLT0LlYwuKBWnS/GOJyQ2Kx+ 4sbMAI1/BBug8oAX0XvL97Ur87TJrsmWItpou0tXYfrnPXP+W5lSvSF9zKu9exc1 Mz0S+I1R/rf06uQj0DVFoT34tLX5z5MnHLicu1xpKdHN5zmDRzTFRTA95q0GKsIp 3SWJfzHEmTQYPe5zaeFsnHA5CY1n8X20ryLrZx+Bi470enr/GoeIVAYI+1zB3Nsf +eu+3j9GMvSwnCH/e2NyRC69qJegTYbrq+HlfoKqLMDZOkDOPx0+gnHSXMA7HfTR XSqj2oCNvwAofHKTMuhPDTS+FHPtF2lo0E8cQ9N5FbrXYOXYI0BAuO2WQSjbITLe kzEJrq1OPwNjk5ZAcCuvZCU+JcJQxtWVOu33idKRLVtKc/R7pGvcIsw= If the user has remote/HEAD set already and it looks like it has changed on the server, then print a message, otherwise set it if we can. Silently pass if the user already has the same remote/HEAD set as reported by the server or if we encounter any errors along the way. Signed-off-by: Bence Ferdinandy --- Notes: v3: - does not rely on remote set-head anymore so it only authenticates once - uses the new REF_CREATE_ONLY to atomically check if the ref exists and only write it if it doesn't - in all other cases the maximum it does is print a warning v4: - instead of the discarded REF_CREATE_ONLY, it uses the existing, but updated transaction api to request a silent create only - it now uses the atomic before_target to determine reporting - refactored for legibility v5: - instead of printing a not too useful message, it now fails silently, this in line with the objective to only set up remote/HEAD automatically if the right thing is trivial, for everything else there is remote set-head - fixed all failing tests - added two new tests, one for checking if remote/HEAD is set to the correct one, and one to test that we do not override remote/HEAD if it has changed on the server from what we have locally v6: - fixed style issues and unintended extra empty line - updated function call with bool to int from previous patch's change - removed calls to error(...) inherited from builtin/remote.c so we actually fail silently - set the test for remote set-head --auto to the correct value here, which was previously erronously set in the remote set-head patch v7: - no change v8: - changed logmsg in call to refs_update_symref from "remote set-head" to "fetch" v9: - follow through with refs_update_symref_extended - fix test errors uncovered by the new patch v10: no change v11: fixed some memory leaks builtin/fetch.c | 86 ++++++++++++ t/t4207-log-decoration-colors.sh | 3 +- t/t5505-remote.sh | 21 ++- t/t5510-fetch.sh | 229 ++++++++++++++++--------------- t/t5512-ls-remote.sh | 2 + t/t5514-fetch-multiple.sh | 17 ++- t/t5516-fetch-push.sh | 3 +- t/t5527-fetch-odd-refs.sh | 3 +- t/t7900-maintenance.sh | 3 +- t/t9210-scalar.sh | 5 +- t/t9211-scalar-clone.sh | 6 +- t/t9902-completion.sh | 65 +++++++++ 12 files changed, 319 insertions(+), 124 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index d9027e4dc9..cadfd2407a 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1578,6 +1578,84 @@ static int backfill_tags(struct display_state *display_state, return retcode; } +static void report_set_head(const char *remote, const char *head_name, + struct strbuf *buf_prev) { + struct strbuf buf_prefix = STRBUF_INIT; + const char *prev_head = NULL; + + strbuf_addf(&buf_prefix, "refs/remotes/%s/", remote); + skip_prefix(buf_prev->buf, buf_prefix.buf, &prev_head); + + if (prev_head && strcmp(prev_head, head_name)) { + printf("'HEAD' at '%s' has changed from '%s' to '%s'\n", + remote, prev_head, head_name); + printf("Run 'git remote set-head %s %s' to follow the change.\n", + remote, head_name); + } + strbuf_release(&buf_prefix); +} + +static const char *strip_refshead(const char *name){ + skip_prefix(name, "refs/heads/", &name); + return name; +} + +static int set_head(const struct ref *remote_refs) +{ + int result = 0; + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, + b_local_head = STRBUF_INIT; + const char *remote = gtransport->remote->name; + char *head_name = NULL; + struct ref *ref, *matches; + struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map; + struct refspec_item refspec = { + .force = 0, + .pattern = 1, + .src = (char *) "refs/heads/*", + .dst = (char *) "refs/heads/*", + }; + struct string_list heads = STRING_LIST_INIT_DUP; + struct ref_store *refs = get_main_ref_store(the_repository); + + get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0); + matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"), + fetch_map, 1); + for (ref = matches; ref; ref = ref->next) { + string_list_append(&heads, strip_refshead(ref->name)); + } + + + if (!heads.nr) + result = 1; + else if (heads.nr > 1) + result = 1; + else + head_name = xstrdup(heads.items[0].string); + if (head_name) { + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name); + /* make sure it's valid */ + if (!refs_ref_exists(refs, b_remote_head.buf)) + result = 1; + else if (refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf, + "fetch", &b_local_head, 1)) + result = 1; + else + report_set_head(remote, head_name, &b_local_head); + + free(head_name); + } + + free_refs(fetch_map); + free_refs(matches); + string_list_clear(&heads, 0); + strbuf_release(&b_head); + strbuf_release(&b_local_head); + strbuf_release(&b_remote_head); + return result; +} + static int do_fetch(struct transport *transport, struct refspec *rs, const struct fetch_config *config) @@ -1647,6 +1725,8 @@ static int do_fetch(struct transport *transport, "refs/tags/"); } + strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); + if (must_list_refs) { trace2_region_enter("fetch", "remote_refs", the_repository); remote_refs = transport_get_remote_refs(transport, @@ -1791,6 +1871,12 @@ static int do_fetch(struct transport *transport, "you need to specify exactly one branch with the --set-upstream option")); } } + if (set_head(remote_refs)) + ; + /* + * Way too many cases where this can go wrong + * so let's just fail silently for now. + */ cleanup: if (retcode) { diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index 73ea9e5155..d55d22cb2f 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -59,7 +59,8 @@ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}v1.0${c_reset}${c_commit}, \ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}B${c_reset}${c_commit})${c_reset} B ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ ${c_tag}tag: ${c_reset}${c_tag}A1${c_reset}${c_commit}, \ -${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit})${c_reset} A1 +${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit}, \ +${c_reset}${c_remoteBranch}other/HEAD${c_reset}${c_commit})${c_reset} A1 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ ${c_stash}refs/stash${c_reset}${c_commit})${c_reset} On main: Changes to A.t ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 0ea86d51a4..4990d00209 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -74,7 +74,7 @@ test_expect_success 'add another remote' ' cd test && git remote add -f second ../two && tokens_match "origin second" "$(git remote)" && - check_tracking_branch second main side another && + check_tracking_branch second main side another HEAD && git for-each-ref "--format=%(refname)" refs/remotes | sed -e "/^refs\/remotes\/origin\//d" \ -e "/^refs\/remotes\/second\//d" >actual && @@ -476,7 +476,7 @@ test_expect_success 'set-head --auto has no problem w/multiple HEADs' ' cd test && git fetch two "refs/heads/*:refs/remotes/two/*" && git remote set-head --auto two >output 2>&1 && - echo "${SQ}two/HEAD${SQ} is now created and points to ${SQ}main${SQ}" >expect && + echo "${SQ}two/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect && test_cmp expect output ) ' @@ -764,8 +764,10 @@ test_expect_success 'reject --no-no-tags' ' ' cat >one/expect <<\EOF + apis/HEAD -> apis/main apis/main apis/side + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -783,11 +785,14 @@ test_expect_success 'update' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side + manduca/HEAD -> manduca/main manduca/main manduca/side + megaloprepus/HEAD -> megaloprepus/main megaloprepus/main megaloprepus/side EOF @@ -795,7 +800,7 @@ EOF test_expect_success 'update with arguments' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -827,10 +832,13 @@ test_expect_success 'update --prune' ' ' cat >one/expect <<-\EOF + apis/HEAD -> apis/main apis/main apis/side + manduca/HEAD -> manduca/main manduca/main manduca/side + megaloprepus/HEAD -> megaloprepus/main megaloprepus/main megaloprepus/side EOF @@ -838,7 +846,7 @@ EOF test_expect_success 'update default' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -850,6 +858,7 @@ test_expect_success 'update default' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -858,7 +867,7 @@ EOF test_expect_success 'update default (overridden, with funny whitespace)' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -872,7 +881,7 @@ test_expect_success 'update default (overridden, with funny whitespace)' ' test_expect_success 'update (with remotes.default defined)' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 0890b9f61c..dfc8d748ba 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -75,6 +75,30 @@ test_expect_success "fetch test for-merge" ' cut -f -2 .git/FETCH_HEAD >actual && test_cmp expected actual' +test_expect_success "fetch test remote HEAD" ' + cd "$D" && + cd two && + git fetch && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch"' + +test_expect_success "fetch test remote HEAD change" ' + cd "$D" && + cd two && + git switch -c other && + git push -u origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git fetch && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch"' + test_expect_success 'fetch --prune on its own works as expected' ' cd "$D" && git clone . prune && @@ -478,7 +502,6 @@ test_expect_success 'unbundle 1' ' test_must_fail git fetch "$D/bundle1" main:main ' - test_expect_success 'bundle 1 has only 3 files ' ' cd "$D" && test_bundle_object_count bundle1 3 @@ -819,7 +842,7 @@ test_expect_success 'fetch from multiple configured URLs in single remote' ' # configured prune tests -set_config_tristate () { +set_config_tristate() { # var=$1 val=$2 case "$2" in unset) @@ -833,12 +856,12 @@ set_config_tristate () { esac } -test_configured_prune () { +test_configured_prune() { test_configured_prune_type "$@" "name" test_configured_prune_type "$@" "link" } -test_configured_prune_type () { +test_configured_prune_type() { fetch_prune=$1 remote_origin_prune=$2 fetch_prune_tags=$3 @@ -848,8 +871,7 @@ test_configured_prune_type () { cmdline=$7 mode=$8 - if test -z "$cmdline_setup" - then + if test -z "$cmdline_setup"; then test_expect_success 'setup cmdline_setup variable for subsequent test' ' remote_url="file://$(git -C one config remote.origin.url)" && remote_fetch="$(git -C one config remote.origin.fetch)" && @@ -857,12 +879,10 @@ test_configured_prune_type () { ' fi - if test "$mode" = 'link' - then + if test "$mode" = 'link'; then new_cmdline="" - if test "$cmdline" = "" - then + if test "$cmdline" = ""; then new_cmdline=$cmdline_setup else new_cmdline=$(perl -e ' @@ -873,10 +893,8 @@ test_configured_prune_type () { fi if test "$fetch_prune_tags" = 'true' || - test "$remote_origin_prune_tags" = 'true' - then - if ! printf '%s' "$cmdline\n" | grep -q refs/remotes/origin/ - then + test "$remote_origin_prune_tags" = 'true'; then + if ! printf '%s' "$cmdline\n" | grep -q refs/remotes/origin/; then new_cmdline="$new_cmdline refs/tags/*:refs/tags/*" fi fi @@ -946,100 +964,100 @@ test_configured_prune_type () { # $7 git-fetch $cmdline: # # $1 $2 $3 $4 $5 $6 $7 -test_configured_prune unset unset unset unset kept kept "" -test_configured_prune unset unset unset unset kept kept "--no-prune" -test_configured_prune unset unset unset unset pruned kept "--prune" -test_configured_prune unset unset unset unset kept pruned \ +test_configured_prune unset unset unset unset kept kept "" +test_configured_prune unset unset unset unset kept kept "--no-prune" +test_configured_prune unset unset unset unset pruned kept "--prune" +test_configured_prune unset unset unset unset kept pruned \ "--prune origin refs/tags/*:refs/tags/*" test_configured_prune unset unset unset unset pruned pruned \ "--prune origin refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/*" -test_configured_prune false unset unset unset kept kept "" -test_configured_prune false unset unset unset kept kept "--no-prune" -test_configured_prune false unset unset unset pruned kept "--prune" +test_configured_prune false unset unset unset kept kept "" +test_configured_prune false unset unset unset kept kept "--no-prune" +test_configured_prune false unset unset unset pruned kept "--prune" -test_configured_prune true unset unset unset pruned kept "" -test_configured_prune true unset unset unset pruned kept "--prune" -test_configured_prune true unset unset unset kept kept "--no-prune" +test_configured_prune true unset unset unset pruned kept "" +test_configured_prune true unset unset unset pruned kept "--prune" +test_configured_prune true unset unset unset kept kept "--no-prune" -test_configured_prune unset false unset unset kept kept "" -test_configured_prune unset false unset unset kept kept "--no-prune" -test_configured_prune unset false unset unset pruned kept "--prune" +test_configured_prune unset false unset unset kept kept "" +test_configured_prune unset false unset unset kept kept "--no-prune" +test_configured_prune unset false unset unset pruned kept "--prune" -test_configured_prune false false unset unset kept kept "" -test_configured_prune false false unset unset kept kept "--no-prune" -test_configured_prune false false unset unset pruned kept "--prune" -test_configured_prune false false unset unset kept pruned \ +test_configured_prune false false unset unset kept kept "" +test_configured_prune false false unset unset kept kept "--no-prune" +test_configured_prune false false unset unset pruned kept "--prune" +test_configured_prune false false unset unset kept pruned \ "--prune origin refs/tags/*:refs/tags/*" test_configured_prune false false unset unset pruned pruned \ "--prune origin refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/*" -test_configured_prune true false unset unset kept kept "" -test_configured_prune true false unset unset pruned kept "--prune" -test_configured_prune true false unset unset kept kept "--no-prune" +test_configured_prune true false unset unset kept kept "" +test_configured_prune true false unset unset pruned kept "--prune" +test_configured_prune true false unset unset kept kept "--no-prune" -test_configured_prune unset true unset unset pruned kept "" -test_configured_prune unset true unset unset kept kept "--no-prune" -test_configured_prune unset true unset unset pruned kept "--prune" +test_configured_prune unset true unset unset pruned kept "" +test_configured_prune unset true unset unset kept kept "--no-prune" +test_configured_prune unset true unset unset pruned kept "--prune" -test_configured_prune false true unset unset pruned kept "" -test_configured_prune false true unset unset kept kept "--no-prune" -test_configured_prune false true unset unset pruned kept "--prune" +test_configured_prune false true unset unset pruned kept "" +test_configured_prune false true unset unset kept kept "--no-prune" +test_configured_prune false true unset unset pruned kept "--prune" -test_configured_prune true true unset unset pruned kept "" -test_configured_prune true true unset unset pruned kept "--prune" -test_configured_prune true true unset unset kept kept "--no-prune" -test_configured_prune true true unset unset kept pruned \ +test_configured_prune true true unset unset pruned kept "" +test_configured_prune true true unset unset pruned kept "--prune" +test_configured_prune true true unset unset kept kept "--no-prune" +test_configured_prune true true unset unset kept pruned \ "--prune origin refs/tags/*:refs/tags/*" -test_configured_prune true true unset unset pruned pruned \ +test_configured_prune true true unset unset pruned pruned \ "--prune origin refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/*" # --prune-tags on its own does nothing, needs --prune as well, same # for fetch.pruneTags without fetch.prune -test_configured_prune unset unset unset unset kept kept "--prune-tags" -test_configured_prune unset unset true unset kept kept "" -test_configured_prune unset unset unset true kept kept "" +test_configured_prune unset unset unset unset kept kept "--prune-tags" +test_configured_prune unset unset true unset kept kept "" +test_configured_prune unset unset unset true kept kept "" # These will prune the tags test_configured_prune unset unset unset unset pruned pruned "--prune --prune-tags" -test_configured_prune true unset true unset pruned pruned "" -test_configured_prune unset true unset true pruned pruned "" +test_configured_prune true unset true unset pruned pruned "" +test_configured_prune unset true unset true pruned pruned "" # remote..pruneTags overrides fetch.pruneTags, just like # remote..prune overrides fetch.prune if set. -test_configured_prune true unset true unset pruned pruned "" -test_configured_prune false true false true pruned pruned "" -test_configured_prune true false true false kept kept "" +test_configured_prune true unset true unset pruned pruned "" +test_configured_prune false true false true pruned pruned "" +test_configured_prune true false true false kept kept "" # When --prune-tags is supplied it's ignored if an explicit refspec is # given, same for the configuration options. test_configured_prune unset unset unset unset pruned kept \ "--prune --prune-tags origin +refs/heads/*:refs/remotes/origin/*" -test_configured_prune unset unset true unset pruned kept \ +test_configured_prune unset unset true unset pruned kept \ "--prune origin +refs/heads/*:refs/remotes/origin/*" -test_configured_prune unset unset unset true pruned kept \ +test_configured_prune unset unset unset true pruned kept \ "--prune origin +refs/heads/*:refs/remotes/origin/*" # Pruning that also takes place if a file:// url replaces a named # remote. However, because there's no implicit # +refs/heads/*:refs/remotes/origin/* refspec and supplying it on the # command-line negates --prune-tags, the branches will not be pruned. -test_configured_prune_type unset unset unset unset kept kept "origin --prune-tags" "name" -test_configured_prune_type unset unset unset unset kept kept "origin --prune-tags" "link" +test_configured_prune_type unset unset unset unset kept kept "origin --prune-tags" "name" +test_configured_prune_type unset unset unset unset kept kept "origin --prune-tags" "link" test_configured_prune_type unset unset unset unset pruned pruned "origin --prune --prune-tags" "name" -test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "link" +test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "link" test_configured_prune_type unset unset unset unset pruned pruned "--prune --prune-tags origin" "name" -test_configured_prune_type unset unset unset unset kept pruned "--prune --prune-tags origin" "link" -test_configured_prune_type unset unset true unset pruned pruned "--prune origin" "name" -test_configured_prune_type unset unset true unset kept pruned "--prune origin" "link" -test_configured_prune_type unset unset unset true pruned pruned "--prune origin" "name" -test_configured_prune_type unset unset unset true kept pruned "--prune origin" "link" -test_configured_prune_type true unset true unset pruned pruned "origin" "name" -test_configured_prune_type true unset true unset kept pruned "origin" "link" -test_configured_prune_type unset true true unset pruned pruned "origin" "name" -test_configured_prune_type unset true true unset kept pruned "origin" "link" -test_configured_prune_type unset true unset true pruned pruned "origin" "name" -test_configured_prune_type unset true unset true kept pruned "origin" "link" +test_configured_prune_type unset unset unset unset kept pruned "--prune --prune-tags origin" "link" +test_configured_prune_type unset unset true unset pruned pruned "--prune origin" "name" +test_configured_prune_type unset unset true unset kept pruned "--prune origin" "link" +test_configured_prune_type unset unset unset true pruned pruned "--prune origin" "name" +test_configured_prune_type unset unset unset true kept pruned "--prune origin" "link" +test_configured_prune_type true unset true unset pruned pruned "origin" "name" +test_configured_prune_type true unset true unset kept pruned "origin" "link" +test_configured_prune_type unset true true unset pruned pruned "origin" "name" +test_configured_prune_type unset true true unset kept pruned "origin" "link" +test_configured_prune_type unset true unset true pruned pruned "origin" "name" +test_configured_prune_type unset true unset true kept pruned "origin" "link" # When all remote.origin.fetch settings are deleted a --prune # --prune-tags still implicitly supplies refs/tags/*:refs/tags/* so @@ -1137,8 +1155,7 @@ test_expect_success 'fetching with auto-gc does not lock up' ' ) ' -for section in fetch transfer -do +for section in fetch transfer; do test_expect_success "$section.hideRefs affects connectivity check" ' GIT_TRACE="$PWD"/trace git -c $section.hideRefs=refs -c \ $section.hideRefs="!refs/tags/" fetch && @@ -1157,21 +1174,23 @@ test_expect_success 'prepare source branch' ' test 3 -le $(wc -l actual && - case "$store_type" in - packed) - grep "^count: 0$" actual ;; - loose) - grep "^packs: 0$" actual ;; - esac || { + case "$store_type" in + packed) + grep "^count: 0$" actual + ;; + loose) + grep "^packs: 0$" actual + ;; + esac || { echo "store_type is $store_type" cat actual false } } -test_unpack_limit () { +test_unpack_limit() { store_type=$1 case "$store_type" in @@ -1192,43 +1211,39 @@ test_unpack_limit () { test_unpack_limit packed test_unpack_limit loose -setup_negotiation_tip () { +setup_negotiation_tip() { SERVER="$1" URL="$2" USE_PROTOCOL_V2="$3" rm -rf "$SERVER" client trace && - git init -b main "$SERVER" && - test_commit -C "$SERVER" alpha_1 && - test_commit -C "$SERVER" alpha_2 && - git -C "$SERVER" checkout --orphan beta && - test_commit -C "$SERVER" beta_1 && - test_commit -C "$SERVER" beta_2 && - - git clone "$URL" client && - - if test "$USE_PROTOCOL_V2" -eq 1 - then - git -C "$SERVER" config protocol.version 2 && - git -C client config protocol.version 2 - fi && - - test_commit -C "$SERVER" beta_s && - git -C "$SERVER" checkout main && - test_commit -C "$SERVER" alpha_s && - git -C "$SERVER" tag -d alpha_1 alpha_2 beta_1 beta_2 + git init -b main "$SERVER" && + test_commit -C "$SERVER" alpha_1 && + test_commit -C "$SERVER" alpha_2 && + git -C "$SERVER" checkout --orphan beta && + test_commit -C "$SERVER" beta_1 && + test_commit -C "$SERVER" beta_2 && + git clone "$URL" client && + if test "$USE_PROTOCOL_V2" -eq 1; then + git -C "$SERVER" config protocol.version 2 && + git -C client config protocol.version 2 + fi && + test_commit -C "$SERVER" beta_s && + git -C "$SERVER" checkout main && + test_commit -C "$SERVER" alpha_s && + git -C "$SERVER" tag -d alpha_1 alpha_2 beta_1 beta_2 } -check_negotiation_tip () { +check_negotiation_tip() { # Ensure that {alpha,beta}_1 are sent as "have", but not {alpha_beta}_2 ALPHA_1=$(git -C client rev-parse alpha_1) && - grep "fetch> have $ALPHA_1" trace && - BETA_1=$(git -C client rev-parse beta_1) && - grep "fetch> have $BETA_1" trace && - ALPHA_2=$(git -C client rev-parse alpha_2) && - ! grep "fetch> have $ALPHA_2" trace && - BETA_2=$(git -C client rev-parse beta_2) && - ! grep "fetch> have $BETA_2" trace + grep "fetch> have $ALPHA_1" trace && + BETA_1=$(git -C client rev-parse beta_1) && + grep "fetch> have $BETA_1" trace && + ALPHA_2=$(git -C client rev-parse alpha_2) && + ! grep "fetch> have $ALPHA_2" trace && + BETA_2=$(git -C client rev-parse beta_2) && + ! grep "fetch> have $BETA_2" trace } test_expect_success '--negotiation-tip limits "have" lines sent' ' diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 64b3491e4e..1b3865e154 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -293,6 +293,8 @@ test_expect_success 'ls-remote with filtered symref (refname)' ' cat >expect <<-EOF && ref: refs/heads/main HEAD $rev HEAD + ref: refs/remotes/origin/main refs/remotes/origin/HEAD + $rev refs/remotes/origin/HEAD EOF git ls-remote --symref . HEAD >actual && test_cmp expect actual diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index 579872c258..e3482b27b2 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -45,14 +45,17 @@ test_expect_success setup ' ' cat > test/expect << EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -97,6 +100,7 @@ cat > expect << EOF origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side @@ -112,8 +116,10 @@ test_expect_success 'git fetch --multiple (but only one remote)' ' ' cat > expect << EOF + one/HEAD -> one/main one/main one/side + two/HEAD -> two/main two/another two/main two/side @@ -141,7 +147,7 @@ test_expect_success 'git fetch --multiple (bad remote names)' ' test_expect_success 'git fetch --all (skipFetchAll)' ' (cd test4 && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -153,11 +159,14 @@ test_expect_success 'git fetch --all (skipFetchAll)' ' ' cat > expect << EOF + one/HEAD -> one/main one/main one/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -165,7 +174,7 @@ EOF test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' ' (cd test4 && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -221,14 +230,17 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' ' create_fetch_all_expect () { cat >expect <<-\EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -265,6 +277,7 @@ test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' ' create_fetch_one_expect () { cat >expect <<-\EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 331778bd42..5a051aa0c7 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1395,7 +1395,8 @@ test_expect_success 'fetch follows tags by default' ' git tag -m "annotated" tag && git for-each-ref >tmp1 && sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 | - sort -k 3 >../expect + sed -n "p; s|refs/heads/main$|refs/remotes/origin/HEAD|p" | + sort -k 4 >../expect ) && test_when_finished "rm -rf dst" && git init dst && diff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh index 98ece27c6a..d3996af6ee 100755 --- a/t/t5527-fetch-odd-refs.sh +++ b/t/t5527-fetch-odd-refs.sh @@ -52,7 +52,8 @@ test_expect_success LONG_REF 'fetch handles extremely long refname' ' long main EOF - git for-each-ref --format="%(subject)" refs/remotes/long >actual && + git for-each-ref --format="%(subject)" refs/remotes/long \ + --exclude=refs/remotes/long/HEAD >actual && test_cmp expect actual ' diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index a66d0e089d..88331d1ceb 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -329,7 +329,8 @@ test_expect_success 'incremental-repack task' ' # Delete refs that have not been repacked in these packs. git for-each-ref --format="delete %(refname)" \ - refs/prefetch refs/tags refs/remotes >refs && + refs/prefetch refs/tags refs/remotes \ + --exclude=refs/remotes/*/HEAD >refs && git update-ref --stdin actual && - echo "refs/remotes/origin/parallel" >expect && + echo "refs/remotes/origin/HEAD" >>expect && + echo "refs/remotes/origin/parallel" >>expect && test_cmp expect actual && test_path_is_missing 1/2 && @@ -220,7 +221,7 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' ' done ' - test_expect_success 'scalar reconfigure --all with detached HEADs' ' +test_expect_success 'scalar reconfigure --all with detached HEADs' ' repos="two three four" && for num in $repos do diff --git a/t/t9211-scalar-clone.sh b/t/t9211-scalar-clone.sh index c16ea67c1d..d9cb6b9a3e 100755 --- a/t/t9211-scalar-clone.sh +++ b/t/t9211-scalar-clone.sh @@ -32,7 +32,7 @@ test_expect_success 'set up repository to clone' ' ) ' -cleanup_clone () { +cleanup_clone() { rm -rf "$1" } @@ -128,7 +128,7 @@ test_expect_success '--single-branch clones HEAD only' ' ( cd $enlistment/src && git for-each-ref refs/remotes/origin >out && - test_line_count = 1 out && + test_line_count = 2 out && grep "refs/remotes/origin/base" out ) && @@ -142,7 +142,7 @@ test_expect_success '--no-single-branch clones all branches' ' ( cd $enlistment/src && git for-each-ref refs/remotes/origin >out && - test_line_count = 2 out && + test_line_count = 3 out && grep "refs/remotes/origin/base" out && grep "refs/remotes/origin/parallel" out ) && diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index cc6aa9f0cd..b663c4609e 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -658,6 +658,7 @@ test_expect_success '__git_refs - simple' ' HEAD main matching-branch + other/HEAD other/branch-in-other other/main-in-other matching-tag @@ -673,6 +674,7 @@ test_expect_success '__git_refs - full refs' ' cat >expected <<-EOF && refs/heads/main refs/heads/matching-branch + refs/remotes/other/HEAD refs/remotes/other/branch-in-other refs/remotes/other/main-in-other refs/tags/matching-tag @@ -729,6 +731,7 @@ test_expect_success '__git_refs - remote on local file system - full refs' ' test_expect_success '__git_refs - configured remote' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -756,6 +759,7 @@ test_expect_success '__git_refs - configured remote - full refs' ' test_expect_success '__git_refs - configured remote - repo given on the command line' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -787,6 +791,7 @@ test_expect_success '__git_refs - configured remote - full refs - repo given on test_expect_success '__git_refs - configured remote - remote name matches a directory' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -875,12 +880,14 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer HEAD main matching-branch + other/HEAD other/ambiguous other/branch-in-other other/main-in-other remote/ambiguous remote/branch-in-remote matching-tag + HEAD branch-in-other branch-in-remote main-in-other @@ -904,6 +911,7 @@ test_expect_success '__git_refs - after --opt=' ' HEAD main matching-branch + other/HEAD other/branch-in-other other/main-in-other matching-tag @@ -919,6 +927,7 @@ test_expect_success '__git_refs - after --opt= - full refs' ' cat >expected <<-EOF && refs/heads/main refs/heads/matching-branch + refs/remotes/other/HEAD refs/remotes/other/branch-in-other refs/remotes/other/main-in-other refs/tags/matching-tag @@ -935,6 +944,7 @@ test_expect_success '__git refs - excluding refs' ' ^HEAD ^main ^matching-branch + ^other/HEAD ^other/branch-in-other ^other/main-in-other ^matching-tag @@ -950,6 +960,7 @@ test_expect_success '__git refs - excluding full refs' ' cat >expected <<-EOF && ^refs/heads/main ^refs/heads/matching-branch + ^refs/remotes/other/HEAD ^refs/remotes/other/branch-in-other ^refs/remotes/other/main-in-other ^refs/tags/matching-tag @@ -975,6 +986,7 @@ test_expect_success '__git_refs - do not filter refs unless told so' ' main matching-branch matching/branch + other/HEAD other/branch-in-other other/main-in-other other/matching/branch-in-other @@ -1095,6 +1107,7 @@ test_expect_success '__git_complete_refs - simple' ' HEAD Z main Z matching-branch Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z matching-tag Z @@ -1123,6 +1136,7 @@ test_expect_success '__git_complete_refs - matching' ' test_expect_success '__git_complete_refs - remote' ' sed -e "s/Z$//" >expected <<-EOF && HEAD Z + HEAD Z branch-in-other Z main-in-other Z EOF @@ -1139,9 +1153,11 @@ test_expect_success '__git_complete_refs - track' ' HEAD Z main Z matching-branch Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z matching-tag Z + HEAD Z branch-in-other Z main-in-other Z EOF @@ -1184,6 +1200,7 @@ test_expect_success '__git_complete_refs - suffix' ' HEAD. main. matching-branch. + other/HEAD. other/branch-in-other. other/main-in-other. matching-tag. @@ -1199,6 +1216,7 @@ test_expect_success '__git_complete_refs - suffix' ' test_expect_success '__git_complete_fetch_refspecs - simple' ' sed -e "s/Z$//" >expected <<-EOF && HEAD:HEAD Z + HEAD:HEAD Z branch-in-other:branch-in-other Z main-in-other:main-in-other Z EOF @@ -1225,6 +1243,7 @@ test_expect_success '__git_complete_fetch_refspecs - matching' ' test_expect_success '__git_complete_fetch_refspecs - prefix' ' sed -e "s/Z$//" >expected <<-EOF && +HEAD:HEAD Z + +HEAD:HEAD Z +branch-in-other:branch-in-other Z +main-in-other:main-in-other Z EOF @@ -1289,6 +1308,7 @@ test_expect_success '__git_complete_worktree_paths with -C' ' test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' ' test_completion "git switch " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1435,11 +1455,13 @@ test_expect_success 'git-bisect - existing view subcommand is recognized and ena test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' ' test_completion "git checkout " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1461,6 +1483,7 @@ test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, compl test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' ' GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1470,6 +1493,7 @@ test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_G test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' ' test_completion "git switch --no-guess --guess " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1490,6 +1514,7 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1498,11 +1523,13 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' ' GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1514,6 +1541,7 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1522,11 +1550,13 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' ' test_completion "git checkout --no-guess --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1538,6 +1568,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1550,6 +1581,7 @@ test_expect_success 'git checkout - with checkout.guess = false, only completes main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1559,11 +1591,13 @@ test_expect_success 'git checkout - with checkout.guess = true, completes refs a test_config checkout.guess true && test_completion "git checkout " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1573,11 +1607,13 @@ test_expect_success 'git checkout - a later --guess overrides previous checkout. test_config checkout.guess false && test_completion "git checkout --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1590,6 +1626,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous checko main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1601,6 +1638,7 @@ test_expect_success 'git switch - with --detach, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1612,6 +1650,7 @@ test_expect_success 'git checkout - with --detach, complete only references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1783,6 +1822,7 @@ test_expect_success 'git switch - with -d, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1794,6 +1834,7 @@ test_expect_success 'git checkout - with -d, complete only references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1801,10 +1842,12 @@ test_expect_success 'git checkout - with -d, complete only references' ' test_expect_success 'git switch - with --track, complete only remote branches' ' test_completion "git switch --track " <<-\EOF && + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF test_completion "git switch -t " <<-\EOF + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1812,10 +1855,12 @@ test_expect_success 'git switch - with --track, complete only remote branches' ' test_expect_success 'git checkout - with --track, complete only remote branches' ' test_completion "git checkout --track " <<-\EOF && + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF test_completion "git checkout -t " <<-\EOF + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1834,6 +1879,7 @@ test_expect_success 'git checkout - with --no-track, complete only local referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1845,6 +1891,7 @@ test_expect_success 'git switch - with -c, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1856,6 +1903,7 @@ test_expect_success 'git switch - with -C, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1867,6 +1915,7 @@ test_expect_success 'git switch - with -c and --track, complete all references' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1878,6 +1927,7 @@ test_expect_success 'git switch - with -C and --track, complete all references' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1889,6 +1939,7 @@ test_expect_success 'git switch - with -c and --no-track, complete all reference main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1900,6 +1951,7 @@ test_expect_success 'git switch - with -C and --no-track, complete all reference main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1911,6 +1963,7 @@ test_expect_success 'git checkout - with -b, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1922,6 +1975,7 @@ test_expect_success 'git checkout - with -B, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1933,6 +1987,7 @@ test_expect_success 'git checkout - with -b and --track, complete all references main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1944,6 +1999,7 @@ test_expect_success 'git checkout - with -B and --track, complete all references main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1955,6 +2011,7 @@ test_expect_success 'git checkout - with -b and --no-track, complete all referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1966,6 +2023,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1973,6 +2031,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen test_expect_success 'git switch - for -c, complete local branches and unique remote branches' ' test_completion "git switch -c " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1982,6 +2041,7 @@ test_expect_success 'git switch - for -c, complete local branches and unique rem test_expect_success 'git switch - for -C, complete local branches and unique remote branches' ' test_completion "git switch -C " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2019,6 +2079,7 @@ test_expect_success 'git switch - for -C with --no-track, complete local branche test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' ' test_completion "git checkout -b " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2028,6 +2089,7 @@ test_expect_success 'git checkout - for -b, complete local branches and unique r test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' ' test_completion "git checkout -B " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2065,6 +2127,7 @@ test_expect_success 'git checkout - for -B with --no-track, complete local branc test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' ' test_completion "git switch --orphan " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2080,6 +2143,7 @@ test_expect_success 'git switch - --orphan with branch already provided complete test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' ' test_completion "git checkout --orphan " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2093,6 +2157,7 @@ test_expect_success 'git checkout - --orphan with branch already provided comple main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF From patchwork Tue Oct 22 19:45:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bence Ferdinandy X-Patchwork-Id: 13846128 Received: from aib29agh127.zrh1.oracleemaildelivery.com (aib29agh127.zrh1.oracleemaildelivery.com [192.29.178.127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA5F114EC55 for ; Tue, 22 Oct 2024 19:49:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.29.178.127 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626582; cv=none; b=mEcDY1mSvkq1R/S120lb01YdZmmYjKY65teusrnLVgPzDiWnN5vdAtgDU2LPjNK+2Vs6p/ReMdDK4pzV4ZfxO47eJM5UqF5ooTFUb+n6Rv0eBvS0yJM2vThvCrYrpMpzUv0v7ci7VZVe3zXL+xHS5vvY0UHY9Huv3inqTit2uJE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729626582; c=relaxed/simple; bh=62nUaqLuKaLvEusuDq03kdMcUfc5DztYA0B/UsxdMEc=; h=From:To:Cc:Subject:Date:Message-id:In-reply-to:References: MIME-version; b=EdCjOE/oR2zxB7bVyBqfDZGt4a2KSFejrix8nTCAyfGIsEiZk4UANrBPwzaqU0UWCg995qu+UIY7Oh6c6zSTemq4A7nliRCWqBRegUOK7exPnLSpkynVdFWETuDC+H92rdqO0AD8LXd2rxvLI612j9wHq7Mgb9p6TaksAJkRLW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b=byKZ7h6+; arc=none smtp.client-ip=192.29.178.127 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=ferdinandy.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zrh1.rp.oracleemaildelivery.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zrh1.rp.oracleemaildelivery.com header.i=@zrh1.rp.oracleemaildelivery.com header.b="byKZ7h6+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=prod-zrh-20200406; d=zrh1.rp.oracleemaildelivery.com; h=Date:To:From:Subject:Message-Id:MIME-Version:Sender:List-Unsubscribe:List-Unsubscribe-Post; bh=jkHHDIjYSynWLR1suICL9Xob1GMrY4FOJ+j0wiXOUR8=; b=byKZ7h6+ZCIxW7SdGwvKObTKlnRl6eg4TDGNUkk7p4pOqUINxW+6YrzMPtMuPtYr4TMu8qV/iCjP KtRs7JMcTCMg5eDjH6WkYGYmrVaSg0xJhUMkSkNlS2l5jm4Ci6Uj/pgBxiqilfCmJOoZZw9m1qHH lTN1F9jWqdgH1/z02kNa2xOcI7BP9A2ysixVnUZ9RmyBYCxCYxSzbALEHDAbAF1dKld74FZlmNMb LddHdRjlCDMii1oWko2KaNecA9+CPCba09mvpgtTQMq2UunUQj9IqSK2XQSaIWnAq1szfi7a2HdU HLH78FAU20cJK3bGMYFHbNEvnIyWVAYofqcqqg== Received: by omta-ad1-fd3-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com (Oracle Communications Messaging Server 8.1.0.1.20240911 64bit (built Sep 11 2024)) with ESMTPS id <0SLR006PTWELGZ90@omta-ad1-fd3-402-eu-zurich-1.omtaad1.vcndpzrh.oraclevcn.com> for git@vger.kernel.org; Tue, 22 Oct 2024 19:49:33 +0000 (GMT) List-Unsubscribe-Post: List-Unsubscribe=One-Click From: Bence Ferdinandy To: git@vger.kernel.org Cc: phillip.wood@dunelm.org.uk, =?utf-8?q?Ren=C3=A9_Scharfe?= , Johannes Schindelin , Junio C Hamano , karthik.188@gmail.com, Taylor Blau , Bence Ferdinandy Subject: [PATCH v11 8/8] fetch set_head: handle mirrored bare repositories Date: Tue, 22 Oct 2024 21:45:45 +0200 Message-id: <20241022194710.3743691-9-bence@ferdinandy.com> In-reply-to: <20241022194710.3743691-1-bence@ferdinandy.com> References: <43d44c82-b93d-4ac9-a5ac-ae5f70982cfd@ferdinandy.com> <20241022194710.3743691-1-bence@ferdinandy.com> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 Content-transfer-encoding: 8bit Reporting-Meta: AAGHA9QqAs6nny66Lrx6h0046xxLuoR2vVLgBl9cs5sCtwXDGDNe9lEtO3nRGarE jTONO6aB3lLZZxuthdXFFUcv6ZVsrs5ix59nFnWqRy460uFLfcKQGX54r4wyVXJ7 nP6pxSe5jhvYFgcViXA/4YpQLIdVu3IVqiGLNI+DkqcbVBr5hiFDP3HUDmLXf/o8 216fQOuCO1+OOZ2uqJ8XZ72EUHaM8j79AK/OyJMEgHrh8W4MDQYrx/VSpPOOTBcX dgFWzRQ6Jk0GyHvPmW5RswTLVuVRSjvCBR+ZtcAA7EW3S5waRyXUbCjQfgcd3a+o tq5we9ZfNfuaq5mQdAqtlnslmoim/AIrSW1jKwV8fW34lekM5SzULn4RFEjcdufD Ce1v4nBPiMjLXtszHiB8mfCKo6a4zp9fPM3PnCK5I9waWo9IgLLGbZd3svRgZ01d Z7irHc2mTXQx7Bln+GEBdlu68qKroLH7sU+zQRGmOTwztnGb1gxwtG0= When adding a remote to bare repository with "git remote add --mirror", running fetch will fail to update HEAD to the remote's HEAD, since it does not know how to handle bare repositories. On the other hand HEAD already has content, since "git init --bare" has already set HEAD to whatever is the default branch set for the user. Unless this - by chance - is the same as the remote's HEAD, HEAD will be pointing to a bad symref. Teach set_head to handle bare repositories, by overwriting HEAD so it mirrors the remote's HEAD. Note, that in this case overriding the local HEAD reference is necessary, since HEAD will exist before fetch can be run, but this should not be an issue, since the whole purpose of --mirror is to be an exact mirror of the remote, so following any changes to HEAD makes sense. Also note, that although "git remote set-head" also fails when trying to update the remote's locally tracked HEAD in a mirrored bare repository, the usage of the command does not make much sense after this patch: fetch will update the remote HEAD correctly, and setting it manually to something else is antithetical to the concept of mirroring. Signed-off-by: Bence Ferdinandy --- Notes: v10: - new patch - handles the issue discovered in https://lore.kernel.org/git/D4ZAELFWJMKN.S88LJ6YK31LZ@ferdinandy.com/T/ v11: no change builtin/fetch.c | 16 ++++++++++++---- t/t5505-remote.sh | 10 ++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index cadfd2407a..8af3efd6ac 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1633,14 +1633,22 @@ static int set_head(const struct ref *remote_refs) else head_name = xstrdup(heads.items[0].string); if (head_name) { - strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote); - strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name); + int is_bare = is_bare_repository(); + if (is_bare) { + strbuf_addstr(&b_head, "HEAD"); + strbuf_addf(&b_remote_head, "refs/heads/%s", head_name); + } else { + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name); + } /* make sure it's valid */ - if (!refs_ref_exists(refs, b_remote_head.buf)) + if (!is_bare && !refs_ref_exists(refs, b_remote_head.buf)) { result = 1; + } else if (refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf, - "fetch", &b_local_head, 1)) + "fetch", &b_local_head, !is_bare)) { result = 1; + } else report_set_head(remote, head_name, &b_local_head); diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 4990d00209..dfa78f3e8d 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -545,6 +545,16 @@ test_expect_success 'add --mirror && prune' ' ) ' +test_expect_success 'add --mirror setting HEAD' ' + mkdir headmirror && + ( + cd headmirror && + git init --bare -b notmain && + git remote add --mirror -f origin ../one && + test "$(git symbolic-ref HEAD)" = "refs/heads/main" + ) +' + test_expect_success 'add --mirror=fetch' ' mkdir mirror-fetch && git init -b main mirror-fetch/parent &&