From patchwork Sat Jan 1 13:50:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702082 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2013C433FE for ; Sat, 1 Jan 2022 13:51:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230343AbiAANu7 (ORCPT ); Sat, 1 Jan 2022 08:50:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229718AbiAANu6 (ORCPT ); Sat, 1 Jan 2022 08:50:58 -0500 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B66C8C061574 for ; Sat, 1 Jan 2022 05:50:58 -0800 (PST) Received: by mail-pg1-x52f.google.com with SMTP id i8so17563164pgt.13 for ; Sat, 01 Jan 2022 05:50:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SZU9dzE64Trn4rpDSIxZOxbqL+E8GnnkMdG00HpP21A=; b=qNUQnVml7wX/7iWhU2kV8MfTdPCxfYq2K2vivrbFjedRbKyGpgtdhofhE3WfIfbXnH WmLbHA5Kz07+fGxCJKc9RRR6fgdTKH4czVnWZAyxp2/8LsENEXuFcGtukTcANxel3XW3 J2vEKpi0LHophGgdqjMcly6EXkcDeA3QrRG2/sZl8+zK6LVarOTpVolremnzhBzqrXbW DEgMHrB4PRSvz6l4iia6MaIjzjxASimWhEtEORYHIIL9XpbQY/1F5rpP0j6IYAXfZCnU +HiwL46mR587Pq/Enn2pqizVoW6WoXbG4YvpxxdZJlCvWxzLiKHoZddfSqJUDr/jqWmO lXtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SZU9dzE64Trn4rpDSIxZOxbqL+E8GnnkMdG00HpP21A=; b=pSFfS/si2U5H7SzBsmS+xO1zQ6KNr/f9eyKvUjvGneHQuezxpkdyXMd0cwYNGCEkur pSmtxG4OJU2mRQPTgH3stGwyG1T3HzO9+g0NBpEcWHO7H9PDFtBCWYFgdHywdLvPbYoC FooSHC+j/wzDsQzp5if0eGiw4z/ky28oXtuaODRNFRF2eskvbWbkyHc83SQ+Qw+jo7QG C2TM4vjXw+cHHy9nCnIBPq/XrTY2ZHIdf/ZApoh1Hn+Z2G7qC9zT4ouVmyo09G0Vd3Jt 6q4/XFcDNs5C3YI43fwffmrRRpFvLFCMusPqE8nMduH0PDI+kEtsvdjgag3V/sbjH+0K C4jQ== X-Gm-Message-State: AOAM533OL9p7Wcpwq1AB8YG90AQuE5kWle/MFu2fpQeWugSH2IXLvwfk uL6knnOxe7vL7D+oUbVCpF4= X-Google-Smtp-Source: ABdhPJwdXQx312i9IWRiwYMnY0DbRTXloWTyI1P2YWj5sxx6XPSg0VPVz5K/koNb/wl9lJHRqo72Tg== X-Received: by 2002:a63:5920:: with SMTP id n32mr34562568pgb.226.1641045058277; Sat, 01 Jan 2022 05:50:58 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.50.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:50:57 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 1/8] ls-tree: remove commented-out code Date: Sat, 1 Jan 2022 21:50:24 +0800 Message-Id: <2fcff7e0d40255e0be9496647787352dd0aeb784.1641043500.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ævar Arnfjörð Bjarmason Remove code added in f35a6d3bce7 (Teach core object handling functions about gitlinks, 2007-04-09), later patched in 7d0b18a4da1 (Add output flushing before fork(), 2008-08-04), and then finally ending up in its current form in d3bee161fef (tree.c: allow read_tree_recursive() to traverse gitlink entries, 2009-01-25). All while being commented-out! Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/ls-tree.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 3a442631c7..5f7c84950c 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -69,15 +69,6 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, const char *type = blob_type; if (S_ISGITLINK(mode)) { - /* - * Maybe we want to have some recursive version here? - * - * Something similar to this incomplete example: - * - if (show_subprojects(base, baselen, pathname)) - retval = READ_TREE_RECURSIVE; - * - */ type = commit_type; } else if (S_ISDIR(mode)) { if (show_recursive(base->buf, base->len, pathname)) { From patchwork Sat Jan 1 13:50:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702084 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0193EC433F5 for ; Sat, 1 Jan 2022 13:51:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231190AbiAANvE (ORCPT ); Sat, 1 Jan 2022 08:51:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230522AbiAANvD (ORCPT ); Sat, 1 Jan 2022 08:51:03 -0500 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 41BC2C06173F for ; Sat, 1 Jan 2022 05:51:03 -0800 (PST) Received: by mail-pg1-x52d.google.com with SMTP id x194so2859107pgx.4 for ; Sat, 01 Jan 2022 05:51:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0rrIqFOKIp4y6IioSd37COY9Fb8tOnPbzYmS/OSpbyE=; b=MrNlwdvbRkIvtwd3HOU+PALdMV281Xfri7RpV5Uu7j427CyIEMqVW7nG+kqg1aPSrq lHs1oUdC4zzU7IZknVYm3YXdLqEWal8UPkMfDxPripiWIhIBIkS7DcX+748x7R/Y30Br hsQonMs2olTkXwoCz35USY0wIF/3cgDkpaRgtHzQjfH9srImFWPoIJdMvGxgmlaGlz6Y eC8AEzI0TTcpYkJu6VEIMjg/0gJvxrdO9YW936oDbQo9oKbXSMx0Y7cnRxbtPn4yyapF HNrdulUemxlUXWR0D1wJWwKKic7jZ9gnatfTWXzuv8Tn7bVX5tcIVZJIyQUNwC+YL0SC CYSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0rrIqFOKIp4y6IioSd37COY9Fb8tOnPbzYmS/OSpbyE=; b=hnF+czGyFn7zbwEBwcewBF+awBLGPnRHwb7/Ue680KvolSqsVJtfOyNkjKZLviClYh kA0fFl5CMV+nBMzWrqTINGDDYS/VYYeb2HU1vUK7vp1jLWCkGVw2qwmZl0dJYD5591Vo DQLzPMf1XmQ4Pt4L1chsF/eBfV5E7BAY49LAo0NPNriuCqWAwYlxwW6ot3TKeBljmZgV ippYqfEuIv6+76k0QVKlS8yrRf8wET+6+CFdabhnZr3t25i/yAabRSX4ig7IvFe5uQcM j9O1/RaP+2CH63RuPZdmTQAYg6XaQBRXBLYcfm73x0kbk3bAJ47ZtQ0ZQ/Chclgyetmc H/sA== X-Gm-Message-State: AOAM533CdweRpUjaxdPg120pEdfbOY08Pmv1lFmw3XrMS3gJwSf/i24H lydymonL3evhTh59ZEqzi4vgGmg20j4iGpiAcoc= X-Google-Smtp-Source: ABdhPJyvn0qU2dmr9nETYw/ClOBv52xJv0CVuIkH7emIbkcH9aBBEz2D79AEUeatSfRfmG2zWD6HXg== X-Received: by 2002:a63:8f50:: with SMTP id r16mr29633100pgn.478.1641045062456; Sat, 01 Jan 2022 05:51:02 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.50.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:02 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 2/8] ls-tree: add missing braces to "else" arms Date: Sat, 1 Jan 2022 21:50:25 +0800 Message-Id: <6fd1dd938303192d5b0a4cdc2914b2ff72cf5a3d.1641043500.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ævar Arnfjörð Bjarmason Add missing {} to the "else" arms in show_tree() per the CodingGuidelines. Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/ls-tree.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 5f7c84950c..0a28f32ccb 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -92,14 +92,16 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, else xsnprintf(size_text, sizeof(size_text), "%"PRIuMAX, (uintmax_t)size); - } else + } else { xsnprintf(size_text, sizeof(size_text), "-"); + } printf("%06o %s %s %7s\t", mode, type, find_unique_abbrev(oid, abbrev), size_text); - } else + } else { printf("%06o %s %s\t", mode, type, find_unique_abbrev(oid, abbrev)); + } } baselen = base->len; strbuf_addstr(base, pathname); From patchwork Sat Jan 1 13:50:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702085 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9060C433F5 for ; Sat, 1 Jan 2022 13:51:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231467AbiAANvJ (ORCPT ); Sat, 1 Jan 2022 08:51:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230522AbiAANvH (ORCPT ); Sat, 1 Jan 2022 08:51:07 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D3E0C06173E for ; Sat, 1 Jan 2022 05:51:07 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id f18-20020a17090aa79200b001ad9cb23022so27905837pjq.4 for ; Sat, 01 Jan 2022 05:51:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=GUvYzVB4cQw1FLm5YyU7PNKurJ532d3yDoFS0YyM2ig=; b=QZnfdFnA4te/cEMR5ZXe9QuM/ajOxVSAJ3vWjgr3b5nka08f7ZavghqLintg3O6L/7 IqUVy/trVhO8wAC4oECuLTJi3PHKmmhCtcIkHxUAKifKUOMBiOrRqMEuqpDWa2HndzTL D3Ow6y7lEPB6rK02uri1Kg35dxo5+EFy0SlBiA7SguPQb3OlUfjdTEjlCnsb9ZLonVjP E82nmuKDd2mw6AjEb9llXMxQ0aMxj1CVOimQLE4lXbrOaF/foszHpV2MJ8Kt8SD8ghLT IIPaUtXee8k9mD7v8NzTdrcopZwltPGNITwIYpYwNFTfArQKljO19PN3csGVR0awljor T2DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GUvYzVB4cQw1FLm5YyU7PNKurJ532d3yDoFS0YyM2ig=; b=i0fJXe1DuaVagMV44l4C2FIqSa6kxB6WnkBrLCbZojlY9O7hrikeTUG8lTAnfG2dXP 9LGNVs7HIG1yLXmI3K013pHiNF80BPErMv15jYa6YGTseUvwkHZLYZx81KSm8uIJKu3x 78sh2K1u+mK9B1D3D1X4UzhQLjvSwJdtTqiXbYBHDFQymLItqjlgw73/upvqC+ie2yE0 /g6cSzOc3kxCW3iqoFSF/8+A53pd+PNkW5/lszM6eHnB64F8rZ9KJhO7o27kkLIKsZop Gs5BwHPUXa0RI1oCdjJfNzY49hoPQACi1rbpTYXd4ex4xLK2+C50Y+MCRqd/fsdYDalc ADEg== X-Gm-Message-State: AOAM530VGZrf6bt/Z2ERV0c/rY272u3Tqx+0JFaA5/uyfA8KrFOc/CN1 9M/LnAPiVmTSmScEkcUZJOE= X-Google-Smtp-Source: ABdhPJz1bsdln2lUbscuVVesOEu8p9IIPrncW8+tBFo2d0jNWnY0kMvr4J9ijamaQM2l/3RahOT09A== X-Received: by 2002:a17:90b:3889:: with SMTP id mu9mr41607218pjb.215.1641045066645; Sat, 01 Jan 2022 05:51:06 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.51.03 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:06 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 3/8] ls-tree: use "enum object_type", not {blob,tree,commit}_type Date: Sat, 1 Jan 2022 21:50:26 +0800 Message-Id: <208654b5e2aebbe988b5a8f478869253a0166e9b.1641043500.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ævar Arnfjörð Bjarmason Change the ls-tree.c code to use type_name() on the enum instead of using the string constants. This doesn't matter either way for performance, but makes this a bit easier to read as we'll no longer need a strcmp() here. Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/ls-tree.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 0a28f32ccb..3f0225b097 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -66,17 +66,17 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, { int retval = 0; int baselen; - const char *type = blob_type; + enum object_type type = OBJ_BLOB; if (S_ISGITLINK(mode)) { - type = commit_type; + type = OBJ_COMMIT; } else if (S_ISDIR(mode)) { if (show_recursive(base->buf, base->len, pathname)) { retval = READ_TREE_RECURSIVE; if (!(ls_options & LS_SHOW_TREES)) return retval; } - type = tree_type; + type = OBJ_TREE; } else if (ls_options & LS_TREE_ONLY) return 0; @@ -84,7 +84,7 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, if (!(ls_options & LS_NAME_ONLY)) { if (ls_options & LS_SHOW_SIZE) { char size_text[24]; - if (!strcmp(type, blob_type)) { + if (type == OBJ_BLOB) { unsigned long size; if (oid_object_info(the_repository, oid, &size) == OBJ_BAD) xsnprintf(size_text, sizeof(size_text), @@ -95,11 +95,11 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, } else { xsnprintf(size_text, sizeof(size_text), "-"); } - printf("%06o %s %s %7s\t", mode, type, + printf("%06o %s %s %7s\t", mode, type_name(type), find_unique_abbrev(oid, abbrev), size_text); } else { - printf("%06o %s %s\t", mode, type, + printf("%06o %s %s\t", mode, type_name(type), find_unique_abbrev(oid, abbrev)); } } From patchwork Sat Jan 1 13:50:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702086 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97007C433F5 for ; Sat, 1 Jan 2022 13:51:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231355AbiAANvL (ORCPT ); Sat, 1 Jan 2022 08:51:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231214AbiAANvL (ORCPT ); Sat, 1 Jan 2022 08:51:11 -0500 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EEA1EC06173E for ; Sat, 1 Jan 2022 05:51:10 -0800 (PST) Received: by mail-pj1-x102d.google.com with SMTP id f18-20020a17090aa79200b001ad9cb23022so27905916pjq.4 for ; Sat, 01 Jan 2022 05:51:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QWcu7CCENPShF+BVcZHyonlcE44FDHbDsXvHqum5v4w=; b=VRtHbqzjh4otSnSjdMGUT5DNzQt31lkpQ//3ydwqp8VdU4vVptXIme8gJkUjAPUwYa tGBKvyx67BlOm7+dvroyqoIEpxYLUQ9wyBY8DLJkqhrZ25vpF78Wci01TlqwLV89T402 rwe5jlkKOSyLDKEgPPFVnx/j1pnRi4lindJ8Ec7I7wG/5qpOxDpSvMeKCTJYsq9fl/Dt CjkV9NTNc3HHa6bvBGT6nPIQzFlyh0LpLZYIYAX+FnGGvbOyDOVxzlKYxgGGOEBaPrLk nrb/vucbMWgNcZXqWnruwIaXqf7ZmIe5lHaXV4i0bagSjT4q3We9wsn8CEAjbq/xb48h nKcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QWcu7CCENPShF+BVcZHyonlcE44FDHbDsXvHqum5v4w=; b=jO/9aGWGnTPKpbyQ3op29JxsjQGyUHXsk/v7oRDu1yHG1qNzVkJATIEtsJehgqm6GI mSgmEunyX3WZ8wLEASCyyjiZEaL4lNhnjGCY4e6RlXjitAe0Sx3t8rYsByElEjHTIf4F 6o0ApcKtGW969/lhABslXS6Lk7kI6yiu42g/X9N4noBezQS3GivIQHjwfPzEKwo8E3M0 kj4G6jxh7rn9AtXHdwWVgxkmGjoE01TVxFDFhFyAJ1169xWO3wd+ODJgrfs3AjFUeQrv 4bPrIENQoLUUyKXLzQ5rZKjbdJkuVkTC/FiFV1UcbFjn/KmMnySQnFVW2YaaKn82YW4R PzMQ== X-Gm-Message-State: AOAM532wVS6Hyg6PKCidHYJNTRkoQBYwQ0369Fr04qwlha99rBU4aqIj Ka7RJ247iMIptWmG+5csKpE= X-Google-Smtp-Source: ABdhPJyxowUgkIHc0MPUWxkgAbAP5RyvzXeI+Eqw8FLNGBcdX11cRy7kd4CZlGc0Rvtu1puXJCrfSQ== X-Received: by 2002:a17:902:ab97:b0:149:8662:1736 with SMTP id f23-20020a170902ab9700b0014986621736mr24385681plr.174.1641045070485; Sat, 01 Jan 2022 05:51:10 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.51.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:10 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 4/8] ls-tree: use "size_t", not "int" for "struct strbuf"'s "len" Date: Sat, 1 Jan 2022 21:50:27 +0800 Message-Id: <2637464fd8f6b8bae6c681f20c10c9fc76dc6d6c.1641043500.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ævar Arnfjörð Bjarmason The "struct strbuf"'s "len" member is a "size_t", not an "int", so let's change our corresponding types accordingly. This also changes the "len" and "speclen" variables, which are likewise used to store the return value of strlen(), which returns "size_t", not "int". Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/ls-tree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 3f0225b097..eecc7482d5 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -31,7 +31,7 @@ static const char * const ls_tree_usage[] = { NULL }; -static int show_recursive(const char *base, int baselen, const char *pathname) +static int show_recursive(const char *base, size_t baselen, const char *pathname) { int i; @@ -43,7 +43,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname) for (i = 0; i < pathspec.nr; i++) { const char *spec = pathspec.items[i].match; - int len, speclen; + size_t len, speclen; if (strncmp(base, spec, baselen)) continue; @@ -65,7 +65,7 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, void *context) { int retval = 0; - int baselen; + size_t baselen; enum object_type type = OBJ_BLOB; if (S_ISGITLINK(mode)) { From patchwork Sat Jan 1 13:50:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702087 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CFFF4C433F5 for ; Sat, 1 Jan 2022 13:51:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231408AbiAANvR (ORCPT ); Sat, 1 Jan 2022 08:51:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232142AbiAANvQ (ORCPT ); Sat, 1 Jan 2022 08:51:16 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8ABBCC06175D for ; Sat, 1 Jan 2022 05:51:15 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id r16-20020a17090a0ad000b001b276aa3aabso19918129pje.0 for ; Sat, 01 Jan 2022 05:51:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5Jkle+8PPnnCZO2+XSpU2oCcYHIXVfKN6K1rnLZUPTA=; b=gZnc5FYn22AUKKGT9eJn5mWoueGS7qjElmmlkUVRAWxFDLvBx/VnBLJTUd/A1VIeT2 QTwo+Wqgn507y09vBLCKCddYitd5q5opPeATau9CIpeYJWx3EFoEm9QPAOoDTo3u5dx9 0Ec7gW7awsqDCy57x8vS3aMpgacF5mwbv09W7LwW5UCgbS7lzTAmWjCbTSoeJuVQRDkQ ii9E4QS3EZKIn1g9nLVMjSF/2OOKXUICHyX/yxlkIcNDxIN74oIYBCn6aWy8GpaOv2t3 jA9ndAUS40KFPDwF7r+I8KrSh5KEdSlyUHMZnnq1WzQ7WX3kAsAb+A3bvBX1BeyCMp7y Y1xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5Jkle+8PPnnCZO2+XSpU2oCcYHIXVfKN6K1rnLZUPTA=; b=dHXi64iXZT+iVcYJcn3BLyE9t5bphx3mY1xexZToO3nS8sxyjae+Bq5Js8PMLmTUxh 3rpz3hBlTQVQYqNZIoasDpACvcMJcnkSlJoCHH+sCRpk/X5cPooEbvHnK0lYwa+/H7nC +vCISDk5O7VibrUjjUnfurbRdZ5+kUGBLuT7Xx7pMfG+WXap3GXY9y35hoAiLMwBgsqr pqsF6gxXAOU8KmD9T6D52DWvukJVZhUIsCHYOKeYuvCSmyrswwkFciQ1+qPf68weRK5R 1povrJIUoNDwHBnHYuK2iSWu2llcX71WHr6JHWPvU91ORIy0q5khH76qpnoMKex1XUXX XrLw== X-Gm-Message-State: AOAM530LhWWxxYe2f4jS0LEZvv4PPCcpWT5QIcfgH5BXJiOleiP9seNr D7srOyHrojg3rThkJb0Fj89XZ7MUVMva9/IyDCM= X-Google-Smtp-Source: ABdhPJxe/+lBXgrFPiwiAvU8CidlxucWRMYidT1EA692obBfPYzlUN0oRtEc3vpkDta1YqgaE007VQ== X-Received: by 2002:a17:90b:1bc7:: with SMTP id oa7mr47188214pjb.200.1641045075087; Sat, 01 Jan 2022 05:51:15 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.51.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:14 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 5/8] ls-tree: split up the "init" part of show_tree() Date: Sat, 1 Jan 2022 21:50:28 +0800 Message-Id: X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ævar Arnfjörð Bjarmason Split up the "init" part of the show_tree() function where we decide what the "type" is, and whether we'll return early. This makes things a bit less readable for now, but we'll soon re-use this in a sibling function, and avoiding the duplication will be worth it. Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/ls-tree.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index eecc7482d5..df8312408d 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -61,25 +61,33 @@ static int show_recursive(const char *base, size_t baselen, const char *pathname return 0; } -static int show_tree(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, void *context) +static int show_tree_init(enum object_type *type, struct strbuf *base, + const char *pathname, unsigned mode, int *retval) { - int retval = 0; - size_t baselen; - enum object_type type = OBJ_BLOB; - if (S_ISGITLINK(mode)) { - type = OBJ_COMMIT; + *type = OBJ_COMMIT; } else if (S_ISDIR(mode)) { if (show_recursive(base->buf, base->len, pathname)) { - retval = READ_TREE_RECURSIVE; + *retval = READ_TREE_RECURSIVE; if (!(ls_options & LS_SHOW_TREES)) - return retval; + return 1; } - type = OBJ_TREE; + *type = OBJ_TREE; } else if (ls_options & LS_TREE_ONLY) - return 0; + return 1; + return 0; +} + +static int show_tree(const struct object_id *oid, struct strbuf *base, + const char *pathname, unsigned mode, void *context) +{ + int retval = 0; + size_t baselen; + enum object_type type = OBJ_BLOB; + + if (show_tree_init(&type, base, pathname, mode, &retval)) + return retval; if (!(ls_options & LS_NAME_ONLY)) { if (ls_options & LS_SHOW_SIZE) { From patchwork Sat Jan 1 13:50:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702088 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03640C433F5 for ; Sat, 1 Jan 2022 13:51:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231522AbiAANvV (ORCPT ); Sat, 1 Jan 2022 08:51:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60044 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232055AbiAANvT (ORCPT ); Sat, 1 Jan 2022 08:51:19 -0500 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98365C06173F for ; Sat, 1 Jan 2022 05:51:19 -0800 (PST) Received: by mail-pj1-x102d.google.com with SMTP id rj2-20020a17090b3e8200b001b1944bad25so27904182pjb.5 for ; Sat, 01 Jan 2022 05:51:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9bsDwJKemLHpNGpJvG7WBeekTir58bZnA7PGch/YEpc=; b=EA19XTUG6lz5fs+f+4P9nCAkEMWBAmBFw8IVnNqN8rVEm6OCkzs+NzAtMsxhIJ8pO/ 8ti+ieaPnbNDYonX1Sdj1jiiwGkS9VVXtATa9iMcrLARiz7JE6ar/Pq1H1FIJpdYvEBb t6FiN1jxTS/vWX9f9ePycORlIlUueXm1hZCt5JukIvPk93mkm3sW7T4uQ5qQGWOwTygC wzGii4SyzFLjxp6mXIdd9TIv0eyrkx7BRo16AdhAPcdDkX0hOPS3PTmxUkryoOYU+rzC dWyDMD9Nie2SpIv2vplMzLflBrnxSg6gVs8t9uM1YTncaCBBxkMcHV1r7tj2Lk7sWvys Zn1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9bsDwJKemLHpNGpJvG7WBeekTir58bZnA7PGch/YEpc=; b=z9Tug2HuthSDkC+PfbfbzcFItb6tuFoS9RDjAhXlODIyi7nkCZd7StoGCd/ZU9VUlx TMI9JnVyyvZZnFlEx1+2o//sZ9YB+PzpS9HDJrFUFXw6daX5dllozsEd5GolsmvEE3Df RjO9hBs/6w0ZUIlhgfaCMKJOdEJLYrRGdyAHlzOlzkrrQlEi0/UdG7PASe4AG22noh8l wwpVDk9S7SmaHDvBJh3aE4Hdh3XTih/aO3Dv5gYT/UfUPIyiJqN9mQWHkehK1WUDS32k Jgy75JBsyyratUD7i1FoopkhoTaFGHNA2RzJ9RsYzEJl1CSt0kVDxL4/sRKHB/G8twOJ soPg== X-Gm-Message-State: AOAM5334vnR11igUkCappJMzNvCjdDN/9guRfh+ECXgGWvBXH/xAQ68h T2a718WIIUKaxW9YXoblqs4= X-Google-Smtp-Source: ABdhPJwXCupJ4dlyBKCEw70UabJ38oi3RieOsmC/vISC4g6hjWJ3KbNO1MChOI7Bm5b+YPqbcRh4Jw== X-Received: by 2002:a17:90b:4c89:: with SMTP id my9mr45093751pjb.152.1641045078889; Sat, 01 Jan 2022 05:51:18 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.51.15 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:18 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 6/8] ls-tree.c: support --object-only option for "git-ls-tree" Date: Sat, 1 Jan 2022 21:50:29 +0800 Message-Id: X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org We usually pipe the output from `git ls-trees` to tools like `sed` or `cut` when we only want to extract some fields. When we want only the pathname component, we can pass `--name-only` option to omit such a pipeline, but there are no options for extracting other fields. Teach the "--object-only" option to the command to only show the object name. This option cannot be used together with "--name-only" or "--long" , they are mutually exclusive (actually "--name-only" and "--long" can be combined together before, this commit by the way fix this bug). A simple refactoring was done to the "show_tree" function, intead by using bitwise operations to recognize the format for printing to stdout. The reason for doing this is that we don't want to increase the readability difficulty with the addition of "-object-only", making this part of the logic easier to read and expand. In terms of performance, there is no loss comparing to the "master" (2ae0a9cb8298185a94e5998086f380a355dd8907), here are the results of the performance tests in my environment based on linux repository: $hyperfine --warmup=10 "/opt/git/master/bin/git ls-tree -r HEAD" Benchmark 1: /opt/git/master/bin/git ls-tree -r HEAD Time (mean ± σ): 105.8 ms ± 2.7 ms [User: 85.7 ms, System: 20.0 ms] Range (min … max): 101.5 ms … 111.3 ms 28 runs $hyperfine --warmup=10 "/opt/git/ls-tree-oid-only/bin/git ls-tree -r HEAD" Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r HEAD Time (mean ± σ): 105.0 ms ± 3.0 ms [User: 83.7 ms, System: 21.2 ms] Range (min … max): 99.3 ms … 109.5 ms 27 runs $hyperfine --warmup=10 "/opt/git/master/bin/git ls-tree -r -l HEAD" Benchmark 1: /opt/git/master/bin/git ls-tree -r -l HEAD Time (mean ± σ): 337.4 ms ± 10.9 ms [User: 308.3 ms, System: 29.0 ms] Range (min … max): 323.0 ms … 355.0 ms 10 runs $hyperfine --warmup=10 "/opt/git/ls-tree-oid-only/bin/git ls-tree -r -l HEAD" Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r -l HEAD Time (mean ± σ): 337.6 ms ± 6.2 ms [User: 309.4 ms, System: 28.1 ms] Range (min … max): 330.4 ms … 349.9 ms 10 runs Signed-off-by: Teng Long --- Documentation/git-ls-tree.txt | 7 +- builtin/ls-tree.c | 140 +++++++++++++++++++++++++--------- t/t3104-ls-tree-oid.sh | 51 +++++++++++++ 3 files changed, 159 insertions(+), 39 deletions(-) create mode 100755 t/t3104-ls-tree-oid.sh diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index db02d6d79a..729370f235 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git ls-tree' [-d] [-r] [-t] [-l] [-z] - [--name-only] [--name-status] [--full-name] [--full-tree] [--abbrev[=]] + [--name-only] [--name-status] [--object-only] [--full-name] [--full-tree] [--abbrev[=]] [...] DESCRIPTION @@ -59,6 +59,11 @@ OPTIONS --name-only:: --name-status:: List only filenames (instead of the "long" output), one per line. + Cannot be combined with `--object-only`. + +--object-only:: + List only names of the objects, one per line. Cannot be combined + with `--name-only` or `--name-status`. --abbrev[=]:: Instead of showing the full 40-byte hexadecimal object diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index df8312408d..85ca7358ba 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -16,22 +16,59 @@ static int line_termination = '\n'; #define LS_RECURSIVE 1 -#define LS_TREE_ONLY 2 -#define LS_SHOW_TREES 4 -#define LS_NAME_ONLY 8 -#define LS_SHOW_SIZE 16 +#define LS_TREE_ONLY (1 << 1) +#define LS_SHOW_TREES (1 << 2) +#define LS_NAME_ONLY (1 << 3) +#define LS_SHOW_SIZE (1 << 4) +#define LS_OBJECT_ONLY (1 << 5) static int abbrev; static int ls_options; static struct pathspec pathspec; static int chomp_prefix; static const char *ls_tree_prefix; +static unsigned int shown_bits; +#define SHOW_FILE_NAME 1 +#define SHOW_SIZE (1 << 1) +#define SHOW_OBJECT_NAME (1 << 2) +#define SHOW_TYPE (1 << 3) +#define SHOW_MODE (1 << 4) +#define SHOW_DEFAULT 29 /* 11101 size is not shown to output by default */ static const char * const ls_tree_usage[] = { N_("git ls-tree [] [...]"), NULL }; -static int show_recursive(const char *base, size_t baselen, const char *pathname) +enum { + MODE_UNSPECIFIED = 0, + MODE_NAME_ONLY, + MODE_OBJECT_ONLY, + MODE_LONG, +}; + +static int cmdmode = MODE_UNSPECIFIED; + +static int parse_shown_fields(void) +{ + if (cmdmode == MODE_NAME_ONLY) { + shown_bits = SHOW_FILE_NAME; + return 0; + } + if (cmdmode == MODE_OBJECT_ONLY) { + shown_bits = SHOW_OBJECT_NAME; + return 0; + } + if (!ls_options || (ls_options & LS_RECURSIVE) + || (ls_options & LS_SHOW_TREES) + || (ls_options & LS_TREE_ONLY)) + shown_bits = SHOW_DEFAULT; + if (cmdmode == MODE_LONG) + shown_bits = SHOW_DEFAULT | SHOW_SIZE; + return 1; +} + +static int show_recursive(const char *base, size_t baselen, + const char *pathname) { int i; @@ -61,6 +98,39 @@ static int show_recursive(const char *base, size_t baselen, const char *pathname return 0; } +static int show_default(const struct object_id *oid, enum object_type type, + const char *pathname, unsigned mode, + struct strbuf *base) +{ + size_t baselen = base->len; + + if (shown_bits & SHOW_SIZE) { + char size_text[24]; + if (type == OBJ_BLOB) { + unsigned long size; + if (oid_object_info(the_repository, oid, &size) == OBJ_BAD) + xsnprintf(size_text, sizeof(size_text), "BAD"); + else + xsnprintf(size_text, sizeof(size_text), + "%" PRIuMAX, (uintmax_t)size); + } else { + xsnprintf(size_text, sizeof(size_text), "-"); + } + printf("%06o %s %s %7s\t", mode, type_name(type), + find_unique_abbrev(oid, abbrev), size_text); + } else { + printf("%06o %s %s\t", mode, type_name(type), + find_unique_abbrev(oid, abbrev)); + } + baselen = base->len; + strbuf_addstr(base, pathname); + write_name_quoted_relative(base->buf, + chomp_prefix ? ls_tree_prefix : NULL, stdout, + line_termination); + strbuf_setlen(base, baselen); + return 1; +} + static int show_tree_init(enum object_type *type, struct strbuf *base, const char *pathname, unsigned mode, int *retval) { @@ -89,34 +159,24 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, if (show_tree_init(&type, base, pathname, mode, &retval)) return retval; - if (!(ls_options & LS_NAME_ONLY)) { - if (ls_options & LS_SHOW_SIZE) { - char size_text[24]; - if (type == OBJ_BLOB) { - unsigned long size; - if (oid_object_info(the_repository, oid, &size) == OBJ_BAD) - xsnprintf(size_text, sizeof(size_text), - "BAD"); - else - xsnprintf(size_text, sizeof(size_text), - "%"PRIuMAX, (uintmax_t)size); - } else { - xsnprintf(size_text, sizeof(size_text), "-"); - } - printf("%06o %s %s %7s\t", mode, type_name(type), - find_unique_abbrev(oid, abbrev), - size_text); - } else { - printf("%06o %s %s\t", mode, type_name(type), - find_unique_abbrev(oid, abbrev)); - } + if (!(shown_bits ^ SHOW_OBJECT_NAME)) { + printf("%s%c", find_unique_abbrev(oid, abbrev), line_termination); + return retval; } - baselen = base->len; - strbuf_addstr(base, pathname); - write_name_quoted_relative(base->buf, - chomp_prefix ? ls_tree_prefix : NULL, - stdout, line_termination); - strbuf_setlen(base, baselen); + + if (!(shown_bits ^ SHOW_FILE_NAME)) { + baselen = base->len; + strbuf_addstr(base, pathname); + write_name_quoted_relative(base->buf, + chomp_prefix ? ls_tree_prefix : NULL, + stdout, line_termination); + strbuf_setlen(base, baselen); + } + + if (!(shown_bits ^ SHOW_DEFAULT) || + !(shown_bits ^ (SHOW_DEFAULT | SHOW_SIZE))) + show_default(oid, type, pathname, mode, base); + return retval; } @@ -134,12 +194,14 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) LS_SHOW_TREES), OPT_SET_INT('z', NULL, &line_termination, N_("terminate entries with NUL byte"), 0), - OPT_BIT('l', "long", &ls_options, N_("include object size"), - LS_SHOW_SIZE), - OPT_BIT(0, "name-only", &ls_options, N_("list only filenames"), - LS_NAME_ONLY), - OPT_BIT(0, "name-status", &ls_options, N_("list only filenames"), - LS_NAME_ONLY), + OPT_CMDMODE('l', "long", &cmdmode, N_("include object size"), + MODE_LONG), + OPT_CMDMODE(0, "name-only", &cmdmode, N_("list only filenames"), + MODE_NAME_ONLY), + OPT_CMDMODE(0, "name-status", &cmdmode, N_("list only filenames"), + MODE_NAME_ONLY), + OPT_CMDMODE(0, "object-only", &cmdmode, N_("list only objects"), + MODE_OBJECT_ONLY), OPT_SET_INT(0, "full-name", &chomp_prefix, N_("use full path names"), 0), OPT_BOOL(0, "full-tree", &full_tree, @@ -170,6 +232,8 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) if (get_oid(argv[0], &oid)) die("Not a valid object name %s", argv[0]); + parse_shown_fields(); + /* * show_recursive() rolls its own matching code and is * generally ignorant of 'struct pathspec'. The magic mask diff --git a/t/t3104-ls-tree-oid.sh b/t/t3104-ls-tree-oid.sh new file mode 100755 index 0000000000..6ce62bd769 --- /dev/null +++ b/t/t3104-ls-tree-oid.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +test_description='git ls-tree objects handling.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit A && + test_commit B && + mkdir -p C && + test_commit C/D.txt && + find *.txt path* \( -type f -o -type l \) -print | + xargs git update-index --add && + tree=$(git write-tree) && + echo $tree +' + +test_expect_success 'usage: --object-only' ' + git ls-tree --object-only $tree >current && + git ls-tree $tree >result && + cut -f1 result | cut -d " " -f3 >expected && + test_cmp current expected +' + +test_expect_success 'usage: --object-only with -r' ' + git ls-tree --object-only -r $tree >current && + git ls-tree -r $tree >result && + cut -f1 result | cut -d " " -f3 >expected && + test_cmp current expected +' + +test_expect_success 'usage: --object-only with --abbrev' ' + git ls-tree --object-only --abbrev=6 $tree >current && + git ls-tree --abbrev=6 $tree >result && + cut -f1 result | cut -d " " -f3 >expected && + test_cmp current expected +' + +test_expect_success 'usage: incompatible options: --name-only with --object-only' ' + test_expect_code 129 git ls-tree --object-only --name-only $tree +' + +test_expect_success 'usage: incompatible options: --name-status with --object-only' ' + test_expect_code 129 git ls-tree --object-only --name-status $tree +' + +test_expect_success 'usage: incompatible options: --long with --object-only' ' + test_expect_code 129 git ls-tree --object-only --long $tree +' + +test_done From patchwork Sat Jan 1 13:50:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702089 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0538C433F5 for ; Sat, 1 Jan 2022 13:51:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231562AbiAANvZ (ORCPT ); Sat, 1 Jan 2022 08:51:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231684AbiAANvX (ORCPT ); Sat, 1 Jan 2022 08:51:23 -0500 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59A96C061574 for ; Sat, 1 Jan 2022 05:51:23 -0800 (PST) Received: by mail-pf1-x42d.google.com with SMTP id 8so25684275pfo.4 for ; Sat, 01 Jan 2022 05:51:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5DcCLwX270d0k6rHYX3DZA8+GHP4G0iWpIVSGR+q9Xo=; b=EuivUkGxgEyfe60c41P9psO9q21B/YaRWb5yvtZDiir77kSlvrtxLWlVVJ8J9dfW/E T1QC4P4QvPusN8mLGmxxXXCNb6CefxAMe1EWuiznVkmA21NZA0Y4zyRT48XpaHVjDCMK OVJW+GDlJ6+d3enWi8njlRp8K2uTLcwCj0FmFvuNoINc3vcV/pPT2zso3mx5oMYR5CI3 VmWfQWzZMJkGnxXmIV52WIWMOg8vAo2rXzvJQ27SAkxpn26EvARFbs7C5OpEBnc5Oq3q 5Qawq/KUfEKZpxchq3QqifgiFHPfoeCMD0NaHl6DBazfc01lik8kpwM8O4M8s1NhuigB 93MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5DcCLwX270d0k6rHYX3DZA8+GHP4G0iWpIVSGR+q9Xo=; b=XAprimuMgA1sRmQFREAk4Fr1VU1Ei5yS+Z/jQBg/gl9z+6UoDDTQaa+BneuIz0wWoI 5hoYSkPToyqAnqPdTAzUFu0C8vJ75BLAzZWiiPppUI1pTk/ahTR2H+bPeLcRIaJKpDcn 2H8CUtFoZHTXFzwmimmAzv8LhQM4onzg1ZUQZGG/e7TLLQtGQ/0DA41vHzfv4fs2UP0I ssjLrxApZhgqDRsNrqxGF7N9aF0I/O0aiI6gTF4iOgpSIzuujx7xRkSS8Rny/nQxbGNv 3dbh3+r5sg6e0yror/OchHt+YuxMqewq9fn/fIr5tFulck9RQzPteWM++b2SWaQs8ooE 2oFQ== X-Gm-Message-State: AOAM532zLZLHX27XaJeojwCkQi7FFXOfmCUMHT7Q+f3/GddOPcY/pQ4s YOobDdCn+Nl8vJqNHQE6q1g= X-Google-Smtp-Source: ABdhPJzuu2uifwvDVZ7MwHbuc0xs2s+cHQYl9ZUB7bqw6uZU4dQaursXhvEqaFfhsTLUDshdkSGK4w== X-Received: by 2002:a63:413:: with SMTP id 19mr34551659pge.382.1641045082492; Sat, 01 Jan 2022 05:51:22 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.51.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:22 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 7/8] ls-tree.c: introduce struct "shown_data" Date: Sat, 1 Jan 2022 21:50:30 +0800 Message-Id: <296ebacafe4d40ffc5282aebb9fee972866c4ccc.1641043500.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org "show_data" is a struct that packages the necessary fields for reusing. This commit is a front-loaded commit for support "--format" argument and does not affect any existing functionality. Signed-off-by: Teng Long --- builtin/ls-tree.c | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 85ca7358ba..009ffeb15d 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -34,6 +34,14 @@ static unsigned int shown_bits; #define SHOW_MODE (1 << 4) #define SHOW_DEFAULT 29 /* 11101 size is not shown to output by default */ +struct shown_data { + unsigned mode; + enum object_type type; + const struct object_id *oid; + const char *pathname; + struct strbuf *base; +}; + static const char * const ls_tree_usage[] = { N_("git ls-tree [] [...]"), NULL @@ -98,17 +106,15 @@ static int show_recursive(const char *base, size_t baselen, return 0; } -static int show_default(const struct object_id *oid, enum object_type type, - const char *pathname, unsigned mode, - struct strbuf *base) +static int show_default(struct shown_data *data) { - size_t baselen = base->len; + size_t baselen = data->base->len; if (shown_bits & SHOW_SIZE) { char size_text[24]; - if (type == OBJ_BLOB) { + if (data->type == OBJ_BLOB) { unsigned long size; - if (oid_object_info(the_repository, oid, &size) == OBJ_BAD) + if (oid_object_info(the_repository, data->oid, &size) == OBJ_BAD) xsnprintf(size_text, sizeof(size_text), "BAD"); else xsnprintf(size_text, sizeof(size_text), @@ -116,18 +122,18 @@ static int show_default(const struct object_id *oid, enum object_type type, } else { xsnprintf(size_text, sizeof(size_text), "-"); } - printf("%06o %s %s %7s\t", mode, type_name(type), - find_unique_abbrev(oid, abbrev), size_text); + printf("%06o %s %s %7s\t", data->mode, type_name(data->type), + find_unique_abbrev(data->oid, abbrev), size_text); } else { - printf("%06o %s %s\t", mode, type_name(type), - find_unique_abbrev(oid, abbrev)); + printf("%06o %s %s\t", data->mode, type_name(data->type), + find_unique_abbrev(data->oid, abbrev)); } - baselen = base->len; - strbuf_addstr(base, pathname); - write_name_quoted_relative(base->buf, + baselen = data->base->len; + strbuf_addstr(data->base, data->pathname); + write_name_quoted_relative(data->base->buf, chomp_prefix ? ls_tree_prefix : NULL, stdout, line_termination); - strbuf_setlen(base, baselen); + strbuf_setlen(data->base, baselen); return 1; } @@ -154,11 +160,16 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, { int retval = 0; size_t baselen; - enum object_type type = OBJ_BLOB; + struct shown_data data = { + .mode = mode, + .type = OBJ_BLOB, + .oid = oid, + .pathname = pathname, + .base = base, + }; - if (show_tree_init(&type, base, pathname, mode, &retval)) + if (show_tree_init(&data.type, base, pathname, mode, &retval)) return retval; - if (!(shown_bits ^ SHOW_OBJECT_NAME)) { printf("%s%c", find_unique_abbrev(oid, abbrev), line_termination); return retval; @@ -175,7 +186,7 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, if (!(shown_bits ^ SHOW_DEFAULT) || !(shown_bits ^ (SHOW_DEFAULT | SHOW_SIZE))) - show_default(oid, type, pathname, mode, base); + show_default(&data); return retval; } From patchwork Sat Jan 1 13:50:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 12702090 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 30AFCC433F5 for ; Sat, 1 Jan 2022 13:51:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232148AbiAANvc (ORCPT ); Sat, 1 Jan 2022 08:51:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232166AbiAANva (ORCPT ); Sat, 1 Jan 2022 08:51:30 -0500 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FA12C061751 for ; Sat, 1 Jan 2022 05:51:27 -0800 (PST) Received: by mail-pf1-x434.google.com with SMTP id 8so25684336pfo.4 for ; Sat, 01 Jan 2022 05:51:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bFwvEt83RjGGkVHF7mq+/T2VM5LTlrI2S4iVFfFlEwE=; b=hlZRCOHsKn+MNycJoZr7a2sibx/Tzdfnt7eKQuL7r55ON7GvKVjCMiYahpR3tUMPzx rYiCW191z1dBnfEtDPUMTLrIJVBGpJUbwQ9EA/8NAY9E4ekB0gnXjIFWJCfltJotH060 xGMAxA+GfoVQosSRC5KAFbzoTvka8YXgmPAWVqa/D4oXnTaNSO9TijsPjzb85w22Egrd uA1V2T7vFz9yzmuJ/oosWxVRCVRHf+iNIkFVuVAekalTrJjd/jjEC2tdTuouHS4TV8Gc +eL3N2+QVIDl0wFn2A3T4SeEAfh0rWGytXbXL1A62SS+YqCO8TMWcm9DerPEuhRojeGT ySKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bFwvEt83RjGGkVHF7mq+/T2VM5LTlrI2S4iVFfFlEwE=; b=3eHpkL70zbu7scUzs4l45hHNq6RDhNhB0yBYacOj5sQgnfgZsLW/72DRO2bo02GpLP +zzSnohPpcLYinUYKhfziphUuLQ4D5UhheQbYR7x0G8QHbq611O6ILibO350eZHWerdo x6bg57WukVvG416Hccr1qfwrV3mDSEVWWVr07dukjXMrSVvjdzlbJWG7MlwX+Jfv7mD9 /kjLiTVY6h+AcuWn6InNFTiGhqnp3A0VzJEA/aMes9fz6+lodM+GEArdhObjMv2uiVfI kw+R3E+m7Q/cdJo5/XT2aLa9SrxwrV0D9TRC5v+y8uyFzNa2yTpE/bsCEDFb5hdOgl7O Dd5w== X-Gm-Message-State: AOAM532kHezPNApU2NiROIEQfF9XlRsO82o+XADIUSDfAtf8sxWGKtuQ xJWGoogfDhb52owa0XTE3TQ= X-Google-Smtp-Source: ABdhPJyufZdzVVJ1PdyIGtChM8R4dx2pWWbzHwwiROMnNxihWZm1Wx+auihi0kzq6TYnXZOrXogGhA== X-Received: by 2002:a63:c145:: with SMTP id p5mr34333776pgi.355.1641045087157; Sat, 01 Jan 2022 05:51:27 -0800 (PST) Received: from code-infra-dev-cbj.ea134 ([140.205.70.41]) by smtp.gmail.com with ESMTPSA id o11sm34022039pfu.150.2022.01.01.05.51.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jan 2022 05:51:26 -0800 (PST) From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, congdanhqx@gmail.com, git@vger.kernel.org, gitster@pobox.com, peff@peff.net, tenglong.tl@alibaba-inc.com Subject: [PATCH v8 8/8] ls-tree.c: introduce "--format" option Date: Sat, 1 Jan 2022 21:50:31 +0800 Message-Id: X-Mailer: git-send-email 2.33.0.rc1.1802.gbb1c3936fb.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Add a --format option to ls-tree. It has an existing default output, and then --long and --name-only options to emit the default output along with the objectsize and, or to only emit object paths. Rather than add --type-only, --object-only etc. we can just support a --format using a strbuf_expand() similar to "for-each-ref --format". We might still add such options in the future for convenience. The --format implementation is slower than the existing code, but this change does not cause any performance regressions. We'll leave the existing show_tree() unchanged, and only run show_tree_fmt() in if a --format different than the hardcoded built-in ones corresponding to the existing modes is provided. I.e. something like the "--long" output would be much slower with this, mainly due to how we need to allocate various things to do with quote.c instead of spewing the output directly to stdout. The new option of '--format' comes from Ævar Arnfjörð Bjarmasonn's idea and suggestion, this commit makes modifications in terms of the original discussion on community [1]. Here is the statistics about performance tests: 1. Default format (hitten the builtin formats): "git ls-tree " vs "--format='%(mode) %(type) %(object)%x09%(file)'" $hyperfine --warmup=10 "/opt/git/master/bin/git ls-tree -r HEAD" Benchmark 1: /opt/git/master/bin/git ls-tree -r HEAD Time (mean ± σ): 105.2 ms ± 3.3 ms [User: 84.3 ms, System: 20.8 ms] Range (min … max): 99.2 ms … 113.2 ms 28 runs $hyperfine --warmup=10 "/opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object)%x09%(file)' HEAD" Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object)%x09%(file)' HEAD Time (mean ± σ): 106.4 ms ± 2.7 ms [User: 86.1 ms, System: 20.2 ms] Range (min … max): 100.2 ms … 110.5 ms 29 runs 2. Default format includes object size (hitten the builtin formats): "git ls-tree -l " vs "--format='%(mode) %(type) %(object) %(size:padded)%x09%(file)'" $hyperfine --warmup=10 "/opt/git/master/bin/git ls-tree -r -l HEAD" Benchmark 1: /opt/git/master/bin/git ls-tree -r -l HEAD Time (mean ± σ): 335.1 ms ± 6.5 ms [User: 304.6 ms, System: 30.4 ms] Range (min … max): 327.5 ms … 348.4 ms 10 runs $hyperfine --warmup=10 "/opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object) %(size:padded)%x09%(file)' HEAD" Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object) %(size:padded)%x09%(file)' HEAD Time (mean ± σ): 337.2 ms ± 8.2 ms [User: 309.2 ms, System: 27.9 ms] Range (min … max): 328.8 ms … 349.4 ms 10 runs Links: [1] https://public-inbox.org/git/RFC-patch-6.7-eac299f06ff-20211217T131635Z-avarab@gmail.com/ Signed-off-by: Teng Long Signed-off-by: Johannes Schindelin --- Documentation/git-ls-tree.txt | 50 ++++++++- builtin/ls-tree.c | 191 ++++++++++++++++++++++++++++------ t/t3105-ls-tree-format.sh | 55 ++++++++++ 3 files changed, 259 insertions(+), 37 deletions(-) create mode 100755 t/t3105-ls-tree-format.sh diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index 729370f235..ef23c0fac1 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -10,9 +10,9 @@ SYNOPSIS -------- [verse] 'git ls-tree' [-d] [-r] [-t] [-l] [-z] - [--name-only] [--name-status] [--object-only] [--full-name] [--full-tree] [--abbrev[=]] - [...] - + [--name-only] [--name-status] [--object-only] + [--full-name] [--full-tree] [--abbrev[=]] + [--format=] [...] DESCRIPTION ----------- Lists the contents of a given tree object, like what "/bin/ls -a" does @@ -79,6 +79,16 @@ OPTIONS Do not limit the listing to the current working directory. Implies --full-name. +--format=:: + A string that interpolates `%(fieldname)` from the result + being shown. It also interpolates `%%` to `%`, and + `%xx` where `xx`are hex digits interpolates to character + with hex code `xx`; for example `%00` interpolates to + `\0` (NUL), `%09` to `\t` (TAB) and `%0a` to `\n` (LF). + When specified, `--format` cannot be combined with other + format-altering options, including `--long`, `--name-only` + and `--object-only`. + [...]:: When paths are given, show them (note that this isn't really raw pathnames, but rather a list of patterns to match). Otherwise @@ -87,6 +97,9 @@ OPTIONS Output Format ------------- + +Default format: + SP SP TAB This output format is compatible with what `--index-info --stdin` of @@ -105,6 +118,37 @@ quoted as explained for the configuration variable `core.quotePath` (see linkgit:git-config[1]). Using `-z` the filename is output verbatim and the line is terminated by a NUL byte. +Customized format: + +It's support to print customized format by `%(fieldname)` with `--format` option. +For example, if you want to only print the and fields with a +JSON style, executing with a specific "--format" like + + git ls-tree --format='{"object":"%(object)", "file":"%(file)"}' + +The output format changes to: + + {"object":"", "file":""} + +FIELD NAMES +----------- + +Various values from structured fields can be used to interpolate +into the resulting output. For each outputing line, the following +names can be used: + +mode:: + The mode of the object. +type:: + The type of the object (`blob` or `tree`). +object:: + The name of the object. +size[:padded]:: + The size of the object ("-" if it's a tree). + It also supports a padded format of size with "%(size:padded)". +file:: + The filename of the object. + GIT --- Part of the linkgit:git[1] suite diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 009ffeb15d..6e3e5a4d06 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -56,23 +56,75 @@ enum { static int cmdmode = MODE_UNSPECIFIED; -static int parse_shown_fields(void) +static const char *format; +static const char *default_format = "%(mode) %(type) %(object)%x09%(file)"; +static const char *long_format = "%(mode) %(type) %(object) %(size:padded)%x09%(file)"; +static const char *name_only_format = "%(file)"; +static const char *object_only_format = "%(object)"; + +static void expand_objectsize(struct strbuf *line, const struct object_id *oid, + const enum object_type type, unsigned int padded) { - if (cmdmode == MODE_NAME_ONLY) { - shown_bits = SHOW_FILE_NAME; - return 0; + if (type == OBJ_BLOB) { + unsigned long size; + if (oid_object_info(the_repository, oid, &size) < 0) + die(_("could not get object info about '%s'"), + oid_to_hex(oid)); + if (padded) + strbuf_addf(line, "%7" PRIuMAX, (uintmax_t)size); + else + strbuf_addf(line, "%" PRIuMAX, (uintmax_t)size); + } else if (padded) { + strbuf_addf(line, "%7s", "-"); + } else { + strbuf_addstr(line, "-"); } - if (cmdmode == MODE_OBJECT_ONLY) { - shown_bits = SHOW_OBJECT_NAME; - return 0; +} + +static size_t expand_show_tree(struct strbuf *line, const char *start, + void *context) +{ + struct shown_data *data = context; + const char *end; + const char *p; + unsigned int errlen; + size_t len; + len = strbuf_expand_literal_cb(line, start, NULL); + if (len) + return len; + + if (*start != '(') + die(_("bad ls-tree format: as '%s'"), start); + + end = strchr(start + 1, ')'); + if (!end) + die(_("bad ls-tree format: element '%s' does not end in ')'"), start); + + len = end - start + 1; + if (skip_prefix(start, "(mode)", &p)) { + strbuf_addf(line, "%06o", data->mode); + } else if (skip_prefix(start, "(type)", &p)) { + strbuf_addstr(line, type_name(data->type)); + } else if (skip_prefix(start, "(size:padded)", &p)) { + expand_objectsize(line, data->oid, data->type, 1); + } else if (skip_prefix(start, "(size)", &p)) { + expand_objectsize(line, data->oid, data->type, 0); + } else if (skip_prefix(start, "(object)", &p)) { + strbuf_addstr(line, find_unique_abbrev(data->oid, abbrev)); + } else if (skip_prefix(start, "(file)", &p)) { + const char *name = data->base->buf; + const char *prefix = chomp_prefix ? ls_tree_prefix : NULL; + struct strbuf quoted = STRBUF_INIT; + struct strbuf sb = STRBUF_INIT; + strbuf_addstr(data->base, data->pathname); + name = relative_path(data->base->buf, prefix, &sb); + quote_c_style(name, "ed, NULL, 0); + strbuf_addstr(line, quoted.buf); + } else { + errlen = (unsigned long)len; + die(_("bad ls-tree format: %%%.*s"), errlen, start); } - if (!ls_options || (ls_options & LS_RECURSIVE) - || (ls_options & LS_SHOW_TREES) - || (ls_options & LS_TREE_ONLY)) - shown_bits = SHOW_DEFAULT; - if (cmdmode == MODE_LONG) - shown_bits = SHOW_DEFAULT | SHOW_SIZE; - return 1; + return len; } static int show_recursive(const char *base, size_t baselen, @@ -106,6 +158,75 @@ static int show_recursive(const char *base, size_t baselen, return 0; } +static int show_tree_init(enum object_type *type, struct strbuf *base, + const char *pathname, unsigned mode, int *retval) +{ + if (S_ISGITLINK(mode)) { + *type = OBJ_COMMIT; + } else if (S_ISDIR(mode)) { + if (show_recursive(base->buf, base->len, pathname)) { + *retval = READ_TREE_RECURSIVE; + if (!(ls_options & LS_SHOW_TREES)) + return 1; + } + *type = OBJ_TREE; + } + else if (ls_options & LS_TREE_ONLY) + return 1; + return 0; +} + +static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, + const char *pathname, unsigned mode, void *context) +{ + size_t baselen; + int retval = 0; + struct strbuf line = STRBUF_INIT; + struct shown_data data = { + .mode = mode, + .type = OBJ_BLOB, + .oid = oid, + .pathname = pathname, + .base = base, + }; + + if (show_tree_init(&data.type, base, pathname, mode, &retval)) + return retval; + + baselen = base->len; + strbuf_expand(&line, format, expand_show_tree, &data); + strbuf_addch(&line, line_termination); + fwrite(line.buf, line.len, 1, stdout); + strbuf_setlen(base, baselen); + return retval; +} + +static int parse_shown_fields(void) +{ + if (cmdmode == MODE_NAME_ONLY || + (format && !strcmp(format, name_only_format))) { + shown_bits = SHOW_FILE_NAME; + return 1; + } + + if (cmdmode == MODE_OBJECT_ONLY || + (format && !strcmp(format, object_only_format))) { + shown_bits = SHOW_OBJECT_NAME; + return 1; + } + + if (!ls_options || (ls_options & LS_RECURSIVE) + || (ls_options & LS_SHOW_TREES) + || (ls_options & LS_TREE_ONLY) + || (format && !strcmp(format, default_format))) + shown_bits = SHOW_DEFAULT; + + if (cmdmode == MODE_LONG || + (format && !strcmp(format, long_format))) + shown_bits = SHOW_DEFAULT | SHOW_SIZE; + return 1; +} + static int show_default(struct shown_data *data) { size_t baselen = data->base->len; @@ -137,24 +258,6 @@ static int show_default(struct shown_data *data) return 1; } -static int show_tree_init(enum object_type *type, struct strbuf *base, - const char *pathname, unsigned mode, int *retval) -{ - if (S_ISGITLINK(mode)) { - *type = OBJ_COMMIT; - } else if (S_ISDIR(mode)) { - if (show_recursive(base->buf, base->len, pathname)) { - *retval = READ_TREE_RECURSIVE; - if (!(ls_options & LS_SHOW_TREES)) - return 1; - } - *type = OBJ_TREE; - } - else if (ls_options & LS_TREE_ONLY) - return 1; - return 0; -} - static int show_tree(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, void *context) { @@ -196,6 +299,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) struct object_id oid; struct tree *tree; int i, full_tree = 0; + read_tree_fn_t fn = show_tree; const struct option ls_tree_options[] = { OPT_BIT('d', NULL, &ls_options, N_("only show trees"), LS_TREE_ONLY), @@ -218,6 +322,9 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "full-tree", &full_tree, N_("list entire tree; not just current directory " "(implies --full-name)")), + OPT_STRING_F(0, "format", &format, N_("format"), + N_("format to use for the output"), + PARSE_OPT_NONEG), OPT__ABBREV(&abbrev), OPT_END() }; @@ -238,6 +345,10 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) ((LS_TREE_ONLY|LS_RECURSIVE) & ls_options)) ls_options |= LS_SHOW_TREES; + if (format && cmdmode) + usage_msg_opt( + _("--format can't be combined with other format-altering options"), + ls_tree_usage, ls_tree_options); if (argc < 1) usage_with_options(ls_tree_usage, ls_tree_options); if (get_oid(argv[0], &oid)) @@ -261,6 +372,18 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) tree = parse_tree_indirect(&oid); if (!tree) die("not a tree object"); - return !!read_tree(the_repository, tree, - &pathspec, show_tree, NULL); + + /* + * The generic show_tree_fmt() is slower than show_tree(), so + * take the fast path if possible. + */ + if (format && (!strcmp(format, default_format) || + !strcmp(format, long_format) || + !strcmp(format, name_only_format) || + !strcmp(format, object_only_format))) + fn = show_tree; + else if (format) + fn = show_tree_fmt; + + return !!read_tree(the_repository, tree, &pathspec, fn, NULL); } diff --git a/t/t3105-ls-tree-format.sh b/t/t3105-ls-tree-format.sh new file mode 100755 index 0000000000..92b4d240e8 --- /dev/null +++ b/t/t3105-ls-tree-format.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +test_description='ls-tree --format' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +test_expect_success 'ls-tree --format usage' ' + test_expect_code 129 git ls-tree --format=fmt -l && + test_expect_code 129 git ls-tree --format=fmt --name-only && + test_expect_code 129 git ls-tree --format=fmt --name-status && + test_expect_code 129 git ls-tree --format=fmt --object-only +' + +test_expect_success 'setup' ' + mkdir dir && + test_commit dir/sub-file && + test_commit top-file +' + +test_ls_tree_format () { + format=$1 && + opts=$2 && + shift 2 && + git ls-tree $opts -r HEAD >expect.raw && + sed "s/^/> /" >expect actual && + test_cmp expect actual +} + +test_expect_success 'ls-tree --format=' ' + test_ls_tree_format \ + "%(mode) %(type) %(object)%x09%(file)" \ + "" +' + +test_expect_success 'ls-tree --format=' ' + test_ls_tree_format \ + "%(mode) %(type) %(object) %(size:padded)%x09%(file)" \ + "--long" +' + +test_expect_success 'ls-tree --format=' ' + test_ls_tree_format \ + "%(file)" \ + "--name-only" +' + +test_expect_success 'ls-tree --format=' ' + test_ls_tree_format \ + "%(object)" \ + "--object-only" +' + +test_done