From patchwork Tue Jan 19 21:27:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12030859 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=-15.8 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,USER_AGENT_GIT 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 E6CDCC433E0 for ; Tue, 19 Jan 2021 21:29:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A370322D08 for ; Tue, 19 Jan 2021 21:29:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728603AbhASV3S (ORCPT ); Tue, 19 Jan 2021 16:29:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727566AbhASV25 (ORCPT ); Tue, 19 Jan 2021 16:28:57 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DF23C061573 for ; Tue, 19 Jan 2021 13:28:17 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id d26so21128451wrb.12 for ; Tue, 19 Jan 2021 13:28:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LcLoWdyBRJser5fVuRzTvu6mdxMRojJEIbm/dV5XOBE=; b=RDTMcbQMFj62ETs38am1GM6r0I7RUAqSP9dj3YeLhMV1Fz+qaYPDlIINyib2239mOe gluqbjWKIG1SCjUypsentFimStjVCFcp5up3UcITishNm39brWI2IkPjRfW3TqurAOi6 JcSzBxY2mi5hq6UsqP1t83ezVK1Y205IvFsy5T5xjEcrmzcJH2REpcS0yc3LQHKDlyX6 EJhxQkPkmvF/x3ooLvUMv1DvxJ6uakMQz40suIgJp1T8sko1Sndg48aU+6oIMFOOnCbw QnHGhoaZjG4eCCZh3U28e1xk4Pl+CH96BpKs6627ZZ9xILMKDDIUkEIWBp0GOgt1/Lpg ZTLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LcLoWdyBRJser5fVuRzTvu6mdxMRojJEIbm/dV5XOBE=; b=alWR7kb5BME5fxF3SGpSue6EaZq1HmhgxAVdDjT48O3KSMQJHswbLeMtkhY/zFrU+/ aZzcGy/P+nziBycI5IFUZGC+ROODWkZoP/RW7AtcWNVtDIxvN4e67OhOLncfVeqcjpnC ArPsc/06Z1VtF8XmWcAzltYebBOx0C5QFBBCQCobpIB3VyvzQoVfNj1KSMtWIK+2v88/ wAMehEACBHbhKa38CEm11dyxkB6tC2qYdqJfDmt5HxglB63/G64nHgr2sxhCHqI+4ohB i6VaB06XgVlpvOTxBagxh0t0FFyjXDg5cGXA5ZD76blSYk0R/eXDmqDSp0lPfC0bPAEd 9AmQ== X-Gm-Message-State: AOAM53077f1c8q5sc5U5/+ZudjXoSmxE5upu3dhdqACANJE8HiR8GbcB eKY7IpFP5gHQF5EAr9QLSn018pTlq+Q= X-Google-Smtp-Source: ABdhPJwcP1+xB0Nj8vjpWqgD8gKd6TGjJXhkU7wfK04TKcgPBAczvcbRHMNZLOUDCX+fgcIRwU3XvA== X-Received: by 2002:a05:6000:124e:: with SMTP id j14mr6293938wrx.310.1611091695548; Tue, 19 Jan 2021 13:28:15 -0800 (PST) Received: from localhost.localdomain ([212.86.35.161]) by smtp.gmail.com with ESMTPSA id r2sm39448819wrn.83.2021.01.19.13.28.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:28:14 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Rafael Silva Subject: [PATCH v3 1/7] worktree: libify should_prune_worktree() Date: Tue, 19 Jan 2021 22:27:33 +0100 Message-Id: <20210119212739.77882-2-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.421.g32f838e276 In-Reply-To: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> References: <20210117234244.95106-1-rafaeloliveira.cs@gmail.com> <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org As part of teaching "git worktree list" to annotate worktree that is a candidate for pruning, let's move should_prune_worktree() from builtin/worktree.c to worktree.c in order to make part of the worktree public API. should_prune_worktree() knows how to select the given worktree for pruning based on an expiration date, however the expiration value is stored in a static file-scope variable and it is not local to the function. In order to move the function, teach should_prune_worktree() to take the expiration date as an argument and document the new parameter that is not immediately obvious. Also, change the function comment to clearly state that the worktree's path is returned in `wtpath` argument. Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- builtin/worktree.c | 75 +--------------------------------------------- worktree.c | 68 +++++++++++++++++++++++++++++++++++++++++ worktree.h | 14 +++++++++ 3 files changed, 83 insertions(+), 74 deletions(-) diff --git a/builtin/worktree.c b/builtin/worktree.c index 71287b2da6..dd886d5029 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -67,79 +67,6 @@ static void delete_worktrees_dir_if_empty(void) rmdir(git_path("worktrees")); /* ignore failed removal */ } -/* - * Return true if worktree entry should be pruned, along with the reason for - * pruning. Otherwise, return false and the worktree's path, or NULL if it - * cannot be determined. Caller is responsible for freeing returned path. - */ -static int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath) -{ - struct stat st; - char *path; - int fd; - size_t len; - ssize_t read_result; - - *wtpath = NULL; - if (!is_directory(git_path("worktrees/%s", id))) { - strbuf_addstr(reason, _("not a valid directory")); - return 1; - } - if (file_exists(git_path("worktrees/%s/locked", id))) - return 0; - if (stat(git_path("worktrees/%s/gitdir", id), &st)) { - strbuf_addstr(reason, _("gitdir file does not exist")); - return 1; - } - fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY); - if (fd < 0) { - strbuf_addf(reason, _("unable to read gitdir file (%s)"), - strerror(errno)); - return 1; - } - len = xsize_t(st.st_size); - path = xmallocz(len); - - read_result = read_in_full(fd, path, len); - if (read_result < 0) { - strbuf_addf(reason, _("unable to read gitdir file (%s)"), - strerror(errno)); - close(fd); - free(path); - return 1; - } - close(fd); - - if (read_result != len) { - strbuf_addf(reason, - _("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"), - (uintmax_t)len, (uintmax_t)read_result); - free(path); - return 1; - } - while (len && (path[len - 1] == '\n' || path[len - 1] == '\r')) - len--; - if (!len) { - strbuf_addstr(reason, _("invalid gitdir file")); - free(path); - return 1; - } - path[len] = '\0'; - if (!file_exists(path)) { - if (stat(git_path("worktrees/%s/index", id), &st) || - st.st_mtime <= expire) { - strbuf_addstr(reason, _("gitdir file points to non-existent location")); - free(path); - return 1; - } else { - *wtpath = path; - return 0; - } - } - *wtpath = path; - return 0; -} - static void prune_worktree(const char *id, const char *reason) { if (show_only || verbose) @@ -195,7 +122,7 @@ static void prune_worktrees(void) if (is_dot_or_dotdot(d->d_name)) continue; strbuf_reset(&reason); - if (should_prune_worktree(d->d_name, &reason, &path)) + if (should_prune_worktree(d->d_name, &reason, &path, expire)) prune_worktree(d->d_name, reason.buf); else if (path) string_list_append(&kept, path)->util = xstrdup(d->d_name); diff --git a/worktree.c b/worktree.c index 821b233479..8ae019af79 100644 --- a/worktree.c +++ b/worktree.c @@ -741,3 +741,71 @@ void repair_worktree_at_path(const char *path, strbuf_release(&realdotgit); strbuf_release(&dotgit); } + +int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire) +{ + struct stat st; + char *path; + int fd; + size_t len; + ssize_t read_result; + + *wtpath = NULL; + if (!is_directory(git_path("worktrees/%s", id))) { + strbuf_addstr(reason, _("not a valid directory")); + return 1; + } + if (file_exists(git_path("worktrees/%s/locked", id))) + return 0; + if (stat(git_path("worktrees/%s/gitdir", id), &st)) { + strbuf_addstr(reason, _("gitdir file does not exist")); + return 1; + } + fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY); + if (fd < 0) { + strbuf_addf(reason, _("unable to read gitdir file (%s)"), + strerror(errno)); + return 1; + } + len = xsize_t(st.st_size); + path = xmallocz(len); + + read_result = read_in_full(fd, path, len); + if (read_result < 0) { + strbuf_addf(reason, _("unable to read gitdir file (%s)"), + strerror(errno)); + close(fd); + free(path); + return 1; + } + close(fd); + + if (read_result != len) { + strbuf_addf(reason, + _("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"), + (uintmax_t)len, (uintmax_t)read_result); + free(path); + return 1; + } + while (len && (path[len - 1] == '\n' || path[len - 1] == '\r')) + len--; + if (!len) { + strbuf_addstr(reason, _("invalid gitdir file")); + free(path); + return 1; + } + path[len] = '\0'; + if (!file_exists(path)) { + if (stat(git_path("worktrees/%s/index", id), &st) || + st.st_mtime <= expire) { + strbuf_addstr(reason, _("gitdir file points to non-existent location")); + free(path); + return 1; + } else { + *wtpath = path; + return 0; + } + } + *wtpath = path; + return 0; +} diff --git a/worktree.h b/worktree.h index f38e6fd5a2..818e1491c7 100644 --- a/worktree.h +++ b/worktree.h @@ -73,6 +73,20 @@ int is_main_worktree(const struct worktree *wt); */ const char *worktree_lock_reason(struct worktree *wt); +/* + * Return true if worktree entry should be pruned, along with the reason for + * pruning. Otherwise, return false and the worktree's path in `wtpath`, or + * NULL if it cannot be determined. Caller is responsible for freeing + * returned path. + * + * `expire` defines a grace period to prune the worktree when its path + * does not exist. + */ +int should_prune_worktree(const char *id, + struct strbuf *reason, + char **wtpath, + timestamp_t expire); + #define WT_VALIDATE_WORKTREE_MISSING_OK (1 << 0) /* From patchwork Tue Jan 19 21:27:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12030861 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=-15.8 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,USER_AGENT_GIT 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 5A05AC433E6 for ; Tue, 19 Jan 2021 21:30:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1016722D71 for ; Tue, 19 Jan 2021 21:30:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729273AbhASVaA (ORCPT ); Tue, 19 Jan 2021 16:30:00 -0500 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 S1728883AbhASV26 (ORCPT ); Tue, 19 Jan 2021 16:28:58 -0500 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 286E1C061575 for ; Tue, 19 Jan 2021 13:28:18 -0800 (PST) Received: by mail-wr1-x42e.google.com with SMTP id d26so21128487wrb.12 for ; Tue, 19 Jan 2021 13:28:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iizqHUX2jzrwgDtQtta8EOZZSEuSd8m6ozy7F8qnSOo=; b=gIJ9EDsgJdrTRbdeGtYhH9rsC1Av8B6hv9k5eLECLsZy+UJQoOIf4Znga6CrUss8lR 4TCGKZt/77PaUGXkOgMGVy17UYdvcZ0RnO196PxQGKQ9oALGZyH3PXd0hGuq+mtVSXTt uq64ezoPwEXXhtxBeX/p4tJCJmLO6nSYmsBbpZhJHpHXfYdKPPQx7/X3sfS/CvE6HP2y sWwxqEglzJFYCyNKKGccbc/wsXDwzHpOuqG13mqysPNuP8Gv6exF/aA88aNrEul5pVs/ X8b/V3k2r9RNvCyWt8HajNKdBxElQs15sPtX9CnYWh+zyZ33ewe6J3C4/NngVpbK6k+S LTGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iizqHUX2jzrwgDtQtta8EOZZSEuSd8m6ozy7F8qnSOo=; b=N81u3nu+1nn6fo03qoL+Rbn74nvtW9ZRbzTOlegkKM8/c+ynwt1jZNZsLLmKzAIJ0J 9IEs3D+9t6yYTj/rusQ1hT2/B0IrDVtK5xxsojD0StBTyy7FXpsCZ6eBrRO/vaA7rKYW 9U0gioVGBgpaBCceV+yQ1/hoS8X7fnD0DLPixSMNQ/nfyp1e9GMg1cmVGeAkY22unhPG fRP45FludVtE4qL5U5pDuhNEv2pP7fHedYllIAPqhxk2huXC+4mLpehfTySG7vzrnzMr kCEpvUaD7scx3cpzqToSWU7FssirQGuqGD+WZRhsQLjN9C+euuxxFhW/zbhc5I13IOlh tsHg== X-Gm-Message-State: AOAM533wDW+0jE1xpH6gYxOpQi0YDIfbxzWuCBKv1KTcG0xzpalfDR5j Gqy1y89s3chioMJiz1xD1ixrJvtUm84= X-Google-Smtp-Source: ABdhPJxJ4TnzRfusda5HGRLqhw6krUgPrBj9G8xqe3Q9CcwYpyQ9rq1thDJrVAEEn0qXt2d2ivtJdA== X-Received: by 2002:a5d:43d2:: with SMTP id v18mr6208470wrr.326.1611091696390; Tue, 19 Jan 2021 13:28:16 -0800 (PST) Received: from localhost.localdomain ([212.86.35.161]) by smtp.gmail.com with ESMTPSA id r2sm39448819wrn.83.2021.01.19.13.28.15 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:28:15 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Rafael Silva Subject: [PATCH v3 2/7] worktree: teach worktree to lazy-load "prunable" reason Date: Tue, 19 Jan 2021 22:27:34 +0100 Message-Id: <20210119212739.77882-3-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.421.g32f838e276 In-Reply-To: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> References: <20210117234244.95106-1-rafaeloliveira.cs@gmail.com> <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Add worktree_prune_reason() to allow a caller to discover whether a worktree is prunable and the reason that it is, much like worktree_lock_reason() indicates whether a worktree is locked and the reason for the lock. As with worktree_lock_reason(), retrieve the prunable reason lazily and cache it in the `worktree` structure. Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- worktree.c | 20 ++++++++++++++++++++ worktree.h | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/worktree.c b/worktree.c index 8ae019af79..fb3e286996 100644 --- a/worktree.c +++ b/worktree.c @@ -15,6 +15,7 @@ void free_worktrees(struct worktree **worktrees) free(worktrees[i]->id); free(worktrees[i]->head_ref); free(worktrees[i]->lock_reason); + free(worktrees[i]->prune_reason); free(worktrees[i]); } free (worktrees); @@ -245,6 +246,25 @@ const char *worktree_lock_reason(struct worktree *wt) return wt->lock_reason; } +const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire) +{ + struct strbuf reason = STRBUF_INIT; + char *path = NULL; + + if (is_main_worktree(wt)) + return NULL; + if (wt->prune_reason_valid) + return wt->prune_reason; + + if (should_prune_worktree(wt->id, &reason, &path, expire)) + wt->prune_reason = strbuf_detach(&reason, NULL); + wt->prune_reason_valid = 1; + + strbuf_release(&reason); + free(path); + return wt->prune_reason; +} + /* convenient wrapper to deal with NULL strbuf */ static void strbuf_addf_gently(struct strbuf *buf, const char *fmt, ...) { diff --git a/worktree.h b/worktree.h index 818e1491c7..8b7c408132 100644 --- a/worktree.h +++ b/worktree.h @@ -11,11 +11,13 @@ struct worktree { char *id; char *head_ref; /* NULL if HEAD is broken or detached */ char *lock_reason; /* private - use worktree_lock_reason */ + char *prune_reason; /* private - use worktree_prune_reason */ struct object_id head_oid; int is_detached; int is_bare; int is_current; int lock_reason_valid; /* private */ + int prune_reason_valid; /* private */ }; /* @@ -73,6 +75,13 @@ int is_main_worktree(const struct worktree *wt); */ const char *worktree_lock_reason(struct worktree *wt); +/* + * Return the reason string if the given worktree should be pruned, otherwise + * NULL if it should not be pruned. `expire` defines a grace period to prune + * the worktree when its path does not exist. + */ +const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire); + /* * Return true if worktree entry should be pruned, along with the reason for * pruning. Otherwise, return false and the worktree's path in `wtpath`, or From patchwork Tue Jan 19 21:27:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12030865 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=-15.8 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,USER_AGENT_GIT 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 4C5D9C433E0 for ; Tue, 19 Jan 2021 21:30:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0B77722D08 for ; Tue, 19 Jan 2021 21:30:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729457AbhASVaR (ORCPT ); Tue, 19 Jan 2021 16:30:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728939AbhASV27 (ORCPT ); Tue, 19 Jan 2021 16:28:59 -0500 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 3C090C061757 for ; Tue, 19 Jan 2021 13:28:19 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id c12so2603803wrc.7 for ; Tue, 19 Jan 2021 13:28:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zYcTW5pLZ9kEy6pRjCU3OU9CXNLu5+2s7QayXEttCdw=; b=aZ8onbjvowccMoBs4C8SeJ/gaOfljfKAtsOza5utNnZQkMQpgnU35eklV1S8vmQKWE Hem6oJ15L5a0YGIBLybYhh8jXyl/pDEG/o0O6vyxHUf4v/YUqy2QwjzBE/WvPinYzxAZ +/X8v5mfnq0oCuU6pvIVIkcGw7QsrIQ+7DmzO5pFL6xlqnGNft2ImRIScSaClVCG8WJE 8rAcpG6pW/lnHi5yoA61drIMteyE8TBxUzfS+rd3JpZhAe+FdVzMamKHBy02LXsssP4I /ni34VE8ciFPJnTNEmToWgpxxZGcuiq4datpgb2JVT3hCvoZ6SRy+5nEr+FE8QoVMfm9 m1AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zYcTW5pLZ9kEy6pRjCU3OU9CXNLu5+2s7QayXEttCdw=; b=CfTCNS3Jt8D/4Imabs3mMtzcaoZDSN0yljj4qQmL3R/NQgAHJWcjXRvpK3HOxKsR3M EezGiceajQWzgK9/tXH32ws46+1VKHAaLzbwXcKL8mxALGhNvC6QOfH1xm15NTCeYW6g LUkgb1H3P2I45dvT9Qs2XcBMU1d/BWy8ysJLzqyZSq7arhHg0B/YGI3/S63/a9x6/3rj RoBiuMSwq3aFqbLq+OTlTlOD9dBhI0DOTHVm/8bHeAiNq63E0PaNtutGI4d4Hn4tn0gc BurkWo2/JI+VmZJ0MvSN1zI6Zm2NLtofnzSH35SlqEAvZJMKgSR9iY70NvlGgFx/uf6s +0kA== X-Gm-Message-State: AOAM533xS0seAUqsiv1nqYcxLHUNUecXhOWCNXH4Ee8fkO42r2iRrv1I IDbxl5e+5cZ2pqTmO5Ecm418OIB7B3E= X-Google-Smtp-Source: ABdhPJzXNHtOR/NesJMw5G0yXwf6CI5bNiJtVLLPchposzt5Q30wS5CSYbkJgwXBVzjRcI7HELp+dA== X-Received: by 2002:adf:ba8b:: with SMTP id p11mr6133432wrg.328.1611091697711; Tue, 19 Jan 2021 13:28:17 -0800 (PST) Received: from localhost.localdomain ([212.86.35.161]) by smtp.gmail.com with ESMTPSA id r2sm39448819wrn.83.2021.01.19.13.28.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:28:16 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Rafael Silva Subject: [PATCH v3 3/7] worktree: teach worktree_lock_reason() to gently handle main worktree Date: Tue, 19 Jan 2021 22:27:35 +0100 Message-Id: <20210119212739.77882-4-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.421.g32f838e276 In-Reply-To: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> References: <20210117234244.95106-1-rafaeloliveira.cs@gmail.com> <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org worktree_lock_reason() aborts with an assertion failure when called on the main worktree since locking the main worktree is nonsensical. Not only is this behavior undocumented, thus callers might not even be aware that the call could potentially crash the program, but it also forces clients to be extra careful: if (!is_main_worktree(wt) && worktree_locked_reason(...)) ... Since we know that locking makes no sense in the context of the main worktree, we can simply return false for the main worktree, thus making client code less complex by eliminating the need for the callers to have inside knowledge about the implementation: if (worktree_lock_reason(...)) ... Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- builtin/worktree.c | 2 +- worktree.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/builtin/worktree.c b/builtin/worktree.c index dd886d5029..df90a5acca 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -604,7 +604,7 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len) strbuf_addstr(&sb, "(error)"); } - if (!is_main_worktree(wt) && worktree_lock_reason(wt)) + if (worktree_lock_reason(wt)) strbuf_addstr(&sb, " locked"); printf("%s\n", sb.buf); diff --git a/worktree.c b/worktree.c index fb3e286996..e00858540e 100644 --- a/worktree.c +++ b/worktree.c @@ -225,7 +225,8 @@ int is_main_worktree(const struct worktree *wt) const char *worktree_lock_reason(struct worktree *wt) { - assert(!is_main_worktree(wt)); + if (is_main_worktree(wt)) + return NULL; if (!wt->lock_reason_valid) { struct strbuf path = STRBUF_INIT; From patchwork Tue Jan 19 21:27:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12030867 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=-15.8 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,USER_AGENT_GIT 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 A5160C433DB for ; Tue, 19 Jan 2021 21:32:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 79BE422D71 for ; Tue, 19 Jan 2021 21:32:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725935AbhASVbr (ORCPT ); Tue, 19 Jan 2021 16:31:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58684 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728865AbhASV24 (ORCPT ); Tue, 19 Jan 2021 16:28:56 -0500 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67150C0613C1 for ; Tue, 19 Jan 2021 13:28:20 -0800 (PST) Received: by mail-wm1-x32d.google.com with SMTP id y187so1030062wmd.3 for ; Tue, 19 Jan 2021 13:28:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/u64ZmgRQoAmUvYV26SSFp1TJT72uV1+D4vkjOPyF2I=; b=OL1y3zuqZbMqmE1eguXoNyaD0FzUVWqledin+qigvSLKmgUFArvqgfYyN+XhNc6TQ4 cJ98qoZYVvYuDC2jL0plFya1BeUgkNOrwxClTaHCd7rckL6F3bT5B+iD0lCv0uDCvOJF 9sN6i2JJAwqmJ2eR4qaiIOXLuGIojDyxIXODQOLjYkgDl43+pSg3rU49pf3jxJ72Hlaw aa3d1Baw+f+hm0hAAkMboLb1bQxuA2yalv3A4+MulNBRywxKrEKVysPUfPPPRuVALrJS 6RHuBBvgy9RhOV9IRCVCNuJE2GmoRBrrbcCkNm7gSYEQouRjiporaE6EqTBAKxPswC54 tNEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/u64ZmgRQoAmUvYV26SSFp1TJT72uV1+D4vkjOPyF2I=; b=uoW1pARHawN59nmLm+tmO5BO9YUEBPZfMDASogsi9j/edx9B2ugNI/b93+iZPxzi/o bfTyGyGsfAEhZKvEWXpNT2KnDSRC1v91IjdaxEp3rZX9ow1C7RVIq9qRaWM6pEZzmlyR DSC76Sb/Qo1oE0MsdmcZ5+P9bM28khSEEhN4WSGVj07lfzZvh3IK84mCZIWe4eoMVtqr br8WIHibXan7bC5uR5gY2f/COYjnVsRE3U8mw/jumI+LTwyTX5qLVC5t0zdlO5ObPGGF D8hRa8v5BQ2PMTPrAm2sLuB+6XVlhsXXVSNZNV5M0p2sfdYBhdDFeJk1FKxJpuMkdEUS rFVg== X-Gm-Message-State: AOAM532OOVUj5cx3ytn0AWna07pJkXOh/RxIxKJcCuFLEI9OV1qA1UeQ 9OBqjT4oMKz7+7ba0iffV0aiXt0qeek= X-Google-Smtp-Source: ABdhPJz4GCDObGWxDsHrrQZOlgn0iwyKbb2OP9Mh8+puKUpaqzIuisznoaTVXjALWsWdUHc0fmuDdA== X-Received: by 2002:a7b:c41a:: with SMTP id k26mr1364183wmi.1.1611091698937; Tue, 19 Jan 2021 13:28:18 -0800 (PST) Received: from localhost.localdomain ([212.86.35.161]) by smtp.gmail.com with ESMTPSA id r2sm39448819wrn.83.2021.01.19.13.28.17 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:28:18 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Rafael Silva Subject: [PATCH v3 4/7] t2402: ensure locked worktree is properly cleaned up Date: Tue, 19 Jan 2021 22:27:36 +0100 Message-Id: <20210119212739.77882-5-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.421.g32f838e276 In-Reply-To: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> References: <20210117234244.95106-1-rafaeloliveira.cs@gmail.com> <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org In c57b3367be (worktree: teach `list` to annotate locked worktree, 2020-10-11) introduced a new test to ensure locked worktrees are listed with "locked" annotation. However, the test does not clean up after itself as "git worktree prune" is not going to remove the locked worktree in the first place. This not only leaves the test in an unclean state it also potentially breaks following tests that relies on the "git worktree list" output. Let's fix that by unlocking the worktree before the "prune" command. Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- t/t2402-worktree-list.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index 795ddca2e4..1866ea09f6 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -66,6 +66,7 @@ test_expect_success '"list" all worktrees with locked annotation' ' git worktree add --detach locked master && git worktree add --detach unlocked master && git worktree lock locked && + test_when_finished "git worktree unlock locked" && git worktree list >out && grep "/locked *[0-9a-f].* locked$" out && ! grep "/unlocked *[0-9a-f].* locked$" out From patchwork Tue Jan 19 21:27:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12030869 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=-15.8 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,USER_AGENT_GIT 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 BEBB4C433E6 for ; Tue, 19 Jan 2021 21:32:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8EB8222DD3 for ; Tue, 19 Jan 2021 21:32:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728780AbhASVcG (ORCPT ); Tue, 19 Jan 2021 16:32:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729275AbhASV3Y (ORCPT ); Tue, 19 Jan 2021 16:29:24 -0500 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78379C0613CF for ; Tue, 19 Jan 2021 13:28:21 -0800 (PST) Received: by mail-wm1-x333.google.com with SMTP id 190so1084646wmz.0 for ; Tue, 19 Jan 2021 13:28:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vmhGbkx8EyI/IgNe17Hgj20SW+tB9VlM22yaB4HhpDI=; b=P/uk8ol6utY/e12fmIGMxSuOr+WUXMjOvlxF0Tl9hnnrx9d5CPdm1DShdD5eTfcVDM YIHr7uMSqG+Ppj8N+BgjK+raWwDeKgKW6NbIyedmd5Uc46qenhQN5xJJdRJh9lY5hkJt dzHX1vwDuXkJSwuMXL3VP+QMM9J4gPaV5W6rEH1+uJQyKS3FwWnbelF3I9uLOQXZ8yU9 lVpU1wLBTFDXNTOHQ7u1VheL7P6F61+Xd8XMZZB3ghRCKQisP8LjCaEXOI/dDkeGmWMJ GD7Nt4sK/Z9GpDPxtC1CMo0PwDN04ja69D7+blFZHQlQ/ZQgCRgIGM8Coy4PMZPrwlts yE8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vmhGbkx8EyI/IgNe17Hgj20SW+tB9VlM22yaB4HhpDI=; b=fQMMby27oxbeIJOe9yMKENRktY46TrlsncfDraf7AXy/gpPbkGl93ez8zAlkD5vjfl jZmxof9S7Dc9BYrHWycRDjFjuWrktMTApmtl5CzRyH3WefJ1Ln8xsWqn9Zi98kgiSiSa yib+iHt30orK+eFYgVyvU6VXhs0t3wnRtnazq7VMIVbGTgHXQzUlD4xJEb+jb0tyc4HX aYYOVZidH8AOt8GevkIUh03XhT0oCIm/Oa4+KGZRv9I99gxmwulSp0M3i4gK72/48pkk YQuocdw9ge/7neYxigpmfMWaxtlHMzCuDL0Gbe6ZOuj0c++3bcs/bAV2GRYhPHefdbXN hV4Q== X-Gm-Message-State: AOAM5316e5K1dQzl44V3oPo/tG8zDpUL0cVL5sZY2biHBLdVAoNG48JN +qKzlNklSCtncIV88vG9vHgW0hinGag= X-Google-Smtp-Source: ABdhPJw7igY1iC6ItxXVhUMNqVUersBnSbPhhoyFtmwWGVYf2IfLCpSxh9Fjfb+n6bZNlSy+wgrtSg== X-Received: by 2002:a1c:8095:: with SMTP id b143mr1321217wmd.71.1611091699918; Tue, 19 Jan 2021 13:28:19 -0800 (PST) Received: from localhost.localdomain ([212.86.35.161]) by smtp.gmail.com with ESMTPSA id r2sm39448819wrn.83.2021.01.19.13.28.18 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:28:19 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Rafael Silva Subject: [PATCH v3 5/7] worktree: teach `list --porcelain` to annotate locked worktree Date: Tue, 19 Jan 2021 22:27:37 +0100 Message-Id: <20210119212739.77882-6-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.421.g32f838e276 In-Reply-To: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> References: <20210117234244.95106-1-rafaeloliveira.cs@gmail.com> <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Commit c57b3367be (worktree: teach `list` to annotate locked worktree, 2020-10-11) taught "git worktree list" to annotate locked worktrees by appending "locked" text to its output, however, this is not listed in the --porcelain format. Teach "list --porcelain" to do the same and add a "locked" attribute followed by its reason, thus making both default and porcelain format consistent. If the locked reason is not available then only "locked" is shown. The output of the "git worktree list --porcelain" becomes like so: $ git worktree list --porcelain ... worktree /path/to/locked HEAD 123abcdea123abcd123acbd123acbda123abcd12 detached locked worktree /path/to/locked-with-reason HEAD abc123abc123abc123abc123abc123abc123abc1 detached locked reason why it is locked ... In porcelain mode, if the lock reason contains special characters such as newlines, they are escaped with backslashes and the entire reason is enclosed in double quotes. For example: $ git worktree list --porcelain ... locked "worktree's path mounted in\nremovable device" ... Furthermore, let's update the documentation to state that some attributes in the porcelain format might be listed alone or together with its value depending whether the value is available or not. Thus documenting the case of the new "locked" attribute. Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- Documentation/git-worktree.txt | 16 ++++++++++++++-- builtin/worktree.c | 13 +++++++++++++ t/t2402-worktree-list.sh | 30 ++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 02a706c4c0..7cb8124f28 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -377,8 +377,10 @@ Porcelain Format The porcelain format has a line per attribute. Attributes are listed with a label and value separated by a single space. Boolean attributes (like `bare` and `detached`) are listed as a label only, and are present only -if the value is true. The first attribute of a working tree is always -`worktree`, an empty line indicates the end of the record. For example: +if the value is true. Some attributes (like `locked`) can be listed as a label +only or with a value depending upon whether a reason is available. The first +attribute of a working tree is always `worktree`, an empty line indicates the +end of the record. For example: ------------ $ git worktree list --porcelain @@ -393,6 +395,16 @@ worktree /path/to/other-linked-worktree HEAD 1234abc1234abc1234abc1234abc1234abc1234a detached +worktree /path/to/linked-worktree-locked-no-reason +HEAD 5678abc5678abc5678abc5678abc5678abc5678c +branch refs/heads/locked-no-reason +locked + +worktree /path/to/linked-worktree-locked-with-reason +HEAD 3456def3456def3456def3456def3456def3456b +branch refs/heads/locked-with-reason +locked reason why is locked + ------------ EXAMPLES diff --git a/builtin/worktree.c b/builtin/worktree.c index df90a5acca..98177f91d4 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -12,6 +12,7 @@ #include "submodule.h" #include "utf8.h" #include "worktree.h" +#include "quote.h" static const char * const worktree_usage[] = { N_("git worktree add [] []"), @@ -569,6 +570,8 @@ static int add(int ac, const char **av, const char *prefix) static void show_worktree_porcelain(struct worktree *wt) { + const char *reason; + printf("worktree %s\n", wt->path); if (wt->is_bare) printf("bare\n"); @@ -579,6 +582,16 @@ static void show_worktree_porcelain(struct worktree *wt) else if (wt->head_ref) printf("branch %s\n", wt->head_ref); } + + reason = worktree_lock_reason(wt); + if (reason && *reason) { + struct strbuf sb = STRBUF_INIT; + quote_c_style(reason, &sb, NULL, 0); + printf("locked %s\n", sb.buf); + strbuf_release(&sb); + } else if (reason) + printf("locked\n"); + printf("\n"); } diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index 1866ea09f6..1fe53c3309 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -72,6 +72,36 @@ test_expect_success '"list" all worktrees with locked annotation' ' ! grep "/unlocked *[0-9a-f].* locked$" out ' +test_expect_success '"list" all worktrees --porcelain with locked' ' + test_when_finished "rm -rf locked1 locked2 unlocked out actual expect && git worktree prune" && + echo "locked" >expect && + echo "locked with reason" >>expect && + git worktree add --detach locked1 && + git worktree add --detach locked2 && + # unlocked worktree should not be annotated with "locked" + git worktree add --detach unlocked && + git worktree lock locked1 && + git worktree lock locked2 --reason "with reason" && + test_when_finished "git worktree unlock locked1 && git worktree unlock locked2" && + git worktree list --porcelain >out && + grep "^locked" out >actual && + test_cmp expect actual +' + +test_expect_success '"list" all worktrees --porcelain with locked reason newline escaped' ' + test_when_finished "rm -rf locked_lf locked_crlf out actual expect && git worktree prune" && + printf "locked \"locked\\\\r\\\\nreason\"\n" >expect && + printf "locked \"locked\\\\nreason\"\n" >>expect && + git worktree add --detach locked_lf && + git worktree add --detach locked_crlf && + git worktree lock locked_lf --reason "$(printf "locked\nreason")" && + git worktree lock locked_crlf --reason "$(printf "locked\r\nreason")" && + test_when_finished "git worktree unlock locked_lf && git worktree unlock locked_crlf" && + git worktree list --porcelain >out && + grep "^locked" out >actual && + test_cmp expect actual +' + test_expect_success 'bare repo setup' ' git init --bare bare1 && echo "data" >file1 && From patchwork Tue Jan 19 21:27:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12030863 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=-15.8 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,USER_AGENT_GIT 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 36BFEC433DB for ; Tue, 19 Jan 2021 21:30:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DAC8722D08 for ; Tue, 19 Jan 2021 21:30:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729449AbhASV3v (ORCPT ); Tue, 19 Jan 2021 16:29:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729161AbhASV3K (ORCPT ); Tue, 19 Jan 2021 16:29:10 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A2DFC061796 for ; Tue, 19 Jan 2021 13:28:22 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id v184so1040603wma.1 for ; Tue, 19 Jan 2021 13:28:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YmQ+BE2KU76AhU11jUK+D8ysRFHmxCZr03Qr/BS8cCM=; b=AFMYiurio5CIaR/yIGjx/um6YTVtwK9gjfSioMtlg4m8a8h5B0hbDuzh/pEUlpgyhG mb9PFnQKNnPt22S3BK2e73/mFvyuaqVRgfFHxGocp0QMOZEkxcdIieodr3Foea+hCTRh tx3r8hf9fSinfolM3qev3og1P9sS71Eh0AGTcUywwcDbAkFuPJMkOwEyBpxfJ8JHXKAU wfC+QJMnPMB5oRfZgLFbSZqwq7IeCxN6ZbPf43mxkFFtVPgzmrO46ckmN5e+PN4SncAH d6B1xfELuHpXNiE8gdFM9F2pm0xRgQjRCjvdsK1OdWAvf/I6i8cfnbe/ggYbdvDkBFsV YRBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YmQ+BE2KU76AhU11jUK+D8ysRFHmxCZr03Qr/BS8cCM=; b=PNq+GN+nfUe/BGkcbkPBAjumdwtKuMnoHWadDt6eMN9xVizZd4jW7+nmYqV+EUmEJ5 RcMyYEsYfU6ycog7XpOGGB5wFRiBgfnALaFWvbZ9WBxAUPohA3Vax5CBh3gAzdHcDATy 2aP4oBra0eztPr+o+vTt7PzLAF5N1gU7oyjW26h2ngVNdpMX3pAzjFWcyprXlNqwq9fa OpIUI7G07oFz0Ezv9gUxF2C9l7J1JCKb4uL/yyNx3euKHj0Vlir5MFQoXYgvCyCKI7qP N15FzV2gll+ARe0pjz1wj1ur4+aL3n+KsKlYDH/drT17U6DcunbSq7mws8Euz+h/ZvuB jh/g== X-Gm-Message-State: AOAM530CCqad2471KmkWFmejFGrmjBlzV5lPfJRxHS7Rs7o24r8Nnda6 lswM5RJmMyhsc3m+gehf7tVw2ZUBde0= X-Google-Smtp-Source: ABdhPJwx1x3YtqAc2kZ071lfuuHzizqH/JXE+08HC3jE5fl+4Wzo3q7qJ75GNpu6NaL5MWTVtWf5Tw== X-Received: by 2002:a1c:f30e:: with SMTP id q14mr1359397wmq.87.1611091700798; Tue, 19 Jan 2021 13:28:20 -0800 (PST) Received: from localhost.localdomain ([212.86.35.161]) by smtp.gmail.com with ESMTPSA id r2sm39448819wrn.83.2021.01.19.13.28.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:28:20 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Rafael Silva Subject: [PATCH v3 6/7] worktree: teach `list` to annotate prunable worktree Date: Tue, 19 Jan 2021 22:27:38 +0100 Message-Id: <20210119212739.77882-7-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.421.g32f838e276 In-Reply-To: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> References: <20210117234244.95106-1-rafaeloliveira.cs@gmail.com> <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The "git worktree list" command shows the absolute path to the worktree, the commit that is checked out, the name of the branch, and a "locked" annotation if the worktree is locked, however, it does not indicate whether the worktree is prunable. The "prune" command will remove a worktree if it is prunable unless `--dry-run` option is specified. This could lead to a worktree being removed without the user realizing before it is too late, in case the user forgets to pass --dry-run for instance. If the "list" command shows which worktree is prunable, the user could verify before running "git worktree prune" and hopefully prevents the working tree to be removed "accidentally" on the worse case scenario. Let's teach "git worktree list" to show when a worktree is a prunable candidate for both default and porcelain format. In the default format a "prunable" text is appended: $ git worktree list /path/to/main aba123 [main] /path/to/linked 123abc [branch-a] /path/to/prunable ace127 (detached HEAD) prunable In the --porcelain format a prunable label is added followed by its reason: $ git worktree list --porcelain ... worktree /path/to/prunable HEAD abc1234abc1234abc1234abc1234abc1234abc12 detached prunable gitdir file points to non-existent location ... Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- Documentation/git-worktree.txt | 26 ++++++++++++++++++++++++-- builtin/worktree.c | 10 ++++++++++ builtin/worktree.cc | 0 t/t2402-worktree-list.sh | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 builtin/worktree.cc diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 7cb8124f28..e0dd291e30 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -97,8 +97,9 @@ list:: List details of each working tree. The main working tree is listed first, followed by each of the linked working trees. The output details include whether the working tree is bare, the revision currently checked out, the -branch currently checked out (or "detached HEAD" if none), and "locked" if -the worktree is locked. +branch currently checked out (or "detached HEAD" if none), "locked" if +the worktree is locked, "prunable" if the worktree can be pruned by `prune` +command. lock:: @@ -234,6 +235,9 @@ This can also be set up as the default behaviour by using the --expire