From patchwork Mon Feb 24 09:08:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Sunshine X-Patchwork-Id: 11399617 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 27056930 for ; Mon, 24 Feb 2020 09:13:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 06F6220870 for ; Mon, 24 Feb 2020 09:13:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="feBrb2J7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727611AbgBXJNC (ORCPT ); Mon, 24 Feb 2020 04:13:02 -0500 Received: from mail-yb1-f171.google.com ([209.85.219.171]:34595 "EHLO mail-yb1-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728000AbgBXJJ5 (ORCPT ); Mon, 24 Feb 2020 04:09:57 -0500 Received: by mail-yb1-f171.google.com with SMTP id u47so4334603ybi.1 for ; Mon, 24 Feb 2020 01:09:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KbWtixSSrwzQ8Z0NPfwwBQ7MERfZZn+r21Qah2tKtkg=; b=feBrb2J7sDSr56iBXA2a27mXwlaxzAdFsoCRnSD61JdYwObL0RI/W6mdw0rKpgSziZ lHP7osP9aKmNGiy9d74iHjQideG5VlC4Fjcx0q3v1xuovgDWk+aHOzyIwGUeXDp78yqX I2beN31E/W50v+r1OtQVqzzIt8J9oqKr3mHKDCSB6g7EYkB2hAfMRJSOoKIG+p+TSXU2 4jVRMWWyD7PQ72/0spwFH5+r6IKbof1k6kVvMJH4EVIGSgMzlOeU8hSf/mCjaKj5gZJh mmjvOK0vLhAzD2Qvl9d7c9xqYwAdUNPIT0b+gP1ijK19sJKGuVYZG1V2twyDuGOK5b1O g/aA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=KbWtixSSrwzQ8Z0NPfwwBQ7MERfZZn+r21Qah2tKtkg=; b=EG9CBeZwHO3Aex6urGDAYtxoB4XIKqf9oGvnfPkWdBVkbbx87F15h22ZOfeZUhzgoj YvWsxk8U9AoBmfKGrE0mgI7G6riwSXSCUCe+7yhBp7HrVAMMiEpLnoThLbH52fhN5s0R khv/9ke/b34D4Z3QACRYhdpyXZzP1Bb5p1keaykVse3ZhVqAUEcNB6TMDZV8BQulmsXh Ksw1NCQOQKXR2l25STJgQ0vMP2zLgE3HA69v1eq+tgOpPg7hp+D1fWdt6l+jeRkYio2J wDpr0c5eXbOEssjUbFhkkWMFLQuLKP9S+OIBMNbu4e1mQD+3qsuHY+6CsxgIqY3ToAz9 cxvw== X-Gm-Message-State: APjAAAUM7cNnnkYBhR4Jr4cE7S2pZzGGtmoqHPCrATU9fWBbHobNv3PA hCbNpXbf/c19msxvs4myaOC8G9+d X-Google-Smtp-Source: APXvYqwfiCoulsFVm7/Kn+HwY6vR6Iy+xA67gUYjwBux21CpOVgu0mOD+pUuJGU8xFnquBkBeot0Bg== X-Received: by 2002:a25:5a41:: with SMTP id o62mr22029386ybb.329.1582535395998; Mon, 24 Feb 2020 01:09:55 -0800 (PST) Received: from localhost.localdomain (user-12l2dpj.cable.mindspring.com. [69.81.55.51]) by smtp.gmail.com with ESMTPSA id g29sm5045988ywk.31.2020.02.24.01.09.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Feb 2020 01:09:55 -0800 (PST) From: Eric Sunshine To: git@vger.kernel.org Cc: Duy Nguyen , Cameron Gunnin , Eric Sunshine Subject: [PATCH 1/3] worktree: improve find_worktree() documentation Date: Mon, 24 Feb 2020 04:08:46 -0500 Message-Id: <20200224090848.54321-2-sunshine@sunshineco.com> X-Mailer: git-send-email 2.25.1.526.gf05a752211 In-Reply-To: <20200224090848.54321-1-sunshine@sunshineco.com> References: <20200224090848.54321-1-sunshine@sunshineco.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Do a better job of explaining that find_worktree()'s main purpose is to locate a worktree based upon input from a user which may be some sort of shorthand for identifying a worktree rather than an actual path. For instance, one shorthand a user can use to identify a worktree is by unique path suffix (i.e. given worktrees at paths "foo/bar" and "foo/baz", the latter can be identified simply as "baz"). The actual heuristics find_worktree() uses to select a worktree may be expanded in the future (for instance, one day it may allow worktree selection by of the .git/worktrees// administrative directory), thus the documentation does not provide a precise description of how matching is performed, instead leaving it open-ended to allow for future enhancement. While at it, drop mention of the non-NULL requirement of `prefix` since NULL has long been allowed. For instance, prefix_filename() has explicitly allowed NULL since 116fb64e43 (prefix_filename: drop length parameter, 2017-03-20), and find_worktree() itself since e4da43b1f0 (prefix_filename: return newly allocated string, 2017-03-20). Signed-off-by: Eric Sunshine --- worktree.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/worktree.h b/worktree.h index caecc7a281..b8a851b92b 100644 --- a/worktree.h +++ b/worktree.h @@ -44,8 +44,18 @@ int submodule_uses_worktrees(const char *path); const char *get_worktree_git_dir(const struct worktree *wt); /* - * Search a worktree that can be unambiguously identified by - * "arg". "prefix" must not be NULL. + * Search for the worktree identified unambiguously by `arg` -- typically + * supplied by the user via the command-line -- which may be a pathname or some + * shorthand uniquely identifying a worktree, thus making it convenient for the + * user to specify a worktree with minimal typing. For instance, if the last + * component (say, "foo") of a worktree's pathname is unique among worktrees + * (say, "work/foo" and "work/bar"), it can be used to identify the worktree + * unambiguously. + * + * `prefix` should be the `prefix` handed to top-level Git commands along with + * `argc` and `argv`. + * + * Return the worktree identified by `arg`, or NULL if not found. */ struct worktree *find_worktree(struct worktree **list, const char *prefix, From patchwork Mon Feb 24 09:08:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Sunshine X-Patchwork-Id: 11399611 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C3C761395 for ; Mon, 24 Feb 2020 09:12:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A29B920873 for ; Mon, 24 Feb 2020 09:12:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IWK50XbM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728044AbgBXJKA (ORCPT ); Mon, 24 Feb 2020 04:10:00 -0500 Received: from mail-yw1-f65.google.com ([209.85.161.65]:41545 "EHLO mail-yw1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728031AbgBXJJ7 (ORCPT ); Mon, 24 Feb 2020 04:09:59 -0500 Received: by mail-yw1-f65.google.com with SMTP id l22so4890777ywc.8 for ; Mon, 24 Feb 2020 01:09:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9ULdO9o2/eahToGb/73glhTnwAFb3IpEjKHGZeffytQ=; b=IWK50XbMJe8XtMpYeRiixP7S0cJCtGJmADliNVOTso0uKt0CuvJ1BMmGBBYum5H8YK dR9qoeQpquP5t6UUci9RGP+kw0AF/s4fn/RaCsAWicFxIqgcp79AtSePwOcq2Gg6fIDg O/KmD4fgGziMEoOZn4VjFoBXEwdFxnOt3bHs2BSpPIlMTQIfD20wK8IDpwPYPYDIUYAy HMaCrFxq9h7FhVHZA2E6NVdxrM+fzX5S+Yv7ayCGIaHcQxaFO2S8SmSM6rZs7voKgw1E oNRaVkxaASxwRbXsgsD2kDTkZWti7gfJFpcC1pSKl8cqMSAamHCjPaSA4r9UAEsChugG /+rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=9ULdO9o2/eahToGb/73glhTnwAFb3IpEjKHGZeffytQ=; b=Vd46cosREqN9iaqcpc0dKh9Gyge/8jPIpzxxuRUl9o21G1V+MfRj+WHqrq6tEbYV/J /HmRXbPXO6KNa9teoNvRu5mW6QUxMDIoJMLcPeCYVj3njvu+WbD6VzDCgG4RupfTFSwy cMR4QUKOb/A2i6FTfAmgtw7220X2TesDu3tkHPfDuZdiuM1q9UokhUuR4RurGMIo8h7U Y9j2KpzDBZ3B7GcYFuudAuQDaGlfWKYcelVq7khfxtJN6MCldTLJ9ONkiyi/VUOPJxhG 62y1yfWOSWTSb5k/j/K8N+N+YHJ+zS2moMxEMHhzq5FVUhlL9gf1ojA0zLoWxFT629h1 YhnQ== X-Gm-Message-State: APjAAAUKTrqh9jJTRRFDhHQhQJr55m/GJO7vfT2erPNFxmSHUr9mqsEq YJiSQ4TxBfZNGUAj/5R4516ZHgjc X-Google-Smtp-Source: APXvYqyMd0iVICJ/SB9uWRZ6rcyxwdeYt4yrLgz1u+uRnj35V6K71iEAzHtgVXOc0QGFT5TPOu5i/A== X-Received: by 2002:a81:5056:: with SMTP id e83mr38656229ywb.414.1582535397287; Mon, 24 Feb 2020 01:09:57 -0800 (PST) Received: from localhost.localdomain (user-12l2dpj.cable.mindspring.com. [69.81.55.51]) by smtp.gmail.com with ESMTPSA id g29sm5045988ywk.31.2020.02.24.01.09.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Feb 2020 01:09:56 -0800 (PST) From: Eric Sunshine To: git@vger.kernel.org Cc: Duy Nguyen , Cameron Gunnin , Eric Sunshine Subject: [PATCH 2/3] worktree: add utility to find worktree by pathname Date: Mon, 24 Feb 2020 04:08:47 -0500 Message-Id: <20200224090848.54321-3-sunshine@sunshineco.com> X-Mailer: git-send-email 2.25.1.526.gf05a752211 In-Reply-To: <20200224090848.54321-1-sunshine@sunshineco.com> References: <20200224090848.54321-1-sunshine@sunshineco.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org find_worktree() employs heuristics to match user provided input -- which may be a pathname or some sort of shorthand -- with an actual worktree. Although this convenience allows a user to identify a worktree with minimal typing, the black-box nature of these heuristics makes it potentially difficult for callers which already know the exact path of a worktree to be confident that the correct worktree will be returned for any specific pathname (particularly a relative one), especially as the heuristics are enhanced and updated. Therefore, add a companion function, find_worktree_by_path(), which deterministically identifies a worktree strictly by pathname with no interpretation and no magic matching. Signed-off-by: Eric Sunshine --- worktree.c | 16 ++++++++++------ worktree.h | 6 ++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/worktree.c b/worktree.c index 5b4793caa3..43c6685d4e 100644 --- a/worktree.c +++ b/worktree.c @@ -215,7 +215,6 @@ struct worktree *find_worktree(struct worktree **list, const char *arg) { struct worktree *wt; - char *path; char *to_free = NULL; if ((wt = find_worktree_by_suffix(list, arg))) @@ -223,11 +222,17 @@ struct worktree *find_worktree(struct worktree **list, if (prefix) arg = to_free = prefix_filename(prefix, arg); - path = real_pathdup(arg, 0); - if (!path) { - free(to_free); + wt = find_worktree_by_path(list, arg); + free(to_free); + return wt; +} + +struct worktree *find_worktree_by_path(struct worktree **list, const char *p) +{ + char *path = real_pathdup(p, 0); + + if (!path) return NULL; - } for (; *list; list++) { const char *wt_path = real_path_if_valid((*list)->path); @@ -235,7 +240,6 @@ struct worktree *find_worktree(struct worktree **list, break; } free(path); - free(to_free); return *list; } diff --git a/worktree.h b/worktree.h index b8a851b92b..d242a6e71c 100644 --- a/worktree.h +++ b/worktree.h @@ -61,6 +61,12 @@ struct worktree *find_worktree(struct worktree **list, const char *prefix, const char *arg); +/* + * Return the worktree corresponding to `path`, or NULL if no such worktree + * exists. + */ +struct worktree *find_worktree_by_path(struct worktree **, const char *path); + /* * Return true if the given worktree is the main one. */ From patchwork Mon Feb 24 09:08:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Sunshine X-Patchwork-Id: 11399613 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 563FE930 for ; Mon, 24 Feb 2020 09:12:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2C1C520880 for ; Mon, 24 Feb 2020 09:12:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QNJrmoju" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728508AbgBXJMx (ORCPT ); Mon, 24 Feb 2020 04:12:53 -0500 Received: from mail-yb1-f193.google.com ([209.85.219.193]:37910 "EHLO mail-yb1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728037AbgBXJKA (ORCPT ); Mon, 24 Feb 2020 04:10:00 -0500 Received: by mail-yb1-f193.google.com with SMTP id x9so2219767ybl.5 for ; Mon, 24 Feb 2020 01:09:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=a/1lnoWGl3+VqZhXRx/qjVg7EIou0SwzOjIR1WqLLhU=; b=QNJrmojuEaxpbPUu21qorIcHrhFgUBOdo7SPBqEBpeSvuwHjQwL87shtFgGxYLXP0Z 2lfkDL3bYoIK3EtAxG5Y4kZCcC20Gn58ZaYbgoPf/xaC8P7VVN1jlaPu+WUwZQvVTmBm fd6LqQEEGaH60c6nZA8vFTxzMTbR3hYECMVbF8D+tPJ/qWMDA7AMn2KUMncPpeNKfaaM 6/CdCB/ve7/zijae7Se3HnIHLoRIyy51ONoSO0nkhD8OP+bAv0LBNG8uomBqUfGX3gXo HcvOSIAzTwJ/tbVLkwvYPpDxq8qJaM0E3UurBtLclP1Iwg0zjhJD7AnPjyeQzE31gUME +Uww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=a/1lnoWGl3+VqZhXRx/qjVg7EIou0SwzOjIR1WqLLhU=; b=qSu7PZ+pEmY2eJVF2dAp8Uf1emQ4z1rvsTKfLfEJV/L5KBBYGyDnBZElygxJBmZCey QVQsOZZd8hthxIkI6E9BxIqqzoY9XqGKZfaBWQBZojjPhSf5yxQmZUy7pa3zumBuc+AF hIqQqDUteY6yujZxAYXjvgNRO3srAoKz2cjwh+6tehwRuApd1VM0akyBIxmU2zoiEDjI h5geBf/EN2RdCGMtg2XmgpmmJTcoAfohHGJnzzIFvGjHPL8xP8NKS7bKkEMH/mHNI3pI LGAN7IkhX44xR/+tbEsYPsHI5bVxKy03yRL8Jiu1irtzOcNBrsX1vOJVhXPHgJOx0JZE p4IQ== X-Gm-Message-State: APjAAAVqbDvDPgFkGAAAqTRIQ9hhUC6uMly8WTO3mS7ZblUTgSNKRvmS MQukV34xzG8QJekqyvsd5Wlw7/xl X-Google-Smtp-Source: APXvYqzArT0lpX1gus3cf8sMcCGjWx+CCdB3FOVvPbwCYJtN6WAgGQc/ZC6tH8qXy7SuhcGOTOHVqQ== X-Received: by 2002:a25:d6d1:: with SMTP id n200mr42937118ybg.488.1582535398397; Mon, 24 Feb 2020 01:09:58 -0800 (PST) Received: from localhost.localdomain (user-12l2dpj.cable.mindspring.com. [69.81.55.51]) by smtp.gmail.com with ESMTPSA id g29sm5045988ywk.31.2020.02.24.01.09.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Feb 2020 01:09:57 -0800 (PST) From: Eric Sunshine To: git@vger.kernel.org Cc: Duy Nguyen , Cameron Gunnin , Eric Sunshine Subject: [PATCH 3/3] worktree: don't allow "add" validation to be fooled by suffix matching Date: Mon, 24 Feb 2020 04:08:48 -0500 Message-Id: <20200224090848.54321-4-sunshine@sunshineco.com> X-Mailer: git-send-email 2.25.1.526.gf05a752211 In-Reply-To: <20200224090848.54321-1-sunshine@sunshineco.com> References: <20200224090848.54321-1-sunshine@sunshineco.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org "git worktree add " performs various checks before approving as a valid location for the new worktree. Aside from ensuring that does not already exist, one of the questions it asks is whether is already a registered worktree. To perform this check, it queries find_worktree() and disallows the "add" operation if find_worktree() finds a match for . As a convenience, however, find_worktree() casts an overly wide net to allow users to identify worktrees by shorthand in order to keep typing to a minimum. For instance, it performs suffix matching which, given subtrees "foo/bar" and "foo/baz", can correctly select the latter when asked only for "baz". "add" validation knows the exact path it is interrogating, so this sort of heuristic-based matching is, at best, questionable for this use-case and, at worst, may may accidentally interpret as matching an existing worktree and incorrectly report it as already registered even when it isn't. (In fact, validate_worktree_add() already contains a special case to avoid accidentally matching against the main worktree, precisely due to this problem.) Avoid the problem of potential accidental matching against an existing worktree by instead taking advantage of find_worktree_by_path() which matches paths deterministically, without applying any sort of magic shorthand matching performed by find_worktree(). Reported-by: Cameron Gunnin Signed-off-by: Eric Sunshine --- builtin/worktree.c | 9 +-------- t/t2400-worktree-add.sh | 9 +++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/builtin/worktree.c b/builtin/worktree.c index d6bc5263f1..24f22800f3 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -234,14 +234,7 @@ static void validate_worktree_add(const char *path, const struct add_opts *opts) die(_("'%s' already exists"), path); worktrees = get_worktrees(0); - /* - * find_worktree()'s suffix matching may undesirably find the main - * rather than a linked worktree (for instance, when the basenames - * of the main worktree and the one being created are the same). - * We're only interested in linked worktrees, so skip the main - * worktree with +1. - */ - wt = find_worktree(worktrees + 1, NULL, path); + wt = find_worktree_by_path(worktrees, path); if (!wt) goto done; diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index b5ece19460..5a7495474a 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -570,6 +570,15 @@ test_expect_success '"add" an existing locked but missing worktree' ' git worktree add --force --force --detach gnoo ' +test_expect_success '"add" not tripped up by magic worktree matching"' ' + # if worktree "sub1/bar" exists, "git worktree add bar" in distinct + # directory `sub2` should not mistakenly complain that `bar` is an + # already-registered worktree + mkdir sub1 sub2 && + git -C sub1 --git-dir=../.git worktree add --detach bozo && + git -C sub2 --git-dir=../.git worktree add --detach bozo +' + test_expect_success FUNNYNAMES 'sanitize generated worktree name' ' git worktree add --detach ". weird*..?.lock.lock" && test -d .git/worktrees/---weird-.-