From patchwork Thu Jun 29 13:23:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin X-Patchwork-Id: 13297040 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9ED45EB64DC for ; Thu, 29 Jun 2023 13:23:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231269AbjF2NXS (ORCPT ); Thu, 29 Jun 2023 09:23:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbjF2NXQ (ORCPT ); Thu, 29 Jun 2023 09:23:16 -0400 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B1B22D4A for ; Thu, 29 Jun 2023 06:23:15 -0700 (PDT) Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-3fa9850bfd9so6447795e9.0 for ; Thu, 29 Jun 2023 06:23:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688044994; x=1690636994; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=ukGnqwfJ5b0sPRfTSAYeT2O8AO2g/cJIDl1GDExy4HI=; b=AUVRIL3lKmaCJnGOBLCpWUIdRUBflLHnKL5HcZ6B2UQGj0t+m3I6qaiI6qCD2UOwAk qxUddG0oSNB257wCO9Xq+pA7MGxhh0KlD/4OWIvDZSAtTONZd4eIA+YNfltgB1oJdSaH Rk4FnVeKM8ZApK4R1DccY6dYzNj2RKB4oiho3Ln+GTRkZP4IEd15m1ea9NDjt+cCewdH i1Nob/QvWpGR5RbKlImQvvTeaqhCqo6Pge2P31xQZkj+2fa+UV8C6VgIcqkCoMq3pN+/ EFoVoDvVlNcYswsbrK1GZw7GYU1+y5jqcf7Ein9IxIFvJL11uTunGeviGln0aVlx1N59 Se5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688044994; x=1690636994; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ukGnqwfJ5b0sPRfTSAYeT2O8AO2g/cJIDl1GDExy4HI=; b=hWhCsz00S8iBqktV85WiP8aYed1O6B4QaucGdGBP0cM2AzkC0Ni/XcN29Bqxt5hFF3 LwLAKo46EQ9rzKwMuOjrHQEiIWQpcHC6lNtNT5Xa/tCZuUNyoySb4UPrxtgPZ4L1O0sf KylJ4RiVRnXHixv7WQSImIvU1Wv4qv8QUxIk6P7jSfxmlysDZfUKcgFzjfp1UFM0EX7J fFYkCVZLzBpul3Ci1+gHOhl4UZ//SzqH9Fy1fkqvGIFTpWzr0PHP/Sui9MnlYSo+GZEL J97UBYyU9IqM8wz8OhnuYkgG0GPzY30qdtE5N2MOpRKap29+GCCM+Kz/gq2Ok6+a5O+o 75Tw== X-Gm-Message-State: AC+VfDyqfHvwj1S6wTi/p40bXX7XMrI7Ds59RNHCODvwgsZBBv9sd3zS ZnAQ0bdVm62b3WMnSaGE5Pd2ScWk4+8= X-Google-Smtp-Source: ACHHUZ6hb1g6EsFt0E8r5cQ32nX0/Uo+c5niW0R0EgQ3a98IAvuP1qAZ1O3RYEjGBmtEf2A6Nj3eAA== X-Received: by 2002:a05:600c:2942:b0:3f7:5d:4a06 with SMTP id n2-20020a05600c294200b003f7005d4a06mr15929636wmd.1.1688044992966; Thu, 29 Jun 2023 06:23:12 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t15-20020a0560001a4f00b00313f676832bsm9638313wry.93.2023.06.29.06.23.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 06:23:12 -0700 (PDT) Message-Id: <7ecfae7d6f63d235e6efe85b1b1d7c8f3fc08c29.1688044991.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 29 Jun 2023 13:23:08 +0000 Subject: [PATCH 1/3] do_read_index(): always mark index as initialized unless erroring out Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes Schindelin , Johannes Schindelin Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Johannes Schindelin From: Johannes Schindelin In 913e0e99b6a (unpack_trees(): protect the handcrafted in-core index from read_cache(), 2008-08-23) a flag was introduced into the `index_state` structure to indicate whether it had been initialized (or more correctly: read and parsed). There was one code path that was not handled, though: when the index file does not yet exist (but the `must_exist` parameter is set to 0 to indicate that that's okay). In this instance, Git wants to go forward with a new, pristine Git index, almost as if the file had existed and contained no index entries or extensions. Since Git wants to handle this situation the same as if an "empty" Git index file existed, let's set the `initialized` flag also in that case. This is necessary to prepare for fixing the bug where the condition `cache_nr == 0` is incorrectly used as an indicator that the index was already read, and the condition `initialized != 0` needs to be used instead. Signed-off-by: Johannes Schindelin --- read-cache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/read-cache.c b/read-cache.c index f4c31a68c85..b10caa9831c 100644 --- a/read-cache.c +++ b/read-cache.c @@ -2285,6 +2285,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) if (fd < 0) { if (!must_exist && errno == ENOENT) { set_new_index_sparsity(istate); + istate->initialized = 1; return 0; } die_errno(_("%s: index file open failed"), path); From patchwork Thu Jun 29 13:23:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin X-Patchwork-Id: 13297041 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DAF11EB64D9 for ; Thu, 29 Jun 2023 13:23:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231422AbjF2NXU (ORCPT ); Thu, 29 Jun 2023 09:23:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230256AbjF2NXR (ORCPT ); Thu, 29 Jun 2023 09:23:17 -0400 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 170FF30C4 for ; Thu, 29 Jun 2023 06:23:16 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-3128fcd58f3so739504f8f.1 for ; Thu, 29 Jun 2023 06:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688044994; x=1690636994; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=Dqow5Rj+lUmHA0rkQnFnECqRQpI3+s3NCSqPH9Hhe/o=; b=VAQYbUVomtalVzCUbP2pJ4fJPzsV24hllDp6oRGXUxDD05EVXSattIfOH8d/JwNdkR XwAyFfOzmdN/ZMjKKtPwrconkfZuh10DwilTSr2Q9PNFZb8TV2dq5x1EU5e3YODdpViW id36aecu37AvRLYdxtK3tVMFTPvFjRqHWaqG6IjSRssmVeE+CA8iHzyfLT2CoEkg7CZR qy9KUu3mgb604y/ZpEQ+IqvSLCzPgdtjHYmCxc5eHMHGTcN9KB4kwmM1qw+MEj7Ahi+n wURRedBcQwN/idp6FoBx8uHOT3IaeifGYWFUa+lVUU1bJ3IuM4ls0gmuCDtvWnoc0QPu r4xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688044994; x=1690636994; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Dqow5Rj+lUmHA0rkQnFnECqRQpI3+s3NCSqPH9Hhe/o=; b=YDG/dOiS6oZERdAxKljTAWa8KcaSz0oMjdpSAq01IkdUi2BKGwAa/hbR7iC62Mmno1 8KXLLWqCQ/kZfEtzL8j03wwQtNlriwHSdSnXG/NFBsRTcoCGN0ajm+HtH8walrVfvE8s 5rbAFTQoeWUqMtw1lBB2LDKXySW7oCnWMlOOywH0IKB+sABrvgx9zBhGpHxuGQdKVgTA Yx3u7s47xmU2NZdJE7XqYHMIGlPy0ByJldDRvxbeVLnGbLny97aecpCoIDufaiWzxc3U k0fWCAIHbd8/C4qdifG/EhVJ+JL22GHw0vGgSkU355zFv3wqCNSgzXLjtaPRgRmMYI+l 9X7Q== X-Gm-Message-State: AC+VfDyNTt/6U3PapYyYrdBb4jG1guG67Unegsu8/+2tiY4UjwBp50E+ jQYBdd3/lZW7sTnBoAmAJugCOnpn5wg= X-Google-Smtp-Source: ACHHUZ50xambgVByZLZWRGBTggjCULIHWtQGor8GkdRvC7ANuaq0PPm+v3Ni/a/cGyooRFTCiTkBnw== X-Received: by 2002:a05:6000:85:b0:314:dc0:2fca with SMTP id m5-20020a056000008500b003140dc02fcamr3122486wrx.29.1688044994142; Thu, 29 Jun 2023 06:23:14 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c15-20020adffb4f000000b00313e4d02be8sm14950339wrs.55.2023.06.29.06.23.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 06:23:13 -0700 (PDT) Message-Id: <81118ce106222993ef17586fb0f249d8319f3b90.1688044991.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 29 Jun 2023 13:23:09 +0000 Subject: [PATCH 2/3] split-index: accept that a base index can be empty Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes Schindelin , Johannes Schindelin Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Johannes Schindelin From: Johannes Schindelin We are about to fix an ancient bug where `do_read_index()` pretended that the index was not initialized when there are no index entries. Before the `index_state` structure gained the `initialized` flag in 913e0e99b6a (unpack_trees(): protect the handcrafted in-core index from read_cache(), 2008-08-23), that was the best we could do (even if it was incorrect: it is totally possible to read a Git index file that contains no index entries). This pattern was repeated also in 998330ac2e7 (read-cache: look for shared index files next to the index, too, 2021-08-26), which we fix here by _not_ mistaking an empty base index for a missing `sharedindex.*` file. Signed-off-by: Johannes Schindelin --- read-cache.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/read-cache.c b/read-cache.c index b10caa9831c..e15a472f54f 100644 --- a/read-cache.c +++ b/read-cache.c @@ -2455,12 +2455,14 @@ int read_index_from(struct index_state *istate, const char *path, base_oid_hex = oid_to_hex(&split_index->base_oid); base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex); - trace2_region_enter_printf("index", "shared/do_read_index", - the_repository, "%s", base_path); - ret = do_read_index(split_index->base, base_path, 0); - trace2_region_leave_printf("index", "shared/do_read_index", - the_repository, "%s", base_path); - if (!ret) { + if (file_exists(base_path)) { + trace2_region_enter_printf("index", "shared/do_read_index", + the_repository, "%s", base_path); + + ret = do_read_index(split_index->base, base_path, 0); + trace2_region_leave_printf("index", "shared/do_read_index", + the_repository, "%s", base_path); + } else { char *path_copy = xstrdup(path); char *base_path2 = xstrfmt("%s/sharedindex.%s", dirname(path_copy), base_oid_hex); From patchwork Thu Jun 29 13:23:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin X-Patchwork-Id: 13297042 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1051FEB64D9 for ; Thu, 29 Jun 2023 13:23:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231839AbjF2NXW (ORCPT ); Thu, 29 Jun 2023 09:23:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231248AbjF2NXS (ORCPT ); Thu, 29 Jun 2023 09:23:18 -0400 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E23502707 for ; Thu, 29 Jun 2023 06:23:16 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-3fbc0609e13so3725895e9.3 for ; Thu, 29 Jun 2023 06:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688044995; x=1690636995; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=PkBMcYW9zMamuiGqnq/zDSAXpT7QhTVpOCEjUVh70DQ=; b=efU2xB1rm7M1HeiDn/A826CP+WkEVTSEXZRJLPP0ldVUc3XFvD1tEUZdVCg/62j3i9 fLMrRAXN9mlX5u6zA901O3Y1AyvhfTgkj5TUaJO1mry5Fl3YwoNjRM8r84MDlJ+Km544 cGx9zuN6n+5N4rClogz/dfsRe3fwVvmTX/ajK/acrx7qMvBNa7Z0RAAThIOXEJUDZzKr N/vDVCuGyQ4KFP8Ztzuevx+YU0NCWadfgoNAOQ3DoMOe+n/mSj8j6Lbdxx1Q2egnH6/W pp93DQ1j/+tWKqnlvlqIyvbMqjvTWzhqN/LgJ+zyOmddBxd3CYw3U6/1Zv9jNFRyp1W9 G8kQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688044995; x=1690636995; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PkBMcYW9zMamuiGqnq/zDSAXpT7QhTVpOCEjUVh70DQ=; b=VokAsNZJteYyA3ElgyrHyiHtjuCzn07kM122fxNohylciuTTBQ7AACM4OjIKRDWYUp Mxx0Onn+EMO8oIymAUpbCqwHb+34jakRDLBe1B0rZLBlbwLXOukMXyag4yg1PM+65Fn8 Us/TFGV+ZjMfAtJzwFMpqNM9VGifsLmUppV1oTmvihUGlR5sjhNwN5C+bnjHe74NMZIy ecLD4qOYRMx93KJh8xXO5ALoIqz7y6QFbRNhC3TvOKLRD9dGKHppLdyfmViTTllNvheM h7ExA+qwyvPhfcuj7f78ietpkqzi7ph7AUysx6/Ui31CgJUry1YDBij+kjIwuVfbEbL6 oWBQ== X-Gm-Message-State: AC+VfDx2acc0usPgWjYSZlZtW6vQ7eNJ2Fp9t/k9DttwdDSqMMyFbFFm 9xYeRva+iCsKEtHoHe7iq0ScCjnTB/o= X-Google-Smtp-Source: ACHHUZ7ArvpFXaiDei7CjkkG/6mSd6p3eTmecljlAAMZjf+Dwd0TyRmFi0s66P6VA896WQgwldKoFw== X-Received: by 2002:a1c:4b10:0:b0:3fb:7724:254b with SMTP id y16-20020a1c4b10000000b003fb7724254bmr7189924wma.9.1688044995034; Thu, 29 Jun 2023 06:23:15 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g11-20020a7bc4cb000000b003fbab76165asm5779643wmk.48.2023.06.29.06.23.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 06:23:14 -0700 (PDT) Message-Id: <08c50b64e2a93300eed196505936e58ce8bb639b.1688044991.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 29 Jun 2023 13:23:10 +0000 Subject: [PATCH 3/3] commit -a -m: allow the top-level tree to become empty again Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Johannes Schindelin , Johannes Schindelin Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Johannes Schindelin From: Johannes Schindelin In 03267e8656c (commit: discard partial cache before (re-)reading it, 2022-11-08), a memory leak was plugged by discarding any partial index before re-reading it. The problem with this memory leak fix is that it was based on an incomplete understanding of the logic introduced in 7168624c353 (Do not generate full commit log message if it is not going to be used, 2007-11-28). That logic was introduced to add a shortcut when committing without editing the commit message interactively. A part of that logic was to ensure that the index was read into memory: if (!active_nr && read_cache() < 0) die(...) Translation to English: If the index has not yet been read, read it, and if that fails, error out. That logic was incorrect, though: It used `!active_nr` as an indicator that the index was not yet read. Usually this is not a problem because in the vast majority of instances, the index contains at least one entry. And it was natural to do it this way because at the time that condition was introduced, the `index_state` structure had no explicit flag to indicate that it was initialized: This flag was only introduced in 913e0e99b6a (unpack_trees(): protect the handcrafted in-core index from read_cache(), 2008-08-23), but that commit did not adjust the code path where no index file was found and a new, pristine index was initialized. Now, when the index does not contain any entry (which is quite common in Git's test suite because it starts quite a many repositories from scratch), subsequent calls to `do_read_index()` will mistake the index not to be initialized, and read it again unnecessarily. This is a problem because after initializing the empty index e.g. the `cache_tree` in that index could have been initialized before a subsequent call to `do_read_index()` wants to ensure an initialized index. And if that subsequent call mistakes the index not to have been initialized, it would lead to leaked memory. The correct fix for that memory leak is to adjust the condition so that it does not mistake `active_nr == 0` to mean that the index has not yet been read. Using the `initialized` flag instead, we avoid that mistake, and as a bonus we can fix a bug at the same time that was introduced by the memory leak fix: When deleting all tracked files and then asking `git commit -a -m ...` to commit the result, Git would internally update the index, then discard and re-read the index undoing the update, and fail to commit anything. This fixes https://github.com/git-for-windows/git/issues/4462 Signed-off-by: Johannes Schindelin --- builtin/commit.c | 7 ++----- t/t2200-add-update.sh | 11 +++++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/builtin/commit.c b/builtin/commit.c index 65a5c0e29d5..4cf2baaf943 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -998,11 +998,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, struct object_id oid; const char *parent = "HEAD"; - if (!the_index.cache_nr) { - discard_index(&the_index); - if (repo_read_index(the_repository) < 0) - die(_("Cannot read index")); - } + if (!the_index.initialized && repo_read_index(the_repository) < 0) + die(_("Cannot read index")); if (amend) parent = "HEAD^1"; diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index be394f1131a..c01492f33f8 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -197,4 +197,15 @@ test_expect_success '"add -u non-existent" should fail' ' ! grep "non-existent" actual ' +test_expect_success '"commit -a" implies "add -u" if index becomes empty' ' + git rm -rf \* && + git commit -m clean-slate && + test_commit file1 && + rm file1.t && + test_tick && + git commit -a -m remove && + git ls-tree HEAD: >out && + test_must_be_empty out +' + test_done