From patchwork Thu Aug 6 16:40:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11703545 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 7C11A722 for ; Thu, 6 Aug 2020 16:50:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CDFD22311C for ; Thu, 6 Aug 2020 16:50:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="soSaiPCD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728369AbgHFQt5 (ORCPT ); Thu, 6 Aug 2020 12:49:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728485AbgHFQlS (ORCPT ); Thu, 6 Aug 2020 12:41:18 -0400 Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E864C0A8939 for ; Thu, 6 Aug 2020 09:41:18 -0700 (PDT) Received: by mail-pl1-x642.google.com with SMTP id u10so18426475plr.7 for ; Thu, 06 Aug 2020 09:41:18 -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=q9dnXzWj3uH+B7A14K52gX/1lSMGIABjfODAH/v6+Lw=; b=soSaiPCD3kkUkr8WdO2xkYSX6Xw03uewQTrKSY6Fs14cq8I076o0v+u/mbeM9NTngc gbxBzfCUPzJcvLX40fGX7W/YntD3m8sXERImN3PRAmH368IYNyY/WCV6TDaZCFB6A8fY wK0mTfBhPIGZiP671x6LFoSK9+S2K9WzjC8yjGTfawzkKJn/Fn7dh3uZqIaNd/q9PYOQ mzUEpkRTMGvMpnocriAAIVMrr3ZsGrU71LV5grIFvszHV9UvF8d8m8vR8AZE2dZLa6kE mRc+rUCAIDnq+tr6IMoVawBFB1jJscv7l5gTUtMSax0GlXxycbt9Rn+xgl6E2gjobcor tKdQ== 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=q9dnXzWj3uH+B7A14K52gX/1lSMGIABjfODAH/v6+Lw=; b=E3f34hL03uTo7OXy8/eAxM56xFlJzhn36SjXB8v2H83pz2+1ne5srFsO9C/7h6JH0H jgxS41xKI4OiqzeiLwOyd3qLz2vcgJOe7ARi/Q9a28aDfMwMA61XPsxA2NyM7hDjEO2q b3cxHRELHHAtyknRyo5uK7N0o7RRfFYvCm+YqAEZw+jLMcAce02HDTSym/wRYTEcNSq0 aXIe6Rts7kj+gREAT50UrK11lbWfcyMVDP7hy2ITG819FhYTi6QvDbgIwnyiRo+lH2p2 S/VXBRF+rLFIgTzfQ0BasRCdcA0Cp5FWYXypE5iLjIt24DyghUXyYosYIft/kzGP6xIR OboQ== X-Gm-Message-State: AOAM532Jx35zTy0oLOBU9A8ega/lyYFU5Bhv6502ZCOctHq0Ar9UInVi LjJ6qLvvBc8FB7AnfZ1jlVz40ohBAxA= X-Google-Smtp-Source: ABdhPJyRrgzVsj9R9lIW/7XGphl5FyAnV3ElvxETiOcZw/B2nDoj8tUZ8tn7YGgf2idcy2mQKCmEPg== X-Received: by 2002:a17:902:9f82:: with SMTP id g2mr8783902plq.254.1596732077101; Thu, 06 Aug 2020 09:41:17 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.60]) by smtp.gmail.com with ESMTPSA id w16sm8008381pjd.50.2020.08.06.09.41.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 09:41:16 -0700 (PDT) From: Shourya Shukla To: git@vger.kernel.org Cc: gitster@pobox.com, christian.couder@gmail.com, kaartic.sivaraam@gmail.com, johannes.schindelin@gmx.de, liu.denton@gmail.com, Shourya Shukla , Christian Couder Subject: [PATCH v2 1/5] submodule: expose the '--for-status' option of summary Date: Thu, 6 Aug 2020 22:10:58 +0530 Message-Id: <20200806164102.6707-2-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200806164102.6707-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-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 'for-status' option is used to compute the summary of submodule(s) in a superproject by skipping the ignored submdules i.e., those with 'submodule..ignore' set to 'all' in the '.gitmodules' or '.git/config', with the latter taking precedence over the former. The option was introduced in d0f64dd44d (git-submodule summary: --for-status option, 2008-04-12), refined in 3ba7407b8b (submodule summary: ignore --for-status option, 2013-09-06) and finally perfected in 927b26f87a (submodule: don't print status output with ignore=all, 2013-09-01). But, it was not mentioned in the 'git submodule' Documentation. Expose the '--for-status' option accepted by the command 'git submodule summary'. Mentored-by: Christian Couder Mentored-by: Kaartic Sivaraam Signed-off-by: Shourya Shukla --- Documentation/git-submodule.txt | 8 +++++++- contrib/completion/git-completion.bash | 2 +- git-submodule.sh | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 7e5f995f77..d944e4c817 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -190,7 +190,7 @@ set-url [--] :: automatically synchronize the submodule's new remote URL configuration. -summary [--cached|--files] [(-n|--summary-limit) ] [commit] [--] [...]:: +summary [--cached|--files] [--for-status] [(-n|--summary-limit) ] [commit] [--] [...]:: Show commit summary between the given commit (defaults to HEAD) and working tree/index. For a submodule in question, a series of commits in the submodule between the given super project commit and the @@ -309,6 +309,12 @@ OPTIONS compares the commit in the index with that in the submodule HEAD when this option is used. +--for-status:: + This option is only valid for the summary command. This command + skips the submodules with `submodule..ignore` set to `all` + in the `.gitmodules` or `.git/config`. The configuration in + `.git/config` overrides the configuration in `.gitmodules`. + -n:: --summary-limit:: This option is only valid for the summary command. diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 0fdb5da83b..2b7b033c17 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -3059,7 +3059,7 @@ _git_submodule () __gitcomp "--default --branch" ;; summary,--*) - __gitcomp "--cached --files --summary-limit" + __gitcomp "--cached --files --for-status --summary-limit" ;; foreach,--*|sync,--*) __gitcomp "--recursive" diff --git a/git-submodule.sh b/git-submodule.sh index 43eb6051d2..dda3fee167 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -13,7 +13,7 @@ USAGE="[--quiet] [--cached] or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference ] [--recursive] [--[no-]single-branch] [--] [...] or: $dashless [--quiet] set-branch (--default|--branch ) [--] or: $dashless [--quiet] set-url [--] - or: $dashless [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] + or: $dashless [--quiet] summary [--cached|--files] [--for-status] [--summary-limit ] [commit] [--] [...] or: $dashless [--quiet] foreach [--recursive] or: $dashless [--quiet] sync [--recursive] [--] [...] or: $dashless [--quiet] absorbgitdirs [--] [...]" From patchwork Thu Aug 6 16:40:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11703521 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 3BBE6138C for ; Thu, 6 Aug 2020 16:44:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 93F3E2311B for ; Thu, 6 Aug 2020 16:44:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="skMN61G2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729130AbgHFQoM (ORCPT ); Thu, 6 Aug 2020 12:44:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41644 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729106AbgHFQmr (ORCPT ); Thu, 6 Aug 2020 12:42:47 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31107C0A893A for ; Thu, 6 Aug 2020 09:41:22 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id s15so15576218pgc.8 for ; Thu, 06 Aug 2020 09:41:22 -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=RDtlGdfbZa+4BbrprtZLywdNnB9QGvhHQOpinvsJ+jo=; b=skMN61G2e/4YID8IbQyjgRSSQw06WyHcZ4G0sPRMRoK22e0tstUXKkr5HdU2YkdBZY i1gFD4Tr3B/mSquWiziDfNFXijvH9sgKL9W9iI/G9FHM9+PKvbkkMAn9BIjTbM2WYAf0 N4gB9FX6BI5xOq/ts8ZvwZnJA+UgO++doySrWXT3lvuTkWKXfzrxjBp37kzFbVOGAdPE Dv/NQYZ9oNKMw0IVD+LH5LvtFdpxne20YykNF3+2SzIUn1MJkGy/q1qfwxGxen7xJ2M2 /n1aHD5WxAkuKcnNw8gN93c1x0lwrhaEtUmwvcUdKceWA3fxGtOCveYVJEwvoWorN3/V 2zQA== 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=RDtlGdfbZa+4BbrprtZLywdNnB9QGvhHQOpinvsJ+jo=; b=OP95u9RZLLwU+iUryw50suZ3xYee3Zu0U4+ZqK5joVmcP0J5wUQ1YVc6WYM1OPS8TK 4iy9cTvx/dpv+b1N+w5H5gys4jAik+0StEg/8fABum1lY5mnPoIVzygKF0JB4tCrC8R8 h/WjgkqZAFXEjxIDsih5jepZ3HgJlnNZ8FDhbxGsLzHXrCy6c1gTwjN4MCPeZ7BdendQ ZBzP3orEV9KqsgAo5jcS5rooa4UynU/BiBp6NK//Zxac4r7DegRHLXJ2GKBASMiQ7T4w YdRXWdodUpoWE05UF8t90QuKMaqETRfBo7EXpoiuJoUBpf3fUoa1qlak5rXmnGU9jF43 Hwbg== X-Gm-Message-State: AOAM532ouwQft0vWa3Ib21Jgf/lw2/NZHT3V+T67EfjxeOh+1pS7pBaY hUNtW1GqdYWzF8vA/lujGfEyk3uwIXs= X-Google-Smtp-Source: ABdhPJz+k+foNkEBsgX3Haht7OYz9yMhlGYxSTwknD2/sqyp2ZfmqYwhEZrz0PmGeix5uOi/S33waA== X-Received: by 2002:aa7:9613:: with SMTP id q19mr9671317pfg.9.1596732081208; Thu, 06 Aug 2020 09:41:21 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.60]) by smtp.gmail.com with ESMTPSA id w16sm8008381pjd.50.2020.08.06.09.41.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 09:41:20 -0700 (PDT) From: Shourya Shukla To: git@vger.kernel.org Cc: gitster@pobox.com, christian.couder@gmail.com, kaartic.sivaraam@gmail.com, johannes.schindelin@gmx.de, liu.denton@gmail.com, Shourya Shukla , Christian Couder , Johannes Schindelin , Philip Oakley Subject: [PATCH v2 2/5] submodule: remove extra line feeds between callback struct and macro Date: Thu, 6 Aug 2020 22:10:59 +0530 Message-Id: <20200806164102.6707-3-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200806164102.6707-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-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 a1c75607c7..3641718d0a 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 Thu Aug 6 16:41:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shourya Shukla X-Patchwork-Id: 11703541 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 6F546138C for ; Thu, 6 Aug 2020 16:48:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C3F412311B for ; Thu, 6 Aug 2020 16:48:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KN99vrOD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729429AbgHFQsr (ORCPT ); Thu, 6 Aug 2020 12:48:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41650 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728695AbgHFQmp (ORCPT ); Thu, 6 Aug 2020 12:42:45 -0400 Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78A42C0A893C for ; Thu, 6 Aug 2020 09:41:26 -0700 (PDT) Received: by mail-pl1-x642.google.com with SMTP id w17so27904820ply.11 for ; Thu, 06 Aug 2020 09:41:26 -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=w7u8wQpZMhwP7ijYPwyMtvsLyxsB0vZqqLb+xJfG2DA=; b=KN99vrODF+YwX5xlAL8iyJjW7bYgjJTnWN0Hh/fGAOPuDqrYSvc3JNYnSo+B0RcPPh AO9AQtMeD8xX9rAQsxwiD13oCZWxSdvSQFGqZ3tTmrAYOwMTrwvI1XajjTsCSfACLH28 ZRim6MpY8QEhLP9JCI5HFPPb/fugf+rPRTx6xi4Z4BlUydXYlqBBx47tzi/dhS42JvbC iWC+UfV28KBLVXw+/7HIONmVB0M03Nng6hY0rv6DtEpOGgn2kkDN4bNmrJR3G1m8/N+H ZOOlzBEbRjAPwISWURzJ+axEVWSmzhktkI5DL35dubQcRD0x4rPKBRijADRC68ppu+3U u+Bw== 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=w7u8wQpZMhwP7ijYPwyMtvsLyxsB0vZqqLb+xJfG2DA=; b=DME3D86OtHP52aaEObclvSNBOA1JehgdG1KwKVvuLYX3kI7cxJf94nlfLU6+vpL0/2 U6qlLZsGmRarb/ma6+CNz4nA0ovzxJnZJ3LtY6/d5AzoonMWk9UCQkjndd+BapLJcaH9 DZPZprlsLtyOZTgiOqE3X62V5BOhKgbk8A/+FOZezLQCGCY8hm6jw+svk3jjB9VF+Rb2 PDyUkpRWW6sMQoP4HH2Kab9t09/YIE8sBREGN2to4pr2U6vnKO9Lx0xKDWrvzgkJ3+nM kRRs7M551iqtyfm02F3dqyPtZHYDxsPkrKx6Wpe0ZB1CImt4wJRydeshdRpNXRzO0IiM qDjA== X-Gm-Message-State: AOAM530LQgAhtQ5aqcRT06GsjFuhMucct6EO23uUpbrJn5hrwUh2npeU jjV91FtAPOTOyyLMOqUbrgI7xWLHZ8I= X-Google-Smtp-Source: ABdhPJyt+eCsTGazwom3frf5jIOvAxZuzcXpOx+SfipoVJrvAhLzQ9QouLsQe26Fq3xoS/RQkz568A== X-Received: by 2002:a17:902:7b82:: with SMTP id w2mr8883173pll.39.1596732085500; Thu, 06 Aug 2020 09:41:25 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.60]) by smtp.gmail.com with ESMTPSA id w16sm8008381pjd.50.2020.08.06.09.41.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 09:41:24 -0700 (PDT) From: Shourya Shukla To: git@vger.kernel.org Cc: gitster@pobox.com, christian.couder@gmail.com, kaartic.sivaraam@gmail.com, johannes.schindelin@gmx.de, liu.denton@gmail.com, Shourya Shukla , Christian Couder Subject: [PATCH v2 3/5] submodule: rename helper functions to avoid ambiguity Date: Thu, 6 Aug 2020 22:11:00 +0530 Message-Id: <20200806164102.6707-4-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200806164102.6707-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-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 d24aaa3047..4a2c631c37 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 e2ef5698c8..097902ee67 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 4dad649f94..22db9e1832 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 Thu Aug 6 16:41: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: 11703543 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 803AC13B1 for ; Thu, 6 Aug 2020 16:49:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D63FA23119 for ; Thu, 6 Aug 2020 16:49:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oo1sZ5r8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729484AbgHFQsv (ORCPT ); Thu, 6 Aug 2020 12:48:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729104AbgHFQmp (ORCPT ); Thu, 6 Aug 2020 12:42:45 -0400 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84B03C0A893D for ; Thu, 6 Aug 2020 09:41:30 -0700 (PDT) Received: by mail-pl1-x643.google.com with SMTP id z20so7169242plo.6 for ; Thu, 06 Aug 2020 09:41:30 -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=xYsWR4N0FaViQvx0u0sEE0dvKb6/ML6Q2YctyD6XQq8=; b=oo1sZ5r8mX7zvtBbwTPc5/d36/izsN85OobelWp7M6A4DFVFAYshI9OsrM+zC6PRCK aqAtH4BJjrD6DWCJopNv7wWEvCe327CW84RAD05brpGbtpWMoY3SiRUZOz8J9Y+I6GFb iVqyLoujBNxmpYjjj//mAWuj5GOhyqis9G4Hrhbx3vZEub0d/Lk42XmtPuCdOLvdfh/A XP/QGN3gSEq9MAYd9rxZCCU7nlhQHY5YqYi0aRx3uZfRbk+TjX5kEhgOaPI7m6eY58DU musGhJAeJl6ywsxQCmkC3YlZkzsP/MTg3gIV+z19fPFI3/3bWs6tud6UbDoKUtHt6zUJ E1/Q== 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=xYsWR4N0FaViQvx0u0sEE0dvKb6/ML6Q2YctyD6XQq8=; b=R6FbozBSwyv8LVqr+umTSaMHQidFiIUT+Un174XOZUvt2aYlOJlYYp+7Adv9by3631 IyJarrk6HStrRYSuia6+rce5PPFNDxJ5gcchtGzfSnutUyMrgs4pT1i1GoJERIxfNziM WJRXK4hVJm0ZgCx0FJG1rBVGtvzGJLhapDC+cOKRSBj58kmAKCA34n2ERZyr0a7VBLcX YrQqVmexFcBYb8S7M6vl4L8u6ZFNycifW9+1geXM7B8tIvGsH/nXXknPDeAT4s5m5Gwg 8tjMOPMnEKH4JI99cPpc9ASd6V0+xhHk3LXzR7GMHiSB53Eoj4SA+spE+LSDO5p0jF8Q sTTA== X-Gm-Message-State: AOAM533AOy04g4b9rdR1Dg0aBJSmYMoHg+KwMNY4/lPMTmKZjffQKWpX mVVevkXUzr96WWXVUY/i2dtu4eumfUU= X-Google-Smtp-Source: ABdhPJyUQ1uDs1zFFo+hiB3ZXUaUyxAK/bYv43xtqyCNtgnjJ04r/FMQrZcZE1D43M4C0C3VtSOMrw== X-Received: by 2002:a17:90a:1d0f:: with SMTP id c15mr9668116pjd.180.1596732089495; Thu, 06 Aug 2020 09:41:29 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.60]) by smtp.gmail.com with ESMTPSA id w16sm8008381pjd.50.2020.08.06.09.41.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 09:41:28 -0700 (PDT) From: Shourya Shukla To: git@vger.kernel.org Cc: gitster@pobox.com, christian.couder@gmail.com, kaartic.sivaraam@gmail.com, johannes.schindelin@gmx.de, liu.denton@gmail.com, Shourya Shukla , Christian Couder Subject: [PATCH v2 4/5] t7421: introduce a test script for verifying 'summary' output Date: Thu, 6 Aug 2020 22:11:01 +0530 Message-Id: <20200806164102.6707-5-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200806164102.6707-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-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'. Mentored-by: Christian Couder Mentored-by: Kaartic Sivaraam Signed-off-by: Shourya Shukla --- t/t7421-submodule-summary-add.sh | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 t/t7421-submodule-summary-add.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 Thu Aug 6 16:41: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: 11703519 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 8F536138C for ; Thu, 6 Aug 2020 16:44:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D65012311B for ; Thu, 6 Aug 2020 16:44:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="q/6fXBRv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728680AbgHFQoI (ORCPT ); Thu, 6 Aug 2020 12:44:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729108AbgHFQmr (ORCPT ); Thu, 6 Aug 2020 12:42:47 -0400 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5442CC0A893E for ; Thu, 6 Aug 2020 09:41:37 -0700 (PDT) Received: by mail-pf1-x42f.google.com with SMTP id u128so27765pfb.6 for ; Thu, 06 Aug 2020 09:41:37 -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=8mdIZs/Pkn/WvMYhW7eSZbuS3HU/Bc2jIkQ3RaFA5qA=; b=q/6fXBRvrDMo/8c9SLGSn8NZZKndvnc1IMp80spI3JkM9hN0s8AFds5K7CERHz14G0 83YQCWHGpLCLNbE5rZJW45LJxM7HiOFOV48miwntGLFnuZn2fMPumv75VHXpWm7+iWts KXGi9hmZMeCP3zFIfNyLlISz8fNQnOCk6M3s1sZ+1IijCJXPluDDXexSAVzjzxPopuj4 Dcu8GuDChqBXhHcV687Mc+AmhDRUS5yTnANI8pHfBXQk+M8K55H8Tok1oW4vX3Bhpzr+ FUR/NZVDnoalOFm1ldp4age7XU8w1lpUdms4HaKXJhJoaGpAx1S8oVEvGhkLCowOG+Fj S38Q== 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=8mdIZs/Pkn/WvMYhW7eSZbuS3HU/Bc2jIkQ3RaFA5qA=; b=ZAus8FBTHo5K5EMONjAA3nev6tn08Z+xW92wt5g5me6TWZJnk56FwObaFqKuZ0SrRz d1v0DJRAsK6Ol5I9DRE9Zm/YBnEOaHfi2mqQ2QGB8l47W//ok6jomF1xBzh/dgAw7Lp1 /WtvIBDyHj/OFZFawIymZtMj+P2qxdw6V3Z4xaCbqePJ8XDUewT9uMNrm9igX5Bl1bRH qHSYyL4wg3m8/upf8hW5dJPewR2SpY3A73ylBo1qUZj8+Ggq5QtM84Ej8+XsN83WJt6+ Efz6Tf523gLDd4QEEZydhKv4iamNozc8T6mMuBTlJHU0g2YB27LZBn3KiFhlNuSkXjKL SIHw== X-Gm-Message-State: AOAM5306Q+ONqNMQm1OKHyHJC/CHoNEBqbHFHndsp6hQX3pTulOgzON6 ILRGkKO8z94ngJqO2T3xPovGuVOktPQ= X-Google-Smtp-Source: ABdhPJw09ef+NkxRXTa1dcYIn+4P79pfBvtScArAIBqFfofALPJKUzMOgY9G51rddDKRMvSZU32Cag== X-Received: by 2002:aa7:8c19:: with SMTP id c25mr9187426pfd.17.1596732094529; Thu, 06 Aug 2020 09:41:34 -0700 (PDT) Received: from localhost.localdomain ([45.127.46.60]) by smtp.gmail.com with ESMTPSA id w16sm8008381pjd.50.2020.08.06.09.41.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 09:41:33 -0700 (PDT) From: Shourya Shukla To: git@vger.kernel.org Cc: gitster@pobox.com, christian.couder@gmail.com, kaartic.sivaraam@gmail.com, johannes.schindelin@gmx.de, liu.denton@gmail.com, Prathamesh Chavan , Christian Couder , Stefan Beller , Johannes Schindelin , Shourya Shukla Subject: [PATCH v2 5/5] submodule: port submodule subcommand 'summary' from shell to C Date: Thu, 6 Aug 2020 22:11:02 +0530 Message-Id: <20200806164102.6707-6-shouryashukla.oo@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200806164102.6707-1-shouryashukla.oo@gmail.com> References: <20200806164102.6707-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 --- builtin/submodule--helper.c | 436 +++++++++++++++++++++++++++++++ git-submodule.sh | 186 +------------ t/t7421-submodule-summary-add.sh | 2 +- 3 files changed, 438 insertions(+), 186 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 3641718d0a..43ed2f645f 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -927,6 +927,441 @@ 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); + argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q", + "--short", NULL); + argv_array_pushf(&cp_rev_parse.args, "%s^0", committish); + argv_array_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); + argv_array_pushl(&cp_log.args, "log", NULL); + + if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) { + if (info->summary_limit > 0) + argv_array_pushf(&cp_log.args, "-%d", + info->summary_limit); + + argv_array_pushl(&cp_log.args, "--pretty= %m %s", + "--first-parent", NULL); + argv_array_pushf(&cp_log.args, "%s...%s", + src_abbrev, + dst_abbrev); + } else if (S_ISGITLINK(p->mod_dst)) { + argv_array_pushl(&cp_log.args, "--pretty= > %s", + "-1", dst_abbrev, NULL); + } else { + argv_array_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; + + argv_array_pushl(&cp_rev_list.args, "rev-list", + "--first-parent", "--count", NULL); + if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) + argv_array_pushf(&cp_rev_list.args, "%s...%s", + src_abbrev, + dst_abbrev); + else + argv_array_push(&cp_rev_list.args, + S_ISGITLINK(p->mod_src) ? + src_abbrev : + dst_abbrev); + argv_array_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 argv_array diff_args = ARGV_ARRAY_INIT; + struct rev_info rev; + struct module_cb_list list = MODULE_CB_LIST_INIT; + + argv_array_push(&diff_args, get_diff_cmd(diff_cmd)); + if (info->cached) + argv_array_push(&diff_args, "--cached"); + argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw", + NULL); + if (head_oid) + argv_array_push(&diff_args, oid_to_hex(head_oid)); + argv_array_push(&diff_args, "--"); + if (info->argc) + argv_array_pushv(&diff_args, info->argv); + + git_config(git_diff_basic_config, NULL); + init_revisions(&rev, info->prefix); + rev.abbrev = 0; + precompose_argv(diff_args.argc, diff_args.argv); + + diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv, + &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); + 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 +2776,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 dda3fee167..236a08f27d 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: