From patchwork Wed Jan 27 08:03:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12049249 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.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,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 CE729C433DB for ; Wed, 27 Jan 2021 08:13:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7FD4B2073C for ; Wed, 27 Jan 2021 08:13:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234669AbhA0INJ (ORCPT ); Wed, 27 Jan 2021 03:13:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231733AbhA0IEi (ORCPT ); Wed, 27 Jan 2021 03:04:38 -0500 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18A56C061788 for ; Wed, 27 Jan 2021 00:03:47 -0800 (PST) Received: by mail-wr1-x436.google.com with SMTP id g10so916302wrx.1 for ; Wed, 27 Jan 2021 00:03:47 -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=RWps2UGHtioDtdFBm/FT1zznV77nX9NKQHzWKzynpLI=; b=JpCMBxn3puw54gML5i6qdpQtRnquEUkHeaddiq7mLH+GPIptVYdeZQtJ/fNotTdPDP yoz9bewJ6G7u/w3xAFGrjSZLCHE4HLS112gD5hxCudlijWhq7r1pNnbk/ZwsDOf1Wi7n Ui83C7vZgOQLK7BjJ3mkL+WYGdJYUropcsOToV4sjRi5qBPfdFnLzv/3e4Xza7sPUfW3 93nKhp9zATFKn04uPpAu8cdxwx12SY+HCE9uf0ji8jMX6qfyL+BjarEswj9J3SQtiOXT MBmxHOKqvSFWn63mMM6PRC4bI3tYWY/BEeYfTk3F68VclmyEh1TPkcRCZdLQlouh7kNL Q6ZQ== 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=RWps2UGHtioDtdFBm/FT1zznV77nX9NKQHzWKzynpLI=; b=n0kCVCLFlccm4UI1B3vjhRruo1rqgrk2gZgDzID1YRJFom8e88YRqWavUj5kmLMf6m Nb0zkrb0L+SrLwSX5EDoL7on6CcvK0H2U1zQ1ziEdvTfs4J8I9rEtb+pjv4KZwwdCo6J p7If+anDzZM3VWc1dYZ88jNgsOBi/w6UFjXjPJpLbuC1cPRv2pJY6tMQv8sZxnpZUza4 jwJar6kGYfM7qYCIdEGCTO5Ig8ExbNvEnqKcB1+cra+YLg5IxmKeIErJrpRHr4ujEx4l E/lDxBKAlFCFtLb3fY+L9qggo44qbq5OiycpISU9WpgqAxXH2L22+7n8FFPPUsO3CBKn HuUg== X-Gm-Message-State: AOAM530xlVKBe0XD2U1lJCNEGQd7ZaNmoc3gnHW9rA5qMDFiUcU/OIvC dqojt1PJDdO6sk9kevp3P7MzuR52P2ur3NQS X-Google-Smtp-Source: ABdhPJzxPB6Wjq7ZUkDw2NyxAaS6JLVDAsI0qfVi+E3ZlsGcza88gBRzpkez1RMONkO3eLS9TEYlcw== X-Received: by 2002:a5d:55c6:: with SMTP id i6mr10181098wrw.145.1611734625394; Wed, 27 Jan 2021 00:03:45 -0800 (PST) Received: from localhost.localdomain ([79.140.115.116]) by smtp.gmail.com with ESMTPSA id m8sm1850237wrv.37.2021.01.27.00.03.43 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jan 2021 00:03:44 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Junio C Hamano , Rafael Silva Subject: [PATCH v4 1/7] worktree: libify should_prune_worktree() Date: Wed, 27 Jan 2021 09:03:04 +0100 Message-Id: <20210127080310.89639-2-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.395.g7821b4e95a In-Reply-To: <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> References: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> <20210127080310.89639-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 Wed Jan 27 08:03:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12049217 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.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,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 A79A7C433DB for ; Wed, 27 Jan 2021 08:07:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5DE5F2074B for ; Wed, 27 Jan 2021 08:07:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234555AbhA0IGu (ORCPT ); Wed, 27 Jan 2021 03:06:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233133AbhA0IEi (ORCPT ); Wed, 27 Jan 2021 03:04:38 -0500 Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B893C06178A for ; Wed, 27 Jan 2021 00:03:52 -0800 (PST) Received: by mail-wr1-x434.google.com with SMTP id 6so905382wri.3 for ; Wed, 27 Jan 2021 00:03:52 -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=XA1+Lc2e4QdsSCNgiFchQFjwSO3Ax99DBxTNz7+IHKY=; b=Ai3HOfrSu1BxreIvoaHlA2qD9oqAN8vWaznLgfhHyV+6+lPHwgNrF51diCi6W8XR3g A5CzyM0Q8wTEYSRMBXxZ3hbK3tf3rNs7NSkfZN7/baIO4XlIt3k+fMpk7CPAnpbvJOCx D/o0m+NZ/jDCu6ccXQO4A79y3IRbksIw93V/itWjTt2N11xXdWnHrGTcGPZiYJVywhAN VgTHCMLnVg6oPyRvBD6/7v7jTimbQbvaWxuNejjWZVKKRKMNOa0Qih8zRNWsSwyEn4Yk vH9eeZid9P9nR3Trv4PBBYtGHxIcC/23TKiahDM1X5CWfb/K9Ju++I0lLD+j4pj1hOzU HCWQ== 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=XA1+Lc2e4QdsSCNgiFchQFjwSO3Ax99DBxTNz7+IHKY=; b=G2xlQEI25SH48enLmmXnqzeI2gM33us/XZmuGwHyO9lN6Uyj2RO1FAhg804WT41+sg RufOmLBtu2XDoCcTVjoD65D5W/zBvVqtdQzGZb5iJKcAtx/bAC9deSMYJ97LkexToRpw AQLg6JmROamcpd9Mpu7OVARroE/aGK7ONMCLg5aSWS7MxCz0dHVS4XJvhoDXV1uuKuYx sRvOehNH6LevnWj/BeTwJVoxYRYmtJ9lGfjMTg565KytPXSinWbd9+0Wxs6ER18D9HHR tw7zemvCrFko9mpBRPbnZdeYEqgXXpYTTbSkWjHC3Uba/ba56fi6oY02MiuQz5mdOBLi eD0Q== X-Gm-Message-State: AOAM533cm/zX95Nz9yN7TLBv7mETs6Z3JmCa/qXnEct5CcUdCxI/7E/A 8sZUAeS/mwpfesxViFDlCnrawo+Ri26fbJVF X-Google-Smtp-Source: ABdhPJxbjAi/stouzrDWZUe80Eb17ep8gD17aZV72r6MucIYewQqEbUoWn1aQGP54xv+4ci0rNJgdw== X-Received: by 2002:adf:e48b:: with SMTP id i11mr9973308wrm.406.1611734630772; Wed, 27 Jan 2021 00:03:50 -0800 (PST) Received: from localhost.localdomain ([79.140.115.116]) by smtp.gmail.com with ESMTPSA id m8sm1850237wrv.37.2021.01.27.00.03.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jan 2021 00:03:50 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Junio C Hamano , Rafael Silva Subject: [PATCH v4 2/7] worktree: teach worktree to lazy-load "prunable" reason Date: Wed, 27 Jan 2021 09:03:05 +0100 Message-Id: <20210127080310.89639-3-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.395.g7821b4e95a In-Reply-To: <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> References: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> <20210127080310.89639-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 Wed Jan 27 08:03:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12049247 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.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,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 28BE3C433DB for ; Wed, 27 Jan 2021 08:13:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C9CF72073C for ; Wed, 27 Jan 2021 08:13:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234556AbhA0IMn (ORCPT ); Wed, 27 Jan 2021 03:12:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232570AbhA0IEr (ORCPT ); Wed, 27 Jan 2021 03:04:47 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91D1FC061574 for ; Wed, 27 Jan 2021 00:03:59 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id 7so922801wrz.0 for ; Wed, 27 Jan 2021 00:03:59 -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=0Sn1LywvgTB3toZxLoD6Grunjry4v4oJNcGLIL0l3Ik=; b=NdozWRItqCvu15sAHk4hKxbguhVzN7wuG/plXe753p/NKRNmg01+tdg2uPlSkNY+9o 9KyWyEGRhZju1drvNrBOKu6CpQCn11VOpBR2axT1SA+bAwpdpvoQlrLIzlkJW6TgxaIH mYkTz0aJQxWul/lGR4wXLeqPE3MjZ8X3SklaYvi9Qm56lcqTkuUPJYdwwaXuB7Vn27tU /52TvG6NKv+T4LjCtPjvPIJlnSBr2KlhQLMTUcphpBHzMC/u0EnCGOGRW5eBgLYZB8nG RFiVAc4dDF33sDtz0gXzR4RA9Oog/MMnwt82by+Pc2DlRnS/wtQ/qVGBgH8pn/y8bzaE dxtQ== 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=0Sn1LywvgTB3toZxLoD6Grunjry4v4oJNcGLIL0l3Ik=; b=Qqi+AINDQ1qLgD8u+BA36ce8pkBNoHSSEPbbl9XmEgG2W5ac+o7R2Cc0OLgddpoXX1 6TJ1cxF0/CjQruHpwjTY5KlN3tsLIZezdP1g178ZbyNy2OmefSKOmPA8pP5zK7Ip8sdQ jVtHKvcKY9mXWl5nuboK1yDjzQl4HFG168RlaLT+yWrSIJLN8V3yl5diMNAOITycQU8x rgK2QO56re3yodSpqwTptWU0MvaZp5KPSTpE67CCnGwVB5j0ca/I1OaRKKWEgs5vPUAh zSYao3vgK+GCRD7g50LtAkAmnJuNijvNP7iQzv1uZq4GY7MTOC8/z4PM9x98b1/EWVSI LcLg== X-Gm-Message-State: AOAM531ukhub9gth8JxOPXtl7lDHlFosJCbB/jOR3qiBj60yI2zb3IBx Sb9Hwy1RXJQXx37OYG20qJ/lDZJvRYP66IMP X-Google-Smtp-Source: ABdhPJzLskYEGh61Q1bmzT66+EJ5tonPXX6P2XUQsxQ+vahlSzMfqykV9JNJtrjrJQu6DgrU5WM1zw== X-Received: by 2002:adf:cd10:: with SMTP id w16mr9869379wrm.90.1611734638143; Wed, 27 Jan 2021 00:03:58 -0800 (PST) Received: from localhost.localdomain ([79.140.115.116]) by smtp.gmail.com with ESMTPSA id m8sm1850237wrv.37.2021.01.27.00.03.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jan 2021 00:03:57 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Junio C Hamano , Rafael Silva Subject: [PATCH v4 3/7] worktree: teach worktree_lock_reason() to gently handle main worktree Date: Wed, 27 Jan 2021 09:03:06 +0100 Message-Id: <20210127080310.89639-4-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.395.g7821b4e95a In-Reply-To: <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> References: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> <20210127080310.89639-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 Wed Jan 27 08:03:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12049251 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.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,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 410C8C433E6 for ; Wed, 27 Jan 2021 08:13:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EAA0A2074A for ; Wed, 27 Jan 2021 08:13:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234623AbhA0INF (ORCPT ); Wed, 27 Jan 2021 03:13:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234577AbhA0IEr (ORCPT ); Wed, 27 Jan 2021 03:04:47 -0500 Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E98AC061756 for ; Wed, 27 Jan 2021 00:04:07 -0800 (PST) Received: by mail-wr1-x434.google.com with SMTP id 6so906006wri.3 for ; Wed, 27 Jan 2021 00:04:07 -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=vqj6Y+/ybIFdAb+x+Qh0z9wl1WIicT2yrNJbXtx3hMQ=; b=aM1rqp7lM4YMZcHtiuztPFcXArWssRx49ZDsPSxvUTvJGtCZeZanfe9Ay/wDzsE6QH e8s+JUp4VbNNzV1sRmy2KwxrWGf8+B8zDmJj8wQ8JrxPo+ihAi7H7rtQkcm3juPSyZAd oUWy6qSN2KME1JoWpSoISV9Yr2PYqw+T07xhcs6FQ9cI9vsvO0+Uz18DavTWlZT7PbB2 jam4WZocRnAGl7lLddDzEuCV7BWGyzZfLAU71CIw2eAvp1/zBmKtZqMLiNR931iGkU1M XyuzGU06PWFRm9V+ZPh+vR2Zu6QorqUxZ6t7jMq7s6rx5fv5eKl0Rour4n7v/sk70oXp iIww== 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=vqj6Y+/ybIFdAb+x+Qh0z9wl1WIicT2yrNJbXtx3hMQ=; b=IbJYLnC0h8/xdkzH/yvNEGpTHdJvIN62qMgnaU1pcR+IboalBxs/mxPp4Mo56fPQ1G mLae5xF4tbQv0PMAN0zBU0a7jX7NwIQ1OC1l/cxCEkVkpr+GHY5s1R57WSS3wptZI/rp szdrW+gFkfd8GdselGyJEVYvcpRv/6Rfc3JIRtvkfG+0MnHh3ZfsZrT03/hsfv0scR3M HJv5V1aBe+HRjI6i/V3vfqPACknWba03GIN4ffCUEQKDJyF22YDPAmXSlKTaZQFYFffG iiJji5naNEvh7iCkGRB4Xe8yH+oJ5M17ZwnsMrOAGRB+4AZT7bqF8LjlcwrAeIeJT993 vEaA== X-Gm-Message-State: AOAM5323FTdvFq0PFcCPkR5eq7xto+t2l5lEP/Ljh+IbrKi/uYM0eAkc S2vlYr1+CbHosTdyGW2t1vEI/SQvQ1lQ6GN6 X-Google-Smtp-Source: ABdhPJw513BrPwuOd5v9nrQ4Mv+cm9wTgAHPyozEYkjjqhhHAzaX+wnRY4VGFA8rZBrWfpTzKqyIWw== X-Received: by 2002:adf:ec52:: with SMTP id w18mr9825765wrn.65.1611734645664; Wed, 27 Jan 2021 00:04:05 -0800 (PST) Received: from localhost.localdomain ([79.140.115.116]) by smtp.gmail.com with ESMTPSA id m8sm1850237wrv.37.2021.01.27.00.04.04 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jan 2021 00:04:04 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Junio C Hamano , Rafael Silva Subject: [PATCH v4 4/7] t2402: ensure locked worktree is properly cleaned up Date: Wed, 27 Jan 2021 09:03:07 +0100 Message-Id: <20210127080310.89639-5-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.395.g7821b4e95a In-Reply-To: <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> References: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org 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 rely 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 Wed Jan 27 08:03:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12049221 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.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,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 776EBC433DB for ; Wed, 27 Jan 2021 08:09:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3EC9F20724 for ; Wed, 27 Jan 2021 08:09:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234621AbhA0IJN (ORCPT ); Wed, 27 Jan 2021 03:09:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234643AbhA0IF6 (ORCPT ); Wed, 27 Jan 2021 03:05:58 -0500 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3FA27C06178B for ; Wed, 27 Jan 2021 00:04:11 -0800 (PST) Received: by mail-wr1-x436.google.com with SMTP id a9so900716wrt.5 for ; Wed, 27 Jan 2021 00:04:11 -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=YQSEliMEDBrpy36NuctS6TIVFb8YhMsxYxTwLT6cPyo=; b=chd6W4aVPBN/nu4jWQyOHBbU1/FbLAHpxkmiM2cgbV6DJzXYtLSFTF0dPBNO7C2GAC PWJF05pgfHhIQftTpkH//18r2dt1qwWEM8fg6/04eSkEDnLG1MMdoesCLwObnSbGNSUY 2XDw5bHHNaLGwOpHqQrDSv049PjSp6rR0PWALSKIgcB9977/Edrlq82TwZWbZvjSFIAN 5/nYZZb5PzPOIcA1XCuXYoitB/wGzIIqvkz8PIhYoGERypuHSdnJgS/qjJTqjO0pqKgf jI7b3Xyb5mjPY49gY/ZMez9eL1ZUNvSHZM1qB98uqNdcsKmWMBapOgl2cr/R3GnRhR4V Ca6w== 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=YQSEliMEDBrpy36NuctS6TIVFb8YhMsxYxTwLT6cPyo=; b=cfNc9nCeVrPlDvL1zQ1seZIuogXIr2gnkQL3YEaBOtqLr02iGk6f4tj3AMYV6iUzba UnZ3UjWSYg32f7wJRdkCm8miZaGCMYqErJes4Q9gyeiuhbh+aaCiP7HkkUNqKYBWg2Ah l2OcMlhUkxphyefZ3WAroyvp+ZAGQzKetPtwXGqNzRLcQplH9U2GQxvlTKzaxG6e5Y7T iPp95sgCiVVbEDAYwZCJQBNuAvaiON7KjZNmsubymuttzirS/bybxSauRUHaYuHiNjvy X9b6FEb6f7fyCJ51KiSCgbsbDL1D31nxqrp1I2PQbNqS54F2TT9RewZdhQdylHTdgUxi Vmcw== X-Gm-Message-State: AOAM530ak5lzuItAEyVPuUjRL0213GtQIKqa7PqLCkKyEHtBMJRnj8iF k9xJ7jl08wEU54uwytGQwk/s8eS0HINcpENr X-Google-Smtp-Source: ABdhPJy6h/ArF1MbfQjOVp/2cC5N9KaEGH3Slvzq+Xs2WBmLmRInEVjXtTzlzHTwbzX3/vRS76VMSQ== X-Received: by 2002:adf:decb:: with SMTP id i11mr8390896wrn.78.1611734649571; Wed, 27 Jan 2021 00:04:09 -0800 (PST) Received: from localhost.localdomain ([79.140.115.116]) by smtp.gmail.com with ESMTPSA id m8sm1850237wrv.37.2021.01.27.00.04.08 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jan 2021 00:04:08 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Junio C Hamano , Rafael Silva Subject: [PATCH v4 5/7] worktree: teach `list --porcelain` to annotate locked worktree Date: Wed, 27 Jan 2021 09:03:08 +0100 Message-Id: <20210127080310.89639-6-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.395.g7821b4e95a In-Reply-To: <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> References: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> <20210127080310.89639-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: Phillip Wood Helped-by: Eric Sunshine Signed-off-by: Rafael Silva --- Documentation/git-worktree.txt | 28 ++++++++++++++++++++++++++-- builtin/worktree.c | 13 +++++++++++++ t/t2402-worktree-list.sh | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 02a706c4c0..426e9b4f76 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,28 @@ 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 + +------------ + +If the lock reason contains "unusual" characters such as newline, they +are escaped and the entire reason is quoted as explained for the +configuration variable `core.quotePath` (see linkgit:git-config[1]). +For Example: + +------------ +$ git worktree list --porcelain +... +locked "reason\nwhy 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..39596e4aa9 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -72,6 +72,38 @@ 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 && + test_when_finished "git worktree unlock locked1" && + git worktree lock locked2 --reason "with reason" && + test_when_finished "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")" && + test_when_finished "git worktree unlock locked_lf" && + git worktree lock locked_crlf --reason "$(printf "locked\r\nreason")" && + test_when_finished "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 Wed Jan 27 08:03:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Silva X-Patchwork-Id: 12049219 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.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,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 08962C433E0 for ; Wed, 27 Jan 2021 08:09:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9D26120724 for ; Wed, 27 Jan 2021 08:09:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234551AbhA0IJE (ORCPT ); Wed, 27 Jan 2021 03:09:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234646AbhA0IF6 (ORCPT ); Wed, 27 Jan 2021 03:05:58 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0EB3C06178C for ; Wed, 27 Jan 2021 00:04:15 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id p15so886113wrq.8 for ; Wed, 27 Jan 2021 00:04:15 -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=e84ELbGj/knhNz7TB16fm016R2aWZyi/WZsxJJgA/eE=; b=md+I1D+0nhwUNxc8u/4jrQ9KFa8KIMinhcLyPHaCbG72DoSG3esp8BFqkfZvRSbIjL inaG7t55jqH57APKPlMTsfxsEv+sEj3Uo5/luodWIM3n8Qxzlr3m7PtMSnC665vx7WE1 CMLpAjj5gJLVBZfRavyvuKPmZC3Z1WI0GjRlVkQN8LZ5wwT/YfyE4SPBB6CtPfo1mcTx raGUGprWwJ07Tfw5CrIV4g8Isx6WATc19t8BKE0RzDjM8yBlcOm/CWuFcADhcYkl8lTK cR3NjGy9zD5SrLuqSm4aksI9z/Dn2SXan0WkZtMbWCc6ASkjEg5ucpAZzULy1lbzxkBv 0Ngw== 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=e84ELbGj/knhNz7TB16fm016R2aWZyi/WZsxJJgA/eE=; b=Cdmh3RCQo4qbog8ZEnUv7XaPXY4ixmzX6lHyj4g6BLfLY2hRAnNpfdLx3i/wCymGI/ Ic1M94lTKHKelJB9g1gW8wZdryWIZMB9xGJry+nb7zCl+TAYnJjXUvJuWuPPH67OE/LN AWOA2k7TFUynFTrwkj6ZsUPR0S4xfHUIFSpH0HIBHrLsAf9UAbhVQiEJB5QfRT+Lb8Qn qFYMn0VGMOGQ+3I9QDQW5y+JxjC3k0kljFdSBLVMLmKD6NVVA9yO7blFWl7mDJGwWSMp 50kwGMAZhSkjTRqkjRUm60OCHIJ8Zd2RBMqFxxP90+jhGEvfK0BuOSlI+X++YglDUVCf MhXA== X-Gm-Message-State: AOAM533im7fr5gCpmkElRl64ysF2Cr0efzGSiWsTjyvFE4eBqw8sHQRc xBGpBSk7h5c9guayYbPanDfIzvUdTndZ3XBd X-Google-Smtp-Source: ABdhPJyat1gN/QrgEOE8qyWQXpq/jDVXqg6+cL5Z8NecEe363uoeDu10tGDBsTEwgRZpi3QH5bSHyA== X-Received: by 2002:adf:e48b:: with SMTP id i11mr9975141wrm.406.1611734654344; Wed, 27 Jan 2021 00:04:14 -0800 (PST) Received: from localhost.localdomain ([79.140.115.116]) by smtp.gmail.com with ESMTPSA id m8sm1850237wrv.37.2021.01.27.00.04.13 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jan 2021 00:04:13 -0800 (PST) From: Rafael Silva To: git@vger.kernel.org Cc: Eric Sunshine , Phillip Wood , Junio C Hamano , Rafael Silva Subject: [PATCH v4 6/7] worktree: teach `list` to annotate prunable worktree Date: Wed, 27 Jan 2021 09:03:09 +0100 Message-Id: <20210127080310.89639-7-rafaeloliveira.cs@gmail.com> X-Mailer: git-send-email 2.30.0.395.g7821b4e95a In-Reply-To: <20210127080310.89639-1-rafaeloliveira.cs@gmail.com> References: <20210119212739.77882-1-rafaeloliveira.cs@gmail.com> <20210127080310.89639-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 ++++++++++ t/t2402-worktree-list.sh | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 426e9b4f76..240c3fd76b 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