From patchwork Fri Jan 22 13:03:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12039421 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8FA6CC433DB for ; Fri, 22 Jan 2021 13:06:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 492D823437 for ; Fri, 22 Jan 2021 13:06:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727877AbhAVNF7 (ORCPT ); Fri, 22 Jan 2021 08:05:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727761AbhAVNFp (ORCPT ); Fri, 22 Jan 2021 08:05:45 -0500 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E394C0617AA for ; Fri, 22 Jan 2021 05:04:10 -0800 (PST) Received: by mail-wr1-x433.google.com with SMTP id 6so5023179wri.3 for ; Fri, 22 Jan 2021 05:04:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=CUC6jgZOZOWDFF1ovzbJBErl1MrlXisC9MNPD0XAhWE=; b=hyRy54fWevS8qdW0uKUh21k712wDLD21JafRYAays4koBHZ6EHkEeavy4GJ15L7HKM aTT11QMUeZvnchyzWn+mmMSs2V4lGjXzVp+COzUSjCsqyhdtLdxfZI+KFJ2xnX8fWwTq CXBQWJJUzcWHLOzpz3WoHnqjUypQrpKRYXs7TlY9uF9bRwGUV1TUcuElErrPEAh3Z34+ TH7h5t70leu+hq4JeZ7T5kANRUquq5CUJqySq99s6OBip4UiM3gbedOAOMnz8eKo1Brs aRz4vPXtxS1a4P0Csv55mkJJf+4+h1SxGmw+pFF2F8Qd/iLoexFty8a5jPGiRL9e+Arh dGvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=CUC6jgZOZOWDFF1ovzbJBErl1MrlXisC9MNPD0XAhWE=; b=Iebc8cX04f2E28slKDePDm1jyFei7a4Ah6SQeFCf2s2TXDkujavGm1CeH791m16HfX exN7X+0TaDasps6iuqiaU6xF1blPNxfF+qOnZqfT5co/Q5U42oPUlZbZ/SW6QWXrq848 rjBPrLc+Yu5EZATCgcV55KbB82y1C0r2fdh6AfcyqzALkEBcCDz5fTo0DleL2K5qojYN IHMJ+WC/Hg5o3cl/XBdojurbzjnXI13TlkDR44kKvi52UZpBV0RN2yvCabG6yhOVqK7D 4q3b6ZhWhfC5swBAbj5gcnMGF+TfRCnoArnkGcnAn3chVWgYoux8QKOhjEpJvEukInKc wkUA== X-Gm-Message-State: AOAM533WOwYV4IEHVCEe5q8xrdvXyw0jf+oW5mcVFVfgjwWbgCuyWSro gtU3r3RQd9rJaZIqWQrVnkzV5MWum00= X-Google-Smtp-Source: ABdhPJx8xloPacidpbOYz9g77LplJnryPmbTxRrrEqa2zIgTk58T2i0q8NV1HWkJ6jpRwNnl/3xRtw== X-Received: by 2002:adf:9261:: with SMTP id 88mr2703016wrj.227.1611320648864; Fri, 22 Jan 2021 05:04:08 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l7sm11360817wmg.41.2021.01.22.05.04.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Jan 2021 05:04:08 -0800 (PST) Message-Id: <984458007edb9ac93630490cea1b0863fb584310.1611320640.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 22 Jan 2021 13:03:59 +0000 Subject: [PATCH v2 8/8] t1092: test interesting sparse-checkout scenarios Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: newren@gmail.com, Derrick Stolee , gitster@pobox.com, Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee These also document some behaviors that differ from a full checkout, and possibly in a way that is not intended. The test is designed to be run with "--run=1,X" where 'X' is an interesting test case. Each test uses 'init_repos' to reset the full and sparse copies of the initial-repo that is created by the first test case. This also makes it possible to have test cases leave the working directory or index in unusual states without disturbing later cases. Signed-off-by: Derrick Stolee --- t/t1092-sparse-checkout-compatibility.sh | 298 +++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100755 t/t1092-sparse-checkout-compatibility.sh diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh new file mode 100755 index 00000000000..141cbe822b6 --- /dev/null +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -0,0 +1,298 @@ +#!/bin/sh + +test_description='compare full workdir to sparse workdir' + +. ./test-lib.sh + +test_expect_success 'setup' ' + git init initial-repo && + ( + cd initial-repo && + echo a >a && + echo "after deep" >e && + echo "after folder1" >g && + mkdir folder1 folder2 deep x && + mkdir deep/deeper1 deep/deeper2 && + mkdir deep/deeper1/deepest && + echo "after deeper1" >deep/e && + echo "after deepest" >deep/deeper1/e && + cp a folder1 && + cp a folder2 && + cp a deep && + cp a deep/deeper1 && + cp a deep/deeper2 && + cp a deep/deeper1/deepest && + git add . && + git commit -m "initial commit" && + git checkout -b base && + for dir in folder1 folder2 deep + do + git checkout -b update-$dir && + echo "updated $dir" >$dir/a && + git commit -a -m "update $dir" || return 1 + done && + + git checkout -b rename-base base && + echo >folder1/larger-content <<-\EOF && + matching + lines + help + inexact + renames + EOF + cp folder1/larger-content folder2/ && + cp folder1/larger-content deep/deeper1/ && + git add . && + git commit -m "add interesting rename content" && + + git checkout -b rename-out-to-out rename-base && + mv folder1/a folder2/b && + mv folder1/larger-content folder2/edited-content && + echo >>folder2/edited-content && + git add . && + git commit -m "rename folder1/... to folder2/..." && + + git checkout -b rename-out-to-in rename-base && + mv folder1/a deep/deeper1/b && + mv folder1/larger-content deep/deeper1/edited-content && + echo >>deep/deeper1/edited-content && + git add . && + git commit -m "rename folder1/... to deep/deeper1/..." && + + git checkout -b rename-in-to-out rename-base && + mv deep/deeper1/a folder1/b && + mv deep/deeper1/larger-content folder1/edited-content && + echo >>folder1/edited-content && + git add . && + git commit -m "rename deep/deeper1/... to folder1/..." && + + git checkout -b deepest base && + echo "updated deepest" >deep/deeper1/deepest/a && + git commit -a -m "update deepest" && + + git checkout -f base && + git reset --hard + ) +' + +init_repos () { + rm -rf full-checkout sparse-checkout sparse-index && + + # create repos in initial state + cp -r initial-repo full-checkout && + git -C full-checkout reset --hard && + + cp -r initial-repo sparse-checkout && + git -C sparse-checkout reset --hard && + git -C sparse-checkout sparse-checkout init --cone && + + # initialize sparse-checkout definitions + git -C sparse-checkout sparse-checkout set deep +} + +run_on_sparse () { + ( + cd sparse-checkout && + $* >../sparse-checkout-out 2>../sparse-checkout-err + ) +} + +run_on_all () { + ( + cd full-checkout && + $* >../full-checkout-out 2>../full-checkout-err + ) && + run_on_sparse $* +} + +test_all_match () { + run_on_all $* && + test_cmp full-checkout-out sparse-checkout-out && + test_cmp full-checkout-err sparse-checkout-err +} + +test_expect_success 'status with options' ' + init_repos && + test_all_match git status --porcelain=v2 && + test_all_match git status --porcelain=v2 -z -u && + test_all_match git status --porcelain=v2 -uno && + run_on_all "touch README.md" && + test_all_match git status --porcelain=v2 && + test_all_match git status --porcelain=v2 -z -u && + test_all_match git status --porcelain=v2 -uno && + test_all_match git add README.md && + test_all_match git status --porcelain=v2 && + test_all_match git status --porcelain=v2 -z -u && + test_all_match git status --porcelain=v2 -uno +' + +test_expect_success 'add, commit, checkout' ' + init_repos && + + write_script edit-contents <<-\EOF && + echo text >>$1 + EOF + run_on_all "../edit-contents README.md" && + + test_all_match git add README.md && + test_all_match git status --porcelain=v2 && + test_all_match git commit -m "Add README.md" && + + test_all_match git checkout HEAD~1 && + test_all_match git checkout - && + + run_on_all "../edit-contents README.md" && + + test_all_match git add -A && + test_all_match git status --porcelain=v2 && + test_all_match git commit -m "Extend README.md" && + + test_all_match git checkout HEAD~1 && + test_all_match git checkout - && + + run_on_all "../edit-contents deep/newfile" && + + test_all_match git status --porcelain=v2 -uno && + test_all_match git status --porcelain=v2 && + test_all_match git add . && + test_all_match git status --porcelain=v2 && + test_all_match git commit -m "add deep/newfile" && + + test_all_match git checkout HEAD~1 && + test_all_match git checkout - +' + +test_expect_success 'checkout and reset --hard' ' + init_repos && + + test_all_match git checkout update-folder1 && + test_all_match git status --porcelain=v2 && + + test_all_match git checkout update-deep && + test_all_match git status --porcelain=v2 && + + test_all_match git checkout -b reset-test && + test_all_match git reset --hard deepest && + test_all_match git reset --hard update-folder1 && + test_all_match git reset --hard update-folder2 +' + +test_expect_success 'diff --staged' ' + init_repos && + + write_script edit-contents <<-\EOF && + echo text >>README.md + EOF + run_on_all "../edit-contents" && + + test_all_match git diff && + test_all_match git diff --staged && + test_all_match git add README.md && + test_all_match git diff && + test_all_match git diff --staged +' + +test_expect_success 'diff with renames' ' + init_repos && + + for branch in rename-out-to-out rename-out-to-in rename-in-to-out + do + test_all_match git checkout rename-base && + test_all_match git checkout $branch -- .&& + test_all_match git diff --staged --no-renames && + test_all_match git diff --staged --find-renames || return 1 + done +' + +test_expect_success 'log with pathspec outside sparse definition' ' + init_repos && + + test_all_match git log -- a && + test_all_match git log -- folder1/a && + test_all_match git log -- folder2/a && + test_all_match git log -- deep/a && + test_all_match git log -- deep/deeper1/a && + test_all_match git log -- deep/deeper1/deepest/a && + + test_all_match git checkout update-folder1 && + test_all_match git log -- folder1/a +' + +test_expect_success 'blame with pathspec inside sparse definition' ' + init_repos && + + test_all_match git blame a && + test_all_match git blame deep/a && + test_all_match git blame deep/deeper1/a && + test_all_match git blame deep/deeper1/deepest/a +' + +# TODO: blame currently does not support blaming files outside of the +# sparse definition. It complains that the file doesn't exist locally. +test_expect_failure 'blame with pathspec outside sparse definition' ' + init_repos && + + test_all_match git blame folder1/a && + test_all_match git blame folder2/a && + test_all_match git blame deep/deeper2/a && + test_all_match git blame deep/deeper2/deepest/a +' + +# TODO: reset currently does not behave as expected when in a +# sparse-checkout. +test_expect_failure 'checkout and reset (mixed)' ' + init_repos && + + test_all_match git checkout -b reset-test update-deep && + test_all_match git reset deepest && + test_all_match git reset update-folder1 && + test_all_match git reset update-folder2 +' + +test_expect_success 'merge' ' + init_repos && + + test_all_match git checkout -b merge update-deep && + test_all_match git merge -m "folder1" update-folder1 && + test_all_match git rev-parse HEAD^{tree} && + test_all_match git merge -m "folder2" update-folder2 && + test_all_match git rev-parse HEAD^{tree} +' + +test_expect_success 'merge with outside renames' ' + init_repos && + + for type in out-to-out out-to-in in-to-out + do + test_all_match git reset --hard && + test_all_match git checkout -f -b merge-$type update-deep && + test_all_match git merge -m "$type" rename-$type && + test_all_match git rev-parse HEAD^{tree} || return 1 + done +' + +test_expect_success 'clean' ' + init_repos && + + echo bogus >>.gitignore && + run_on_all cp ../.gitignore . && + test_all_match git add .gitignore && + test_all_match git commit -m ignore-bogus-files && + + run_on_sparse mkdir folder1 && + run_on_all touch folder1/bogus && + + test_all_match git status --porcelain=v2 && + test_all_match git clean -f && + test_all_match git status --porcelain=v2 && + + test_all_match git clean -xf && + test_all_match git status --porcelain=v2 && + + test_all_match git clean -xdf && + test_all_match git status --porcelain=v2 && + + test_path_is_dir sparse-checkout/folder1 +' + +test_done