From patchwork Wed Aug 12 19:44:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11711277 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5AE7014E3 for ; Wed, 12 Aug 2020 19:44:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 439982080C for ; Wed, 12 Aug 2020 19:44:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SDwZOtjz" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726587AbgHLTo0 (ORCPT ); Wed, 12 Aug 2020 15:44:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726512AbgHLToY (ORCPT ); Wed, 12 Aug 2020 15:44:24 -0400 Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF556C061383 for ; Wed, 12 Aug 2020 12:44:24 -0700 (PDT) Received: by mail-pj1-x1041.google.com with SMTP id ha11so1646900pjb.1 for ; Wed, 12 Aug 2020 12:44:24 -0700 (PDT) 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=jBZglFFSf02qtWUl+ct3vdPNpDjMNvbwAl4CJ3eay8Y=; b=SDwZOtjzAzjmTYZ6yCS0LIkc9gmzOtURORPZwRFJzb3XoWzuGtyTpurnWQxC+fcEdy fRfHrFHBspCRqgj5DGm+/Bzuy9GuQPK8nVArvMx4IibFAPJA97ibGHANVZEGK3StRhJe e/xVdEQ1VGDO2sLUZtDlusKKiX/6p0dJ7gQslrz+WClQhFDoeZLxBgoeR0x3dnY5PhUu 01K66Qy172UFeND65Nm9aIHm4IypXyR1QGyQaxjXbEei15fRkSDPUzJYW2jcuIjxYT75 F68EX8g+AcY7V/QNWpqxLFSpGyLwoz7ZFIIF5uxhHuXLdXFa/UGqB1mOjpdq7xBCt/La UnbQ== 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=jBZglFFSf02qtWUl+ct3vdPNpDjMNvbwAl4CJ3eay8Y=; b=f9q53tETFRcpTB7F54argf90Y0rGwp8H0iS2Omlo5NRQFZIAoVqPoj5bOszEMsv3Iu A1tZYww0fhFSCupH7mN9mbYSfATMttViVLZYAhjPeagLSBdsXGsrfHpDL8SYvd4DONHS MzVcL/0q8doH2bUJNQ++sNrDyDD0vbwNY2Rv349AEHeWXs5Z1wpN5xoO46o+twtga+bq ocui7MuAnSc0cGQsvrAofWmNYloXRjHp88is4Oq2SxuVTwo8QHsKUOYLvVaiw9ua73zy x2VkDnLIlRf8KnBNgrP/Ji35AOuQOmKCX8BWgdwhpvrOauCOVhUXb0pLqSj04aN+H8oD Lg7w== X-Gm-Message-State: AOAM530b+uZoF7Uvoo/fe7T1fCLslcs98vybUI5Jqg2JQDeTgPXw8JVf M1l7HC+Zss1p401iVNCzlV2PlPoM9N0= X-Google-Smtp-Source: ABdhPJwp9VwqI0b2hDq4sp0z0slyTzcNUyJL+hYXW5i2hYj4ai4hTdl8Qcdid8s6tO7G4qXnpDV+8w== X-Received: by 2002:a17:902:d346:: with SMTP id l6mr807264plk.77.1597261464288; Wed, 12 Aug 2020 12:44:24 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.132]) by smtp.gmail.com with ESMTPSA id q17sm3183965pfh.32.2020.08.12.12.44.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Aug 2020 12:44:23 -0700 (PDT) From: Shourya Shukla To: shouryashukla.oo@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, Johannes.Schindelin@gmx.de, kaartic.sivaraam@gmail.com, liu.denton@gmail.com, Christian Couder , Philip Oakley Subject: [PATCH v3 1/4] submodule: remove extra line feeds between callback struct and macro Date: Thu, 13 Aug 2020 01:14:01 +0530 Message-Id: <20200812194404.17028-2-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812194404.17028-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-1-shouryashukla.oo@gmail.com> <20200812194404.17028-1-shouryashukla.oo@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Many `submodule--helper` subcommands follow the convention that a struct defines their callback data, and the declaration of that struct is followed immediately by a macro to use in static initializers, without any separating empty line. Let's align the `init`, `status` and `sync` subcommands with that convention. Mentored-by: Christian Couder Mentored-by: Kaartic Sivaraam Helped-by: Johannes Schindelin Helped-by: Philip Oakley Signed-off-by: Shourya Shukla --- builtin/submodule--helper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index df135abbf1..a03dc84ea4 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -612,7 +612,6 @@ struct init_cb { const char *prefix; unsigned int flags; }; - #define INIT_CB_INIT { NULL, 0 } static void init_submodule(const char *path, const char *prefix, @@ -742,7 +741,6 @@ struct status_cb { const char *prefix; unsigned int flags; }; - #define STATUS_CB_INIT { NULL, 0 } static void print_status(unsigned int flags, char state, const char *path, @@ -933,7 +931,6 @@ struct sync_cb { const char *prefix; unsigned int flags; }; - #define SYNC_CB_INIT { NULL, 0 } static void sync_submodule(const char *path, const char *prefix, From patchwork Wed Aug 12 19:44:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11711281 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ACF6E14E3 for ; Wed, 12 Aug 2020 19:44:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 92D0C20866 for ; Wed, 12 Aug 2020 19:44:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J6cObPTc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726606AbgHLTo2 (ORCPT ); Wed, 12 Aug 2020 15:44:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38492 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726512AbgHLTo2 (ORCPT ); Wed, 12 Aug 2020 15:44:28 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C3CBC061383 for ; Wed, 12 Aug 2020 12:44:28 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id 74so1526321pfx.13 for ; Wed, 12 Aug 2020 12:44:28 -0700 (PDT) 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=f5tz4muLPsQXMqQZAFj1rC+PmGmwn43+GIIj65b/ZPE=; b=J6cObPTcWUih7VKDo8WPlCtcq040sOhfz112AUG4wXwLu0lQonEkhp3djragLzO//o Yvxwu3GZAoECigF3GHI6CIirSx6FwQvWR7fHBZMyytEEPVk7XXugPIv8aZSSwsk2xco/ PTHdBEeDfSRA7NjfQFqxAJFV0kA05zIqsm2UvZ53ZcBYD0rmXCxkM9e80nh9vVjWUNt1 GegJk2xaxsdzRSsGBO1d6Ca6tEfAKu25RsfqR7UdqrrvnjpyxJ83uAApMDpWx1ZQG4yr 6GebKdUcP2YFsAh6QZk2nb00V+enCQh1d4keJECiOvJ+2negoUSf8ySZwucwG9KVRzfM HGOg== 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=f5tz4muLPsQXMqQZAFj1rC+PmGmwn43+GIIj65b/ZPE=; b=DbthBBhWRGisssrKqvrXW7vS1TuCLAYEEff+IJYn0WBjaMKLo5fQA0ld4inHuYw7LD MKRJU0/IO8HtSKC8Ybi1hcvNXEsF3H8h28rVsmP+jLxlsZ/bE2VMmn1L20+9di2fo6S+ y17Xh2GGaMIAyiqmWuN13lD2LezrCBB7ynmnQNtrWLO7rJnP9DfKJcJ1Zp+ir2nzDz9y 8GB8xCZBgxZnN287Rcczz+yxhVKiPt0UiLy5MA6vlbfUGMLBKDmtL/8ByzumMkpPHxJk dsiOGgH4FF7iB+7dv1ncWhFX3lFx5oJPcUI02L9z5BTYgePF4XDIcgUnJ6DcCJvm7kpx MDfg== X-Gm-Message-State: AOAM5320grTMi/Ai9Y61Qts9dy6C+IkOz/FgoWgfhh8j8DVWi5btpbFD VBHEpjOpHfiPRF15atVTcLE= X-Google-Smtp-Source: ABdhPJzu60HHSR1tjANVXwfNvcAxrtuSrb5eTjw6alTrU4h6aV0lJV5j5g0PK0GYnHOoEsXUu8Dv2w== X-Received: by 2002:a63:3589:: with SMTP id c131mr665848pga.158.1597261467691; Wed, 12 Aug 2020 12:44:27 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.132]) by smtp.gmail.com with ESMTPSA id q17sm3183965pfh.32.2020.08.12.12.44.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Aug 2020 12:44:27 -0700 (PDT) From: Shourya Shukla To: shouryashukla.oo@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, Johannes.Schindelin@gmx.de, kaartic.sivaraam@gmail.com, liu.denton@gmail.com, Christian Couder Subject: [PATCH v3 2/4] submodule: rename helper functions to avoid ambiguity Date: Thu, 13 Aug 2020 01:14:02 +0530 Message-Id: <20200812194404.17028-3-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812194404.17028-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-1-shouryashukla.oo@gmail.com> <20200812194404.17028-1-shouryashukla.oo@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The helper functions: show_submodule_summary(), prepare_submodule_summary() and print_submodule_summary() are used by the builtin_diff() function in diff.c to generate a summary of submodules in the context of a diff. Functions with similar names are to be introduced in the upcoming port of submodule's summary subcommand. So, rename the helper functions to '*_diff_submodule_summary()' to avoid ambiguity. Mentored-by: Christian Couder Mentored-by: Kaartic Sivaraam Signed-off-by: Shourya Shukla --- diff.c | 2 +- submodule.c | 10 +++++----- submodule.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/diff.c b/diff.c index f9709de7b4..46175e40a6 100644 --- a/diff.c +++ b/diff.c @@ -3429,7 +3429,7 @@ static void builtin_diff(const char *name_a, if (o->submodule_format == DIFF_SUBMODULE_LOG && (!one->mode || S_ISGITLINK(one->mode)) && (!two->mode || S_ISGITLINK(two->mode))) { - show_submodule_summary(o, one->path ? one->path : two->path, + show_submodule_diff_summary(o, one->path ? one->path : two->path, &one->oid, &two->oid, two->dirty_submodule); return; diff --git a/submodule.c b/submodule.c index a52b93a87f..8273647b73 100644 --- a/submodule.c +++ b/submodule.c @@ -438,7 +438,7 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt, */ } -static int prepare_submodule_summary(struct rev_info *rev, const char *path, +static int prepare_submodule_diff_summary(struct rev_info *rev, const char *path, struct commit *left, struct commit *right, struct commit_list *merge_bases) { @@ -459,7 +459,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path, return prepare_revision_walk(rev); } -static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o) +static void print_submodule_diff_summary(struct repository *r, struct rev_info *rev, struct diff_options *o) { static const char format[] = " %m %s"; struct strbuf sb = STRBUF_INIT; @@ -610,7 +610,7 @@ static void show_submodule_header(struct diff_options *o, strbuf_release(&sb); } -void show_submodule_summary(struct diff_options *o, const char *path, +void show_submodule_diff_summary(struct diff_options *o, const char *path, struct object_id *one, struct object_id *two, unsigned dirty_submodule) { @@ -632,12 +632,12 @@ void show_submodule_summary(struct diff_options *o, const char *path, goto out; /* Treat revision walker failure the same as missing commits */ - if (prepare_submodule_summary(&rev, path, left, right, merge_bases)) { + if (prepare_submodule_diff_summary(&rev, path, left, right, merge_bases)) { diff_emit_submodule_error(o, "(revision walker failed)\n"); goto out; } - print_submodule_summary(sub, &rev, o); + print_submodule_diff_summary(sub, &rev, o); out: if (merge_bases) diff --git a/submodule.h b/submodule.h index 9ce85c03fe..4ac6e31cf1 100644 --- a/submodule.h +++ b/submodule.h @@ -69,7 +69,7 @@ int parse_submodule_update_strategy(const char *value, struct submodule_update_strategy *dst); const char *submodule_strategy_to_string(const struct submodule_update_strategy *s); void handle_ignore_submodules_arg(struct diff_options *, const char *); -void show_submodule_summary(struct diff_options *o, const char *path, +void show_submodule_diff_summary(struct diff_options *o, const char *path, struct object_id *one, struct object_id *two, unsigned dirty_submodule); void show_submodule_inline_diff(struct diff_options *o, const char *path, From patchwork Wed Aug 12 19:44:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11711283 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10DDA722 for ; Wed, 12 Aug 2020 19:44:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E719B20774 for ; Wed, 12 Aug 2020 19:44:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ee6aKjNX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726651AbgHLToc (ORCPT ); Wed, 12 Aug 2020 15:44:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726593AbgHLTob (ORCPT ); Wed, 12 Aug 2020 15:44:31 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 77D12C061383 for ; Wed, 12 Aug 2020 12:44:31 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id a79so1534956pfa.8 for ; Wed, 12 Aug 2020 12:44:31 -0700 (PDT) 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=w1MPiDX7ZUZQhhAr2HsU79nnNU8nJB0SBkJ4MkD3/+w=; b=Ee6aKjNX0sNluN5N9P6iJiX+4vsr4yQ6gLvm/CzmDn2XHaGyS444ylHy7nYQxuEu0C sy2RuHw42hzy9i8Tz7DjlGEoXn8cMr9Y/s3hSwGEdqJB10aCHeam20vETW8gZWnmsykt p/7JVr/0VOhaJuaAOUfitMADEKHspCcNJxqHHcg64Y/E9dyQEvrSdCfMRax3IqXgEK+8 rx4QmgzdNZX9512836qUo4bADEKVfuRGJ+Zik8J6tyjxCMAoEz4evEPCc/tj0fiV3rcZ TvvEk8I+c5BREDvNAjJSZoaIRk4msTsygsCpn6hW4Ll1n4FtpXngA2yisngQFkFNiE4l XbeQ== 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=w1MPiDX7ZUZQhhAr2HsU79nnNU8nJB0SBkJ4MkD3/+w=; b=CnPtdrgyaltTHTdyGV/X08YBeMryZHmAa2/w/ST4dR38jDeC/odfKolszzGj7/XJun 6ES3+qDexfMhttoDgjhQuq+vbMc5C436xVtHcsQqtl6SG1bIL3yIBIf+ojUy8Mquk3YE urUoPBZh40l26rT2YQRRgQSNcD2jTgGgtW4XmmOYP6OIYzegiLDFFvJvOcqbuZTtiH8F 2j6EOkey6wGQuNfCoD4O+W0MJdNbwH2wGkIWGbFN2TAsRx2swvmfbGtmizXm61mt0R0q +DlI1eS0Lk0OidnAas7LeusX2bboDWjM/aI7ebDdXz4G28+vtkjCpiiUZaxOeBq5lIfY sGoA== X-Gm-Message-State: AOAM533moFga+so6jAjoQC1Cp/XvZv2hBpkgKM0Bd8w6BgjsLQxJHEyo 5OhBViAHxMe9nWlwE4NC6quiSexpmvA= X-Google-Smtp-Source: ABdhPJzoSa0iB4G3stMxneO8bUgAjwGgvCrg1YUMxvZorrs1IuTejQlPcXGZsVZeWoarYijlpq7kKg== X-Received: by 2002:a63:5825:: with SMTP id m37mr652971pgb.257.1597261470942; Wed, 12 Aug 2020 12:44:30 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.132]) by smtp.gmail.com with ESMTPSA id q17sm3183965pfh.32.2020.08.12.12.44.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Aug 2020 12:44:30 -0700 (PDT) From: Shourya Shukla To: shouryashukla.oo@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, Johannes.Schindelin@gmx.de, kaartic.sivaraam@gmail.com, liu.denton@gmail.com, Christian Couder Subject: [PATCH v3 3/4] t7421: introduce a test script for verifying 'summary' output Date: Thu, 13 Aug 2020 01:14:03 +0530 Message-Id: <20200812194404.17028-4-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812194404.17028-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-1-shouryashukla.oo@gmail.com> <20200812194404.17028-1-shouryashukla.oo@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org 't7401-submodule-summary.sh' uses 'git add' to add submodules. Therefore, some commands such as 'git submodule init' and 'git submodule deinit' do not work as expected. So, introduce a test script for verifying the 'summary' output for submodules added using 'git submodule add' and notify regarding the above mentioned behaviour in t7401 itself. Mentored-by: Christian Couder Mentored-by: Kaartic Sivaraam Signed-off-by: Shourya Shukla --- t/t7401-submodule-summary.sh | 4 ++ t/t7421-submodule-summary-add.sh | 69 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100755 t/t7421-submodule-summary-add.sh diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 9bc841d085..45c5d2424e 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -7,6 +7,10 @@ test_description='Summary support for submodules This test tries to verify the sanity of summary subcommand of git submodule. ' +# NOTE: This test script uses 'git add' instead of 'git submodule add' to add +# submodules to the superproject. Some submodule subcommands such as init and +# deinit might not work as expected in this script. t7421 does not have this +# caveat. . ./test-lib.sh diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh new file mode 100755 index 0000000000..829fe26d6d --- /dev/null +++ b/t/t7421-submodule-summary-add.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Copyright (C) 2020 Shourya Shukla +# + +test_description='Summary support for submodules, adding them using git submodule add + +This test script tries to verify the sanity of summary subcommand of git submodule +while making sure to add submodules using `git submodule add` instead of +`git add` as done in t7401. +' + +. ./test-lib.sh + +test_expect_success 'summary test environment setup' ' + git init sm && + test_commit -C sm "add file" file file-content file-tag && + + git submodule add ./sm my-subm && + test_tick && + git commit -m "add submodule" +' + +test_expect_success 'submodule summary output for initialized submodule' ' + test_commit -C sm "add file2" file2 file2-content file2-tag && + git submodule update --remote && + test_tick && + git commit -m "update submodule" my-subm && + git submodule summary HEAD^ >actual && + rev1=$(git -C sm rev-parse --short HEAD^) && + rev2=$(git -C sm rev-parse --short HEAD) && + cat >expected <<-EOF && + * my-subm ${rev1}...${rev2} (1): + > add file2 + + EOF + test_cmp expected actual +' + +test_expect_success 'submodule summary output for deinitialized submodule' ' + git submodule deinit my-subm && + git submodule summary HEAD^ >actual && + test_must_be_empty actual && + git submodule update --init my-subm && + git submodule summary HEAD^ >actual && + rev1=$(git -C sm rev-parse --short HEAD^) && + rev2=$(git -C sm rev-parse --short HEAD) && + cat >expected <<-EOF && + * my-subm ${rev1}...${rev2} (1): + > add file2 + + EOF + test_cmp expected actual +' + +test_expect_success 'submodule summary output for submodules with changed paths' ' + git mv my-subm subm && + git commit -m "change submodule path" && + rev=$(git -C sm rev-parse --short HEAD^) && + git submodule summary HEAD^^ -- my-subm >actual 2>err && + test_i18ngrep "fatal:.*my-subm" err && + cat >expected <<-EOF && + * my-subm ${rev}...0000000: + + EOF + test_cmp expected actual +' + +test_done From patchwork Wed Aug 12 19:44:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11711285 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 98598722 for ; Wed, 12 Aug 2020 19:44:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F6EC208B3 for ; Wed, 12 Aug 2020 19:44:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GG/GSTJT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726664AbgHLToh (ORCPT ); Wed, 12 Aug 2020 15:44:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726593AbgHLToh (ORCPT ); Wed, 12 Aug 2020 15:44:37 -0400 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01C64C061383 for ; Wed, 12 Aug 2020 12:44:37 -0700 (PDT) Received: by mail-pg1-x535.google.com with SMTP id 189so932302pgg.13 for ; Wed, 12 Aug 2020 12:44:36 -0700 (PDT) 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=9U+pWsrYjN3oGQNmxUoJ8rPd2c/g+jkN5YseQsMeCs8=; b=GG/GSTJTCUXRFAtUVwqPSiQNPmAiKDY3l0ds7xYbmUmDHxnuTseOkN3Dd+o00ox6NW gz+es2MUq7ynRTD++qY89Uuav6V1pjWv4ULslD3hD2w9K9eAv+kvoMIArJU/HghgnTOf aeHDpMtNhUYVj5BFpjCNoNUULfCCGOxn/azZTqju7p/+kvHgsRzKj3lwFuUQHUIjFAZQ ecEJWlvFHWto3WJAe6sKv6bX4IQg6y8SAfYVmChoySsd+piImIt0ZELGF9HwHtPYhD7K y15/cfHdwbqofv+KZczFvNIiowlZ5O83ZhrAsAgsxATc8FfCHzTn0rKCt40pCrQZxe6Z iEMw== 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=9U+pWsrYjN3oGQNmxUoJ8rPd2c/g+jkN5YseQsMeCs8=; b=kRxZIWLK0Zf+y2znKqmYnxo0NpN4xSkvWlmRGXSvC7GWlFReZ+3PW22WmYEOVg+1i6 kdBuUAwCyTx4Z5qUPWrRAgLTN7HIVcYYBqOJGjScKQ9zqsTyPJBsdcJmQoqfvk2sMw71 htY0ME6suly0jOxIovDCp3BM6cPTfV2iqvMpZBRmGfhtef3eRzh6PZ7w++WEwYxVwrOA nX/rcQ1MY7fNWUM8xpYGWI/vi7mabZ+ig5wKC4xo7xfU6oNWWRvbgm53YVxz0Ch6FFpN BTrn5Ow01zQ6z7v8/Q7rSkTh8/VTXSRm6IG8m7/66Le2MEMAGggzVovm3ELT7tgZ9GUc PNXw== X-Gm-Message-State: AOAM531bSyV54A/Z5kgrQQnHPkgjbxX2lWUMjKXA3+/cGCHZC5XXrA0s RLqqibc2oUI4K2QkR9BEDkU= X-Google-Smtp-Source: ABdhPJyDlH0SSVSw4d0zQ6RtX7HlroDZE0/PhJubSco+Xr2NsROt+yE4Zapq+hr74FdveWHTtw7zQg== X-Received: by 2002:aa7:972f:: with SMTP id k15mr1054020pfg.209.1597261474713; Wed, 12 Aug 2020 12:44:34 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.132]) by smtp.gmail.com with ESMTPSA id q17sm3183965pfh.32.2020.08.12.12.44.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Aug 2020 12:44:34 -0700 (PDT) From: Shourya Shukla To: shouryashukla.oo@gmail.com Cc: christian.couder@gmail.com, git@vger.kernel.org, gitster@pobox.com, Johannes.Schindelin@gmx.de, kaartic.sivaraam@gmail.com, liu.denton@gmail.com, Prathamesh Chavan , Christian Couder , Stefan Beller Subject: [PATCH v3 4/4] submodule: port submodule subcommand 'summary' from shell to C Date: Thu, 13 Aug 2020 01:14:04 +0530 Message-Id: <20200812194404.17028-5-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812194404.17028-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-1-shouryashukla.oo@gmail.com> <20200812194404.17028-1-shouryashukla.oo@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Prathamesh Chavan Convert submodule subcommand 'summary' to a builtin and call it via 'git-submodule.sh'. The shell version had to call $diff_cmd twice, once to find the modified modules cared by the user and then again, with that list of modules to do various operations for computing the summary of those modules. On the other hand, the C version does not need a second call to $diff_cmd since it reuses the module list from the first call to do the aforementioned tasks. In the C version, we use the combination of setting a child process' working directory to the submodule path and then calling 'prepare_submodule_repo_env()' which also sets the 'GIT_DIR' to '.git', so that we can be certain that those spawned processes will not access the superproject's ODB by mistake. A behavioural difference between the C and the shell version is that the shell version outputs two line feeds after the 'git log' output when run outside of the tests while the C version outputs one line feed in any case. The reason for this is that the shell version calls log with '--pretty=format:' whose output is followed by two echo calls; 'format' does not have "terminator" semantics like its 'tformat' counterpart. So, the log output is terminated by a newline only when invoked by the user and not when invoked from the scripts. This results in the one & two line feed differences in the shell version. On the other hand, the C version calls log with '--pretty=' which is equivalent to '--pretty:tformat:' which is then followed by a 'printf("\n")'. Due to its "terminator" semantics the log output is always terminated by newline and hence one line feed in any case. Also, when we try to pass an option-like argument after a non-option argument, for instance: git submodule summary HEAD --foo-bar (or) git submodule summary HEAD --cached That argument would be treated like a path to the submodule for which the user is requesting a summary. So, the option ends up having no effect. Though, passing '--quiet' is an exception to this: git submodule summary HEAD --quiet While 'summary' doesn't support '--quiet', we don't get an output for the above command as '--quiet' is treated as a path which means we get an output only if a submodule whose path is '--quiet' exists. The error message in case of computing a summary for non-existent submodules in the C version is different from that of the shell version. Since the new error message is not marked for translation, change the 'test_i18ngrep' in t7421.4 to 'grep'. Mentored-by: Christian Couder Mentored-by: Stefan Beller Mentored-by: Kaartic Sivaraam Helped-by: Johannes Schindelin Signed-off-by: Prathamesh Chavan Signed-off-by: Shourya Shukla Signed-off-by: Johannes Schindelin --- builtin/submodule--helper.c | 429 +++++++++++++++++++++++++++++++ git-submodule.sh | 186 +------------- t/t7421-submodule-summary-add.sh | 2 +- 3 files changed, 431 insertions(+), 186 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a03dc84ea4..63ea39025d 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -927,6 +927,434 @@ static int module_name(int argc, const char **argv, const char *prefix) return 0; } +struct module_cb { + unsigned int mod_src; + unsigned int mod_dst; + struct object_id oid_src; + struct object_id oid_dst; + char status; + const char *sm_path; +}; +#define MODULE_CB_INIT { 0, 0, NULL, NULL, '\0', NULL } + +struct module_cb_list { + struct module_cb **entries; + int alloc, nr; +}; +#define MODULE_CB_LIST_INIT { NULL, 0, 0 } + +struct summary_cb { + int argc; + const char **argv; + const char *prefix; + unsigned int cached: 1; + unsigned int for_status: 1; + unsigned int files: 1; + int summary_limit; +}; +#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0 } + +enum diff_cmd { + DIFF_INDEX, + DIFF_FILES +}; + +static char* verify_submodule_committish(const char *sm_path, + const char *committish) +{ + struct child_process cp_rev_parse = CHILD_PROCESS_INIT; + struct strbuf result = STRBUF_INIT; + + cp_rev_parse.git_cmd = 1; + cp_rev_parse.dir = sm_path; + prepare_submodule_repo_env(&cp_rev_parse.env_array); + strvec_pushl(&cp_rev_parse.args, "rev-parse", "-q", "--short", NULL); + strvec_pushf(&cp_rev_parse.args, "%s^0", committish); + strvec_push(&cp_rev_parse.args, "--"); + + if (capture_command(&cp_rev_parse, &result, 0)) + return NULL; + + strbuf_trim_trailing_newline(&result); + return strbuf_detach(&result, NULL); +} + +static void print_submodule_summary(struct summary_cb *info, char* errmsg, + int total_commits, const char *displaypath, + const char *src_abbrev, const char *dst_abbrev, + int missing_src, int missing_dst, + struct module_cb *p) +{ + if (p->status == 'T') { + if (S_ISGITLINK(p->mod_dst)) + printf(_("* %s %s(blob)->%s(submodule)"), + displaypath, src_abbrev, dst_abbrev); + else + printf(_("* %s %s(submodule)->%s(blob)"), + displaypath, src_abbrev, dst_abbrev); + } else { + printf("* %s %s...%s", + displaypath, src_abbrev, dst_abbrev); + } + + if (total_commits < 0) + printf(":\n"); + else + printf(" (%d):\n", total_commits); + + if (errmsg) { + printf(_("%s"), errmsg); + } else if (total_commits > 0) { + struct child_process cp_log = CHILD_PROCESS_INIT; + + cp_log.git_cmd = 1; + cp_log.dir = p->sm_path; + prepare_submodule_repo_env(&cp_log.env_array); + strvec_pushl(&cp_log.args, "log", NULL); + + if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) { + if (info->summary_limit > 0) + strvec_pushf(&cp_log.args, "-%d", + info->summary_limit); + + strvec_pushl(&cp_log.args, "--pretty= %m %s", + "--first-parent", NULL); + strvec_pushf(&cp_log.args, "%s...%s", + src_abbrev, dst_abbrev); + } else if (S_ISGITLINK(p->mod_dst)) { + strvec_pushl(&cp_log.args, "--pretty= > %s", + "-1", dst_abbrev, NULL); + } else { + strvec_pushl(&cp_log.args, "--pretty= < %s", + "-1", src_abbrev, NULL); + } + run_command(&cp_log); + } + printf("\n"); +} + +static void generate_submodule_summary(struct summary_cb *info, + struct module_cb *p) +{ + char *displaypath, *src_abbrev, *dst_abbrev; + int missing_src = 0, missing_dst = 0; + char *errmsg = NULL; + int total_commits = -1; + + if (!info->cached && oideq(&p->oid_dst, &null_oid)) { + if (S_ISGITLINK(p->mod_dst)) { + struct ref_store *refs = get_submodule_ref_store(p->sm_path); + if (refs) + refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst); + } else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) { + struct stat st; + int fd = open(p->sm_path, O_RDONLY); + + if (fd < 0 || fstat(fd, &st) < 0 || + index_fd(&the_index, &p->oid_dst, fd, &st, OBJ_BLOB, + p->sm_path, 0)) + error(_("couldn't hash object from '%s'"), p->sm_path); + } else { + /* for a submodule removal (mode:0000000), don't warn */ + if (p->mod_dst) + warning(_("unexpected mode %d\n"), p->mod_dst); + } + } + + if (S_ISGITLINK(p->mod_src)) { + src_abbrev = verify_submodule_committish(p->sm_path, + oid_to_hex(&p->oid_src)); + if (!src_abbrev) { + missing_src = 1; + /* + * As `rev-parse` failed, we fallback to getting + * the abbreviated hash using oid_src. We do + * this as we might still need the abbreviated + * hash in cases like a submodule type change, etc. + */ + src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7); + } + } else { + /* + * The source does not point to a submodule. + * So, we fallback to getting the abbreviation using + * oid_src as we might still need the abbreviated + * hash in cases like submodule add, etc. + */ + src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7); + } + + if (S_ISGITLINK(p->mod_dst)) { + dst_abbrev = verify_submodule_committish(p->sm_path, + oid_to_hex(&p->oid_dst)); + if (!dst_abbrev) { + missing_dst = 1; + /* + * As `rev-parse` failed, we fallback to getting + * the abbreviated hash using oid_dst. We do + * this as we might still need the abbreviated + * hash in cases like a submodule type change, etc. + */ + dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7); + } + } else { + /* + * The destination does not point to a submodule. + * So, we fallback to getting the abbreviation using + * oid_dst as we might still need the abbreviated + * hash in cases like a submodule removal, etc. + */ + dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7); + } + + displaypath = get_submodule_displaypath(p->sm_path, info->prefix); + + if (!missing_src && !missing_dst) { + struct child_process cp_rev_list = CHILD_PROCESS_INIT; + struct strbuf sb_rev_list = STRBUF_INIT; + + strvec_pushl(&cp_rev_list.args, "rev-list", + "--first-parent", "--count", NULL); + if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) + strvec_pushf(&cp_rev_list.args, "%s...%s", + src_abbrev, dst_abbrev); + else + strvec_push(&cp_rev_list.args, S_ISGITLINK(p->mod_src) ? + src_abbrev : dst_abbrev); + strvec_push(&cp_rev_list.args, "--"); + + cp_rev_list.git_cmd = 1; + cp_rev_list.dir = p->sm_path; + prepare_submodule_repo_env(&cp_rev_list.env_array); + + if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) + total_commits = atoi(sb_rev_list.buf); + + strbuf_release(&sb_rev_list); + } else { + /* + * Don't give error msg for modification whose dst is not + * submodule, i.e., deleted or changed to blob + */ + if (S_ISGITLINK(p->mod_dst)) { + struct strbuf errmsg_str = STRBUF_INIT; + if (missing_src && missing_dst) { + strbuf_addf(&errmsg_str, " Warn: %s doesn't contain commits %s and %s\n", + displaypath, oid_to_hex(&p->oid_src), + oid_to_hex(&p->oid_dst)); + } else { + strbuf_addf(&errmsg_str, " Warn: %s doesn't contain commit %s\n", + displaypath, missing_src ? + oid_to_hex(&p->oid_src) : + oid_to_hex(&p->oid_dst)); + } + errmsg = strbuf_detach(&errmsg_str, NULL); + } + } + + print_submodule_summary(info, errmsg, total_commits, + displaypath, src_abbrev, + dst_abbrev, missing_src, + missing_dst, p); + + free(displaypath); + free(src_abbrev); + free(dst_abbrev); +} + +static void prepare_submodule_summary(struct summary_cb *info, + struct module_cb_list *list) +{ + int i; + for (i = 0; i < list->nr; i++) { + const struct submodule *sub; + struct module_cb *p = list->entries[i]; + struct strbuf sm_gitdir = STRBUF_INIT; + + if (p->status == 'D' || p->status == 'T') { + generate_submodule_summary(info, p); + continue; + } + + if (info->for_status && p->status != 'A' && + (sub = submodule_from_path(the_repository, + &null_oid, p->sm_path))) { + char *config_key = NULL; + const char *value; + int ignore_all = 0; + + config_key = xstrfmt("submodule.%s.ignore", + sub->name); + if (!git_config_get_string_const(config_key, &value)) + ignore_all = !strcmp(value, "all"); + else if (sub->ignore) + ignore_all = !strcmp(sub->ignore, "all"); + + free(config_key); + if (ignore_all) + continue; + } + + /* Also show added or modified modules which are checked out */ + strbuf_addstr(&sm_gitdir, p->sm_path); + if (is_nonbare_repository_dir(&sm_gitdir)) + generate_submodule_summary(info, p); + strbuf_release(&sm_gitdir); + } +} + +static void submodule_summary_callback(struct diff_queue_struct *q, + struct diff_options *options, + void *data) +{ + int i; + struct module_cb_list *list = data; + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + struct module_cb *temp; + + if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode)) + continue; + temp = (struct module_cb*)malloc(sizeof(struct module_cb)); + temp->mod_src = p->one->mode; + temp->mod_dst = p->two->mode; + temp->oid_src = p->one->oid; + temp->oid_dst = p->two->oid; + temp->status = p->status; + temp->sm_path = xstrdup(p->one->path); + + ALLOC_GROW(list->entries, list->nr + 1, list->alloc); + list->entries[list->nr++] = temp; + } +} + +static const char *get_diff_cmd(enum diff_cmd diff_cmd) +{ + switch (diff_cmd) { + case DIFF_INDEX: return "diff-index"; + case DIFF_FILES: return "diff-files"; + default: BUG("bad diff_cmd value %d", diff_cmd); + } +} + +static int compute_summary_module_list(struct object_id *head_oid, + struct summary_cb *info, + enum diff_cmd diff_cmd) +{ + struct strvec diff_args = STRVEC_INIT; + struct rev_info rev; + struct module_cb_list list = MODULE_CB_LIST_INIT; + + strvec_push(&diff_args, get_diff_cmd(diff_cmd)); + if (info->cached) + strvec_push(&diff_args, "--cached"); + strvec_pushl(&diff_args, "--ignore-submodules=dirty", "--raw", NULL); + if (head_oid) + strvec_push(&diff_args, oid_to_hex(head_oid)); + strvec_push(&diff_args, "--"); + if (info->argc) + strvec_pushv(&diff_args, info->argv); + + git_config(git_diff_basic_config, NULL); + init_revisions(&rev, info->prefix); + rev.abbrev = 0; + precompose_argv(diff_args.nr, diff_args.v); + setup_revisions(diff_args.nr, diff_args.v, &rev, NULL); + rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK; + rev.diffopt.format_callback = submodule_summary_callback; + rev.diffopt.format_callback_data = &list; + + if (!info->cached) { + if (diff_cmd == DIFF_INDEX) + setup_work_tree(); + if (read_cache_preload(&rev.diffopt.pathspec) < 0) { + perror("read_cache_preload"); + return -1; + } + } else if (read_cache() < 0) { + perror("read_cache"); + return -1; + } + + if (diff_cmd == DIFF_INDEX) + run_diff_index(&rev, info->cached); + else + run_diff_files(&rev, 0); + prepare_submodule_summary(info, &list); + strvec_clear(&diff_args); + return 0; +} + +static int module_summary(int argc, const char **argv, const char *prefix) +{ + struct summary_cb info = SUMMARY_CB_INIT; + int cached = 0; + int for_status = 0; + int files = 0; + int summary_limit = -1; + enum diff_cmd diff_cmd = DIFF_INDEX; + struct object_id head_oid; + int ret; + + struct option module_summary_options[] = { + OPT_BOOL(0, "cached", &cached, + N_("use the commit stored in the index instead of the submodule HEAD")), + OPT_BOOL(0, "files", &files, + N_("to compare the commit in the index with that in the submodule HEAD")), + OPT_BOOL(0, "for-status", &for_status, + N_("skip submodules with 'ignore_config' value set to 'all'")), + OPT_INTEGER('n', "summary-limit", &summary_limit, + N_("limit the summary size")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper summary [] [commit] [--] []"), + NULL + }; + + argc = parse_options(argc, argv, prefix, module_summary_options, + git_submodule_helper_usage, 0); + + if (!summary_limit) + return 0; + + if (!get_oid(argc ? argv[0] : "HEAD", &head_oid)) { + if (argc) { + argv++; + argc--; + } + } else if (!argc || !strcmp(argv[0], "HEAD")) { + /* before the first commit: compare with an empty tree */ + oidcpy(&head_oid, the_hash_algo->empty_tree); + if (argc) { + argv++; + argc--; + } + } else { + if (get_oid("HEAD", &head_oid)) + die(_("could not fetch a revision for HEAD")); + } + + if (files) { + if (cached) + die(_("--cached and --files are mutually exclusive")); + diff_cmd = DIFF_FILES; + } + + info.argc = argc; + info.argv = argv; + info.prefix = prefix; + info.cached = !!cached; + info.files = !!files; + info.for_status = !!for_status; + info.summary_limit = summary_limit; + + ret = compute_summary_module_list((diff_cmd == DIFF_INDEX) ? &head_oid : NULL, + &info, diff_cmd); + return ret; +} + struct sync_cb { const char *prefix; unsigned int flags; @@ -2341,6 +2769,7 @@ static struct cmd_struct commands[] = { {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, + {"summary", module_summary, SUPPORT_SUPER_PREFIX}, {"remote-branch", resolve_remote_submodule_branch, 0}, {"push-check", push_check, 0}, {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 43eb6051d2..6fb12585cb 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -59,31 +59,6 @@ die_if_unmatched () fi } -# -# Print a submodule configuration setting -# -# $1 = submodule name -# $2 = option name -# $3 = default value -# -# Checks in the usual git-config places first (for overrides), -# otherwise it falls back on .gitmodules. This allows you to -# distribute project-wide defaults in .gitmodules, while still -# customizing individual repositories if necessary. If the option is -# not in .gitmodules either, print a default value. -# -get_submodule_config () { - name="$1" - option="$2" - default="$3" - value=$(git config submodule."$name"."$option") - if test -z "$value" - then - value=$(git submodule--helper config submodule."$name"."$option") - fi - printf '%s' "${value:-$default}" -} - isnumber() { n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1" @@ -831,166 +806,7 @@ cmd_summary() { shift done - test $summary_limit = 0 && return - - if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"}) - then - head=$rev - test $# = 0 || shift - elif test -z "$1" || test "$1" = "HEAD" - then - # before the first commit: compare with an empty tree - head=$(git hash-object -w -t tree --stdin module) - if test "$status" = D || test "$status" = T - then - printf '%s\n' "$sm_path" - continue - fi - # Respect the ignore setting for --for-status. - if test -n "$for_status" - then - name=$(git submodule--helper name "$sm_path") - ignore_config=$(get_submodule_config "$name" ignore none) - test $status != A && test $ignore_config = all && continue - fi - # Also show added or modified modules which are checked out - GIT_DIR="$sm_path/.git" git rev-parse --git-dir >/dev/null 2>&1 && - printf '%s\n' "$sm_path" - done - ) - - test -z "$modules" && return - - git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules | - sane_egrep '^:([0-7]* )?160000' | - cut -c2- | - while read -r mod_src mod_dst sha1_src sha1_dst status name - do - if test -z "$cached" && - is_zero_oid $sha1_dst - then - case "$mod_dst" in - 160000) - sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD) - ;; - 100644 | 100755 | 120000) - sha1_dst=$(git hash-object $name) - ;; - 000000) - ;; # removed - *) - # unexpected type - eval_gettextln "unexpected mode \$mod_dst" >&2 - continue ;; - esac - fi - missing_src= - missing_dst= - - test $mod_src = 160000 && - ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null && - missing_src=t - - test $mod_dst = 160000 && - ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null && - missing_dst=t - - display_name=$(git submodule--helper relative-path "$name" "$wt_prefix") - - total_commits= - case "$missing_src,$missing_dst" in - t,) - errmsg="$(eval_gettext " Warn: \$display_name doesn't contain commit \$sha1_src")" - ;; - ,t) - errmsg="$(eval_gettext " Warn: \$display_name doesn't contain commit \$sha1_dst")" - ;; - t,t) - errmsg="$(eval_gettext " Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")" - ;; - *) - errmsg= - total_commits=$( - if test $mod_src = 160000 && test $mod_dst = 160000 - then - range="$sha1_src...$sha1_dst" - elif test $mod_src = 160000 - then - range=$sha1_src - else - range=$sha1_dst - fi - GIT_DIR="$name/.git" \ - git rev-list --first-parent $range -- | wc -l - ) - total_commits=" ($(($total_commits + 0)))" - ;; - esac - - sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null || - echo $sha1_src | cut -c1-7) - sha1_abbr_dst=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_dst 2>/dev/null || - echo $sha1_dst | cut -c1-7) - - if test $status = T - then - blob="$(gettext "blob")" - submodule="$(gettext "submodule")" - if test $mod_dst = 160000 - then - echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:" - else - echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:" - fi - else - echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:" - fi - if test -n "$errmsg" - then - # Don't give error msg for modification whose dst is not submodule - # i.e. deleted or changed to blob - test $mod_dst = 160000 && echo "$errmsg" - else - if test $mod_src = 160000 && test $mod_dst = 160000 - then - limit= - test $summary_limit -gt 0 && limit="-$summary_limit" - GIT_DIR="$name/.git" \ - git log $limit --pretty='format: %m %s' \ - --first-parent $sha1_src...$sha1_dst - elif test $mod_dst = 160000 - then - GIT_DIR="$name/.git" \ - git log --pretty='format: > %s' -1 $sha1_dst - else - GIT_DIR="$name/.git" \ - git log --pretty='format: < %s' -1 $sha1_src - fi - echo - fi - echo - done + git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${prefix:+--prefix "$prefix"} ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@" } # # List all submodules, prefixed with: diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh index 829fe26d6d..59a9b00467 100755 --- a/t/t7421-submodule-summary-add.sh +++ b/t/t7421-submodule-summary-add.sh @@ -58,7 +58,7 @@ test_expect_success 'submodule summary output for submodules with changed paths' git commit -m "change submodule path" && rev=$(git -C sm rev-parse --short HEAD^) && git submodule summary HEAD^^ -- my-subm >actual 2>err && - test_i18ngrep "fatal:.*my-subm" err && + grep "fatal:.*my-subm" err && cat >expected <<-EOF && * my-subm ${rev}...0000000: