From patchwork Mon Sep 27 16:33:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520303 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40A6DC433EF for ; Mon, 27 Sep 2021 16:34:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 297E3610E8 for ; Mon, 27 Sep 2021 16:34:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235540AbhI0Qfr (ORCPT ); Mon, 27 Sep 2021 12:35:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58708 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235497AbhI0Qfc (ORCPT ); Mon, 27 Sep 2021 12:35:32 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A870C061714 for ; Mon, 27 Sep 2021 09:33:51 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id r23so27666814wra.6 for ; Mon, 27 Sep 2021 09:33:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=2ME/dZ4fzArIJqmFKq/Lz334GlShsg34B/tWiC3aR9w=; b=fvXENtXaRSB0nbwwrKZPZyviConFeRfaidyrkOsYUVZOk2SlswUgZZQ3uiTQHHzAGb s7u3+o//pEXWH9yVtjAHRH+sbEsu8o3coj7YQkCGnpQ0lwl9K74eu1f8/HJiDNuMcVfB CdWtTWiWIJ3wcgEmqjdLRhqrX6nrBRemTxmojoKf7aXs7DkmrJx/Hn80dFSbHJDHd1bI EcK1Cwwtr+bwTuWLlZ02fxh6/Hypd+ux6uMZEMtcFnZyXT1+hzUBDqTp21XCOsooZV+t 76q+g++4SKOAzjg37qkRf3cGkl8JdTgu21Rp719UXtDPw6uSG04rSDpobP2fSaI1s0Lm CUug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=2ME/dZ4fzArIJqmFKq/Lz334GlShsg34B/tWiC3aR9w=; b=FarJn3z74fHuIhbl9tfJ+VQkhLCivfys3Lpv6SELXrMfBZznjzaM+X8iAVN/3kcxRr 3jSnJziydavFJFSPw9iTrNZe9kVIfMB+9HYZxJbOHiR/tCMOhpne28B0VEiE0Xi9qmsp mDYejvT/TpJ2AzkqofTnONKXbSwe5Hlqx8ZwOwuni6O3X5gnm6NHu0P4sYl6zONJLons GuhPUz5dEwPapnliF2/S6dEAbZiPZ95K+9qyZgOMue5CeJdNnMYf2PhvRkShLW6Zv6mN Q6cyd9jNxUm4HAmDlGp6YW8b2v8oCPucU3OcQhYlTPotpsWxko6gv6TeWr1xTEVXAZqV WNsQ== X-Gm-Message-State: AOAM530LOdatcbaSfZ0QrZz0qTWW1XGngN9Ea9cSy9uUeZ166aoAfTfK FIcp2aT+XSLfjZlyHR0S5RjP+5raXDE= X-Google-Smtp-Source: ABdhPJze+isU98dey4uj0YTQH5jxwd/TanpBKB19zhaAQN/a/IolEdraoJRwnVPvknD3RUvi8tIqxw== X-Received: by 2002:a05:6000:1809:: with SMTP id m9mr952720wrh.396.1632760430218; Mon, 27 Sep 2021 09:33:50 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id z5sm4066wmp.26.2021.09.27.09.33.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:49 -0700 (PDT) Message-Id: <66270ffc74ecf4f2ce0ebc7379be84d5470c82ef.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:38 +0000 Subject: [PATCH v3 01/11] t2500: add various tests for nuking untracked files Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Noting that unpack_trees treats reset=1 & update=1 as license to nuke untracked files, I looked for code paths that use this combination and tried to generate testcases which demonstrated unintentional loss of untracked files and directories. I found several. I also include testcases for `git reset --{hard,merge,keep}`. A hard reset is perhaps the most direct test of unpack_tree's reset=1 behavior, but we cannot make `git reset --hard` preserve untracked files without some migration work. Also, the two commands `checkout --force` (because of the --force) and `read-tree --reset` (because it's plumbing and we need to keep it backward compatible) were left out as we expect those to continue removing untracked files and directories. Signed-off-by: Elijah Newren --- t/t2500-untracked-overwriting.sh | 244 +++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 t/t2500-untracked-overwriting.sh diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh new file mode 100755 index 00000000000..2412d121ea8 --- /dev/null +++ b/t/t2500-untracked-overwriting.sh @@ -0,0 +1,244 @@ +#!/bin/sh + +test_description='Test handling of overwriting untracked files' + +. ./test-lib.sh + +test_setup_reset () { + git init reset_$1 && + ( + cd reset_$1 && + test_commit init && + + git branch stable && + git branch work && + + git checkout work && + test_commit foo && + + git checkout stable + ) +} + +test_expect_success 'reset --hard will nuke untracked files/dirs' ' + test_setup_reset hard && + ( + cd reset_hard && + git ls-tree -r stable && + git log --all --name-status --oneline && + git ls-tree -r work && + + mkdir foo.t && + echo precious >foo.t/file && + echo foo >expect && + + git reset --hard work && + + # check that untracked directory foo.t/ was nuked + test_path_is_file foo.t && + test_cmp expect foo.t + ) +' + +test_expect_success 'reset --merge will preserve untracked files/dirs' ' + test_setup_reset merge && + ( + cd reset_merge && + + mkdir foo.t && + echo precious >foo.t/file && + cp foo.t/file expect && + + test_must_fail git reset --merge work 2>error && + test_cmp expect foo.t/file && + grep "Updating .foo.t. would lose untracked files" error + ) +' + +test_expect_success 'reset --keep will preserve untracked files/dirs' ' + test_setup_reset keep && + ( + cd reset_keep && + + mkdir foo.t && + echo precious >foo.t/file && + cp foo.t/file expect && + + test_must_fail git reset --merge work 2>error && + test_cmp expect foo.t/file && + grep "Updating.*foo.t.*would lose untracked files" error + ) +' + +test_setup_checkout_m () { + git init checkout && + ( + cd checkout && + test_commit init && + + test_write_lines file has some >filler && + git add filler && + git commit -m filler && + + git branch stable && + + git switch -c work && + echo stuff >notes.txt && + test_write_lines file has some words >filler && + git add notes.txt filler && + git commit -m filler && + + git checkout stable + ) +} + +test_expect_failure 'checkout -m does not nuke untracked file' ' + test_setup_checkout_m && + ( + cd checkout && + + # Tweak filler + test_write_lines this file has some >filler && + # Make an untracked file, save its contents in "expect" + echo precious >notes.txt && + cp notes.txt expect && + + test_must_fail git checkout -m work && + test_cmp expect notes.txt + ) +' + +test_setup_sequencing () { + git init sequencing_$1 && + ( + cd sequencing_$1 && + test_commit init && + + test_write_lines this file has some words >filler && + git add filler && + git commit -m filler && + + mkdir -p foo/bar && + test_commit foo/bar/baz && + + git branch simple && + git branch fooey && + + git checkout fooey && + git rm foo/bar/baz.t && + echo stuff >>filler && + git add -u && + git commit -m "changes" && + + git checkout simple && + echo items >>filler && + echo newstuff >>newfile && + git add filler newfile && + git commit -m another + ) +} + +test_expect_failure 'git rebase --abort and untracked files' ' + test_setup_sequencing rebase_abort_and_untracked && + ( + cd sequencing_rebase_abort_and_untracked && + git checkout fooey && + test_must_fail git rebase simple && + + cat init.t && + git rm init.t && + echo precious >init.t && + cp init.t expect && + git status --porcelain && + test_must_fail git rebase --abort && + test_cmp expect init.t + ) +' + +test_expect_failure 'git rebase fast forwarding and untracked files' ' + test_setup_sequencing rebase_fast_forward_and_untracked && + ( + cd sequencing_rebase_fast_forward_and_untracked && + git checkout init && + echo precious >filler && + cp filler expect && + test_must_fail git rebase init simple && + test_cmp expect filler + ) +' + +test_expect_failure 'git rebase --autostash and untracked files' ' + test_setup_sequencing rebase_autostash_and_untracked && + ( + cd sequencing_rebase_autostash_and_untracked && + git checkout simple && + git rm filler && + mkdir filler && + echo precious >filler/file && + cp filler/file expect && + git rebase --autostash init && + test_path_is_file filler/file + ) +' + +test_expect_failure 'git stash and untracked files' ' + test_setup_sequencing stash_and_untracked_files && + ( + cd sequencing_stash_and_untracked_files && + git checkout simple && + git rm filler && + mkdir filler && + echo precious >filler/file && + cp filler/file expect && + git status --porcelain && + git stash push && + git status --porcelain && + test_path_is_file filler/file + ) +' + +test_expect_failure 'git am --abort and untracked dir vs. unmerged file' ' + test_setup_sequencing am_abort_and_untracked && + ( + cd sequencing_am_abort_and_untracked && + git format-patch -1 --stdout fooey >changes.mbox && + test_must_fail git am --3way changes.mbox && + + # Delete the conflicted file; we will stage and commit it later + rm filler && + + # Put an unrelated untracked directory there + mkdir filler && + echo foo >filler/file1 && + echo bar >filler/file2 && + + test_must_fail git am --abort 2>errors && + test_path_is_dir filler && + grep "Updating .filler. would lose untracked files in it" errors + ) +' + +test_expect_failure 'git am --skip and untracked dir vs deleted file' ' + test_setup_sequencing am_skip_and_untracked && + ( + cd sequencing_am_skip_and_untracked && + git checkout fooey && + git format-patch -1 --stdout simple >changes.mbox && + test_must_fail git am --3way changes.mbox && + + # Delete newfile + rm newfile && + + # Put an unrelated untracked directory there + mkdir newfile && + echo foo >newfile/file1 && + echo bar >newfile/file2 && + + # Change our mind about resolutions, just skip this patch + test_must_fail git am --skip 2>errors && + test_path_is_dir newfile && + grep "Updating .newfile. would lose untracked files in it" errors + ) +' + +test_done From patchwork Mon Sep 27 16:33:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520299 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCD95C433EF for ; Mon, 27 Sep 2021 16:34:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A1B5660EFD for ; Mon, 27 Sep 2021 16:34:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235534AbhI0Qfn (ORCPT ); Mon, 27 Sep 2021 12:35:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235498AbhI0Qfc (ORCPT ); Mon, 27 Sep 2021 12:35:32 -0400 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A505C061740 for ; Mon, 27 Sep 2021 09:33:52 -0700 (PDT) Received: by mail-wm1-x335.google.com with SMTP id a131so1027432wmd.1 for ; Mon, 27 Sep 2021 09:33:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=fdxSgXAkjKOC6rvLjgYPcBbfMtTZ4/NxPILc4lAO8W8=; b=PpkmOA/EuJHaIh49PBItTNN2G2izMj+3NjgLeiKBh1j1lRotaS+Bok08J5kKW54gfX 9pgjQ7X35/Lu7gFP2Yd5kZXRk2B9EYzcGsuKsYWZLnAKw8rbsQSpokZyMdk7kFPqPJzL CCDFmzTFC7ja+eOfBf7OUjfI9S3n02pnMyBN/AS1DXN9T3kihk1UZ9AJ/chsoAK68RYm lgyvO4LdXbNFpaINt7WvJtkLWtQHvBpTdB6rL8DJ8wcPY5WBgzNRjuoFe8G4JinE0lqv Ff2k42CpB3Lz+5MfBCsEBv6Op5JpeRWRTk75pjjVUwMnmS/gzQEzMo5MNjJGShA5j/5/ +SyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=fdxSgXAkjKOC6rvLjgYPcBbfMtTZ4/NxPILc4lAO8W8=; b=bUXWAERb+rFDa+/MUIHpF+sa9N57Nfj3T2EPpmvsefNz0Y1sDSwaAF6t7zbr0H+QRp nSuf11G6BvdmI1TwBGCfjZE638ziAfAjq/k1pBv5f1cLw/D15a+AUXM4/7pi2WszbBwJ 1RG/1brGghXB826SUoUKFloCd7ZIWnGl7LbZo8NbJtbn4MlBWxEbQHqfXzakjy6PIJvy eBeZa/nQXw56oy0VPoYl8ggoJAbY2MHcR18szl0FJwCE8M3KH+C20/0iAwqFP4W0mo6B 3c3PZQS7lv9smegbfymxbVR5tS6VopQE4bxIgcP4wKg8nxtJ1V7GtR6Yo0Ci5SNE7aWX UaMQ== X-Gm-Message-State: AOAM530CccaeApkXo6+rN1X3R82BLtL1Tokees0S1TGjOs6tEY3SzGGT /z9yE2RItpscI+wwOvL84T5OA8bR5Tg= X-Google-Smtp-Source: ABdhPJzsU8/MosRXOmhYq+3efc1U8SGHXFQuzyv5RLHyMFujkGFvg6hbw6G9uySyWEFcE/KX2lBaxg== X-Received: by 2002:a1c:149:: with SMTP id 70mr16392364wmb.187.1632760430731; Mon, 27 Sep 2021 09:33:50 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id z12sm3554674wrv.31.2021.09.27.09.33.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:50 -0700 (PDT) Message-Id: <0c74285b25311c83bb158cf89a551160a0f3a5d3.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:39 +0000 Subject: [PATCH v3 02/11] checkout, read-tree: fix leak of unpack_trees_options.dir Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Signed-off-by: Elijah Newren --- builtin/checkout.c | 4 ++++ builtin/read-tree.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/builtin/checkout.c b/builtin/checkout.c index 8c69dcdf72a..5335435d616 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -760,6 +760,10 @@ static int merge_working_tree(const struct checkout_opts *opts, init_tree_desc(&trees[1], tree->buffer, tree->size); ret = unpack_trees(2, trees, &topts); + if (topts.dir) { + dir_clear(topts.dir); + FREE_AND_NULL(topts.dir); + } clear_unpack_trees_porcelain(&topts); if (ret == -1) { /* diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 485e7b04794..96102c222bf 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -250,6 +250,11 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if (unpack_trees(nr_trees, t, &opts)) return 128; + if (opts.dir) { + dir_clear(opts.dir); + FREE_AND_NULL(opts.dir); + } + if (opts.debug_unpack || opts.dry_run) return 0; /* do not write the index out */ From patchwork Mon Sep 27 16:33:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520301 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 118C6C433FE for ; Mon, 27 Sep 2021 16:34:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F134060EE2 for ; Mon, 27 Sep 2021 16:34:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235501AbhI0Qfp (ORCPT ); Mon, 27 Sep 2021 12:35:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235500AbhI0Qfc (ORCPT ); Mon, 27 Sep 2021 12:35:32 -0400 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98A49C061765 for ; Mon, 27 Sep 2021 09:33:52 -0700 (PDT) Received: by mail-wm1-x336.google.com with SMTP id r83-20020a1c4456000000b0030cfc00ca5fso1121092wma.2 for ; Mon, 27 Sep 2021 09:33:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=aviX4T1h7rX20CLNtcvp9q28vNsQYDozXgXCTyqxX5c=; b=J0LZ0/rtxzSe1Z06JGAVr3h/8uV8vvK7gqPm335Uul4xWm+d0Q8NJ1VUzeGUIbmO6O qJiyTpq9EDYWAjKSya6pwnyG6ZAfLobBixqCkhJWTJumN1dm6n8mqIEN5Oxjq/5ks+sv mgo/fmwFnk1qk3gVvr0e3MykXvfIItGFIDjUwHXkzOKVtLlVep6KmV014+DR/ik0JkE3 KFlUqI6sK8ISAnhhQQ6BFRBrUjI5OIaRpC0c4DeGC5BRcRUwLPiiuxmUpXxuYtwoyBCz zoU14yF3s42FU98I5opxUCMWSgzom7PewrtQpe6XRDUgvUJut8qxUi8yxrl22MCIzWLA aA2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=aviX4T1h7rX20CLNtcvp9q28vNsQYDozXgXCTyqxX5c=; b=hegDdqSY4/7r0/T7u7m62vQOW75tSGhd2ndaPd3LNFbasx+stFP6fAlit0Os/oBtks 2D+QGPwWbYpYrY5J1AiqSWV/g7GJccvrcPWZj7Q1C4L/dBaSSOdpQJ5DxxAENZQ3yu1y ClFjySFggdj+pOJhQU590kCkU6F4/uTarLdYyPtgZ4fB2xIC5ZR738UszighvpHenXmY emka5j9ygPZjvmg7nsO29vwP5u0dIx9ADXQOBueEyY/QxXvumLI4ttFF/m/izu8+Q/au Sg7ezcedPYq3LkAhhhZ2YuD+sOf4/JQRcrKbzxAgMY+JUcU4Av3AsgrVq2tAEwR8ALPy /jyg== X-Gm-Message-State: AOAM530s93pxPKgTpfZDXxNURYniEd++QGfIn3i5cTNj/Dc8zG/fZWtf rYNCWUcLOhWZCPlBT1gSisGz4TBfvW8= X-Google-Smtp-Source: ABdhPJzYq3NKU62VgynmL6D71kJgNMqapK8lLbsPzzip7dJqVhBR5TXfDbGnBL8sYuCu+GTNUuJMyw== X-Received: by 2002:a05:600c:3b87:: with SMTP id n7mr842179wms.93.1632760431223; Mon, 27 Sep 2021 09:33:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o17sm13860780wrs.25.2021.09.27.09.33.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:50 -0700 (PDT) Message-Id: <2501a0c552ad5147f61a96b9ebe45c5199e1dbfd.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:40 +0000 Subject: [PATCH v3 03/11] read-tree, merge-recursive: overwrite ignored files by default Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This fixes a long-standing patchwork of ignored files handling in read-tree and merge-recursive, called out and suggested by Junio long ago. Quoting from commit dcf0c16ef1 ("core.excludesfile clean-up" 2007-11-16): git-read-tree takes --exclude-per-directory=, not because the flexibility was needed. Again, this was because the option predates the standardization of the ignore files. ... On the other hand, I think it makes perfect sense to fix git-read-tree, git-merge-recursive and git-clean to follow the same rule as other commands. I do not think of a valid use case to give an exclude-per-directory that is nonstandard to read-tree command, outside a "negative" test in the t1004 test script. This patch is the first step to untangle this mess. The next step would be to teach read-tree, merge-recursive and clean (in C) to use setup_standard_excludes(). History shows each of these were partially or fully fixed: * clean was taught the new trick in 1617adc7a0 ("Teach git clean to use setup_standard_excludes()", 2007-11-14). * read-tree was primarily used by checkout & merge scripts. checkout and merge later became builtins and were both fixed to use the new setup_standard_excludes() handling in fc001b526c ("checkout,merge: loosen overwriting untracked file check based on info/exclude", 2011-11-27). So the primary users were fixed, though read-tree itself was not. * merge-recursive has now been replaced as the default merge backend by merge-ort. merge-ort fixed this by using setup_standard_excludes() starting early in its implementation; see commit 6681ce5cf6 ("merge-ort: add implementation of checkout()", 2020-12-13), largely due to its design depending on checkout() and thus being influenced by the checkout code. However, merge-recursive itself was not fixed here, in part because its design meant it had difficulty differentiating between untracked files, ignored files, leftover tracked files that haven't been removed yet due to order of processing files, and files written by itself due to collisions). Make the conversion more complete by now handling read-tree and handling at least the unpack_trees() portion of merge-recursive. While merge-recursive is on its way out, fixing the unpack_trees() portion is easy and facilitates some of the later changes in this series. Note that fixing read-tree makes the --exclude-per-directory option to read-tree useless, so we remove it from the documentation (though we continue to accept it if passed). The read-tree changes happen to fix a bug in t1013. Signed-off-by: Elijah Newren --- Documentation/git-read-tree.txt | 18 +----------------- builtin/read-tree.c | 25 ++++++++++--------------- merge-recursive.c | 11 ++++++++++- t/t1013-read-tree-submodule.sh | 1 - 4 files changed, 21 insertions(+), 34 deletions(-) diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 5fa8bab64c2..0222a27c5af 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -10,8 +10,7 @@ SYNOPSIS -------- [verse] 'git read-tree' [[-m [--trivial] [--aggressive] | --reset | --prefix=] - [-u [--exclude-per-directory=] | -i]] - [--index-output=] [--no-sparse-checkout] + [-u | -i]] [--index-output=] [--no-sparse-checkout] (--empty | [ []]) @@ -88,21 +87,6 @@ OPTIONS The command will refuse to overwrite entries that already existed in the original index file. ---exclude-per-directory=:: - When running the command with `-u` and `-m` options, the - merge result may need to overwrite paths that are not - tracked in the current branch. The command usually - refuses to proceed with the merge to avoid losing such a - path. However this safety valve sometimes gets in the - way. For example, it often happens that the other - branch added a file that used to be a generated file in - your branch, and the safety valve triggers when you try - to switch to that branch after you ran `make` but before - running `make clean` to remove the generated file. This - option tells the command to read per-directory exclude - file (usually '.gitignore') and allows such an untracked - but explicitly ignored file to be overwritten. - --index-output=:: Instead of writing the results out to `$GIT_INDEX_FILE`, write the resulting index in the named file. While the diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 96102c222bf..73cb957a69b 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -38,7 +38,7 @@ static int list_tree(struct object_id *oid) } static const char * const read_tree_usage[] = { - N_("git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=) [-u [--exclude-per-directory=] | -i]] [--no-sparse-checkout] [--index-output=] (--empty | [ []])"), + N_("git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=) [-u | -i]] [--no-sparse-checkout] [--index-output=] (--empty | [ []])"), NULL }; @@ -53,24 +53,16 @@ static int index_output_cb(const struct option *opt, const char *arg, static int exclude_per_directory_cb(const struct option *opt, const char *arg, int unset) { - struct dir_struct *dir; struct unpack_trees_options *opts; BUG_ON_OPT_NEG(unset); opts = (struct unpack_trees_options *)opt->value; - if (opts->dir) - die("more than one --exclude-per-directory given."); - - dir = xcalloc(1, sizeof(*opts->dir)); - dir->flags |= DIR_SHOW_IGNORED; - dir->exclude_per_dir = arg; - opts->dir = dir; - /* We do not need to nor want to do read-directory - * here; we are merely interested in reusing the - * per directory ignore stack mechanism. - */ + if (!opts->update) + die("--exclude-per-directory is meaningless unless -u"); + if (strcmp(arg, ".gitignore")) + die("--exclude-per-directory argument must be .gitignore"); return 0; } @@ -209,8 +201,11 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if ((opts.update || opts.index_only) && !opts.merge) die("%s is meaningless without -m, --reset, or --prefix", opts.update ? "-u" : "-i"); - if ((opts.dir && !opts.update)) - die("--exclude-per-directory is meaningless unless -u"); + if (opts.update && !opts.reset) { + CALLOC_ARRAY(opts.dir, 1); + opts.dir->flags |= DIR_SHOW_IGNORED; + setup_standard_excludes(opts.dir); + } if (opts.merge && !opts.index_only) setup_work_tree(); diff --git a/merge-recursive.c b/merge-recursive.c index e594d4c3fa1..233d9f686ad 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -408,8 +408,13 @@ static int unpack_trees_start(struct merge_options *opt, memset(&opt->priv->unpack_opts, 0, sizeof(opt->priv->unpack_opts)); if (opt->priv->call_depth) opt->priv->unpack_opts.index_only = 1; - else + else { opt->priv->unpack_opts.update = 1; + /* FIXME: should only do this if !overwrite_ignore */ + CALLOC_ARRAY(opt->priv->unpack_opts.dir, 1); + opt->priv->unpack_opts.dir->flags |= DIR_SHOW_IGNORED; + setup_standard_excludes(opt->priv->unpack_opts.dir); + } opt->priv->unpack_opts.merge = 1; opt->priv->unpack_opts.head_idx = 2; opt->priv->unpack_opts.fn = threeway_merge; @@ -423,6 +428,10 @@ static int unpack_trees_start(struct merge_options *opt, init_tree_desc_from_tree(t+2, merge); rc = unpack_trees(3, t, &opt->priv->unpack_opts); + if (opt->priv->unpack_opts.dir) { + dir_clear(opt->priv->unpack_opts.dir); + FREE_AND_NULL(opt->priv->unpack_opts.dir); + } cache_tree_free(&opt->repo->index->cache_tree); /* diff --git a/t/t1013-read-tree-submodule.sh b/t/t1013-read-tree-submodule.sh index b6df7444c05..bfc90d4cf27 100755 --- a/t/t1013-read-tree-submodule.sh +++ b/t/t1013-read-tree-submodule.sh @@ -6,7 +6,6 @@ test_description='read-tree can handle submodules' . "$TEST_DIRECTORY"/lib-submodule-update.sh KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1 -KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1 test_submodule_switch_recursing_with_args "read-tree -u -m" From patchwork Mon Sep 27 16:33:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520309 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 862E1C433F5 for ; Mon, 27 Sep 2021 16:34:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6EE856103B for ; Mon, 27 Sep 2021 16:34:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235559AbhI0Qfx (ORCPT ); Mon, 27 Sep 2021 12:35:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58720 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235505AbhI0Qfc (ORCPT ); Mon, 27 Sep 2021 12:35:32 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CADEC061769 for ; Mon, 27 Sep 2021 09:33:53 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id g16so53029284wrb.3 for ; Mon, 27 Sep 2021 09:33:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=yIedRzplGiQDHiWuPxxWeYHFV27L00E6qb7aSf5eEeU=; b=cWFPhBldtdrsqiKBjMWkS2g+9z6jdGjKtabVI6bxjJ7+l0ow2gY04wFogLRxzPizlo uqfaTYMTi1LH21OPzW2hHNDmK15hccHaG/D3fhmm1giEx8oA4K7zQREmfSl85SG6pl5w QEpjE0KCkSPO0hjbJyPr5mM6EbceTYCa5nvVdrNd/p1Q6ziDVJTdlUvpqcVxmHUi3P2K g+Y1s5+10MJZMzhmaliF1z8oD6NQBKQY6n/Zg9pzG1GlRU6Dzbg+9G7OBeq6y1fdP1/U ojy0wzB7lobYt2AugKgfYNGZ5DarLFWzFSAkyaMsV/S+BEwN1jJFEpQOk5FvjBJcDxgV OkCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=yIedRzplGiQDHiWuPxxWeYHFV27L00E6qb7aSf5eEeU=; b=etlmc/JpfqUjYozAHQdKwY4gfAynVq74fOYDFbqNrRULuNIwL4oTjiYY2FqFRYRX9H KKJUx6qLOHzWj3JtBbWK9QMsjS4NbbS7TazvPvrxUOjf+IwWnSj3q5pQiVwgo7zsOZfg BOpnkzS00SsIMEy966wtDMuZd6HTQZy8KcZ8IU3p33xAD4IniD+6Cm7xR1weIRQbatpX KKx1NKI3gcQFHXdZsudxgEdRsg4eIEgJfpx1zWZl8UUXgHaXAnb0CwAYOq47frRkF5Ow 8+NUHgHXHXb3Vkh6F6CTb8nUGzz62Z6T50QjFz+HaXBhFQSR1966w6ng3zM/h0FB0SlA WkMw== X-Gm-Message-State: AOAM533og4DsIKqrCCvm/DaHg/JuHSulgMvAIRgsMfnl/PuZYSXjPslF R13VvYvNldOsn2ccfxIzh3OOaE8NQ4Y= X-Google-Smtp-Source: ABdhPJwqevtRNkblQDyYKpT0iqP8PxamWrOHNMEZnxrXuOeZTtF776tEsZNhDdVwdkqnnMk+yhv6oQ== X-Received: by 2002:adf:d1eb:: with SMTP id g11mr964892wrd.194.1632760431791; Mon, 27 Sep 2021 09:33:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id y18sm16675089wrq.6.2021.09.27.09.33.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:51 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:41 +0000 Subject: [PATCH v3 04/11] unpack-trees: introduce preserve_ignored to unpack_trees_options Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Currently, every caller of unpack_trees() that wants to ensure ignored files are overwritten by default needs to: * allocate unpack_trees_options.dir * flip the DIR_SHOW_IGNORED flag in unpack_trees_options.dir->flags * call setup_standard_excludes AND then after the call to unpack_trees() needs to * call dir_clear() * deallocate unpack_trees_options.dir That's a fair amount of boilerplate, and every caller uses identical code. Make this easier by instead introducing a new boolean value where the default value (0) does what we want so that new callers of unpack_trees() automatically get the appropriate behavior. And move all the handling of unpack_trees_options.dir into unpack_trees() itself. While preserve_ignored = 0 is the behavior we feel is the appropriate default, we defer fixing commands to use the appropriate default until a later commit. So, this commit introduces several locations where we manually set preserve_ignored=1. This makes it clear where code paths were previously preserving ignored files when they should not have been; a future commit will flip these to instead use a value of 0 to get the behavior we want. Signed-off-by: Elijah Newren --- builtin/am.c | 3 +++ builtin/checkout.c | 11 ++--------- builtin/clone.c | 2 ++ builtin/merge.c | 2 ++ builtin/read-tree.c | 13 +++---------- builtin/reset.c | 2 ++ builtin/stash.c | 3 +++ merge-ort.c | 8 +------- merge-recursive.c | 8 +------- merge.c | 8 +------- reset.c | 2 ++ sequencer.c | 2 ++ unpack-trees.c | 10 ++++++++++ unpack-trees.h | 1 + 14 files changed, 35 insertions(+), 40 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index e4a0ff9cd7c..1ee70692bc3 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1918,6 +1918,9 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset) opts.update = 1; opts.merge = 1; opts.reset = reset; + if (!reset) + /* FIXME: Default should be to remove ignored files */ + opts.preserve_ignored = 1; opts.fn = twoway_merge; init_tree_desc(&t[0], head->buffer, head->size); init_tree_desc(&t[1], remote->buffer, remote->size); diff --git a/builtin/checkout.c b/builtin/checkout.c index 5335435d616..5e7957dd068 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -648,6 +648,7 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o, opts.skip_unmerged = !worktree; opts.reset = 1; opts.merge = 1; + opts.preserve_ignored = 0; opts.fn = oneway_merge; opts.verbose_update = o->show_progress; opts.src_index = &the_index; @@ -746,11 +747,7 @@ static int merge_working_tree(const struct checkout_opts *opts, new_branch_info->commit ? &new_branch_info->commit->object.oid : &new_branch_info->oid, NULL); - if (opts->overwrite_ignore) { - topts.dir = xcalloc(1, sizeof(*topts.dir)); - topts.dir->flags |= DIR_SHOW_IGNORED; - setup_standard_excludes(topts.dir); - } + topts.preserve_ignored = !opts->overwrite_ignore; tree = parse_tree_indirect(old_branch_info->commit ? &old_branch_info->commit->object.oid : the_hash_algo->empty_tree); @@ -760,10 +757,6 @@ static int merge_working_tree(const struct checkout_opts *opts, init_tree_desc(&trees[1], tree->buffer, tree->size); ret = unpack_trees(2, trees, &topts); - if (topts.dir) { - dir_clear(topts.dir); - FREE_AND_NULL(topts.dir); - } clear_unpack_trees_porcelain(&topts); if (ret == -1) { /* diff --git a/builtin/clone.c b/builtin/clone.c index ff1d3d447a3..be1c3840d62 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -687,6 +687,8 @@ static int checkout(int submodule_progress) opts.update = 1; opts.merge = 1; opts.clone = 1; + /* FIXME: Default should be to remove ignored files */ + opts.preserve_ignored = 1; opts.fn = oneway_merge; opts.verbose_update = (option_verbosity >= 0); opts.src_index = &the_index; diff --git a/builtin/merge.c b/builtin/merge.c index 3fbdacc7db4..1e5fff095fc 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -680,6 +680,8 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, opts.verbose_update = 1; opts.trivial_merges_only = 1; opts.merge = 1; + /* FIXME: Default should be to remove ignored files */ + opts.preserve_ignored = 1; trees[nr_trees] = parse_tree_indirect(common); if (!trees[nr_trees++]) return -1; diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 73cb957a69b..443d206eca6 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -201,11 +201,9 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if ((opts.update || opts.index_only) && !opts.merge) die("%s is meaningless without -m, --reset, or --prefix", opts.update ? "-u" : "-i"); - if (opts.update && !opts.reset) { - CALLOC_ARRAY(opts.dir, 1); - opts.dir->flags |= DIR_SHOW_IGNORED; - setup_standard_excludes(opts.dir); - } + if (opts.update && !opts.reset) + opts.preserve_ignored = 0; + /* otherwise, opts.preserve_ignored is irrelevant */ if (opts.merge && !opts.index_only) setup_work_tree(); @@ -245,11 +243,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if (unpack_trees(nr_trees, t, &opts)) return 128; - if (opts.dir) { - dir_clear(opts.dir); - FREE_AND_NULL(opts.dir); - } - if (opts.debug_unpack || opts.dry_run) return 0; /* do not write the index out */ diff --git a/builtin/reset.c b/builtin/reset.c index 51c9e2f43ff..7f38656f018 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -67,6 +67,8 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t case KEEP: case MERGE: opts.update = 1; + /* FIXME: Default should be to remove ignored files */ + opts.preserve_ignored = 1; break; case HARD: opts.update = 1; diff --git a/builtin/stash.c b/builtin/stash.c index 8f42360ca91..88287b890d5 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -258,6 +258,9 @@ static int reset_tree(struct object_id *i_tree, int update, int reset) opts.merge = 1; opts.reset = reset; opts.update = update; + if (update && !reset) + /* FIXME: Default should be to remove ignored files */ + opts.preserve_ignored = 1; opts.fn = oneway_merge; if (unpack_trees(nr_trees, t, &opts)) diff --git a/merge-ort.c b/merge-ort.c index 35aa979c3a4..0d64ec716bd 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -4045,11 +4045,7 @@ static int checkout(struct merge_options *opt, unpack_opts.quiet = 0; /* FIXME: sequencer might want quiet? */ unpack_opts.verbose_update = (opt->verbosity > 2); unpack_opts.fn = twoway_merge; - if (1/* FIXME: opts->overwrite_ignore*/) { - CALLOC_ARRAY(unpack_opts.dir, 1); - unpack_opts.dir->flags |= DIR_SHOW_IGNORED; - setup_standard_excludes(unpack_opts.dir); - } + unpack_opts.preserve_ignored = 0; /* FIXME: !opts->overwrite_ignore*/ parse_tree(prev); init_tree_desc(&trees[0], prev->buffer, prev->size); parse_tree(next); @@ -4057,8 +4053,6 @@ static int checkout(struct merge_options *opt, ret = unpack_trees(2, trees, &unpack_opts); clear_unpack_trees_porcelain(&unpack_opts); - dir_clear(unpack_opts.dir); - FREE_AND_NULL(unpack_opts.dir); return ret; } diff --git a/merge-recursive.c b/merge-recursive.c index 233d9f686ad..2be3f5d4044 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -411,9 +411,7 @@ static int unpack_trees_start(struct merge_options *opt, else { opt->priv->unpack_opts.update = 1; /* FIXME: should only do this if !overwrite_ignore */ - CALLOC_ARRAY(opt->priv->unpack_opts.dir, 1); - opt->priv->unpack_opts.dir->flags |= DIR_SHOW_IGNORED; - setup_standard_excludes(opt->priv->unpack_opts.dir); + opt->priv->unpack_opts.preserve_ignored = 0; } opt->priv->unpack_opts.merge = 1; opt->priv->unpack_opts.head_idx = 2; @@ -428,10 +426,6 @@ static int unpack_trees_start(struct merge_options *opt, init_tree_desc_from_tree(t+2, merge); rc = unpack_trees(3, t, &opt->priv->unpack_opts); - if (opt->priv->unpack_opts.dir) { - dir_clear(opt->priv->unpack_opts.dir); - FREE_AND_NULL(opt->priv->unpack_opts.dir); - } cache_tree_free(&opt->repo->index->cache_tree); /* diff --git a/merge.c b/merge.c index 6e736881d90..2382ff66d35 100644 --- a/merge.c +++ b/merge.c @@ -53,7 +53,6 @@ int checkout_fast_forward(struct repository *r, struct unpack_trees_options opts; struct tree_desc t[MAX_UNPACK_TREES]; int i, nr_trees = 0; - struct dir_struct dir = DIR_INIT; struct lock_file lock_file = LOCK_INIT; refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL); @@ -80,11 +79,7 @@ int checkout_fast_forward(struct repository *r, } memset(&opts, 0, sizeof(opts)); - if (overwrite_ignore) { - dir.flags |= DIR_SHOW_IGNORED; - setup_standard_excludes(&dir); - opts.dir = &dir; - } + opts.preserve_ignored = !overwrite_ignore; opts.head_idx = 1; opts.src_index = r->index; @@ -101,7 +96,6 @@ int checkout_fast_forward(struct repository *r, clear_unpack_trees_porcelain(&opts); return -1; } - dir_clear(&dir); clear_unpack_trees_porcelain(&opts); if (write_locked_index(r->index, &lock_file, COMMIT_LOCK)) diff --git a/reset.c b/reset.c index 79310ae071b..41b3e2d88de 100644 --- a/reset.c +++ b/reset.c @@ -56,6 +56,8 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action, unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge; unpack_tree_opts.update = 1; unpack_tree_opts.merge = 1; + /* FIXME: Default should be to remove ignored files */ + unpack_tree_opts.preserve_ignored = 1; init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL); if (!detach_head) unpack_tree_opts.reset = 1; diff --git a/sequencer.c b/sequencer.c index 614d56f5e21..098566c68d9 100644 --- a/sequencer.c +++ b/sequencer.c @@ -3699,6 +3699,8 @@ static int do_reset(struct repository *r, unpack_tree_opts.fn = oneway_merge; unpack_tree_opts.merge = 1; unpack_tree_opts.update = 1; + /* FIXME: Default should be to remove ignored files */ + unpack_tree_opts.preserve_ignored = 1; init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL); if (repo_read_index_unmerged(r)) { diff --git a/unpack-trees.c b/unpack-trees.c index 8ea0a542da8..1e4eae1dc7d 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1707,6 +1707,12 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options ensure_full_index(o->dst_index); } + if (!o->preserve_ignored) { + CALLOC_ARRAY(o->dir, 1); + o->dir->flags |= DIR_SHOW_IGNORED; + setup_standard_excludes(o->dir); + } + if (!core_apply_sparse_checkout || !o->update) o->skip_sparse_checkout = 1; if (!o->skip_sparse_checkout && !o->pl) { @@ -1868,6 +1874,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options done: if (free_pattern_list) clear_pattern_list(&pl); + if (o->dir) { + dir_clear(o->dir); + FREE_AND_NULL(o->dir); + } trace2_region_leave("unpack_trees", "unpack_trees", the_repository); trace_performance_leave("unpack_trees"); return ret; diff --git a/unpack-trees.h b/unpack-trees.h index 2d88b19dca7..f98cfd49d7b 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -49,6 +49,7 @@ struct unpack_trees_options { unsigned int reset, merge, update, + preserve_ignored, clone, index_only, nontrivial_merge, From patchwork Mon Sep 27 16:33:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520307 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27C65C433EF for ; Mon, 27 Sep 2021 16:34:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1158C610E8 for ; Mon, 27 Sep 2021 16:34:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235554AbhI0Qfx (ORCPT ); Mon, 27 Sep 2021 12:35:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235508AbhI0Qfc (ORCPT ); Mon, 27 Sep 2021 12:35:32 -0400 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B512AC06176C for ; Mon, 27 Sep 2021 09:33:53 -0700 (PDT) Received: by mail-wm1-x336.google.com with SMTP id a131so1027476wmd.1 for ; Mon, 27 Sep 2021 09:33:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=Do76wM0OPvO9kahfV2sjcKK/sz7g2IIRR/4/OtP4ObI=; b=qqG4XF6/XWzfjXfdqduHKNpoDkIOd2GccgwbfxNsrwmIAvk54BszB7tLhF4WuID0f5 QLjq9PO7FVvTGEfwB9NMR5Dbw9m/7yTBh6OUg2qvVwnv0tvMBhA0hw6phFN+mg0yVnNg 4oYI1QxXaGRqRdl4jKYolVJ9i1A6jg73qZwWt5mdMGxM7vTAu95TfL7ktOGrKKw7lcs+ UTqbHLy3I4uUMz553Ina7WDyz6VPrWYsVce5yS2yzFvywJpNb7iCGHw9EwD0nXr1OMOS 6HLwF7c0md1YVFTsX6j7zXYH8nW7aICb7hcLXjjHOLHZMGd32n/gRqSBnEd4xW7kQRd7 3Ksg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=Do76wM0OPvO9kahfV2sjcKK/sz7g2IIRR/4/OtP4ObI=; b=eXswiqTr5l6nONPRwUfUOb4l7gteZDb/uRL/Q2UmKtWPs5CwUuS+iBneAuBuzeFHVI siKxif5lb+TGxzmPUZ9c2UsWheHTgLVCxXaRPd9Svbmnc6rUd22UGJntPoTjmz7KR53d 2n0nB0qWzFsIa9d9cZjAUwYATxtF1m2Q9XRYrGQz899pfr3LK4xLdziT6NEkw8UqkTA2 PUipq/pAxeE3dwFrRozX08QtEe5ZuZS8libpvjIshs9nihnTpMfFoB0o6oTmsrGWJWZf X/KJ8v2wVRasJoIi+hbmvXpoaTh99f/0Y4d9AV1Ca614bqREiemiOwBZaZZ8rQRq+IcZ um9g== X-Gm-Message-State: AOAM531+2+T6rwozbKSCPy7fGJ518xJUDwluKETyD52GQLz2chsQ2m3X GTsZF8es2bp+RI9dQfriSgK6lPOvV5E= X-Google-Smtp-Source: ABdhPJwj68T3RFe1pvix1sNMqkjMNqr2DQCgaztxFjkw61dtuyVzx071AkuX83YKl4a+hhMktVvUog== X-Received: by 2002:a05:600c:298:: with SMTP id 24mr24678wmk.18.1632760432405; Mon, 27 Sep 2021 09:33:52 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id m4sm3391wml.28.2021.09.27.09.33.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:52 -0700 (PDT) Message-Id: <0d119142778dce8617dd9b2c102b5f5bfdc9dc0f.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:42 +0000 Subject: [PATCH v3 05/11] unpack-trees: make dir an internal-only struct Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Avoid accidental misuse or confusion over ownership by clearly making unpack_trees_options.dir an internal-only variable. Signed-off-by: Elijah Newren --- unpack-trees.c | 7 +++++-- unpack-trees.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/unpack-trees.c b/unpack-trees.c index 1e4eae1dc7d..e067cce0fcd 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1694,9 +1694,12 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options static struct cache_entry *dfc; struct pattern_list pl; int free_pattern_list = 0; + struct dir_struct dir = DIR_INIT; if (len > MAX_UNPACK_TREES) die("unpack_trees takes at most %d trees", MAX_UNPACK_TREES); + if (o->dir) + BUG("o->dir is for internal use only"); trace_performance_enter(); trace2_region_enter("unpack_trees", "unpack_trees", the_repository); @@ -1708,7 +1711,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options } if (!o->preserve_ignored) { - CALLOC_ARRAY(o->dir, 1); + o->dir = &dir; o->dir->flags |= DIR_SHOW_IGNORED; setup_standard_excludes(o->dir); } @@ -1876,7 +1879,7 @@ done: clear_pattern_list(&pl); if (o->dir) { dir_clear(o->dir); - FREE_AND_NULL(o->dir); + o->dir = NULL; } trace2_region_leave("unpack_trees", "unpack_trees", the_repository); trace_performance_leave("unpack_trees"); diff --git a/unpack-trees.h b/unpack-trees.h index f98cfd49d7b..61da25dafee 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -67,7 +67,6 @@ struct unpack_trees_options { dry_run; const char *prefix; int cache_bottom; - struct dir_struct *dir; struct pathspec *pathspec; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_WARNING_TYPES]; @@ -89,6 +88,7 @@ struct unpack_trees_options { struct index_state result; struct pattern_list *pl; /* for internal use */ + struct dir_struct *dir; /* for internal use only */ struct checkout_metadata meta; }; From patchwork Mon Sep 27 16:33:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520305 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 374AFC43217 for ; Mon, 27 Sep 2021 16:34:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1FDCD60EE2 for ; Mon, 27 Sep 2021 16:34:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235548AbhI0Qft (ORCPT ); Mon, 27 Sep 2021 12:35:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235509AbhI0Qfc (ORCPT ); Mon, 27 Sep 2021 12:35:32 -0400 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 556BFC06176D for ; Mon, 27 Sep 2021 09:33:54 -0700 (PDT) Received: by mail-wm1-x329.google.com with SMTP id a131so1027497wmd.1 for ; Mon, 27 Sep 2021 09:33:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=LlVQbrKENKAU+AkK6zfNEUhLWVCPj3o/f0XLF00ZEb0=; b=Fk5eyvY9Rxwn7nfG0jkZlQTYJ371GLP8rbzqXzL4ia+dq1kHn0MTWhYS5QZ/aJa9N2 f9/uKjtbjW+4IsIx4JjCQxE6KW7SjbXnIHoGCMIk8uA7QsKB9T7HlQ2T+z1AJKi/GXQr iZ7PmVXZ9D5dQOruet9+WqwTwkb8TgzD2Dubpo7lQtw+AdxM8MPLCcNHUeHcu87JWTT4 VNEU2TYNCxSWOTam+1lifFT/M1qODAA7CAhUnlWiMYbVXrkfDPLLlXt2OFDzzUatFIf/ a0DgaxM/pjDzkL24cfAm8h3s1gXrJyRqWV8+cytFyxkHI0a0uNfBwi4dp4w6aURMUnLR 4XLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=LlVQbrKENKAU+AkK6zfNEUhLWVCPj3o/f0XLF00ZEb0=; b=PKE3rblvwnFYCDrl1hDqnASDay9wa4Y31yQ2FG+w4c79JBet0i48gZKA3LKApqR9Xw TOCLwdcU5tKB797Iw30aDkNlF0AZCDNrvSfMGvokA8weebZNB4BHFpcJ1PZnqLtLom/6 lBRzNLz5wr+nfS3q/01oLiXyFO5ZqUTJxO+gj4cL9XmskZc5bT8eN/grpnNI8ayzuzYx VoAnkmk3vssGPtmibRsJRVfI9MBC2ggqOqxR6WbJG9Me5SNp0wRxmhUPe4+d2w03OY+c tJA3Kf023Uf50zykL17ct6CXfQsHb/s+crNml74QaOh08BWGP4Z7l8EJidIf/a+sjcJm EG4g== X-Gm-Message-State: AOAM5338ABOqGas/QRUl6S8wAPUkROoqxNSkXduZLTbOkOS4fsBpqRGO J+Jm+YeLGvrXTbD/Y5s7cQHBjbMbpcw= X-Google-Smtp-Source: ABdhPJwBvTK+hRpWF5bmoSMPH88G/980rdrCUmw4Vj9eHgHUvqKxKDJr+vkFV4koEeyxlCJRoI+CRw== X-Received: by 2002:a7b:cde8:: with SMTP id p8mr851517wmj.160.1632760432918; Mon, 27 Sep 2021 09:33:52 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o3sm17902898wra.52.2021.09.27.09.33.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:52 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:43 +0000 Subject: [PATCH v3 06/11] Remove ignored files by default when they are in the way Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Change several commands to remove ignored files by default when they are in the way. Since some commands (checkout, merge) take a --no-overwrite-ignore option to allow the user to configure this, and it may make sense to add that option to more commands (and in the case of merge, actually plumb that configuration option through to more of the backends than just the fast-forwarding special case), add little comments about where such flags would be used. Incidentally, this fixes a test failure in t7112. Signed-off-by: Elijah Newren --- builtin/am.c | 3 +-- builtin/clone.c | 3 +-- builtin/merge.c | 3 +-- builtin/reset.c | 3 +-- builtin/stash.c | 3 +-- merge-ort.c | 2 +- reset.c | 3 +-- sequencer.c | 3 +-- t/t7112-reset-submodule.sh | 1 - 9 files changed, 8 insertions(+), 16 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 1ee70692bc3..57738eff0c5 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1919,8 +1919,7 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset) opts.merge = 1; opts.reset = reset; if (!reset) - /* FIXME: Default should be to remove ignored files */ - opts.preserve_ignored = 1; + opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ opts.fn = twoway_merge; init_tree_desc(&t[0], head->buffer, head->size); init_tree_desc(&t[1], remote->buffer, remote->size); diff --git a/builtin/clone.c b/builtin/clone.c index be1c3840d62..11ec6c5f2c8 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -687,8 +687,7 @@ static int checkout(int submodule_progress) opts.update = 1; opts.merge = 1; opts.clone = 1; - /* FIXME: Default should be to remove ignored files */ - opts.preserve_ignored = 1; + opts.preserve_ignored = 0; opts.fn = oneway_merge; opts.verbose_update = (option_verbosity >= 0); opts.src_index = &the_index; diff --git a/builtin/merge.c b/builtin/merge.c index 1e5fff095fc..0ccd5e1ac83 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -680,8 +680,7 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, opts.verbose_update = 1; opts.trivial_merges_only = 1; opts.merge = 1; - /* FIXME: Default should be to remove ignored files */ - opts.preserve_ignored = 1; + opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ trees[nr_trees] = parse_tree_indirect(common); if (!trees[nr_trees++]) return -1; diff --git a/builtin/reset.c b/builtin/reset.c index 7f38656f018..5df01cc42e0 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -67,8 +67,7 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t case KEEP: case MERGE: opts.update = 1; - /* FIXME: Default should be to remove ignored files */ - opts.preserve_ignored = 1; + opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ break; case HARD: opts.update = 1; diff --git a/builtin/stash.c b/builtin/stash.c index 88287b890d5..d60cdaf32f5 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -259,8 +259,7 @@ static int reset_tree(struct object_id *i_tree, int update, int reset) opts.reset = reset; opts.update = update; if (update && !reset) - /* FIXME: Default should be to remove ignored files */ - opts.preserve_ignored = 1; + opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ opts.fn = oneway_merge; if (unpack_trees(nr_trees, t, &opts)) diff --git a/merge-ort.c b/merge-ort.c index 0d64ec716bd..04596b5e7b3 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -4045,7 +4045,7 @@ static int checkout(struct merge_options *opt, unpack_opts.quiet = 0; /* FIXME: sequencer might want quiet? */ unpack_opts.verbose_update = (opt->verbosity > 2); unpack_opts.fn = twoway_merge; - unpack_opts.preserve_ignored = 0; /* FIXME: !opts->overwrite_ignore*/ + unpack_opts.preserve_ignored = 0; /* FIXME: !opts->overwrite_ignore */ parse_tree(prev); init_tree_desc(&trees[0], prev->buffer, prev->size); parse_tree(next); diff --git a/reset.c b/reset.c index 41b3e2d88de..f40a8ecf663 100644 --- a/reset.c +++ b/reset.c @@ -56,8 +56,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action, unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge; unpack_tree_opts.update = 1; unpack_tree_opts.merge = 1; - /* FIXME: Default should be to remove ignored files */ - unpack_tree_opts.preserve_ignored = 1; + unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL); if (!detach_head) unpack_tree_opts.reset = 1; diff --git a/sequencer.c b/sequencer.c index 098566c68d9..6872b7b00a4 100644 --- a/sequencer.c +++ b/sequencer.c @@ -3699,8 +3699,7 @@ static int do_reset(struct repository *r, unpack_tree_opts.fn = oneway_merge; unpack_tree_opts.merge = 1; unpack_tree_opts.update = 1; - /* FIXME: Default should be to remove ignored files */ - unpack_tree_opts.preserve_ignored = 1; + unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL); if (repo_read_index_unmerged(r)) { diff --git a/t/t7112-reset-submodule.sh b/t/t7112-reset-submodule.sh index 19830d90365..a3e2413bc33 100755 --- a/t/t7112-reset-submodule.sh +++ b/t/t7112-reset-submodule.sh @@ -6,7 +6,6 @@ test_description='reset can handle submodules' . "$TEST_DIRECTORY"/lib-submodule-update.sh KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1 -KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1 test_submodule_switch_recursing_with_args "reset --keep" From patchwork Mon Sep 27 16:33:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520311 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A331C433EF for ; Mon, 27 Sep 2021 16:34:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 533966108E for ; Mon, 27 Sep 2021 16:34:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235582AbhI0QgC (ORCPT ); Mon, 27 Sep 2021 12:36:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235514AbhI0Qfl (ORCPT ); Mon, 27 Sep 2021 12:35:41 -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 248C1C061604 for ; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id v127so1028217wme.5 for ; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=aA0MYltKQxVCDDNWaQYZRR4lnBogMvPxAtvTgr89s84=; b=T1sbKpOswU2fYIKftPA0g+FzIaAi+7SBLXw2cCAwNZIcneQGdN6yGL7h3nRxiE8har GfmIRfOs8hRFqAVfi+095GBXGUTkcJg2DHjL65OHy8fKcBVwMp0cTyIVCm/bZKNfPUCL U+y6bQBcOECOWfW71zOcJ7YbBNuz8jtB3Xz1HTprBSoO1QAeT9KM5OoGGq9/B3PRyq61 Rj9LfPLZitvbgz8TM+PldLjxHLc/1LKTvsFBzoOHu2mmgW8c2VRW09B7FlyBdMKD47Wd aF1uTdXNMNvCkzVsOQ57xIXnCtrXZHN+qdUjQqzASeUzPAZTbw61bQTh9yySqRPt0maa XcgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=aA0MYltKQxVCDDNWaQYZRR4lnBogMvPxAtvTgr89s84=; b=nX+f3Y7obG9yoS9GUgWtB6CiayuUb9tbQ724j09MqN7ZF70uvRSjqMuunUu1egwKnX Hrh8BCL8fit+lsjDcezdzaiyKPk0MZ11s9l1SK/+kI2n2w+MiDpMmzICNzCpv645epIZ KxVOC9VGg5sbCCVE1LJ/BWJSdGOmHrdLSEkWshUMXSYGKP6dZglCUh1pBASEHtdvHjH+ joSrY/e+f4UwZQ1e3+HKd5SyLelUpwfJCsqFikd/LxmAJW5VvxoemeNPA2sze6G7xgC7 Qc7oQjRkjUi2yEOTKCkeIX3Clc2O1YkSAhyrZ8xCByrbW4O2F7sjnqNOY0gi/i58Vi/Y mu6w== X-Gm-Message-State: AOAM531UWRYeazBczROZE27QqRZP2m/M5i2ljKRRzMEJZxFQYA/wsm/T WPulG006E/DCYFp0L8WBFBNR7iyuG5c= X-Google-Smtp-Source: ABdhPJyUkGURzGVll/TDrN9mtpQBAM1nArSJRJUsiz/H9R7ACWZ5FwFT4ecIL0KfRirOmqG7iF8bFQ== X-Received: by 2002:a7b:c08e:: with SMTP id r14mr6974988wmh.161.1632760433579; Mon, 27 Sep 2021 09:33:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h18sm17052447wrb.33.2021.09.27.09.33.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:53 -0700 (PDT) Message-Id: <9eb20121fc3886436cef91670e32217466d03ba7.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:44 +0000 Subject: [PATCH v3 07/11] Change unpack_trees' 'reset' flag into an enum Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Traditionally, unpack_trees_options->reset was used to signal that it was okay to delete any untracked files in the way. This was used by `git read-tree --reset`, but then started appearing in other places as well. However, many of the other uses should not be deleting untracked files in the way. Change this value to an enum so that a value of 1 (i.e. "true") can be split into two: UNPACK_RESET_PROTECT_UNTRACKED, UNPACK_RESET_OVERWRITE_UNTRACKED In order to catch accidental misuses (i.e. where folks call it the way they traditionally used to), define the special enum value of UNPACK_RESET_INVALID = 1 which will trigger a BUG(). Modify existing callers so that read-tree --reset reset --hard checkout --force continue using the UNPACK_RESET_OVERWRITE_UNTRACKED logic, while other callers, including am checkout without --force stash (though currently dead code; reset always had a value of 0) numerous callers from rebase/sequencer to reset_head() will use the new UNPACK_RESET_PROTECT_UNTRACKED value. Also, note that it has been reported that 'git checkout ' currently also allows overwriting untracked files[1]. That case should also be fixed, but it does not use unpack_trees() and thus is outside the scope of the current changes. [1] https://lore.kernel.org/git/15dad590-087e-5a48-9238-5d2826950506@gmail.com/ Signed-off-by: Elijah Newren --- builtin/am.c | 5 ++--- builtin/checkout.c | 5 +++-- builtin/read-tree.c | 3 +++ builtin/reset.c | 9 +++++++-- builtin/stash.c | 4 ++-- reset.c | 2 +- t/t2500-untracked-overwriting.sh | 6 +++--- unpack-trees.c | 10 +++++++++- unpack-trees.h | 11 +++++++++-- 9 files changed, 39 insertions(+), 16 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 57738eff0c5..f296226e95f 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1917,9 +1917,8 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset) opts.dst_index = &the_index; opts.update = 1; opts.merge = 1; - opts.reset = reset; - if (!reset) - opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ + opts.reset = reset ? UNPACK_RESET_PROTECT_UNTRACKED : 0; + opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ opts.fn = twoway_merge; init_tree_desc(&t[0], head->buffer, head->size); init_tree_desc(&t[1], remote->buffer, remote->size); diff --git a/builtin/checkout.c b/builtin/checkout.c index 5e7957dd068..cbf73b8c9f6 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -646,9 +646,10 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o, opts.head_idx = -1; opts.update = worktree; opts.skip_unmerged = !worktree; - opts.reset = 1; + opts.reset = o->force ? UNPACK_RESET_OVERWRITE_UNTRACKED : + UNPACK_RESET_PROTECT_UNTRACKED; + opts.preserve_ignored = (!o->force && !o->overwrite_ignore); opts.merge = 1; - opts.preserve_ignored = 0; opts.fn = oneway_merge; opts.verbose_update = o->show_progress; opts.src_index = &the_index; diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 443d206eca6..2109c4c9e5c 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -166,6 +166,9 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if (1 < opts.merge + opts.reset + prefix_set) die("Which one? -m, --reset, or --prefix?"); + if (opts.reset) + opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED; + /* * NEEDSWORK * diff --git a/builtin/reset.c b/builtin/reset.c index 5df01cc42e0..73935953494 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -71,9 +71,14 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t break; case HARD: opts.update = 1; - /* fallthrough */ + opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED; + break; + case MIXED: + opts.reset = UNPACK_RESET_PROTECT_UNTRACKED; + /* but opts.update=0, so working tree not updated */ + break; default: - opts.reset = 1; + BUG("invalid reset_type passed to reset_index"); } read_cache_unmerged(); diff --git a/builtin/stash.c b/builtin/stash.c index d60cdaf32f5..0e3662a230c 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -256,9 +256,9 @@ static int reset_tree(struct object_id *i_tree, int update, int reset) opts.src_index = &the_index; opts.dst_index = &the_index; opts.merge = 1; - opts.reset = reset; + opts.reset = reset ? UNPACK_RESET_PROTECT_UNTRACKED : 0; opts.update = update; - if (update && !reset) + if (update) opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ opts.fn = oneway_merge; diff --git a/reset.c b/reset.c index f40a8ecf663..f214df3d96c 100644 --- a/reset.c +++ b/reset.c @@ -59,7 +59,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action, unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL); if (!detach_head) - unpack_tree_opts.reset = 1; + unpack_tree_opts.reset = UNPACK_RESET_PROTECT_UNTRACKED; if (repo_read_index_unmerged(r) < 0) { ret = error(_("could not read index")); diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh index 2412d121ea8..18604360df8 100755 --- a/t/t2500-untracked-overwriting.sh +++ b/t/t2500-untracked-overwriting.sh @@ -92,7 +92,7 @@ test_setup_checkout_m () { ) } -test_expect_failure 'checkout -m does not nuke untracked file' ' +test_expect_success 'checkout -m does not nuke untracked file' ' test_setup_checkout_m && ( cd checkout && @@ -138,7 +138,7 @@ test_setup_sequencing () { ) } -test_expect_failure 'git rebase --abort and untracked files' ' +test_expect_success 'git rebase --abort and untracked files' ' test_setup_sequencing rebase_abort_and_untracked && ( cd sequencing_rebase_abort_and_untracked && @@ -155,7 +155,7 @@ test_expect_failure 'git rebase --abort and untracked files' ' ) ' -test_expect_failure 'git rebase fast forwarding and untracked files' ' +test_expect_success 'git rebase fast forwarding and untracked files' ' test_setup_sequencing rebase_fast_forward_and_untracked && ( cd sequencing_rebase_fast_forward_and_untracked && diff --git a/unpack-trees.c b/unpack-trees.c index e067cce0fcd..812e4c66713 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1696,6 +1696,9 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options int free_pattern_list = 0; struct dir_struct dir = DIR_INIT; + if (o->reset == UNPACK_RESET_INVALID) + BUG("o->reset had a value of 1; should be UNPACK_TREES_*_UNTRACKED"); + if (len > MAX_UNPACK_TREES) die("unpack_trees takes at most %d trees", MAX_UNPACK_TREES); if (o->dir) @@ -1710,6 +1713,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options ensure_full_index(o->dst_index); } + if (o->reset == UNPACK_RESET_OVERWRITE_UNTRACKED && + o->preserve_ignored) + BUG("UNPACK_RESET_OVERWRITE_UNTRACKED incompatible with preserved ignored files"); + if (!o->preserve_ignored) { o->dir = &dir; o->dir->flags |= DIR_SHOW_IGNORED; @@ -2233,7 +2240,8 @@ static int verify_absent_1(const struct cache_entry *ce, int len; struct stat st; - if (o->index_only || o->reset || !o->update) + if (o->index_only || !o->update || + o->reset == UNPACK_RESET_OVERWRITE_UNTRACKED) return 0; len = check_leading_path(ce->name, ce_namelen(ce), 0); diff --git a/unpack-trees.h b/unpack-trees.h index 61da25dafee..71ffb7eeb0c 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -45,9 +45,15 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, */ void clear_unpack_trees_porcelain(struct unpack_trees_options *opts); +enum unpack_trees_reset_type { + UNPACK_RESET_NONE = 0, /* traditional "false" value; still valid */ + UNPACK_RESET_INVALID = 1, /* "true" no longer valid; use below values */ + UNPACK_RESET_PROTECT_UNTRACKED, + UNPACK_RESET_OVERWRITE_UNTRACKED +}; + struct unpack_trees_options { - unsigned int reset, - merge, + unsigned int merge, update, preserve_ignored, clone, @@ -65,6 +71,7 @@ struct unpack_trees_options { exiting_early, show_all_errors, dry_run; + enum unpack_trees_reset_type reset; const char *prefix; int cache_bottom; struct pathspec *pathspec; From patchwork Mon Sep 27 16:33:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520313 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E0B8C433FE for ; Mon, 27 Sep 2021 16:34:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 089326103B for ; Mon, 27 Sep 2021 16:34:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235494AbhI0QgD (ORCPT ); Mon, 27 Sep 2021 12:36:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235515AbhI0Qfl (ORCPT ); Mon, 27 Sep 2021 12:35:41 -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 782FEC06176E for ; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id k7so1112413wrd.13 for ; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=zU0LDvN716nciP0nufay8LdjyzhL3MrjsT30DOiqbpY=; b=Q0s4lTzYEUG/tPCSG4MkVD1dMyEek6R9sgUA1oVWoSJ8wXBtDC/qwJwnwXXXsTm9EV 1w6w4/Q3/qzmZXqGIS0+d2xOShEHqu6AAbId7/1LUJ3htsflIJMlG26XB08oO3dlC0e7 9sLuGBOFaGYFRLqKkSaJ2GCnWXKDb0gVNMHXxAtwXfZ4AUALYLZU9Yaf7qSCxn3/Nayl Zd+YlXVg0fr+SEke5FlMWr4kWKP9eVpId5BqXaLjd7jNadnMc0E8p9H7GcwwWQaL7iSe c43mo/w/W6azySiLZMBSn8iVJ1aZhYRnM44MPs+12xgZf/iGCH0ilyNwqtlZHc9w5/7M CW+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=zU0LDvN716nciP0nufay8LdjyzhL3MrjsT30DOiqbpY=; b=vFQGpTifyhVJ+/jtDZgPHDJzmeDi4jWA9AFBLox9hE18YNdR4BpjHAicuHbx6sHYT1 niHFaHimiKzDOlgkSTyQ8uBezCg6QW+nTUHPfdCY5Lel1YVW1xKXnEzamYs/G7FC+Y79 MSdwYzNuYE5Q59AUPnhz4wAtNYBpm6xpIbVH9qDWSBVl3pmiQisg1v7wzNmxjUfodt9l WqaO/HZKdJ8it7R3m8gEtQ36+EC4r9UkO13aPW3vGtBVNL9weCBWQwAI0rCbnKrMfA+M G0BiprthrPWM7Y+PDWpxLNojruG2zS+4J/XgvuZ6yeOyXz/rcSdgLeN/+aDL5NUQDTKe iMQg== X-Gm-Message-State: AOAM5307l4x+h1DhUTaMIeHyW1arqSEu83YmCiPq0DUZpllnc1Le0U00 s7jWs9AoKJTz3x+oDtA9hvitnDz5Hug= X-Google-Smtp-Source: ABdhPJxiGadVi/22lNvh0xxN2pkrb0yfx98voAoehCyL43Mg99dpHU3F+CKURmBulaAQowq3mIYO8Q== X-Received: by 2002:a5d:64e2:: with SMTP id g2mr857720wri.323.1632760434168; Mon, 27 Sep 2021 09:33:54 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a25sm321wmj.34.2021.09.27.09.33.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:53 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:45 +0000 Subject: [PATCH v3 08/11] unpack-trees: avoid nuking untracked dir in way of unmerged file Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Signed-off-by: Elijah Newren --- t/t2500-untracked-overwriting.sh | 2 +- unpack-trees.c | 35 ++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh index 18604360df8..5ec66058cfc 100755 --- a/t/t2500-untracked-overwriting.sh +++ b/t/t2500-untracked-overwriting.sh @@ -197,7 +197,7 @@ test_expect_failure 'git stash and untracked files' ' ) ' -test_expect_failure 'git am --abort and untracked dir vs. unmerged file' ' +test_expect_success 'git am --abort and untracked dir vs. unmerged file' ' test_setup_sequencing am_abort_and_untracked && ( cd sequencing_am_abort_and_untracked && diff --git a/unpack-trees.c b/unpack-trees.c index 812e4c66713..080118f2325 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -2178,9 +2178,15 @@ static int icase_exists(struct unpack_trees_options *o, const char *name, int le return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); } +enum absent_checking_type { + COMPLETELY_ABSENT, + ABSENT_ANY_DIRECTORY +}; + static int check_ok_to_remove(const char *name, int len, int dtype, const struct cache_entry *ce, struct stat *st, enum unpack_trees_error_types error_type, + enum absent_checking_type absent_type, struct unpack_trees_options *o) { const struct cache_entry *result; @@ -2215,6 +2221,10 @@ static int check_ok_to_remove(const char *name, int len, int dtype, return 0; } + /* If we only care about directories, then we can remove */ + if (absent_type == ABSENT_ANY_DIRECTORY) + return 0; + /* * The previous round may already have decided to * delete this path, which is in a subdirectory that @@ -2235,6 +2245,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype, */ static int verify_absent_1(const struct cache_entry *ce, enum unpack_trees_error_types error_type, + enum absent_checking_type absent_type, struct unpack_trees_options *o) { int len; @@ -2261,7 +2272,8 @@ static int verify_absent_1(const struct cache_entry *ce, NULL, o); else ret = check_ok_to_remove(path, len, DT_UNKNOWN, NULL, - &st, error_type, o); + &st, error_type, + absent_type, o); } free(path); return ret; @@ -2276,7 +2288,7 @@ static int verify_absent_1(const struct cache_entry *ce, return check_ok_to_remove(ce->name, ce_namelen(ce), ce_to_dtype(ce), ce, &st, - error_type, o); + error_type, absent_type, o); } } @@ -2286,14 +2298,23 @@ static int verify_absent(const struct cache_entry *ce, { if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE)) return 0; - return verify_absent_1(ce, error_type, o); + return verify_absent_1(ce, error_type, COMPLETELY_ABSENT, o); +} + +static int verify_absent_if_directory(const struct cache_entry *ce, + enum unpack_trees_error_types error_type, + struct unpack_trees_options *o) +{ + if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE)) + return 0; + return verify_absent_1(ce, error_type, ABSENT_ANY_DIRECTORY, o); } static int verify_absent_sparse(const struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { - return verify_absent_1(ce, error_type, o); + return verify_absent_1(ce, error_type, COMPLETELY_ABSENT, o); } static int merged_entry(const struct cache_entry *ce, @@ -2367,6 +2388,12 @@ static int merged_entry(const struct cache_entry *ce, * Previously unmerged entry left as an existence * marker by read_index_unmerged(); */ + if (verify_absent_if_directory(merge, + ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) { + discard_cache_entry(merge); + return -1; + } + invalidate_ce_path(old, o); } From patchwork Mon Sep 27 16:33:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520315 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC46BC433F5 for ; Mon, 27 Sep 2021 16:34:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D5E0C6103B for ; Mon, 27 Sep 2021 16:34:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235506AbhI0QgE (ORCPT ); Mon, 27 Sep 2021 12:36:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58762 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235519AbhI0Qfl (ORCPT ); Mon, 27 Sep 2021 12:35:41 -0400 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA980C061770 for ; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) Received: by mail-wm1-x332.google.com with SMTP id b204-20020a1c80d5000000b0030cd967c674so351829wmd.0 for ; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=HTuOzR5JByGoTcKS7MpQdfwDOj0Z8IxDv5TAv4cmJYc=; b=a7PTa8xMtAQyXXySo6GcHMLSwYdmw7BmUcA//m650VFiQSP83GAgNH1fuZ/ghFHUq/ SlFxtsGReJUV3Tf7vM00jzF+hV6tuvhNul+DqMhlSPZXTHtyBOOXZQOLvWmktpoVwr7M 5S/TUgEOFt+JWF9wLPGAmM1V4uy+3k/W65i7K14//V3hSgySDYTfjFr77V6eBd2AyUmF gZ1HNxr+J7Z2ukfNHGEeXAno92CJ1UDSzV1yVBr5jHXTuErcZN/WNpebolGriI+4nWZE 8miME7k5N7642wZr8MP8OXC2Hv3DltCWz7PZIUL6Y3jpXTAmdZPBpz2dJejzh9Wi7Xn4 xj2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=HTuOzR5JByGoTcKS7MpQdfwDOj0Z8IxDv5TAv4cmJYc=; b=doogsHUYhJ22hb9dW8vKoE12omYt/jVBUHZffRUd6StohuVbJxSQZTwKSNg0eS0bGo 3rLuUJ38TT4btrLG6q0sbrqccvX0502LRV7BbhWDFdIWYomWCtm2HNw+o8S+bw+QxnTN EypWlD2d6jmANr/Pop8vCJG6izoMMmTd30LNoFanR6JFBFqLvYO3IHA64aTdcGpOewzM 2nP+0f1Ddnx2f/fm2ChdO+QhEmwO1Yaik8kkW+ikgf0l1HeCV5O7IEID604ywWyrM8bg ownJ3uXSm7w0QrmsphcW14wDXjL2ZhkMUMChN+TN9iX7zctKvdune4wz1KOmIoKKF2A8 HnNw== X-Gm-Message-State: AOAM532zGOLoZjp2PeXneYTNAJmmKiH+K2PdMftjjXzt4PfNSwEST2UG 1nh+THXkbyEHXXwXl7UCR82ieXSlmDA= X-Google-Smtp-Source: ABdhPJyhGShoUcaD0ZNNtEZ+nxYicCi3VjSktn3bZ0TbWwWXJEJm+AfmP0hgIlmf4FtMwxP1mZXitQ== X-Received: by 2002:a1c:f703:: with SMTP id v3mr13172400wmh.177.1632760434652; Mon, 27 Sep 2021 09:33:54 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c9sm15795498wmb.41.2021.09.27.09.33.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:54 -0700 (PDT) Message-Id: <1a770681704691e32722f1abbe292e8523c7f455.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:46 +0000 Subject: [PATCH v3 09/11] unpack-trees: avoid nuking untracked dir in way of locally deleted file Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Signed-off-by: Elijah Newren --- t/t2500-untracked-overwriting.sh | 2 +- unpack-trees.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh index 5ec66058cfc..5c0bf4d21fc 100755 --- a/t/t2500-untracked-overwriting.sh +++ b/t/t2500-untracked-overwriting.sh @@ -218,7 +218,7 @@ test_expect_success 'git am --abort and untracked dir vs. unmerged file' ' ) ' -test_expect_failure 'git am --skip and untracked dir vs deleted file' ' +test_expect_success 'git am --skip and untracked dir vs deleted file' ' test_setup_sequencing am_skip_and_untracked && ( cd sequencing_am_skip_and_untracked && diff --git a/unpack-trees.c b/unpack-trees.c index 080118f2325..a7e1712d236 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -2411,7 +2411,10 @@ static int deleted_entry(const struct cache_entry *ce, if (verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_REMOVED, o)) return -1; return 0; + } else if (verify_absent_if_directory(ce, ERROR_WOULD_LOSE_UNTRACKED_REMOVED, o)) { + return -1; } + if (!(old->ce_flags & CE_CONFLICTED) && verify_uptodate(old, o)) return -1; add_entry(o, ce, CE_REMOVE, 0); From patchwork Mon Sep 27 16:33:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520317 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5610FC433FE for ; Mon, 27 Sep 2021 16:34:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 408EE60EE2 for ; Mon, 27 Sep 2021 16:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235535AbhI0QgE (ORCPT ); Mon, 27 Sep 2021 12:36:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235520AbhI0Qfl (ORCPT ); Mon, 27 Sep 2021 12:35:41 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 931B4C061771 for ; Mon, 27 Sep 2021 09:33:56 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id g16so53029569wrb.3 for ; Mon, 27 Sep 2021 09:33:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=4flcDxnWAKshHJowklyWsYUv/4ql0eXm7FSKYXZjCq8=; b=YcCqAUxc/RSw2fcoA8n2p+GaImBIA4LpoP/zaiKWEixKJCnXTPHJNbAJgiz74gn2lr Aa6onHKhLxp5S3zQnemMO91PPuMK81A70EvYab9dBzxCLELz+T05Jz1fCgItFIzr2CVw e8rcsaUrQ2XQIOnnRJ93OiTdA47/IYm2P8MGRwczuTt5PuKa1EDbJt/fOAbHkOsIu0FV TRrzHxTECbEPjZ0+vKIybgf+yeHH0nA7Wtgcr8NGtA80RpjrhjoxMtFlWglwjgBvMP5i ZYmG5Q781O0mHSmn1MOmPyvikSsugiVv6xH/tlOWeM4COM/s+oZovExSz3vF/GW4vP5U nsLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=4flcDxnWAKshHJowklyWsYUv/4ql0eXm7FSKYXZjCq8=; b=aE9CFydV0JIsI+z+tUzIJO7ObI7dYq5bORPAs2Ek44Ev9slJJsHEW5XsSAVD2bJ3Ex r0DcsGSgeXKFHSRdydNl4oHW8KD3E8PCsaVKS0nl7FR6Oma0O5P5jwF73D5TqC5be68d PJ4Is7qkDuRbqQOOZzYIKom/LV88eAFHi52HABj1wIp/bQcukwwZea5vw5S1WoDQdPQV xV3s+Uxht948G9aJe9p+M0rgcjuUqieaxA7/yTmyw6s1gngxiyhkrFgJQQc7JYsZwFI/ qdgCJfHdmA8dEZCcemk4N3m8rlwc/y2AohpDwBVLVCn5rWy/OjaVwljSLEZBWYgLlVig Y+PA== X-Gm-Message-State: AOAM532NQRVuElhGOjmyVq+detPvmgObHuhxbIC2TXsbyU1DG2opCCKm 6o7FpAaWpoAPzWgZbL6NUoHY701Wx5A= X-Google-Smtp-Source: ABdhPJzA2zmiPCBWhqw+/Kr/uIDIbpudcrAc4JBnmvjsIIES+PxGcUAow5/WVDf0lILeWj5HYwTzhw== X-Received: by 2002:a05:6000:18a:: with SMTP id p10mr863941wrx.161.1632760435256; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g21sm15429wmk.10.2021.09.27.09.33.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:54 -0700 (PDT) Message-Id: <6b42a80bf3d46e16980d0724e8b07101225239d0.1632760428.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:47 +0000 Subject: [PATCH v3 10/11] Comment important codepaths regarding nuking untracked files/dirs Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren In the last few commits we focused on code in unpack-trees.c that mistakenly removed untracked files or directories. There may be more of those, but in this commit we change our focus: callers of toplevel commands that are expected to remove untracked files or directories. As noted previously, we have toplevel commands that are expected to delete untracked files such as 'read-tree --reset', 'reset --hard', and 'checkout --force'. However, that does not mean that other highlevel commands that happen to call these other commands thought about or conveyed to users the possibility that untracked files could be removed. Audit the code for such callsites, and add comments near existing callsites to mention whether these are safe or not. My auditing is somewhat incomplete, though; it skipped several cases: * git-rebase--preserve-merges.sh: is in the process of being deprecated/removed, so I won't leave a note that there are likely more bugs in that script. * contrib/git-new-workdir: why is the -f flag being used in a new empty directory?? It shouldn't hurt, but it seems useless. * git-p4.py: Don't see why -f is needed for a new dir (maybe it's not and is just superfluous), but I'm not at all familiar with the p4 stuff * git-archimport.perl: Don't care; arch is long since dead * git-cvs*.perl: Don't care; cvs is long since dead Also, the reset --hard in builtin/worktree.c looks safe, due to only running in an empty directory. Signed-off-by: Elijah Newren --- builtin/stash.c | 1 + builtin/submodule--helper.c | 4 ++++ contrib/rerere-train.sh | 2 +- submodule.c | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/builtin/stash.c b/builtin/stash.c index 0e3662a230c..aa31163a5a1 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1521,6 +1521,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } else { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; + /* BUG: this nukes untracked files in the way */ strvec_pushl(&cp.args, "reset", "--hard", "-q", "--no-recurse-submodules", NULL); if (run_command(&cp)) { diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5336daf186d..e13f2a0bcd0 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -3090,6 +3090,10 @@ static int add_submodule(const struct add_data *add_data) prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.dir = add_data->sm_path; + /* + * NOTE: we only get here if add_data->force is true, so + * passing --force to checkout is reasonable. + */ strvec_pushl(&cp.args, "checkout", "-f", "-q", NULL); if (add_data->branch) { diff --git a/contrib/rerere-train.sh b/contrib/rerere-train.sh index eeee45dd341..75125d6ae00 100755 --- a/contrib/rerere-train.sh +++ b/contrib/rerere-train.sh @@ -91,7 +91,7 @@ do git checkout -q $commit -- . git rerere fi - git reset -q --hard + git reset -q --hard # Might nuke untracked files... done if test -z "$branch" diff --git a/submodule.c b/submodule.c index 78aed03d928..c8ba93cc708 100644 --- a/submodule.c +++ b/submodule.c @@ -1908,6 +1908,7 @@ static void submodule_reset_index(const char *path) strvec_pushf(&cp.args, "--super-prefix=%s%s/", get_super_prefix_or_empty(), path); + /* TODO: determine if this might overwright untracked files */ strvec_pushl(&cp.args, "read-tree", "-u", "--reset", NULL); strvec_push(&cp.args, empty_tree_oid_hex()); From patchwork Mon Sep 27 16:33:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12520319 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64910C433EF for ; Mon, 27 Sep 2021 16:34:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4EE756103B for ; Mon, 27 Sep 2021 16:34:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235599AbhI0QgG (ORCPT ); Mon, 27 Sep 2021 12:36:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235522AbhI0Qfl (ORCPT ); Mon, 27 Sep 2021 12:35:41 -0400 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A687C061772 for ; Mon, 27 Sep 2021 09:33:57 -0700 (PDT) Received: by mail-wm1-x32f.google.com with SMTP id g19-20020a1c9d13000000b003075062d4daso485361wme.0 for ; Mon, 27 Sep 2021 09:33:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=5lP2C1cPbEMfe/VUNzBw0385qhXCQ10cKlGFDXXepgs=; b=Y8Qp/MLhw2ZS4iohD5h9LACjWc00Agjf5gK7cqNj5qZkV/qzuyaMlaepAhsCxKm48w LPO35XRaUjX53PgARf/8G3cbVr9f9KhcGjqk5/kKnh5c0aMjNFQqVoOiw2WUyLZB5+/S Y+WtGpYq507wWf4CiWmKrXILEvMHDdaoyQJFN26to7oqSTs9Zc0X+hhjl7JFmBFS9/Nm 64W1zy2X49wb+rK09MCVUcJ7I4R6USH3uVsOP5oV+zmXyLcvibYtbknktAqqIRFywf9/ 4XOg5qbST/x6S2hckeVqfEFO3aJd1crd6PabtQNWNhIfraSIkTlIx+P+QgrhSvI7E9iN sEiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=5lP2C1cPbEMfe/VUNzBw0385qhXCQ10cKlGFDXXepgs=; b=Jcxg6nom6GMgq3CBz81PbvPqV4m24+ck24jh087T+LQERbW3X8RswH9JGS81GwPk4V V7ZzyZeuxJSAP01JL3/LKYn696gVf2rfJBOja8MST4YbnUFzS4XguXeMmyVzDtjxXzOx l5BLL569lTuJ/cZlX6BWSNsppKemtRfrD+T5EJ+B0B9KYz71aQfV2NKF8tybOJ/M1Qxi jiyrMdQ1TW3X21pFGbkBs+QZV61001aQ/RAZp90xtmRP9c9fH32Oz5MexPo6bSUMnmT1 lAnIvlF4/1ePN+sutwKb4uzJAswd+SKmv1m9bRkjfs/JDLlBoHwBpD3i8VJ0s8o3SB7m 3Lyw== X-Gm-Message-State: AOAM530Zd1nZJLNvnsaRAZR097ul9JVsRx7w5dTMA9lJoUWnfLBSOns2 DOnPyImptovsRHCSpeIKI8uz+CMzWtk= X-Google-Smtp-Source: ABdhPJwx87xUVBvjVZhucTxc6BoeR29Y3PxdCTaLcpAU3bxMkqinbhlzsron5v1Oo69vyRhQYN4a1w== X-Received: by 2002:a1c:d4:: with SMTP id 203mr11706902wma.87.1632760435768; Mon, 27 Sep 2021 09:33:55 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id v17sm7644526wro.34.2021.09.27.09.33.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 09:33:55 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 27 Sep 2021 16:33:48 +0000 Subject: [PATCH v3 11/11] Documentation: call out commands that nuke untracked files/directories Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Fedor Biryukov , Philip Oakley , Phillip Wood , Elijah Newren , Eric Sunshine , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Some commands have traditionally also removed untracked files (or directories) that were in the way of a tracked file we needed. Document these cases. Signed-off-by: Elijah Newren --- Documentation/git-checkout.txt | 5 +++-- Documentation/git-read-tree.txt | 5 +++-- Documentation/git-reset.txt | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index b1a6fe44997..d473c9bf387 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -118,8 +118,9 @@ OPTIONS -f:: --force:: When switching branches, proceed even if the index or the - working tree differs from `HEAD`. This is used to throw away - local changes. + working tree differs from `HEAD`, and even if there are untracked + files in the way. This is used to throw away local changes and + any untracked files or directories that are in the way. + When checking out paths from the index, do not fail upon unmerged entries; instead, unmerged entries are ignored. diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 0222a27c5af..8c3aceb8324 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -38,8 +38,9 @@ OPTIONS --reset:: Same as -m, except that unmerged entries are discarded instead - of failing. When used with `-u`, updates leading to loss of - working tree changes will not abort the operation. + of failing. When used with `-u`, updates leading to loss of + working tree changes or untracked files or directories will not + abort the operation. -u:: After a successful merge, update the files in the work diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 252e2d4e47d..6f7685f53d5 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -69,7 +69,8 @@ linkgit:git-add[1]). --hard:: Resets the index and working tree. Any changes to tracked files in the - working tree since `` are discarded. + working tree since `` are discarded. Any untracked files or + directories in the way of writing any tracked files are simply deleted. --merge:: Resets the index and updates the files in the working tree that are