{"thread":{"id":"53694","subject":"[PATCH 1/2] [RFC] wt-status: show sparse checkout status as well","startedAt":"2020-06-16T23:33:39Z","lastAt":"2020-06-22T16:35:39Z","messageCount":19,"participants":["Elijah Newren via GitGitGadget","Derrick Stolee","Elijah Newren","Junio C Hamano","SZEDER Gábor"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"399944","messageId":"462cee857ef30c413eda0abe655b123f32b3877e.1592350413.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.git.git.1592350413.gitgitgadget@gmail.com","subject":"[PATCH 1/2] [RFC] wt-status: show sparse checkout status as well","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-16T23:33:32Z","receivedAt":"2020-06-16T23:33:39Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSome of the early feedback of folks trying out sparse-checkouts at\n$dayjob is that sparse checkouts can sometimes be disorienting; users\ncan forget that they had a sparse-checkout and then wonder where files\nwent.  Add some output to 'git status' in the form of a simple line that\nstates:\n\n    You are in a sparse checkout with 35% of files present.\n\nwhere, obviously, the exact figure changes depending on what percentage\nof files from the index do not have the SKIP_WORKTREE bit set.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n wt-status.c | 35 +++++++++++++++++++++++++++++++++++\n wt-status.h |  1 +\n 2 files changed, 36 insertions(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 98dfa6f73f9..687d2ab1ba1 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1484,6 +1484,16 @@ static void show_bisect_in_progress(struct wt_status *s,\n \twt_longstatus_print_trailer(s);\n }\n \n+static void show_sparse_checkout_in_use(struct wt_status *s,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (s->state.sparse_checkout_percentage != -1)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t\t _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n+\t\t\t\t s->state.sparse_checkout_percentage);\n+\twt_longstatus_print_trailer(s);\n+}\n+\n /*\n  * Extract branch information from rebase/bisect\n  */\n@@ -1623,6 +1633,27 @@ int wt_status_check_bisect(const struct worktree *wt,\n \treturn 0;\n }\n \n+static void wt_status_check_sparse_checkout(struct repository *r,\n+\t\t\t\t\t    struct wt_status_state *state)\n+{\n+\tint skip_worktree = 0;\n+\tint i;\n+\n+\tif (!core_apply_sparse_checkout) {\n+\t\tstate->sparse_checkout_percentage = -1;\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < r->index->cache_nr; i++) {\n+\t\tstruct cache_entry *ce = r->index->cache[i];\n+\t\tif (ce_skip_worktree(ce))\n+\t\t\tskip_worktree++;\n+\t}\n+\n+\tstate->sparse_checkout_percentage =\n+\t\t100 - (100 * skip_worktree)/r->index->cache_nr;\n+}\n+\n void wt_status_get_state(struct repository *r,\n \t\t\t struct wt_status_state *state,\n \t\t\t int get_detached_from)\n@@ -1658,6 +1689,7 @@ void wt_status_get_state(struct repository *r,\n \t}\n \tif (get_detached_from)\n \t\twt_status_get_detached_from(r, state);\n+\twt_status_check_sparse_checkout(r, state);\n }\n \n static void wt_longstatus_print_state(struct wt_status *s)\n@@ -1681,6 +1713,9 @@ static void wt_longstatus_print_state(struct wt_status *s)\n \t\tshow_revert_in_progress(s, state_color);\n \tif (state->bisect_in_progress)\n \t\tshow_bisect_in_progress(s, state_color);\n+\n+\tif (state->sparse_checkout_percentage != -1)\n+\t\tshow_sparse_checkout_in_use(s, state_color);\n }\n \n static void wt_longstatus_print(struct wt_status *s)\ndiff --git a/wt-status.h b/wt-status.h\nindex 73ab5d4da1c..4550004003a 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -90,6 +90,7 @@ struct wt_status_state {\n \tint bisect_in_progress;\n \tint revert_in_progress;\n \tint detached_at;\n+\tint sparse_checkout_percentage; /* -1 == not in sparse checkout */\n \tchar *branch;\n \tchar *onto;\n \tchar *detached_from;\n-- \ngitgitgadget\n\n"},{"id":"399945","messageId":"64613ad7ad6e5224c9d36fd1fd6222cbd3538705.1592350413.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.git.git.1592350413.gitgitgadget@gmail.com","subject":"[PATCH 2/2] [RFC] git-prompt: include sparsity state as well","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-16T23:33:33Z","receivedAt":"2020-06-16T23:33:39Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThe current git prompt includes a lot of possible state information, from\nvarious flavors of rebases to cherry-picks, or merges, or bisects.  Add\nsparsity as another state flavor (though one which can be present\nsimultaneously with any of rebase/cherry-pick/merge/bisect).  This extra\nstate is shown with an extra\n    |SPARSE\nsubstring before the other states.  (Sparsity is probably not going to\nchange much within a repository, while temporary operations will.  So we\nwant the temporary operation related state changes to be listed last, to\nmake them appear closer to where the user types and make them more\nlikely to be noticed.)  Thus, for example, the prompt might look like:\n    (branchname|SPARSE|REBASE 6/10)\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-prompt.sh | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex 014cd7c3cfc..3e7344a4014 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -421,6 +421,11 @@ __git_ps1 ()\n \t\treturn $exit\n \tfi\n \n+\tlocal sparse=\"\"\n+\tif [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n+\t    sparse=\"|SPARSE\"\n+\tfi\n+\n \tlocal r=\"\"\n \tlocal b=\"\"\n \tlocal step=\"\"\n@@ -543,7 +548,7 @@ __git_ps1 ()\n \tfi\n \n \tlocal f=\"$w$i$s$u\"\n-\tlocal gitstring=\"$c$b${f:+$z$f}$r$p\"\n+\tlocal gitstring=\"$c$b${f:+$z$f}${sparse}$r$p\"\n \n \tif [ $pcmode = yes ]; then\n \t\tif [ \"${__git_printf_supports_v-}\" != yes ]; then\n-- \ngitgitgadget\n"},{"id":"399946","messageId":"pull.808.git.git.1592350413.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":null,"subject":"[PATCH 0/2] Sparse checkout status","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-16T23:33:31Z","receivedAt":"2020-06-16T23:33:40Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Some of the feedback of folks trying out sparse-checkouts at $dayjob is that\nsparse checkouts can sometimes be disorienting; users can forget that they\nhad a sparse-checkout and then wonder where files went. This series adds\nsome output to 'git status' and modifies git-prompt slightly as an attempt\nto help.\n\nFor reference, I suspect that in repositories that are large enough that\npeople always use sparse-checkouts (e.g. windows or office repos), that this\nisn't a problem. But when the repository is approximately\nlinux-kernel-sized, then it is reasonable for some folks to have a full\ncheckout. sparse-checkouts, however, can provide various build system and\nIDE performance improvements, so we have a split of users who have\nsparse-checkouts and those who have full checkouts. It's easy for users who\nare bridging in between the two worlds or just trying out sparse-checkouts\nfor the first time to get confused.\n\nElijah Newren (2):\n  [RFC] wt-status: show sparse checkout status as well\n  [RFC] git-prompt: include sparsity state as well\n\n contrib/completion/git-prompt.sh |  7 ++++++-\n wt-status.c                      | 35 ++++++++++++++++++++++++++++++++\n wt-status.h                      |  1 +\n 3 files changed, 42 insertions(+), 1 deletion(-)\n\n\nbase-commit: eebb51ba8cab97c0b3f3f18eaab7796803b8494b\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-808%2Fnewren%2Fsparse-checkout-status-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-808/newren/sparse-checkout-status-v1\nPull-Request: https://github.com/git/git/pull/808\n-- \ngitgitgadget\n"},{"id":"399974","messageId":"e8e59662-7e8b-6aae-da28-c4b5ee225ac8@gmail.com","threadId":"53694","inReplyTo":"462cee857ef30c413eda0abe655b123f32b3877e.1592350413.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/2] [RFC] wt-status: show sparse checkout status as well","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2020-06-17T14:50:49Z","receivedAt":"2020-06-17T14:50:54Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 6/16/2020 7:33 PM, Elijah Newren via GitGitGadget wrote:\n> From: Elijah Newren <newren@gmail.com>\n> \n> Some of the early feedback of folks trying out sparse-checkouts at\n> $dayjob is that sparse checkouts can sometimes be disorienting; users\n> can forget that they had a sparse-checkout and then wonder where files\n> went.  Add some output to 'git status' in the form of a simple line that\n> states:\n> \n>     You are in a sparse checkout with 35% of files present.\n\nI like this idea.\n\nAside: I think there was some ideas around a \"git sparse-checkout stats\"\nsubcommand that would help users identify how large their sparse-checkout\ndefinition is compared to the full index. That would also want to drill\ndown into directories, so it would need to be more advanced than what you\nhave here.\n\nThere is some prior work in the \"gvfs health\" commmand in VFS for Git.\nWe use this to help users self-diagnose when they have \"over hydrated\"\ntheir working directory. Here is a sample use:\n\n  /c/_git/t/ForTests/src (master)\n  $ gvfs health\n  \n  Gathering repository data...\n  \n  Health of directory:\n  Total files in HEAD commit:           548 | 100%\n  Files managed by VFS for Git (fast):   30 |   5%\n  Files managed by Git:                   1 |   0%\n  \n  Total hydration percentage:                   6%\n  \n  Most hydrated top level directories:\n   19 / 524 | GVFS\n    0 / 8   | GitHooksLoader\n    0 / 3   | Scripts\n  \n  Repository status: OK\n  \n  /c/_git/t/ForTests/src (master)\n  $ cd GVFS\n  \n  /c/_git/t/ForTests/src/GVFS (master)\n  $ gvfs health\n  \n  Gathering repository data...\n  \n  Health of directory: GVFS/\n  Total files in HEAD commit:           524 | 100%\n  Files managed by VFS for Git (fast):   19 |   4%\n  Files managed by Git:                   0 |   0%\n  \n  Total hydration percentage:                   4%\n  \n  Most hydrated top level directories:\n   0 / 33 | FastFetch\n   0 / 92 | GVFS.Common\n   0 / 97 | GVFS.FunctionalTests\n   0 / 22 | GVFS.GVFlt\n   0 / 7  | GVFS.Hooks\n  \n  Repository status: OK\n\nThis is just a reference for something that has been helpful\nfor some users. In VFS for Git, the hydration is not explicit\nbut instead implicit by filesystem use. There could still be\nsome value in the sparse-checkout case.\n\n> where, obviously, the exact figure changes depending on what percentage\n> of files from the index do not have the SKIP_WORKTREE bit set.\n> \n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n>  wt-status.c | 35 +++++++++++++++++++++++++++++++++++\n>  wt-status.h |  1 +\n>  2 files changed, 36 insertions(+)\n> \n> diff --git a/wt-status.c b/wt-status.c\n> index 98dfa6f73f9..687d2ab1ba1 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -1484,6 +1484,16 @@ static void show_bisect_in_progress(struct wt_status *s,\n>  \twt_longstatus_print_trailer(s);\n>  }\n>  \n> +static void show_sparse_checkout_in_use(struct wt_status *s,\n> +\t\t\t\t\tconst char *color)\n> +{\n> +\tif (s->state.sparse_checkout_percentage != -1)\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n> +\t\t\t\t s->state.sparse_checkout_percentage);\n\nThere is some concern over breaking third-party tools that\nparse \"git status\". However, we have had the machine-readable\nformats out for a long time.\n\nI briefly thought about putting this message to stderr to be\nsafe, but some tools scan stderr (incorrectly) to say \"any\noutput to stderr must mean an error in the process.\"\n\n> +\twt_longstatus_print_trailer(s);\n> +}\n> +\n>  /*\n>   * Extract branch information from rebase/bisect\n>   */\n> @@ -1623,6 +1633,27 @@ int wt_status_check_bisect(const struct worktree *wt,\n>  \treturn 0;\n>  }\n>  \n> +static void wt_status_check_sparse_checkout(struct repository *r,\n> +\t\t\t\t\t    struct wt_status_state *state)\n> +{\n> +\tint skip_worktree = 0;\n> +\tint i;\n> +\n> +\tif (!core_apply_sparse_checkout) {\n\nSince this method is static, we can assume that it is only\ncalled after the index was loaded, which requires reading\nthe config and initializing this value. Good.\n\n> +\t\tstate->sparse_checkout_percentage = -1;\n> +\t\treturn;\n> +\t}\n> +\n> +\tfor (i = 0; i < r->index->cache_nr; i++) {\n> +\t\tstruct cache_entry *ce = r->index->cache[i];\n> +\t\tif (ce_skip_worktree(ce))\n> +\t\t\tskip_worktree++;\n> +\t}\n> +\n> +\tstate->sparse_checkout_percentage =\n> +\t\t100 - (100 * skip_worktree)/r->index->cache_nr;\n> +}\n> +\n>  void wt_status_get_state(struct repository *r,\n>  \t\t\t struct wt_status_state *state,\n>  \t\t\t int get_detached_from)\n> @@ -1658,6 +1689,7 @@ void wt_status_get_state(struct repository *r,\n>  \t}\n>  \tif (get_detached_from)\n>  \t\twt_status_get_detached_from(r, state);\n> +\twt_status_check_sparse_checkout(r, state);\n>  }\n>  \n>  static void wt_longstatus_print_state(struct wt_status *s)\n> @@ -1681,6 +1713,9 @@ static void wt_longstatus_print_state(struct wt_status *s)\n>  \t\tshow_revert_in_progress(s, state_color);\n>  \tif (state->bisect_in_progress)\n>  \t\tshow_bisect_in_progress(s, state_color);\n> +\n> +\tif (state->sparse_checkout_percentage != -1)\n> +\t\tshow_sparse_checkout_in_use(s, state_color);\n>  }\n>  \n>  static void wt_longstatus_print(struct wt_status *s)\n> diff --git a/wt-status.h b/wt-status.h\n> index 73ab5d4da1c..4550004003a 100644\n> --- a/wt-status.h\n> +++ b/wt-status.h\n> @@ -90,6 +90,7 @@ struct wt_status_state {\n>  \tint bisect_in_progress;\n>  \tint revert_in_progress;\n>  \tint detached_at;\n> +\tint sparse_checkout_percentage; /* -1 == not in sparse checkout */\n\nMy only complaint is that maybe this \"-1\" should be a\n#define macro with a name such as SPARSE_CHECKOUT_DISABLED.\n\nThanks,\n-Stolee\n\n"},{"id":"399975","messageId":"CABPp-BG1AhRaz5oWQMhLnsbMoiNr8-xmV1CoTvTQj0Lg4_Np0g@mail.gmail.com","threadId":"53694","inReplyTo":"e8e59662-7e8b-6aae-da28-c4b5ee225ac8@gmail.com","subject":"Re: [PATCH 1/2] [RFC] wt-status: show sparse checkout status as well","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-06-17T15:46:39Z","receivedAt":"2020-06-17T15:46:54Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jun 17, 2020 at 7:50 AM Derrick Stolee <stolee@gmail.com> wrote:\n>\n> On 6/16/2020 7:33 PM, Elijah Newren via GitGitGadget wrote:\n> > From: Elijah Newren <newren@gmail.com>\n> >\n> > Some of the early feedback of folks trying out sparse-checkouts at\n> > $dayjob is that sparse checkouts can sometimes be disorienting; users\n> > can forget that they had a sparse-checkout and then wonder where files\n> > went.  Add some output to 'git status' in the form of a simple line that\n> > states:\n> >\n> >     You are in a sparse checkout with 35% of files present.\n>\n> I like this idea.\n>\n> Aside: I think there was some ideas around a \"git sparse-checkout stats\"\n> subcommand that would help users identify how large their sparse-checkout\n> definition is compared to the full index. That would also want to drill\n> down into directories, so it would need to be more advanced than what you\n> have here.\n\nYeah having an \"info\" or \"status\" or \"stats\" subcommand to\nsparse-checkout I think would make sense.  I think having some simple\nmessage of some kind in \"git status\" would help alert/remind someone\nthat they have a sparse checkout, and then they can run some\nsparse-checkout command if they want to drill down more.\n\n> There is some prior work in the \"gvfs health\" commmand in VFS for Git.\n> We use this to help users self-diagnose when they have \"over hydrated\"\n> their working directory. Here is a sample use:\n>\n>   /c/_git/t/ForTests/src (master)\n>   $ gvfs health\n>\n>   Gathering repository data...\n>\n>   Health of directory:\n>   Total files in HEAD commit:           548 | 100%\n>   Files managed by VFS for Git (fast):   30 |   5%\n>   Files managed by Git:                   1 |   0%\n>\n>   Total hydration percentage:                   6%\n>\n>   Most hydrated top level directories:\n>    19 / 524 | GVFS\n>     0 / 8   | GitHooksLoader\n>     0 / 3   | Scripts\n>\n>   Repository status: OK\n>\n>   /c/_git/t/ForTests/src (master)\n>   $ cd GVFS\n>\n>   /c/_git/t/ForTests/src/GVFS (master)\n>   $ gvfs health\n>\n>   Gathering repository data...\n>\n>   Health of directory: GVFS/\n>   Total files in HEAD commit:           524 | 100%\n>   Files managed by VFS for Git (fast):   19 |   4%\n>   Files managed by Git:                   0 |   0%\n>\n>   Total hydration percentage:                   4%\n>\n>   Most hydrated top level directories:\n>    0 / 33 | FastFetch\n>    0 / 92 | GVFS.Common\n>    0 / 97 | GVFS.FunctionalTests\n>    0 / 22 | GVFS.GVFlt\n>    0 / 7  | GVFS.Hooks\n>\n>   Repository status: OK\n>\n> This is just a reference for something that has been helpful\n> for some users. In VFS for Git, the hydration is not explicit\n> but instead implicit by filesystem use. There could still be\n> some value in the sparse-checkout case.\n\nYeah, I think a `git sparse-checkout` subcommand named 'info' or\n'status' with some kind of extra details could be useful, especially\nif/when your in-tree sparse checkout definitions are in use.  Our\nlocal 'sparsify' script has an --info flag which reports some\ninformation, though not as detailed as your gvfs health command:\n\n    $ ./sparsify --info\n    You are now in a sparse checkout with only 9874 of the 56079 files.\n    Sparse modules requested:\n      $MODULE_1\n      $MODULE_2\n    No user-specified additional paths -- tools/scripts/etc.\n    Note: You have leftover .gitignore'd files in 197 directories;\n          these likely represent build artifacts.\n          To remove, run: ./sparsify --update --remove-old-ignores\n\nThe last three lines are a repeat of the same output shown at\n'./sparsify --modules ...' time; I sent a separate email about that.\nThe fifth line might bear some explaining and be interesting as well:\nsince we have a dependency system where users specify some modules\n(directories) and then sparsify figures out all the other directories\nthat those ones depend upon, there isn't flexibility to select\nadditional files or directories the user may want.  We instead allow\nthe user to populate .git/info/sparse-checkout-user (not sure I'm\nstill a fan of the filename/location, but it's what I picked at the\ntime), which provides a list of additional directories that will be\nadded to the sparse-checkout on top of the dependencies of the modules\nthe user specifies.\n\n> > where, obviously, the exact figure changes depending on what percentage\n> > of files from the index do not have the SKIP_WORKTREE bit set.\n> >\n> > Signed-off-by: Elijah Newren <newren@gmail.com>\n> > ---\n> >  wt-status.c | 35 +++++++++++++++++++++++++++++++++++\n> >  wt-status.h |  1 +\n> >  2 files changed, 36 insertions(+)\n> >\n> > diff --git a/wt-status.c b/wt-status.c\n> > index 98dfa6f73f9..687d2ab1ba1 100644\n> > --- a/wt-status.c\n> > +++ b/wt-status.c\n> > @@ -1484,6 +1484,16 @@ static void show_bisect_in_progress(struct wt_status *s,\n> >       wt_longstatus_print_trailer(s);\n> >  }\n> >\n> > +static void show_sparse_checkout_in_use(struct wt_status *s,\n> > +                                     const char *color)\n> > +{\n> > +     if (s->state.sparse_checkout_percentage != -1)\n> > +             status_printf_ln(s, color,\n> > +                              _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n> > +                              s->state.sparse_checkout_percentage);\n>\n> There is some concern over breaking third-party tools that\n> parse \"git status\". However, we have had the machine-readable\n> formats out for a long time.\n>\n> I briefly thought about putting this message to stderr to be\n> safe, but some tools scan stderr (incorrectly) to say \"any\n> output to stderr must mean an error in the process.\"\n\nIf we hadn't taken steps over a decade ago (Sep 5, 2009) to avert this\nexact problem, then I'd be sympathetic to this concern.  But since\nwe've had --porcelain for over a decade I'm just not.  Third-party\ntools that are parsing git-status have had far more than enough time\nto switch, and if they haven't, maybe we could consider changing the\nstatus output to help remind them that they need to.  ;-)\n\nHowever, there is another point here that is very interesting: I only\nmodified the long status output, but it's possible I also should have\nmodified other formats too.  In particular, both the --short and\n--porcelain=v2 formats (Porcelain V2 defines an extensible set of\nheaders and explicitly says that parsers should ignore headers they\ndon't recognize, so adding a header to it is in line with its design\nand won't break existing parsers.)\n\n>\n> > +     wt_longstatus_print_trailer(s);\n> > +}\n> > +\n> >  /*\n> >   * Extract branch information from rebase/bisect\n> >   */\n> > @@ -1623,6 +1633,27 @@ int wt_status_check_bisect(const struct worktree *wt,\n> >       return 0;\n> >  }\n> >\n> > +static void wt_status_check_sparse_checkout(struct repository *r,\n> > +                                         struct wt_status_state *state)\n> > +{\n> > +     int skip_worktree = 0;\n> > +     int i;\n> > +\n> > +     if (!core_apply_sparse_checkout) {\n>\n> Since this method is static, we can assume that it is only\n> called after the index was loaded, which requires reading\n> the config and initializing this value. Good.\n>\n> > +             state->sparse_checkout_percentage = -1;\n> > +             return;\n> > +     }\n> > +\n> > +     for (i = 0; i < r->index->cache_nr; i++) {\n> > +             struct cache_entry *ce = r->index->cache[i];\n> > +             if (ce_skip_worktree(ce))\n> > +                     skip_worktree++;\n> > +     }\n> > +\n> > +     state->sparse_checkout_percentage =\n> > +             100 - (100 * skip_worktree)/r->index->cache_nr;\n> > +}\n> > +\n> >  void wt_status_get_state(struct repository *r,\n> >                        struct wt_status_state *state,\n> >                        int get_detached_from)\n> > @@ -1658,6 +1689,7 @@ void wt_status_get_state(struct repository *r,\n> >       }\n> >       if (get_detached_from)\n> >               wt_status_get_detached_from(r, state);\n> > +     wt_status_check_sparse_checkout(r, state);\n> >  }\n> >\n> >  static void wt_longstatus_print_state(struct wt_status *s)\n> > @@ -1681,6 +1713,9 @@ static void wt_longstatus_print_state(struct wt_status *s)\n> >               show_revert_in_progress(s, state_color);\n> >       if (state->bisect_in_progress)\n> >               show_bisect_in_progress(s, state_color);\n> > +\n> > +     if (state->sparse_checkout_percentage != -1)\n> > +             show_sparse_checkout_in_use(s, state_color);\n> >  }\n> >\n> >  static void wt_longstatus_print(struct wt_status *s)\n> > diff --git a/wt-status.h b/wt-status.h\n> > index 73ab5d4da1c..4550004003a 100644\n> > --- a/wt-status.h\n> > +++ b/wt-status.h\n> > @@ -90,6 +90,7 @@ struct wt_status_state {\n> >       int bisect_in_progress;\n> >       int revert_in_progress;\n> >       int detached_at;\n> > +     int sparse_checkout_percentage; /* -1 == not in sparse checkout */\n>\n> My only complaint is that maybe this \"-1\" should be a\n> #define macro with a name such as SPARSE_CHECKOUT_DISABLED.\n\nGood point, I'll update it.\n\nThanks!\nElijah\n"},{"id":"400086","messageId":"pull.808.v2.git.git.1592513398.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.git.git.1592350413.gitgitgadget@gmail.com","subject":"[PATCH v2 0/2] Sparse checkout status","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-18T20:49:56Z","receivedAt":"2020-06-18T20:50:03Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Some of the feedback of folks trying out sparse-checkouts at $dayjob is that\nsparse checkouts can sometimes be disorienting; users can forget that they\nhad a sparse-checkout and then wonder where files went. This series adds\nsome output to 'git status' and modifies git-prompt slightly as an attempt\nto help.\n\nNote that as per discussion on v1, we may want to later add a git\nsparse-checkout subcommand named something like 'stats' or 'info' or\n'status' that provides more detailed information for users to dig deeper.\nThat would be an additional improvement for helping users find out more\ninformation once they realize or remember they are in a sparse checkout,\nthis is just aimed at giving them a simple reminder.\n\nChanges since v1:\n\n * Replaced the -1 magic constant with SPARSE_CHECKOUT_DISABLED\n * Fixed a possible division by 0 (when there are no entries in the index\n   AND sparse checkout is enabled; not sure when that'd ever happen but\n   still better to guard against...)\n * Slight wording tweaks for the git-prompt commit message\n * Removed the RFC label\n\nElijah Newren (2):\n  wt-status: show sparse checkout status as well\n  git-prompt: include sparsity state as well\n\n contrib/completion/git-prompt.sh |  7 +++++-\n wt-status.c                      | 41 ++++++++++++++++++++++++++++++++\n wt-status.h                      |  2 ++\n 3 files changed, 49 insertions(+), 1 deletion(-)\n\n\nbase-commit: b3d7a52fac39193503a0b6728771d1bf6a161464\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-808%2Fnewren%2Fsparse-checkout-status-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-808/newren/sparse-checkout-status-v2\nPull-Request: https://github.com/git/git/pull/808\n\nRange-diff vs v1:\n\n 1:  462cee857ef ! 1:  e266bc39d99 [RFC] wt-status: show sparse checkout status as well\n     @@ Metadata\n      Author: Elijah Newren <newren@gmail.com>\n      \n       ## Commit message ##\n     -    [RFC] wt-status: show sparse checkout status as well\n     +    wt-status: show sparse checkout status as well\n      \n          Some of the early feedback of folks trying out sparse-checkouts at\n          $dayjob is that sparse checkouts can sometimes be disorienting; users\n     @@ wt-status.c: static void show_bisect_in_progress(struct wt_status *s,\n      +static void show_sparse_checkout_in_use(struct wt_status *s,\n      +\t\t\t\t\tconst char *color)\n      +{\n     -+\tif (s->state.sparse_checkout_percentage != -1)\n     -+\t\tstatus_printf_ln(s, color,\n     -+\t\t\t\t _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n     -+\t\t\t\t s->state.sparse_checkout_percentage);\n     ++\tif (s->state.sparse_checkout_percentage == SPARSE_CHECKOUT_DISABLED)\n     ++\t\treturn;\n     ++\n     ++\tstatus_printf_ln(s, color,\n     ++\t\t\t _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n     ++\t\t\t s->state.sparse_checkout_percentage);\n      +\twt_longstatus_print_trailer(s);\n      +}\n      +\n     @@ wt-status.c: int wt_status_check_bisect(const struct worktree *wt,\n      +\tint skip_worktree = 0;\n      +\tint i;\n      +\n     -+\tif (!core_apply_sparse_checkout) {\n     -+\t\tstate->sparse_checkout_percentage = -1;\n     ++\tif (!core_apply_sparse_checkout || r->index->cache_nr == 0) {\n     ++\t\t/*\n     ++\t\t * Don't compute percentage of checked out files if we\n     ++\t\t * aren't in a sparse checkout or would get division by 0.\n     ++\t\t */\n     ++\t\tstate->sparse_checkout_percentage = SPARSE_CHECKOUT_DISABLED;\n      +\t\treturn;\n      +\t}\n      +\n     @@ wt-status.c: static void wt_longstatus_print_state(struct wt_status *s)\n       \tif (state->bisect_in_progress)\n       \t\tshow_bisect_in_progress(s, state_color);\n      +\n     -+\tif (state->sparse_checkout_percentage != -1)\n     ++\tif (state->sparse_checkout_percentage != SPARSE_CHECKOUT_DISABLED)\n      +\t\tshow_sparse_checkout_in_use(s, state_color);\n       }\n       \n       static void wt_longstatus_print(struct wt_status *s)\n      \n       ## wt-status.h ##\n     +@@ wt-status.h: enum wt_status_format {\n     + \n     + #define HEAD_DETACHED_AT _(\"HEAD detached at \")\n     + #define HEAD_DETACHED_FROM _(\"HEAD detached from \")\n     ++#define SPARSE_CHECKOUT_DISABLED -1\n     + \n     + struct wt_status_state {\n     + \tint merge_in_progress;\n      @@ wt-status.h: struct wt_status_state {\n       \tint bisect_in_progress;\n       \tint revert_in_progress;\n       \tint detached_at;\n     -+\tint sparse_checkout_percentage; /* -1 == not in sparse checkout */\n     ++\tint sparse_checkout_percentage; /* SPARSE_CHECKOUT_DISABLED if not sparse */\n       \tchar *branch;\n       \tchar *onto;\n       \tchar *detached_from;\n 2:  64613ad7ad6 ! 2:  17254b30a5b [RFC] git-prompt: include sparsity state as well\n     @@ Metadata\n      Author: Elijah Newren <newren@gmail.com>\n      \n       ## Commit message ##\n     -    [RFC] git-prompt: include sparsity state as well\n     +    git-prompt: include sparsity state as well\n      \n     -    The current git prompt includes a lot of possible state information, from\n     -    various flavors of rebases to cherry-picks, or merges, or bisects.  Add\n     +    The current git prompt includes a lot of possible state information from\n     +    cherry-picks, merges, bisects, and various flavors of rebases.  Add\n          sparsity as another state flavor (though one which can be present\n          simultaneously with any of rebase/cherry-pick/merge/bisect).  This extra\n          state is shown with an extra\n              |SPARSE\n     -    substring before the other states.  (Sparsity is probably not going to\n     -    change much within a repository, while temporary operations will.  So we\n     -    want the temporary operation related state changes to be listed last, to\n     -    make them appear closer to where the user types and make them more\n     -    likely to be noticed.)  Thus, for example, the prompt might look like:\n     +    substring before the other states, providing a prompt that looks like:\n              (branchname|SPARSE|REBASE 6/10)\n      \n     +    The reason for showing the \"|SPARSE\" substring before other states is to\n     +    emphasize those other states.  Sparsity is probably not going to change\n     +    much within a repository, while temporary operations will.  So we want\n     +    the state changes related to temporary operations to be listed last, to\n     +    make them appear closer to where the user types and make them more\n     +    likely to be noticed.\n     +\n          Signed-off-by: Elijah Newren <newren@gmail.com>\n      \n       ## contrib/completion/git-prompt.sh ##\n\n-- \ngitgitgadget\n"},{"id":"400087","messageId":"e266bc39d99006715482c5186912717651987f3e.1592513398.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.v2.git.git.1592513398.gitgitgadget@gmail.com","subject":"[PATCH v2 1/2] wt-status: show sparse checkout status as well","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-18T20:49:57Z","receivedAt":"2020-06-18T20:50:06Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSome of the early feedback of folks trying out sparse-checkouts at\n$dayjob is that sparse checkouts can sometimes be disorienting; users\ncan forget that they had a sparse-checkout and then wonder where files\nwent.  Add some output to 'git status' in the form of a simple line that\nstates:\n\n    You are in a sparse checkout with 35% of files present.\n\nwhere, obviously, the exact figure changes depending on what percentage\nof files from the index do not have the SKIP_WORKTREE bit set.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n wt-status.c | 41 +++++++++++++++++++++++++++++++++++++++++\n wt-status.h |  2 ++\n 2 files changed, 43 insertions(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 98dfa6f73f9..c560cbe860a 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1484,6 +1484,18 @@ static void show_bisect_in_progress(struct wt_status *s,\n \twt_longstatus_print_trailer(s);\n }\n \n+static void show_sparse_checkout_in_use(struct wt_status *s,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (s->state.sparse_checkout_percentage == SPARSE_CHECKOUT_DISABLED)\n+\t\treturn;\n+\n+\tstatus_printf_ln(s, color,\n+\t\t\t _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n+\t\t\t s->state.sparse_checkout_percentage);\n+\twt_longstatus_print_trailer(s);\n+}\n+\n /*\n  * Extract branch information from rebase/bisect\n  */\n@@ -1623,6 +1635,31 @@ int wt_status_check_bisect(const struct worktree *wt,\n \treturn 0;\n }\n \n+static void wt_status_check_sparse_checkout(struct repository *r,\n+\t\t\t\t\t    struct wt_status_state *state)\n+{\n+\tint skip_worktree = 0;\n+\tint i;\n+\n+\tif (!core_apply_sparse_checkout || r->index->cache_nr == 0) {\n+\t\t/*\n+\t\t * Don't compute percentage of checked out files if we\n+\t\t * aren't in a sparse checkout or would get division by 0.\n+\t\t */\n+\t\tstate->sparse_checkout_percentage = SPARSE_CHECKOUT_DISABLED;\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < r->index->cache_nr; i++) {\n+\t\tstruct cache_entry *ce = r->index->cache[i];\n+\t\tif (ce_skip_worktree(ce))\n+\t\t\tskip_worktree++;\n+\t}\n+\n+\tstate->sparse_checkout_percentage =\n+\t\t100 - (100 * skip_worktree)/r->index->cache_nr;\n+}\n+\n void wt_status_get_state(struct repository *r,\n \t\t\t struct wt_status_state *state,\n \t\t\t int get_detached_from)\n@@ -1658,6 +1695,7 @@ void wt_status_get_state(struct repository *r,\n \t}\n \tif (get_detached_from)\n \t\twt_status_get_detached_from(r, state);\n+\twt_status_check_sparse_checkout(r, state);\n }\n \n static void wt_longstatus_print_state(struct wt_status *s)\n@@ -1681,6 +1719,9 @@ static void wt_longstatus_print_state(struct wt_status *s)\n \t\tshow_revert_in_progress(s, state_color);\n \tif (state->bisect_in_progress)\n \t\tshow_bisect_in_progress(s, state_color);\n+\n+\tif (state->sparse_checkout_percentage != SPARSE_CHECKOUT_DISABLED)\n+\t\tshow_sparse_checkout_in_use(s, state_color);\n }\n \n static void wt_longstatus_print(struct wt_status *s)\ndiff --git a/wt-status.h b/wt-status.h\nindex 73ab5d4da1c..f1fa0ec1a75 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -79,6 +79,7 @@ enum wt_status_format {\n \n #define HEAD_DETACHED_AT _(\"HEAD detached at \")\n #define HEAD_DETACHED_FROM _(\"HEAD detached from \")\n+#define SPARSE_CHECKOUT_DISABLED -1\n \n struct wt_status_state {\n \tint merge_in_progress;\n@@ -90,6 +91,7 @@ struct wt_status_state {\n \tint bisect_in_progress;\n \tint revert_in_progress;\n \tint detached_at;\n+\tint sparse_checkout_percentage; /* SPARSE_CHECKOUT_DISABLED if not sparse */\n \tchar *branch;\n \tchar *onto;\n \tchar *detached_from;\n-- \ngitgitgadget\n\n"},{"id":"400088","messageId":"17254b30a5bcbbe3e14dd47272dfcb4c867030dd.1592513398.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.v2.git.git.1592513398.gitgitgadget@gmail.com","subject":"[PATCH v2 2/2] git-prompt: include sparsity state as well","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-18T20:49:58Z","receivedAt":"2020-06-18T20:50:09Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThe current git prompt includes a lot of possible state information from\ncherry-picks, merges, bisects, and various flavors of rebases.  Add\nsparsity as another state flavor (though one which can be present\nsimultaneously with any of rebase/cherry-pick/merge/bisect).  This extra\nstate is shown with an extra\n    |SPARSE\nsubstring before the other states, providing a prompt that looks like:\n    (branchname|SPARSE|REBASE 6/10)\n\nThe reason for showing the \"|SPARSE\" substring before other states is to\nemphasize those other states.  Sparsity is probably not going to change\nmuch within a repository, while temporary operations will.  So we want\nthe state changes related to temporary operations to be listed last, to\nmake them appear closer to where the user types and make them more\nlikely to be noticed.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-prompt.sh | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex 014cd7c3cfc..3e7344a4014 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -421,6 +421,11 @@ __git_ps1 ()\n \t\treturn $exit\n \tfi\n \n+\tlocal sparse=\"\"\n+\tif [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n+\t    sparse=\"|SPARSE\"\n+\tfi\n+\n \tlocal r=\"\"\n \tlocal b=\"\"\n \tlocal step=\"\"\n@@ -543,7 +548,7 @@ __git_ps1 ()\n \tfi\n \n \tlocal f=\"$w$i$s$u\"\n-\tlocal gitstring=\"$c$b${f:+$z$f}$r$p\"\n+\tlocal gitstring=\"$c$b${f:+$z$f}${sparse}$r$p\"\n \n \tif [ $pcmode = yes ]; then\n \t\tif [ \"${__git_printf_supports_v-}\" != yes ]; then\n-- \ngitgitgadget\n"},{"id":"400093","messageId":"xmqqwo44kpyk.fsf@gitster.c.googlers.com","threadId":"53694","inReplyTo":"pull.808.v2.git.git.1592513398.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/2] Sparse checkout status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-06-18T21:45:55Z","receivedAt":"2020-06-18T21:46:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Some of the feedback of folks trying out sparse-checkouts at $dayjob is that\n> sparse checkouts can sometimes be disorienting; users can forget that they\n> had a sparse-checkout and then wonder where files went. This series adds\n> some output to 'git status' and modifies git-prompt slightly as an attempt\n> to help.\n>\n> Note that as per discussion on v1, we may want to later add a git\n> sparse-checkout subcommand named something like 'stats' or 'info' or\n> 'status' that provides more detailed information for users to dig deeper.\n> That would be an additional improvement for helping users find out more\n> information once they realize or remember they are in a sparse checkout,\n> this is just aimed at giving them a simple reminder.\n>\n> Changes since v1:\n>\n>  * Replaced the -1 magic constant with SPARSE_CHECKOUT_DISABLED\n>  * Fixed a possible division by 0 (when there are no entries in the index\n>    AND sparse checkout is enabled; not sure when that'd ever happen but\n>    still better to guard against...)\n>  * Slight wording tweaks for the git-prompt commit message\n>  * Removed the RFC label\n>\n> Elijah Newren (2):\n>   wt-status: show sparse checkout status as well\n>   git-prompt: include sparsity state as well\n>\n>  contrib/completion/git-prompt.sh |  7 +++++-\n>  wt-status.c                      | 41 ++++++++++++++++++++++++++++++++\n>  wt-status.h                      |  2 ++\n>  3 files changed, 49 insertions(+), 1 deletion(-)\n\nAny change to Documentation/git-status.txt?\n\n"},{"id":"400098","messageId":"CABPp-BHLDhRTpdjfrG5WLjwxkegC--RXrjzxV+ufYKnH+Kdifw@mail.gmail.com","threadId":"53694","inReplyTo":"xmqqwo44kpyk.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 0/2] Sparse checkout status","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-06-18T23:18:15Z","receivedAt":"2020-06-18T23:18:32Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jun 18, 2020 at 2:46 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> \"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n> > Some of the feedback of folks trying out sparse-checkouts at $dayjob is that\n> > sparse checkouts can sometimes be disorienting; users can forget that they\n> > had a sparse-checkout and then wonder where files went. This series adds\n> > some output to 'git status' and modifies git-prompt slightly as an attempt\n> > to help.\n> >\n> > Note that as per discussion on v1, we may want to later add a git\n> > sparse-checkout subcommand named something like 'stats' or 'info' or\n> > 'status' that provides more detailed information for users to dig deeper.\n> > That would be an additional improvement for helping users find out more\n> > information once they realize or remember they are in a sparse checkout,\n> > this is just aimed at giving them a simple reminder.\n> >\n> > Changes since v1:\n> >\n> >  * Replaced the -1 magic constant with SPARSE_CHECKOUT_DISABLED\n> >  * Fixed a possible division by 0 (when there are no entries in the index\n> >    AND sparse checkout is enabled; not sure when that'd ever happen but\n> >    still better to guard against...)\n> >  * Slight wording tweaks for the git-prompt commit message\n> >  * Removed the RFC label\n> >\n> > Elijah Newren (2):\n> >   wt-status: show sparse checkout status as well\n> >   git-prompt: include sparsity state as well\n> >\n> >  contrib/completion/git-prompt.sh |  7 +++++-\n> >  wt-status.c                      | 41 ++++++++++++++++++++++++++++++++\n> >  wt-status.h                      |  2 ++\n> >  3 files changed, 49 insertions(+), 1 deletion(-)\n>\n> Any change to Documentation/git-status.txt?\n\nReasonable question; I didn't think of it.  But on a related note, in\nthe eight years we've had status output for various other forms of\nstate (in-progress operations like merge, cherry-pick, rebase, or\nbisect), these haven't been documented either.  Was that also\noversight, or was there a reason it was left out?\n\nIf oversight, should I just document all those others while I'm at it?\n"},{"id":"400142","messageId":"20200619161528.GI2898@szeder.dev","threadId":"53694","inReplyTo":"17254b30a5bcbbe3e14dd47272dfcb4c867030dd.1592513398.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 2/2] git-prompt: include sparsity state as well","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2020-06-19T16:15:28Z","receivedAt":"2020-06-19T16:15:43Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Thu, Jun 18, 2020 at 08:49:58PM +0000, Elijah Newren via GitGitGadget wrote:\n> From: Elijah Newren <newren@gmail.com>\n> \n> The current git prompt includes a lot of possible state information from\n> cherry-picks, merges, bisects, and various flavors of rebases.  Add\n> sparsity as another state flavor (though one which can be present\n> simultaneously with any of rebase/cherry-pick/merge/bisect).  This extra\n> state is shown with an extra\n>     |SPARSE\n> substring before the other states, providing a prompt that looks like:\n>     (branchname|SPARSE|REBASE 6/10)\n> \n> The reason for showing the \"|SPARSE\" substring before other states is to\n> emphasize those other states.  Sparsity is probably not going to change\n> much within a repository, while temporary operations will.  So we want\n> the state changes related to temporary operations to be listed last, to\n> make them appear closer to where the user types and make them more\n> likely to be noticed.\n\nI understand why some users prefer to be reminded when they are in a\nrepository that uses sparse checkout.  However, perhaps not all users\nwant to be reminded, and I'm sure that not all users want to increase\nthe width of their prompt by 7 characters (e.g. in standard-width\nterminals).\n\n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n>  contrib/completion/git-prompt.sh | 7 ++++++-\n>  1 file changed, 6 insertions(+), 1 deletion(-)\n> \n> diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\n> index 014cd7c3cfc..3e7344a4014 100644\n> --- a/contrib/completion/git-prompt.sh\n> +++ b/contrib/completion/git-prompt.sh\n> @@ -421,6 +421,11 @@ __git_ps1 ()\n>  \t\treturn $exit\n>  \tfi\n>  \n> +\tlocal sparse=\"\"\n> +\tif [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n> +\t    sparse=\"|SPARSE\"\n\nNit: indentation.\n\n> +\tfi\n> +\n>  \tlocal r=\"\"\n>  \tlocal b=\"\"\n>  \tlocal step=\"\"\n> @@ -543,7 +548,7 @@ __git_ps1 ()\n>  \tfi\n>  \n>  \tlocal f=\"$w$i$s$u\"\n> -\tlocal gitstring=\"$c$b${f:+$z$f}$r$p\"\n> +\tlocal gitstring=\"$c$b${f:+$z$f}${sparse}$r$p\"\n>  \n>  \tif [ $pcmode = yes ]; then\n>  \t\tif [ \"${__git_printf_supports_v-}\" != yes ]; then\n> -- \n> gitgitgadget\n"},{"id":"400144","messageId":"xmqqftarj9qu.fsf@gitster.c.googlers.com","threadId":"53694","inReplyTo":"20200619161528.GI2898@szeder.dev","subject":"Re: [PATCH v2 2/2] git-prompt: include sparsity state as well","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-06-19T16:33:45Z","receivedAt":"2020-06-19T16:33:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder.dev@gmail.com> writes:\n\n>> +\tlocal sparse=\"\"\n>> +\tif [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n>> +\t    sparse=\"|SPARSE\"\n>\n> Nit: indentation.\n\nAlso, do we want \"==\" there?  I thought [ ... ] (unlike [[ ... ]])\nwas a mere synonym for \"test\", to which \"==\" is a bug.\n\n"},{"id":"400146","messageId":"xmqqbllfj9na.fsf@gitster.c.googlers.com","threadId":"53694","inReplyTo":"xmqqftarj9qu.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 2/2] git-prompt: include sparsity state as well","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-06-19T16:35:53Z","receivedAt":"2020-06-19T16:36:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> SZEDER Gábor <szeder.dev@gmail.com> writes:\n>\n>>> +\tlocal sparse=\"\"\n>>> +\tif [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n>>> +\t    sparse=\"|SPARSE\"\n>>\n>> Nit: indentation.\n>\n> Also, do we want \"==\" there?  I thought [ ... ] (unlike [[ ... ]])\n> was a mere synonym for \"test\", to which \"==\" is a bug.\n\nAh, OK, this script is very bash specific so POSIX portability rules\ndo not matter.  == is just fine as = there.\n\nSorry for the noise.\n"},{"id":"400262","messageId":"CABPp-BFh94eP89CNCrXknaUbm7cHzpn8N4xYWZTsVYWGrB8RkQ@mail.gmail.com","threadId":"53694","inReplyTo":"CABPp-BHLDhRTpdjfrG5WLjwxkegC--RXrjzxV+ufYKnH+Kdifw@mail.gmail.com","subject":"Re: [PATCH v2 0/2] Sparse checkout status","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-06-21T01:34:39Z","receivedAt":"2020-06-21T01:38:22Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jun 18, 2020 at 4:18 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Jun 18, 2020 at 2:46 PM Junio C Hamano <gitster@pobox.com> wrote:\n> >\n> > \"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> >\n> > > Some of the feedback of folks trying out sparse-checkouts at $dayjob is that\n> > > sparse checkouts can sometimes be disorienting; users can forget that they\n> > > had a sparse-checkout and then wonder where files went. This series adds\n> > > some output to 'git status' and modifies git-prompt slightly as an attempt\n> > > to help.\n> > >\n> > > Note that as per discussion on v1, we may want to later add a git\n> > > sparse-checkout subcommand named something like 'stats' or 'info' or\n> > > 'status' that provides more detailed information for users to dig deeper.\n> > > That would be an additional improvement for helping users find out more\n> > > information once they realize or remember they are in a sparse checkout,\n> > > this is just aimed at giving them a simple reminder.\n> > >\n> > > Changes since v1:\n> > >\n> > >  * Replaced the -1 magic constant with SPARSE_CHECKOUT_DISABLED\n> > >  * Fixed a possible division by 0 (when there are no entries in the index\n> > >    AND sparse checkout is enabled; not sure when that'd ever happen but\n> > >    still better to guard against...)\n> > >  * Slight wording tweaks for the git-prompt commit message\n> > >  * Removed the RFC label\n> > >\n> > > Elijah Newren (2):\n> > >   wt-status: show sparse checkout status as well\n> > >   git-prompt: include sparsity state as well\n> > >\n> > >  contrib/completion/git-prompt.sh |  7 +++++-\n> > >  wt-status.c                      | 41 ++++++++++++++++++++++++++++++++\n> > >  wt-status.h                      |  2 ++\n> > >  3 files changed, 49 insertions(+), 1 deletion(-)\n> >\n> > Any change to Documentation/git-status.txt?\n>\n> Reasonable question; I didn't think of it.  But on a related note, in\n> the eight years we've had status output for various other forms of\n> state (in-progress operations like merge, cherry-pick, rebase, or\n> bisect), these haven't been documented either.  Was that also\n> oversight, or was there a reason it was left out?\n>\n> If oversight, should I just document all those others while I'm at it?\n\nSo, I went to look at this.  Documentation/git-status.txt documents in\ndetail the short status format, the porcelain V1 format, and the\nporcelain V2 format.  There are two side comments that the long format\nis the default, and that status.submoduleSummary affects the long\noutput, but the only thing it says to document the contents of the\nlong format is:\n\"\"\"\nThe default, long format, is designed to be human readable,\nverbose and descriptive.  Its contents and format are subject to change\nat any time.\n\"\"\"\nIt would thus feel odd to mention the sparsity status within the long\nformat when nothing else within that format is documented.  I suspect\nthat's why it was never added when rebase/merge/cherry-pick/bisect\nstate notifications were added to the long format.\n"},{"id":"400263","messageId":"e266bc39d99006715482c5186912717651987f3e.1592716887.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.v3.git.git.1592716887.gitgitgadget@gmail.com","subject":"[PATCH v3 1/3] wt-status: show sparse checkout status as well","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-21T05:21:25Z","receivedAt":"2020-06-21T05:21:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSome of the early feedback of folks trying out sparse-checkouts at\n$dayjob is that sparse checkouts can sometimes be disorienting; users\ncan forget that they had a sparse-checkout and then wonder where files\nwent.  Add some output to 'git status' in the form of a simple line that\nstates:\n\n    You are in a sparse checkout with 35% of files present.\n\nwhere, obviously, the exact figure changes depending on what percentage\nof files from the index do not have the SKIP_WORKTREE bit set.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n wt-status.c | 41 +++++++++++++++++++++++++++++++++++++++++\n wt-status.h |  2 ++\n 2 files changed, 43 insertions(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 98dfa6f73f9..c560cbe860a 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1484,6 +1484,18 @@ static void show_bisect_in_progress(struct wt_status *s,\n \twt_longstatus_print_trailer(s);\n }\n \n+static void show_sparse_checkout_in_use(struct wt_status *s,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (s->state.sparse_checkout_percentage == SPARSE_CHECKOUT_DISABLED)\n+\t\treturn;\n+\n+\tstatus_printf_ln(s, color,\n+\t\t\t _(\"You are in a sparse checkout with %d%% of tracked files present.\"),\n+\t\t\t s->state.sparse_checkout_percentage);\n+\twt_longstatus_print_trailer(s);\n+}\n+\n /*\n  * Extract branch information from rebase/bisect\n  */\n@@ -1623,6 +1635,31 @@ int wt_status_check_bisect(const struct worktree *wt,\n \treturn 0;\n }\n \n+static void wt_status_check_sparse_checkout(struct repository *r,\n+\t\t\t\t\t    struct wt_status_state *state)\n+{\n+\tint skip_worktree = 0;\n+\tint i;\n+\n+\tif (!core_apply_sparse_checkout || r->index->cache_nr == 0) {\n+\t\t/*\n+\t\t * Don't compute percentage of checked out files if we\n+\t\t * aren't in a sparse checkout or would get division by 0.\n+\t\t */\n+\t\tstate->sparse_checkout_percentage = SPARSE_CHECKOUT_DISABLED;\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < r->index->cache_nr; i++) {\n+\t\tstruct cache_entry *ce = r->index->cache[i];\n+\t\tif (ce_skip_worktree(ce))\n+\t\t\tskip_worktree++;\n+\t}\n+\n+\tstate->sparse_checkout_percentage =\n+\t\t100 - (100 * skip_worktree)/r->index->cache_nr;\n+}\n+\n void wt_status_get_state(struct repository *r,\n \t\t\t struct wt_status_state *state,\n \t\t\t int get_detached_from)\n@@ -1658,6 +1695,7 @@ void wt_status_get_state(struct repository *r,\n \t}\n \tif (get_detached_from)\n \t\twt_status_get_detached_from(r, state);\n+\twt_status_check_sparse_checkout(r, state);\n }\n \n static void wt_longstatus_print_state(struct wt_status *s)\n@@ -1681,6 +1719,9 @@ static void wt_longstatus_print_state(struct wt_status *s)\n \t\tshow_revert_in_progress(s, state_color);\n \tif (state->bisect_in_progress)\n \t\tshow_bisect_in_progress(s, state_color);\n+\n+\tif (state->sparse_checkout_percentage != SPARSE_CHECKOUT_DISABLED)\n+\t\tshow_sparse_checkout_in_use(s, state_color);\n }\n \n static void wt_longstatus_print(struct wt_status *s)\ndiff --git a/wt-status.h b/wt-status.h\nindex 73ab5d4da1c..f1fa0ec1a75 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -79,6 +79,7 @@ enum wt_status_format {\n \n #define HEAD_DETACHED_AT _(\"HEAD detached at \")\n #define HEAD_DETACHED_FROM _(\"HEAD detached from \")\n+#define SPARSE_CHECKOUT_DISABLED -1\n \n struct wt_status_state {\n \tint merge_in_progress;\n@@ -90,6 +91,7 @@ struct wt_status_state {\n \tint bisect_in_progress;\n \tint revert_in_progress;\n \tint detached_at;\n+\tint sparse_checkout_percentage; /* SPARSE_CHECKOUT_DISABLED if not sparse */\n \tchar *branch;\n \tchar *onto;\n \tchar *detached_from;\n-- \ngitgitgadget\n\n"},{"id":"400264","messageId":"pull.808.v3.git.git.1592716887.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.v2.git.git.1592513398.gitgitgadget@gmail.com","subject":"[PATCH v3 0/3] Sparse checkout status","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-21T05:21:24Z","receivedAt":"2020-06-21T05:21:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Some of the feedback of folks trying out sparse-checkouts at $dayjob is that\nsparse checkouts can sometimes be disorienting; users can forget that they\nhad a sparse-checkout and then wonder where files went. This series adds\nsome output to 'git status' and modifies git-prompt slightly as an attempt\nto help.\n\n(As per discussion on v1, a \"git sparse-checkout [status|info|status]\" might\nsupplement the changes from this series later; this is just aimed at giving\nusers a simple reminder that they are in a sparse checkout.)\n\nChanges since v2:\n\n * Added an extra commit to document how git-prompt works with in-progress\n   state of operations (rebase/merge/cherry-pick/revert/bisect), since I\n   want to refer to it for comparison later in the docs.\n * As requested by SZEDER, added the ability to shorten or remove the\n   information relating to sparsity state in the git-prompt.\n * Since there are now three options for whether and how to show information\n   related to sparsity state, I put a fair amount of effort into reasoning\n   among the options about what is a good default and why; I included this\n   in the final commit message. (While I suspect that we can easily change\n   the default for the prompt in the future based on the big warning at the\n   top of git-sparse-checkout.txt, having the rationale up-front for the\n   original decision may help us out in the future.)\n\nElijah Newren (3):\n  wt-status: show sparse checkout status as well\n  git-prompt: document how in-progress operations affect the prompt\n  git-prompt: include sparsity state as well\n\n contrib/completion/git-prompt.sh | 26 ++++++++++++++++++--\n wt-status.c                      | 41 ++++++++++++++++++++++++++++++++\n wt-status.h                      |  2 ++\n 3 files changed, 67 insertions(+), 2 deletions(-)\n\n\nbase-commit: b3d7a52fac39193503a0b6728771d1bf6a161464\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-808%2Fnewren%2Fsparse-checkout-status-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-808/newren/sparse-checkout-status-v3\nPull-Request: https://github.com/git/git/pull/808\n\nRange-diff vs v2:\n\n 1:  e266bc39d99 = 1:  e266bc39d99 wt-status: show sparse checkout status as well\n -:  ----------- > 2:  1fd1b919684 git-prompt: document how in-progress operations affect the prompt\n 2:  17254b30a5b ! 3:  d99202f8e14 git-prompt: include sparsity state as well\n     @@ Metadata\n       ## Commit message ##\n          git-prompt: include sparsity state as well\n      \n     -    The current git prompt includes a lot of possible state information from\n     -    cherry-picks, merges, bisects, and various flavors of rebases.  Add\n     -    sparsity as another state flavor (though one which can be present\n     -    simultaneously with any of rebase/cherry-pick/merge/bisect).  This extra\n     -    state is shown with an extra\n     +    git-prompt includes the current branch, a bunch of single character\n     +    mini-state displayers, and some much longer in-progress state\n     +    notifications.  The current branch is always shown.  The single\n     +    character mini-state displayers are all off by default (they are not\n     +    self explanatory) but each has an environment variable for turning it\n     +    on.  The in-progress state notifications provide no configuration\n     +    options for turning them off, and can be up to 15 characters long (e.g.\n     +    \"|REBASE (12/18)\" or \"|CHERRY-PICKING\").\n     +\n     +    The single character mini-state tends to be used for things like \"Do you\n     +    have any stashes in refs/stash?\" or \"Are you ahead or behind of\n     +    upstream?\".  These are things which users can take advantage of but do\n     +    not affect most normal git operations.  The in-progress states, by\n     +    contrast, suggest the user needs to interact differently and may also\n     +    prevent some normal operations from succeeding (e.g. git switch may show\n     +    an error instead of switching branches).\n     +\n     +    Sparsity is like the in-progress states in that it suggests a\n     +    fundamental different interaction with the repository (many of the files\n     +    from the repository are not present in your working copy!).  A few\n     +    commits ago added sparsity information to wt_longstatus_print_state(),\n     +    grouping it with other in-progress state displays.  We do similarly here\n     +    with the prompt and show the extra state, by default, with an extra\n              |SPARSE\n     -    substring before the other states, providing a prompt that looks like:\n     +    This state can be present simultaneously with the in-progress states, in\n     +    which case it will appear before the other states; for example,\n              (branchname|SPARSE|REBASE 6/10)\n      \n          The reason for showing the \"|SPARSE\" substring before other states is to\n     @@ Commit message\n          make them appear closer to where the user types and make them more\n          likely to be noticed.\n      \n     +    The fact that sparsity isn't just cached metadata or additional\n     +    information is what leads us to show it more similarly to the\n     +    in-progress states, but the fact that sparsity is not transient like the\n     +    in-progress states might cause some users to want an abbreviated\n     +    notification of sparsity state or perhaps even be able to turn it off.\n     +    Allow GIT_PS1_COMPRESSSPARSESTATE to be set to request that it be\n     +    shortened to a single character ('?'), and GIT_PS1_OMITSPARSESTATE to be\n     +    set to request that sparsity state be omitted from the prompt entirely.\n     +\n          Signed-off-by: Elijah Newren <newren@gmail.com>\n      \n       ## contrib/completion/git-prompt.sh ##\n     +@@\n     + # revert, cherry-pick, or bisect, the prompt will include information\n     + # related to the operation, often in the form \"|<OPERATION-NAME>\".\n     + #\n     ++# When the repository has a sparse-checkout, a notification of the form\n     ++# \"|SPARSE\" will be included in the prompt.  This can be shortened to a\n     ++# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted\n     ++# by setting GIT_PS1_OMITSPARSESTATE.\n     ++#\n     + # By default, __git_ps1 will compare HEAD to your SVN upstream if it can\n     + # find one, or @{upstream} otherwise.  Once you have set\n     + # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by\n      @@ contrib/completion/git-prompt.sh: __git_ps1 ()\n       \t\treturn $exit\n       \tfi\n       \n      +\tlocal sparse=\"\"\n     -+\tif [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n     -+\t    sparse=\"|SPARSE\"\n     ++\tif [ -z \"${GIT_PS1_COMPRESSSPARSESTATE}\" ] &&\n     ++\t   [ -z \"${GIT_PS1_OMITSPARSESTATE}\" ] &&\n     ++\t   [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n     ++\t\tsparse=\"|SPARSE\"\n      +\tfi\n      +\n       \tlocal r=\"\"\n       \tlocal b=\"\"\n       \tlocal step=\"\"\n      @@ contrib/completion/git-prompt.sh: __git_ps1 ()\n     + \tlocal i=\"\"\n     + \tlocal s=\"\"\n     + \tlocal u=\"\"\n     ++\tlocal h=\"\"\n     + \tlocal c=\"\"\n     + \tlocal p=\"\"\n     + \n     +@@ contrib/completion/git-prompt.sh: __git_ps1 ()\n     + \t\t\tu=\"%${ZSH_VERSION+%}\"\n     + \t\tfi\n     + \n     ++\t\tif [ -n \"${GIT_PS1_COMPRESSSPARSESTATE}\" ] &&\n     ++\t\t   [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n     ++\t\t\th=\"?\"\n     ++\t\tfi\n     ++\n     + \t\tif [ -n \"${GIT_PS1_SHOWUPSTREAM-}\" ]; then\n     + \t\t\t__git_ps1_show_upstream\n     + \t\tfi\n     +@@ contrib/completion/git-prompt.sh: __git_ps1 ()\n     + \t\tb=\"\\${__git_ps1_branch_name}\"\n       \tfi\n       \n     - \tlocal f=\"$w$i$s$u\"\n     +-\tlocal f=\"$w$i$s$u\"\n      -\tlocal gitstring=\"$c$b${f:+$z$f}$r$p\"\n     ++\tlocal f=\"$h$w$i$s$u\"\n      +\tlocal gitstring=\"$c$b${f:+$z$f}${sparse}$r$p\"\n       \n       \tif [ $pcmode = yes ]; then\n\n-- \ngitgitgadget\n"},{"id":"400265","messageId":"d99202f8e1443f517b16811b7d2ba2593898e9d0.1592716887.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.v3.git.git.1592716887.gitgitgadget@gmail.com","subject":"[PATCH v3 3/3] git-prompt: include sparsity state as well","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-21T05:21:27Z","receivedAt":"2020-06-21T05:21:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\ngit-prompt includes the current branch, a bunch of single character\nmini-state displayers, and some much longer in-progress state\nnotifications.  The current branch is always shown.  The single\ncharacter mini-state displayers are all off by default (they are not\nself explanatory) but each has an environment variable for turning it\non.  The in-progress state notifications provide no configuration\noptions for turning them off, and can be up to 15 characters long (e.g.\n\"|REBASE (12/18)\" or \"|CHERRY-PICKING\").\n\nThe single character mini-state tends to be used for things like \"Do you\nhave any stashes in refs/stash?\" or \"Are you ahead or behind of\nupstream?\".  These are things which users can take advantage of but do\nnot affect most normal git operations.  The in-progress states, by\ncontrast, suggest the user needs to interact differently and may also\nprevent some normal operations from succeeding (e.g. git switch may show\nan error instead of switching branches).\n\nSparsity is like the in-progress states in that it suggests a\nfundamental different interaction with the repository (many of the files\nfrom the repository are not present in your working copy!).  A few\ncommits ago added sparsity information to wt_longstatus_print_state(),\ngrouping it with other in-progress state displays.  We do similarly here\nwith the prompt and show the extra state, by default, with an extra\n    |SPARSE\nThis state can be present simultaneously with the in-progress states, in\nwhich case it will appear before the other states; for example,\n    (branchname|SPARSE|REBASE 6/10)\n\nThe reason for showing the \"|SPARSE\" substring before other states is to\nemphasize those other states.  Sparsity is probably not going to change\nmuch within a repository, while temporary operations will.  So we want\nthe state changes related to temporary operations to be listed last, to\nmake them appear closer to where the user types and make them more\nlikely to be noticed.\n\nThe fact that sparsity isn't just cached metadata or additional\ninformation is what leads us to show it more similarly to the\nin-progress states, but the fact that sparsity is not transient like the\nin-progress states might cause some users to want an abbreviated\nnotification of sparsity state or perhaps even be able to turn it off.\nAllow GIT_PS1_COMPRESSSPARSESTATE to be set to request that it be\nshortened to a single character ('?'), and GIT_PS1_OMITSPARSESTATE to be\nset to request that sparsity state be omitted from the prompt entirely.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-prompt.sh | 22 ++++++++++++++++++++--\n 1 file changed, 20 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex 179b96e4936..e6cd5464e5c 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -74,6 +74,11 @@\n # revert, cherry-pick, or bisect, the prompt will include information\n # related to the operation, often in the form \"|<OPERATION-NAME>\".\n #\n+# When the repository has a sparse-checkout, a notification of the form\n+# \"|SPARSE\" will be included in the prompt.  This can be shortened to a\n+# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted\n+# by setting GIT_PS1_OMITSPARSESTATE.\n+#\n # By default, __git_ps1 will compare HEAD to your SVN upstream if it can\n # find one, or @{upstream} otherwise.  Once you have set\n # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by\n@@ -425,6 +430,13 @@ __git_ps1 ()\n \t\treturn $exit\n \tfi\n \n+\tlocal sparse=\"\"\n+\tif [ -z \"${GIT_PS1_COMPRESSSPARSESTATE}\" ] &&\n+\t   [ -z \"${GIT_PS1_OMITSPARSESTATE}\" ] &&\n+\t   [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n+\t\tsparse=\"|SPARSE\"\n+\tfi\n+\n \tlocal r=\"\"\n \tlocal b=\"\"\n \tlocal step=\"\"\n@@ -496,6 +508,7 @@ __git_ps1 ()\n \tlocal i=\"\"\n \tlocal s=\"\"\n \tlocal u=\"\"\n+\tlocal h=\"\"\n \tlocal c=\"\"\n \tlocal p=\"\"\n \n@@ -528,6 +541,11 @@ __git_ps1 ()\n \t\t\tu=\"%${ZSH_VERSION+%}\"\n \t\tfi\n \n+\t\tif [ -n \"${GIT_PS1_COMPRESSSPARSESTATE}\" ] &&\n+\t\t   [ \"$(git config --bool core.sparseCheckout)\" == \"true\" ]; then\n+\t\t\th=\"?\"\n+\t\tfi\n+\n \t\tif [ -n \"${GIT_PS1_SHOWUPSTREAM-}\" ]; then\n \t\t\t__git_ps1_show_upstream\n \t\tfi\n@@ -546,8 +564,8 @@ __git_ps1 ()\n \t\tb=\"\\${__git_ps1_branch_name}\"\n \tfi\n \n-\tlocal f=\"$w$i$s$u\"\n-\tlocal gitstring=\"$c$b${f:+$z$f}$r$p\"\n+\tlocal f=\"$h$w$i$s$u\"\n+\tlocal gitstring=\"$c$b${f:+$z$f}${sparse}$r$p\"\n \n \tif [ $pcmode = yes ]; then\n \t\tif [ \"${__git_printf_supports_v-}\" != yes ]; then\n-- \ngitgitgadget\n"},{"id":"400266","messageId":"1fd1b919684173d0971869a9aaf8554055760d63.1592716887.git.gitgitgadget@gmail.com","threadId":"53694","inReplyTo":"pull.808.v3.git.git.1592716887.gitgitgadget@gmail.com","subject":"[PATCH v3 2/3] git-prompt: document how in-progress operations affect the prompt","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-06-21T05:21:26Z","receivedAt":"2020-06-21T05:22:20Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-prompt.sh | 4 ++++\n 1 file changed, 4 insertions(+)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex 014cd7c3cfc..179b96e4936 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -70,6 +70,10 @@\n # state symbols by setting GIT_PS1_STATESEPARATOR. The default separator\n # is SP.\n #\n+# When there is an in-progress operation such as a merge, rebase,\n+# revert, cherry-pick, or bisect, the prompt will include information\n+# related to the operation, often in the form \"|<OPERATION-NAME>\".\n+#\n # By default, __git_ps1 will compare HEAD to your SVN upstream if it can\n # find one, or @{upstream} otherwise.  Once you have set\n # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by\n-- \ngitgitgadget\n\n"},{"id":"400285","messageId":"xmqqk0zzdpnt.fsf@gitster.c.googlers.com","threadId":"53694","inReplyTo":"d99202f8e1443f517b16811b7d2ba2593898e9d0.1592716887.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 3/3] git-prompt: include sparsity state as well","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-06-22T16:35:34Z","receivedAt":"2020-06-22T16:35:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Elijah Newren <newren@gmail.com>\n> ...\n> The reason for showing the \"|SPARSE\" substring before other states is to\n> ...\n> The fact that sparsity isn't just cached metadata or additional\n> information is what leads us to show it more similarly to the\n> in-progress states, but the fact that sparsity is not transient like the\n> in-progress states might cause some users to want an abbreviated\n> notification of sparsity state or perhaps even be able to turn it off.\n> Allow GIT_PS1_COMPRESSSPARSESTATE to be set to request that it be\n> shortened to a single character ('?'), and GIT_PS1_OMITSPARSESTATE to be\n> set to request that sparsity state be omitted from the prompt entirely.\n\nNicely explained.  It somewhat feels a bit overkill to have two\n(i.e. compress vs omit) knobs---the other \"semi-permanent\" state\nthat may be of interest but could become too noisy only have one\nknob that toggles between showing a short-and-non-intrusive sign\nand not showing anything at all with GIT_PS1_SHOWSTASHSTATE, and\nthat smells like a better balance to me, but I dunno.\n\nThanks.  Will queue.\n"}]}