{"thread":{"id":"45004","subject":"[PATCH 3/4] git-prompt.sh: fix for submodule 'dirty' indicator","startedAt":"2017-01-30T20:45:20Z","lastAt":"2017-04-07T16:14:33Z","messageCount":53,"participants":["Benjamin Fuchs","Junio C Hamano","SZEDER Gábor","Stefan Beller","Jacob Keller","Jonathan Nieder","Duy Nguyen","Michael J Gruber"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"310548","messageId":"1485809065-11978-4-git-send-email-email@benjaminfuchs.de","threadId":"45004","inReplyTo":"1485809065-11978-1-git-send-email-email@benjaminfuchs.de","subject":"[PATCH 3/4] git-prompt.sh: fix for submodule 'dirty' indicator","fromName":"Benjamin Fuchs","fromEmail":"email@benjaminfuchs.de","sentAt":"2017-01-30T20:44:24Z","receivedAt":"2017-01-30T20:45:20Z","isPatch":true,"sender":{"key":"email@benjaminfuchs.de","avatar":null},"body":"Fixing wrong git diff line.\n\nSigned-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n---\n contrib/completion/git-prompt.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex c44b9a2..43b28e9 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -306,9 +306,9 @@ __git_ps1_submodule ()\n \tlocal submodule_name=\"$(basename \"$git_dir\")\"\n \tif [ \"$submodule_name\" != \".git\" ] && [ \"$submodule_name\" != \".\" ]; then\n \t\tlocal parent_top=\"${git_dir%.git*}\"\n-\t\tlocal submodule_top=\"${git_dir#*modules}\"\n+\t\tlocal submodule_top=\"${git_dir#*modules/}\"\n \t\tlocal status=\"\"\n-\t\tgit diff -C \"$parent_top\" --no-ext-diff --ignore-submodules=dirty --quiet -- \"$submodule_top\" 2>/dev/null || status=\"+\"\n+\t\tgit -C \"$parent_top\" diff --no-ext-diff --ignore-submodules=dirty --quiet -- \"$submodule_top\" 2>/dev/null || status=\"+\"\n \t\tprintf \"$status$submodule_name:\"\n \tfi\n }\n@@ -544,7 +544,7 @@ __git_ps1 ()\n \n \tlocal sub=\"\"\n \tif [ -n \"${GIT_PS1_SHOWSUBMODULE}\" ]; then\n-\t\tsub=\"$(__git_ps1_submodule $g)\"\n+\t\tsub=\"$(__git_ps1_submodule \"$g\")\"\n \tfi\n \n \tlocal f=\"$w$i$s$u\"\n-- \n2.7.4\n\n"},{"id":"310549","messageId":"1485809065-11978-1-git-send-email-email@benjaminfuchs.de","threadId":"45004","inReplyTo":null,"subject":"[PATCH 0/4] git-prompt.sh: Full patch for submodule indicator","fromName":"Benjamin Fuchs","fromEmail":"email@benjaminfuchs.de","sentAt":"2017-01-30T20:44:21Z","receivedAt":"2017-01-30T20:45:24Z","isPatch":true,"sender":{"key":"email@benjaminfuchs.de","avatar":null},"body":"Hi everyone,\nsince I didn't get a response I decided to sent my patch again. Maybe it was because\nI to sent my consecutive commits the wrong way, so a new try.\nFirst thanks again Steffen and Gábor for your feedback.\nBased on the first feedback I rework the indicator and it is now way cheaper then the\nfirst version and has a 'dirty' indicator now.\nTests exist also now.\nLooking forward to more feedback!\nGreetings,\nBenjamin\n\nBenjamin Fuchs (4):\n  git-prompt.sh: add submodule indicator\n  git-prompt.sh: rework of submodule indicator\n  git-prompt.sh: fix for submodule 'dirty' indicator\n  git-prompt.sh: add tests for submodule indicator\n\n contrib/completion/git-prompt.sh | 36 ++++++++++++++++++++++++++++++++-\n t/t9903-bash-prompt.sh           | 43 ++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 78 insertions(+), 1 deletion(-)\n\n-- \n2.7.4\n\n"},{"id":"310550","messageId":"1485809065-11978-5-git-send-email-email@benjaminfuchs.de","threadId":"45004","inReplyTo":"1485809065-11978-1-git-send-email-email@benjaminfuchs.de","subject":"[PATCH 4/4] git-prompt.sh: add tests for submodule indicator","fromName":"Benjamin Fuchs","fromEmail":"email@benjaminfuchs.de","sentAt":"2017-01-30T20:44:25Z","receivedAt":"2017-01-30T20:45:26Z","isPatch":true,"sender":{"key":"email@benjaminfuchs.de","avatar":null},"body":"Signed-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n---\n t/t9903-bash-prompt.sh | 43 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 43 insertions(+)\n\ndiff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh\nindex 97c9b32..4dce366 100755\n--- a/t/t9903-bash-prompt.sh\n+++ b/t/t9903-bash-prompt.sh\n@@ -37,6 +37,11 @@ test_expect_success 'setup for prompt tests' '\n \tgit commit -m \"yet another b2\" file &&\n \tmkdir ignored_dir &&\n \techo \"ignored_dir/\" >>.gitignore &&\n+\tgit checkout -b submodule &&\n+\tgit submodule add ./. sub &&\n+\tgit -C sub checkout master &&\n+\tgit add sub &&\n+\tgit commit -m submodule &&\n \tgit checkout master\n '\n \n@@ -755,4 +760,42 @@ test_expect_success 'prompt - hide if pwd ignored - inside gitdir (stderr)' '\n \ttest_cmp expected \"$actual\"\n '\n \n+test_expect_success 'prompt - submodule indicator' '\n+\tprintf \" (sub:master)\" >expected &&\n+\tgit checkout submodule &&\n+\ttest_when_finished \"git checkout master\" &&\n+\t(\n+\t\tcd sub &&\n+\t\tGIT_PS1_SHOWSUBMODULE=1 &&\n+\t\t__git_ps1 >\"$actual\"\n+\t) &&\n+\ttest_cmp expected \"$actual\"\n+'\n+\n+test_expect_success 'prompt - submodule indicator - verify false' '\n+\tprintf \" (master)\" >expected &&\n+\tgit checkout submodule &&\n+\ttest_when_finished \"git checkout master\" &&\n+\t(\n+\t\tcd sub &&\n+\t\tGIT_PS1_SHOWSUBMODULE= &&\n+\t\t__git_ps1 >\"$actual\"\n+\t) &&\n+\ttest_cmp expected \"$actual\"\n+'\n+\n+test_expect_success 'prompt - submodule indicator - dirty status indicator' '\n+\tprintf \" (+sub:b1)\" >expected &&\n+\tgit checkout submodule &&\n+\tgit -C sub checkout b1 &&\n+\ttest_when_finished \"git checkout master\" &&\n+\t(\n+\t\tcd sub &&\n+\t\tGIT_PS1_SHOWSUBMODULE=1 &&\n+\t\t__git_ps1 >\"$actual\"\n+\t) &&\n+\ttest_cmp expected \"$actual\"\n+'\n+\n+\n test_done\n-- \n2.7.4\n\n"},{"id":"310551","messageId":"1485809065-11978-3-git-send-email-email@benjaminfuchs.de","threadId":"45004","inReplyTo":"1485809065-11978-1-git-send-email-email@benjaminfuchs.de","subject":"[PATCH 2/4] git-prompt.sh: rework of submodule indicator","fromName":"Benjamin Fuchs","fromEmail":"email@benjaminfuchs.de","sentAt":"2017-01-30T20:44:23Z","receivedAt":"2017-01-30T20:45:30Z","isPatch":true,"sender":{"key":"email@benjaminfuchs.de","avatar":null},"body":"Rework of the first patch. The prompt now will look like this:\n(+name:master). I tried to considere all suggestions.\nTests still missing.\n\nSigned-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n---\n contrib/completion/git-prompt.sh | 49 ++++++++++++++++++++--------------------\n 1 file changed, 24 insertions(+), 25 deletions(-)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex 4c82e7f..c44b9a2 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -95,8 +95,10 @@\n # repository level by setting bash.hideIfPwdIgnored to \"false\".\n #\n # If you would like __git_ps1 to indicate that you are in a submodule,\n-# set GIT_PS1_SHOWSUBMODULE. In this case a \"sub:\" will be added before\n-# the branch name.\n+# set GIT_PS1_SHOWSUBMODULE to a nonempty value. In this case the name\n+# of the submodule will be prepended to the branch name (e.g. module:master).\n+# The name will be prepended by \"+\" if the currently checked out submodule\n+# commit does not match the SHA-1 found in the index of the containing repository.\n \n # check whether printf supports -v\n __git_printf_supports_v=\n@@ -288,30 +290,27 @@ __git_eread ()\n \ttest -r \"$f\" && read \"$@\" <\"$f\"\n }\n \n-# __git_is_submodule\n-# Based on:\n-# http://stackoverflow.com/questions/7359204/git-command-line-know-if-in-submodule\n-__git_is_submodule ()\n-{\n-\tlocal git_dir parent_git module_name path\n-\t# Find the root of this git repo, then check if its parent dir is also a repo\n-\tgit_dir=\"$(git rev-parse --show-toplevel)\"\n-\tmodule_name=\"$(basename \"$git_dir\")\"\n-\tparent_git=\"$(cd \"$git_dir/..\" && git rev-parse --show-toplevel 2> /dev/null)\"\n-\tif [[ -n $parent_git ]]; then\n-\t\t# List all the submodule paths for the parent repo\n-\t\twhile read path\n-\t\tdo\n-\t\t\tif [[ \"$path\" != \"$module_name\" ]]; then continue; fi\n-\t\t\tif [[ -d \"$git_dir/../$path\" ]];    then return 0; fi\n-\t\tdone < <(cd $parent_git && git submodule --quiet foreach 'echo $path' 2> /dev/null)\n-    fi\n-    return 1\n-}\n-\n+# __git_ps1_submodule\n+#\n+# $1 - git_dir path\n+#\n+# Returns the name of the submodule if we are currently inside one. The name\n+# will be prepended by \"+\" if the currently checked out submodule commit does\n+# not match the SHA-1 found in the index of the containing repository.\n+# NOTE: git_dir looks like in a ...\n+# - submodule: \"GIT_PARENT/.git/modules/PATH_TO_SUBMODULE\"\n+# - parent: \"GIT_PARENT/.git\" (exception \".\" in .git)\n __git_ps1_submodule ()\n {\n-\t__git_is_submodule && printf \"sub:\"\n+\tlocal git_dir=\"$1\"\n+\tlocal submodule_name=\"$(basename \"$git_dir\")\"\n+\tif [ \"$submodule_name\" != \".git\" ] && [ \"$submodule_name\" != \".\" ]; then\n+\t\tlocal parent_top=\"${git_dir%.git*}\"\n+\t\tlocal submodule_top=\"${git_dir#*modules}\"\n+\t\tlocal status=\"\"\n+\t\tgit diff -C \"$parent_top\" --no-ext-diff --ignore-submodules=dirty --quiet -- \"$submodule_top\" 2>/dev/null || status=\"+\"\n+\t\tprintf \"$status$submodule_name:\"\n+\tfi\n }\n \n # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n@@ -545,7 +544,7 @@ __git_ps1 ()\n \n \tlocal sub=\"\"\n \tif [ -n \"${GIT_PS1_SHOWSUBMODULE}\" ]; then\n-\t\tsub=\"$(__git_ps1_submodule)\"\n+\t\tsub=\"$(__git_ps1_submodule $g)\"\n \tfi\n \n \tlocal f=\"$w$i$s$u\"\n-- \n2.7.4\n\n"},{"id":"310552","messageId":"1485809065-11978-2-git-send-email-email@benjaminfuchs.de","threadId":"45004","inReplyTo":"1485809065-11978-1-git-send-email-email@benjaminfuchs.de","subject":"[PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Benjamin Fuchs","fromEmail":"email@benjaminfuchs.de","sentAt":"2017-01-30T20:44:22Z","receivedAt":"2017-01-30T20:45:33Z","isPatch":true,"sender":{"key":"email@benjaminfuchs.de","avatar":null},"body":"I expirienced that working with submodules can be confusing. This indicator\nwill make you notice very easy when you switch into a submodule.\nThe new prompt will look like this: (sub:master)\nAdding a new optional env variable for the new feature.\n\nSigned-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n---\n contrib/completion/git-prompt.sh | 37 ++++++++++++++++++++++++++++++++++++-\n 1 file changed, 36 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\nindex 97eacd7..4c82e7f 100644\n--- a/contrib/completion/git-prompt.sh\n+++ b/contrib/completion/git-prompt.sh\n@@ -93,6 +93,10 @@\n # directory is set up to be ignored by git, then set\n # GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the\n # repository level by setting bash.hideIfPwdIgnored to \"false\".\n+#\n+# If you would like __git_ps1 to indicate that you are in a submodule,\n+# set GIT_PS1_SHOWSUBMODULE. In this case a \"sub:\" will be added before\n+# the branch name.\n \n # check whether printf supports -v\n __git_printf_supports_v=\n@@ -284,6 +288,32 @@ __git_eread ()\n \ttest -r \"$f\" && read \"$@\" <\"$f\"\n }\n \n+# __git_is_submodule\n+# Based on:\n+# http://stackoverflow.com/questions/7359204/git-command-line-know-if-in-submodule\n+__git_is_submodule ()\n+{\n+\tlocal git_dir parent_git module_name path\n+\t# Find the root of this git repo, then check if its parent dir is also a repo\n+\tgit_dir=\"$(git rev-parse --show-toplevel)\"\n+\tmodule_name=\"$(basename \"$git_dir\")\"\n+\tparent_git=\"$(cd \"$git_dir/..\" && git rev-parse --show-toplevel 2> /dev/null)\"\n+\tif [[ -n $parent_git ]]; then\n+\t\t# List all the submodule paths for the parent repo\n+\t\twhile read path\n+\t\tdo\n+\t\t\tif [[ \"$path\" != \"$module_name\" ]]; then continue; fi\n+\t\t\tif [[ -d \"$git_dir/../$path\" ]];    then return 0; fi\n+\t\tdone < <(cd $parent_git && git submodule --quiet foreach 'echo $path' 2> /dev/null)\n+    fi\n+    return 1\n+}\n+\n+__git_ps1_submodule ()\n+{\n+\t__git_is_submodule && printf \"sub:\"\n+}\n+\n # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n # when called from PS1 using command substitution\n # in this mode it prints text to add to bash PS1 prompt (includes branch name)\n@@ -513,8 +543,13 @@ __git_ps1 ()\n \t\tb=\"\\${__git_ps1_branch_name}\"\n \tfi\n \n+\tlocal sub=\"\"\n+\tif [ -n \"${GIT_PS1_SHOWSUBMODULE}\" ]; then\n+\t\tsub=\"$(__git_ps1_submodule)\"\n+\tfi\n+\n \tlocal f=\"$w$i$s$u\"\n-\tlocal gitstring=\"$c$b${f:+$z$f}$r$p\"\n+\tlocal gitstring=\"$c$sub$b${f:+$z$f}$r$p\"\n \n \tif [ $pcmode = yes ]; then\n \t\tif [ \"${__git_printf_supports_v-}\" != yes ]; then\n-- \n2.7.4\n\n"},{"id":"310578","messageId":"xmqqr33krtww.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"1485809065-11978-2-git-send-email-email@benjaminfuchs.de","subject":"Re: [PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-01-30T23:48:31Z","receivedAt":"2017-01-30T23:48:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Benjamin Fuchs <email@benjaminfuchs.de> writes:\n\n> I expirienced that working with submodules can be confusing. This indicator\n> will make you notice very easy when you switch into a submodule.\n\nI am not quite sure what the above wants to say.  If you work on two\nprojects, A and B, then having something that quickly reminds you\nwhich one you are in is beneficial and people often do so by having\nthe current directory name in the prompt.  \n\nThe log message needs to explain why working on a submodule C of a\nproject A is any more special, i.e. why are the existing ways the\nusers are using to remind them between A and B cannot be used for C.\n\n> diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\n> index 97eacd7..4c82e7f 100644\n> --- a/contrib/completion/git-prompt.sh\n> +++ b/contrib/completion/git-prompt.sh\n> @@ -93,6 +93,10 @@\n>  # directory is set up to be ignored by git, then set\n>  # GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the\n>  # repository level by setting bash.hideIfPwdIgnored to \"false\".\n> +#\n> +# If you would like __git_ps1 to indicate that you are in a submodule,\n> +# set GIT_PS1_SHOWSUBMODULE. In this case a \"sub:\" will be added before\n> +# the branch name.\n>  \n>  # check whether printf supports -v\n>  __git_printf_supports_v=\n> @@ -284,6 +288,32 @@ __git_eread ()\n>  \ttest -r \"$f\" && read \"$@\" <\"$f\"\n>  }\n>  \n> +# __git_is_submodule\n> +# Based on:\n> +# http://stackoverflow.com/questions/7359204/git-command-line-know-if-in-submodule\n> +__git_is_submodule ()\n\nIt seems like this function is checking if you are \"IN\" submodule,\nnot \"IS\" submodule.  A misnamed function?\n\n> +{\n> +\tlocal git_dir parent_git module_name path\n> +\t# Find the root of this git repo, then check if its parent dir is also a repo\n> +\tgit_dir=\"$(git rev-parse --show-toplevel)\"\n> +\tmodule_name=\"$(basename \"$git_dir\")\"\n\nThis does not give \"module_name\" in the sense the word is used in\nthe submodule subsystem.  If this variable is useful, call that\nwith \"path\" in its name (I do not think it alone is useful at all).\n\n> +\tparent_git=\"$(cd \"$git_dir/..\" && git rev-parse --show-toplevel 2> /dev/null)\"\n> +\tif [[ -n $parent_git ]]; then\n> +\t\t# List all the submodule paths for the parent repo\n> +\t\twhile read path\n> +\t\tdo\n> +\t\t\tif [[ \"$path\" != \"$module_name\" ]]; then continue; fi\n> +\t\t\tif [[ -d \"$git_dir/../$path\" ]];    then return 0; fi\n> +\t\tdone < <(cd $parent_git && git submodule --quiet foreach 'echo $path' 2> /dev/null)\n\nInstead of doing this \"loop over submodules and just get true or\nfalse\", it may make a lot more sense to find the module name and\nreport that.  That would allow you to have the actual submodule\nname, not a generic \"sub:\" which does not help the users to tell\nwhich one of 47 submodules they have in their top-level project\nthey are currently in.\n\nIf your projects are layed out like so\n\n\t/home/bf/projects/A/\n\t/home/bf/projects/A/lib/B/ -- submodule\n\t/home/bf/projects/A/Doc/ -- another submodule\n\t/home/bf/projects/A/Doc/technical -- a subdirectory of Doc submodule\n\nand you are in /home/bf/projects/A/Doc/technical/ subdirectory, your\n$git_dir variable (which is grossly misnamed, too; call it \"top\"\nperhaps?) would be \"/home/bf/projects/A/Doc\" and then your\n$parent_git variable (again, that is misnamed; call it\n\"parent_top\"?) would be \"/home/bf/projects/A\".  The submodule path\nto the submodule you are currently in is \"Doc\" (you learn it as the\ndifference between these two).\n\nYou can ask the top-level project the name of the submodule that is\ncurrently at \"Doc\" with \"submodule--helper name\".  Unless the project\nhas moved it since it first added the submodule, the module name may\nalso be \"Doc\", but if it were moved, it may be different.\n\nAnd that \"module name\" is a more useful thing than a hardcoded\nstring \"sub:\" to use in the prompt, I would think.\n"},{"id":"310579","messageId":"c872072a-4754-051d-81e7-1e2166560733@benjaminfuchs.de","threadId":"45004","inReplyTo":"xmqqr33krtww.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Benjamin Fuchs","fromEmail":"email@benjaminfuchs.de","sentAt":"2017-01-31T00:10:15Z","receivedAt":"2017-01-31T00:12:15Z","isPatch":true,"sender":{"key":"email@benjaminfuchs.de","avatar":null},"body":"Hi Junio,\nthanks for your reply. Some of your suggestions are covered by my rework \nin Patch [2/4].\nIn [2/4] I got rid of the loop by feedback of Gábor.\nSorry if my patch wasn't well formed.\n\nOn 31.01.2017 00:48, Junio C Hamano wrote:\n> Benjamin Fuchs <email@benjaminfuchs.de> writes:\n>\n>> I expirienced that working with submodules can be confusing. This indicator\n>> will make you notice very easy when you switch into a submodule.\n> I am not quite sure what the above wants to say.  If you work on two\n> projects, A and B, then having something that quickly reminds you\n> which one you are in is beneficial and people often do so by having\n> the current directory name in the prompt.\n>\n> The log message needs to explain why working on a submodule C of a\n> project A is any more special, i.e. why are the existing ways the\n> users are using to remind them between A and B cannot be used for C.\nA submodule can be anywhere in your parent git repository. And while \nwalking through the\nparent repository it is sometime a good reminder to know when to just \nentered a submodule.\nBecause now all git command will work on the submodule. I guess this \nindicator is a good way\nto show that.\nAnd with patch [2/4] (and fixed it with [3/4]) I also introduced the \n\"dirty\" indicator for the submodule, which can\nshow you, that your current checked out state in the submodule is not \nthe one committed\nto the parent.\n\n>\n>> diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\n>> index 97eacd7..4c82e7f 100644\n>> --- a/contrib/completion/git-prompt.sh\n>> +++ b/contrib/completion/git-prompt.sh\n>> @@ -93,6 +93,10 @@\n>>   # directory is set up to be ignored by git, then set\n>>   # GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the\n>>   # repository level by setting bash.hideIfPwdIgnored to \"false\".\n>> +#\n>> +# If you would like __git_ps1 to indicate that you are in a submodule,\n>> +# set GIT_PS1_SHOWSUBMODULE. In this case a \"sub:\" will be added before\n>> +# the branch name.\n>>   \n>>   # check whether printf supports -v\n>>   __git_printf_supports_v=\n>> @@ -284,6 +288,32 @@ __git_eread ()\n>>   \ttest -r \"$f\" && read \"$@\" <\"$f\"\n>>   }\n>>   \n>> +# __git_is_submodule\n>> +# Based on:\n>> +# http://stackoverflow.com/questions/7359204/git-command-line-know-if-in-submodule\n>> +__git_is_submodule ()\n> It seems like this function is checking if you are \"IN\" submodule,\n> not \"IS\" submodule.  A misnamed function?\nReworked in Patch [2/4]\n>> +{\n>> +\tlocal git_dir parent_git module_name path\n>> +\t# Find the root of this git repo, then check if its parent dir is also a repo\n>> +\tgit_dir=\"$(git rev-parse --show-toplevel)\"\n>> +\tmodule_name=\"$(basename \"$git_dir\")\"\n> This does not give \"module_name\" in the sense the word is used in\n> the submodule subsystem.  If this variable is useful, call that\n> with \"path\" in its name (I do not think it alone is useful at all).\nReworked in Patch [2/4]\n>\n>> +\tparent_git=\"$(cd \"$git_dir/..\" && git rev-parse --show-toplevel 2> /dev/null)\"\n>> +\tif [[ -n $parent_git ]]; then\n>> +\t\t# List all the submodule paths for the parent repo\n>> +\t\twhile read path\n>> +\t\tdo\n>> +\t\t\tif [[ \"$path\" != \"$module_name\" ]]; then continue; fi\n>> +\t\t\tif [[ -d \"$git_dir/../$path\" ]];    then return 0; fi\n>> +\t\tdone < <(cd $parent_git && git submodule --quiet foreach 'echo $path' 2> /dev/null)\n> Instead of doing this \"loop over submodules and just get true or\n> false\", it may make a lot more sense to find the module name and\n> report that.  That would allow you to have the actual submodule\n> name, not a generic \"sub:\" which does not help the users to tell\n> which one of 47 submodules they have in their top-level project\n> they are currently in.\n>\n> If your projects are layed out like so\n>\n> \t/home/bf/projects/A/\n> \t/home/bf/projects/A/lib/B/ -- submodule\n> \t/home/bf/projects/A/Doc/ -- another submodule\n> \t/home/bf/projects/A/Doc/technical -- a subdirectory of Doc submodule\n>\n> and you are in /home/bf/projects/A/Doc/technical/ subdirectory, your\n> $git_dir variable (which is grossly misnamed, too; call it \"top\"\n> perhaps?) would be \"/home/bf/projects/A/Doc\" and then your\n> $parent_git variable (again, that is misnamed; call it\n> \"parent_top\"?) would be \"/home/bf/projects/A\".  The submodule path\n> to the submodule you are currently in is \"Doc\" (you learn it as the\n> difference between these two).\n>\n> You can ask the top-level project the name of the submodule that is\n> currently at \"Doc\" with \"submodule--helper name\".  Unless the project\n> has moved it since it first added the submodule, the module name may\n> also be \"Doc\", but if it were moved, it may be different.\n>\n> And that \"module name\" is a more useful thing than a hardcoded\n> string \"sub:\" to use in the prompt, I would think.\nReworked in Patch [2/4].\n\n"},{"id":"310588","messageId":"xmqqk29bsz2o.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"c872072a-4754-051d-81e7-1e2166560733@benjaminfuchs.de","subject":"Re: [PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-01-31T03:11:43Z","receivedAt":"2017-01-31T03:12:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Benjamin Fuchs <email@benjaminfuchs.de> writes:\n\n> In [2/4] I got rid of the loop by feedback of Gábor.\n> Sorry if my patch wasn't well formed.\n\nWhile it might be the way other development communities work, in the\nGit development community, we do not work that way when presenting\nyour second and subsequent attempt to the community.\n\nHaving the initial draft from the original developers that records\nthe bugs and misdesigns in an earlier parts of a series and separate\npatches that record how the problems were fixed to arrive at the\nfinal shape of the codebase might be interesting to the original\ndevelopers, and they may even find such a history valuable, but in\nthe context of the history that will be recorded in the official\ntree of the project for eternity, that just adds useless noise.\n\nInstead of keeping the original, in which problems were pointed out,\nand adding later commits to correct them incrementally, a patch is\n\"rerolled\".  That is, you are expected to learn from the review\ncomments and pretend as if you did the work from scratch and you\nalready possessed the wisdom lent by the reviewers when you started\nyour work.  In the \"rerolled\" patches you send, you pretend as if\nyou worked without making mistakes you made in the earlier rounds at\nall, producing (more) perfect patches from the beginning.  \n\nIn reality, you may locally be using Git tools like rebase,\ncherry-pick and \"add -p\" while preparing these \"rerolled\" rounds of\npatches, but the name of the game is to hide that effort from the\npublic and pretend to be a perfect human, recording the result of\nexercising your best ability in the official history ;-).\n\nSo this is OK:\n\n    0/3: I want to improve X, and for that I identified that I need\n    A, B and C done.  A or B alone is already an improvement, but A\n    and B together makes it even more useful, and implementation of\n    C requires patches to do A and B.\n\n    1/3: do A\n    2/3: do B\n    3/3: do C, building on A and B\n\nThis is not:\n\n    0/3: I want to improve X, and for that I need to do C.\n    1/3: I couldn't do C, and I did A instead.\n    2/3: A was totally useless. I fix it to do B.\n    3/3: B is not very useful, either. I fix it to do C.\n\n"},{"id":"310608","messageId":"20170131180633.22369-1-szeder.dev@gmail.com","threadId":"45004","inReplyTo":"1485809065-11978-3-git-send-email-email@benjaminfuchs.de","subject":"Re: [PATCH 2/4] git-prompt.sh: rework of submodule indicator","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2017-01-31T18:06:33Z","receivedAt":"2017-01-31T18:12:07Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"\n> Rework of the first patch. The prompt now will look like this:\n> (+name:master). I tried to considere all suggestions.\n> Tests still missing.\n> \n> Signed-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n> ---\n>  contrib/completion/git-prompt.sh | 49 ++++++++++++++++++++--------------------\n>  1 file changed, 24 insertions(+), 25 deletions(-)\n> \n> diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh\n> index 4c82e7f..c44b9a2 100644\n> --- a/contrib/completion/git-prompt.sh\n> +++ b/contrib/completion/git-prompt.sh\n> @@ -95,8 +95,10 @@\n>  # repository level by setting bash.hideIfPwdIgnored to \"false\".\n>  #\n>  # If you would like __git_ps1 to indicate that you are in a submodule,\n> -# set GIT_PS1_SHOWSUBMODULE. In this case a \"sub:\" will be added before\n> -# the branch name.\n> +# set GIT_PS1_SHOWSUBMODULE to a nonempty value. In this case the name\n> +# of the submodule will be prepended to the branch name (e.g. module:master).\n> +# The name will be prepended by \"+\" if the currently checked out submodule\n> +# commit does not match the SHA-1 found in the index of the containing repository.\n>  \n>  # check whether printf supports -v\n>  __git_printf_supports_v=\n> @@ -288,30 +290,27 @@ __git_eread ()\n>  \ttest -r \"$f\" && read \"$@\" <\"$f\"\n>  }\n>  \n> -# __git_is_submodule\n> -# Based on:\n> -# http://stackoverflow.com/questions/7359204/git-command-line-know-if-in-submodule\n> -__git_is_submodule ()\n> -{\n> -\tlocal git_dir parent_git module_name path\n> -\t# Find the root of this git repo, then check if its parent dir is also a repo\n> -\tgit_dir=\"$(git rev-parse --show-toplevel)\"\n> -\tmodule_name=\"$(basename \"$git_dir\")\"\n> -\tparent_git=\"$(cd \"$git_dir/..\" && git rev-parse --show-toplevel 2> /dev/null)\"\n> -\tif [[ -n $parent_git ]]; then\n> -\t\t# List all the submodule paths for the parent repo\n> -\t\twhile read path\n> -\t\tdo\n> -\t\t\tif [[ \"$path\" != \"$module_name\" ]]; then continue; fi\n> -\t\t\tif [[ -d \"$git_dir/../$path\" ]];    then return 0; fi\n> -\t\tdone < <(cd $parent_git && git submodule --quiet foreach 'echo $path' 2> /dev/null)\n> -    fi\n> -    return 1\n> -}\n> -\n> +# __git_ps1_submodule\n> +#\n> +# $1 - git_dir path\n> +#\n> +# Returns the name of the submodule if we are currently inside one. The name\n> +# will be prepended by \"+\" if the currently checked out submodule commit does\n> +# not match the SHA-1 found in the index of the containing repository.\n> +# NOTE: git_dir looks like in a ...\n> +# - submodule: \"GIT_PARENT/.git/modules/PATH_TO_SUBMODULE\"\n> +# - parent: \"GIT_PARENT/.git\" (exception \".\" in .git)\n>  __git_ps1_submodule ()\n>  {\n> -\t__git_is_submodule && printf \"sub:\"\n> +\tlocal git_dir=\"$1\"\n> +\tlocal submodule_name=\"$(basename \"$git_dir\")\"\n> +\tif [ \"$submodule_name\" != \".git\" ] && [ \"$submodule_name\" != \".\" ]; then\n> +\t\tlocal parent_top=\"${git_dir%.git*}\"\n> +\t\tlocal submodule_top=\"${git_dir#*modules}\"\n> +\t\tlocal status=\"\"\n> +\t\tgit diff -C \"$parent_top\" --no-ext-diff --ignore-submodules=dirty --quiet -- \"$submodule_top\" 2>/dev/null || status=\"+\"\n\nThis 'git diff' has to read the index of the parent repository, right?\nThat can be potentially very expensive, if the parent repository, and\nthus its index, is big.\n\nYou might want to provide finer granularity controls and separate the\n\"$PWD is in a submodule\" indicator from the \"submodule commit doesn't\nmatch\" indicator.  Even if someone is in general interested in the\nformer, he might have some huge repositories where he would prefer to\ndisable the latter, because executing 'git diff' would make the prompt\nlag.\n\nI'm not sure we need brand new control knobs, though.  Perhaps we can\nget away by checking the env and config variables used for the dirty\nindex and worktree status indicator, after all they, too, are about\nwhether to run 'git diff' for the prompt in a repository or not.\n\n> +\t\tprintf \"$status$submodule_name:\"\n> +\tfi\n>  }\n>  \n>  # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n> @@ -545,7 +544,7 @@ __git_ps1 ()\n>  \n>  \tlocal sub=\"\"\n>  \tif [ -n \"${GIT_PS1_SHOWSUBMODULE}\" ]; then\n> -\t\tsub=\"$(__git_ps1_submodule)\"\n> +\t\tsub=\"$(__git_ps1_submodule $g)\"\n\nIn Bash, and in shells in general, the visibility of variables works\ndifferently than in \"regular\" programming languages:\n\n  - Any variable existing in a caller, even the ones declared as\n    'local' in the caller, are visible in all callees.\n    \n    This means you don't have to pass $g as parameter to\n    __git_ps1_submodule(), because you can access it inside that\n    function directly.  This has the benefit that there is one less\n    place where you can forget to quote a path variable :)\n\n  - If the callee modifies any variable that isn't declared as local\n    in the callee, then the caller will see the modified value of that\n    variable, unless the callee was invoked in a subshell.\n\n    Here your sole purpose is to set $sub to something like \"+sub:\",\n    which is determined in __git_ps1_submodule().  You don't need the\n    command substitution for that, you can set $sub directly in\n    __git_ps1_submodule(), sparing the overhead of fork()ing a\n    subshell.  That's important for the sake of git users on Windows.\n\n>  \tfi\n>  \n>  \tlocal f=\"$w$i$s$u\"\n-- \n2.7.4\n\n\n"},{"id":"310610","messageId":"CAM0VKj=j8Fy8AQvYbbvwPf5kkV1GYYONADNsQO5RDNTUzdYt8w@mail.gmail.com","threadId":"45004","inReplyTo":"1485809065-11978-5-git-send-email-email@benjaminfuchs.de","subject":"Re: [PATCH 4/4] git-prompt.sh: add tests for submodule indicator","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2017-01-31T18:32:45Z","receivedAt":"2017-01-31T18:40:58Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Mon, Jan 30, 2017 at 9:44 PM, Benjamin Fuchs <email@benjaminfuchs.de> wrote:\n> Signed-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n> ---\n>  t/t9903-bash-prompt.sh | 43 +++++++++++++++++++++++++++++++++++++++++++\n>  1 file changed, 43 insertions(+)\n>\n> diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh\n> index 97c9b32..4dce366 100755\n> --- a/t/t9903-bash-prompt.sh\n> +++ b/t/t9903-bash-prompt.sh\n> @@ -37,6 +37,11 @@ test_expect_success 'setup for prompt tests' '\n>         git commit -m \"yet another b2\" file &&\n>         mkdir ignored_dir &&\n>         echo \"ignored_dir/\" >>.gitignore &&\n> +       git checkout -b submodule &&\n> +       git submodule add ./. sub &&\n\n./. ?\n\n> +       git -C sub checkout master &&\n> +       git add sub &&\n> +       git commit -m submodule &&\n>         git checkout master\n>  '\n>\n> @@ -755,4 +760,42 @@ test_expect_success 'prompt - hide if pwd ignored - inside gitdir (stderr)' '\n>         test_cmp expected \"$actual\"\n>  '\n>\n> +test_expect_success 'prompt - submodule indicator' '\n> +       printf \" (sub:master)\" >expected &&\n> +       git checkout submodule &&\n> +       test_when_finished \"git checkout master\" &&\n> +       (\n> +               cd sub &&\n> +               GIT_PS1_SHOWSUBMODULE=1 &&\n> +               __git_ps1 >\"$actual\"\n> +       ) &&\n> +       test_cmp expected \"$actual\"\n> +'\n> +\n> +test_expect_success 'prompt - submodule indicator - verify false' '\n\nI was puzzled by the \"verify false\" here.  You mean \"disabled\", right?\n\n> +       printf \" (master)\" >expected &&\n> +       git checkout submodule &&\n> +       test_when_finished \"git checkout master\" &&\n> +       (\n> +               cd sub &&\n> +               GIT_PS1_SHOWSUBMODULE= &&\n> +               __git_ps1 >\"$actual\"\n> +       ) &&\n> +       test_cmp expected \"$actual\"\n> +'\n> +\n> +test_expect_success 'prompt - submodule indicator - dirty status indicator' '\n> +       printf \" (+sub:b1)\" >expected &&\n> +       git checkout submodule &&\n> +       git -C sub checkout b1 &&\n> +       test_when_finished \"git checkout master\" &&\n> +       (\n> +               cd sub &&\n> +               GIT_PS1_SHOWSUBMODULE=1 &&\n> +               __git_ps1 >\"$actual\"\n> +       ) &&\n> +       test_cmp expected \"$actual\"\n> +'\n> +\n> +\n>  test_done\n> --\n> 2.7.4\n>\n"},{"id":"310625","messageId":"CAGZ79kZv=LoP+nG0GVtU_Zi+_SX8_98AXFqzXNh=xM6ASy+=Gw@mail.gmail.com","threadId":"45004","inReplyTo":"xmqq37fyriji.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 4/4] git-prompt.sh: add tests for submodule indicator","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-01-31T22:12:50Z","receivedAt":"2017-01-31T22:12:57Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Jan 31, 2017 at 2:06 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> SZEDER Gábor <szeder.dev@gmail.com> writes:\n>\n>> On Mon, Jan 30, 2017 at 9:44 PM, Benjamin Fuchs <email@benjaminfuchs.de> wrote:\n>>> Signed-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n>>> ---\n>>>  t/t9903-bash-prompt.sh | 43 +++++++++++++++++++++++++++++++++++++++++++\n>>>  1 file changed, 43 insertions(+)\n>>>\n>>> diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh\n>>> index 97c9b32..4dce366 100755\n>>> --- a/t/t9903-bash-prompt.sh\n>>> +++ b/t/t9903-bash-prompt.sh\n>>> @@ -37,6 +37,11 @@ test_expect_success 'setup for prompt tests' '\n>>>         git commit -m \"yet another b2\" file &&\n>>>         mkdir ignored_dir &&\n>>>         echo \"ignored_dir/\" >>.gitignore &&\n>>> +       git checkout -b submodule &&\n>>> +       git submodule add ./. sub &&\n>>\n>> ./. ?\n>\n> Good eyes.  This is a pattern we are trying to wean ourselves off\n> of.  E.g. cf.\n>\n>     https://public-inbox.org/git/20170105192904.1107-2-sbeller@google.com/#t\n>\n> Hopefully this reminds us to resurrect and finish the test fixes in\n> that thread?\n\nI plan to eventually, yes. but that is a refactoring, that has lower prio\nthan getting checkout working recursing into submodules.\n"},{"id":"310626","messageId":"xmqq37fyriji.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"CAM0VKj=j8Fy8AQvYbbvwPf5kkV1GYYONADNsQO5RDNTUzdYt8w@mail.gmail.com","subject":"Re: [PATCH 4/4] git-prompt.sh: add tests for submodule indicator","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-01-31T22:06:25Z","receivedAt":"2017-01-31T22:15:06Z","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> On Mon, Jan 30, 2017 at 9:44 PM, Benjamin Fuchs <email@benjaminfuchs.de> wrote:\n>> Signed-off-by: Benjamin Fuchs <email@benjaminfuchs.de>\n>> ---\n>>  t/t9903-bash-prompt.sh | 43 +++++++++++++++++++++++++++++++++++++++++++\n>>  1 file changed, 43 insertions(+)\n>>\n>> diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh\n>> index 97c9b32..4dce366 100755\n>> --- a/t/t9903-bash-prompt.sh\n>> +++ b/t/t9903-bash-prompt.sh\n>> @@ -37,6 +37,11 @@ test_expect_success 'setup for prompt tests' '\n>>         git commit -m \"yet another b2\" file &&\n>>         mkdir ignored_dir &&\n>>         echo \"ignored_dir/\" >>.gitignore &&\n>> +       git checkout -b submodule &&\n>> +       git submodule add ./. sub &&\n>\n> ./. ?\n\nGood eyes.  This is a pattern we are trying to wean ourselves off\nof.  E.g. cf.\n\n    https://public-inbox.org/git/20170105192904.1107-2-sbeller@google.com/#t\n\nHopefully this reminds us to resurrect and finish the test fixes in\nthat thread?\n"},{"id":"310898","messageId":"CAGZ79kY_1ELUZ2wZwNbQ+HrDnRBM3ngt9HKHKPmvaJEcoAFTtg@mail.gmail.com","threadId":"45004","inReplyTo":"xmqqk29bsz2o.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-02-06T04:23:13Z","receivedAt":"2017-02-06T04:23:22Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Jan 30, 2017 at 7:11 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Benjamin Fuchs <email@benjaminfuchs.de> writes:\n>\n>> In [2/4] I got rid of the loop by feedback of Gábor.\n>> Sorry if my patch wasn't well formed.\n>\n> While it might be the way other development communities work, in the\n> Git development community, we do not work that way when presenting\n> your second and subsequent attempt to the community.\n>\n> Having the initial draft from the original developers that records\n> the bugs and misdesigns in an earlier parts of a series and separate\n> patches that record how the problems were fixed to arrive at the\n> final shape of the codebase might be interesting to the original\n> developers, and they may even find such a history valuable, but in\n> the context of the history that will be recorded in the official\n> tree of the project for eternity, that just adds useless noise.\n>\n> Instead of keeping the original, in which problems were pointed out,\n> and adding later commits to correct them incrementally, a patch is\n> \"rerolled\".  That is, you are expected to learn from the review\n> comments and pretend as if you did the work from scratch and you\n> already possessed the wisdom lent by the reviewers when you started\n> your work.  In the \"rerolled\" patches you send, you pretend as if\n> you worked without making mistakes you made in the earlier rounds at\n> all, producing (more) perfect patches from the beginning.\n>\n> In reality, you may locally be using Git tools like rebase,\n> cherry-pick and \"add -p\" while preparing these \"rerolled\" rounds of\n> patches, but the name of the game is to hide that effort from the\n> public and pretend to be a perfect human, recording the result of\n> exercising your best ability in the official history ;-).\n>\n> So this is OK:\n>\n>     0/3: I want to improve X, and for that I identified that I need\n>     A, B and C done.  A or B alone is already an improvement, but A\n>     and B together makes it even more useful, and implementation of\n>     C requires patches to do A and B.\n>\n>     1/3: do A\n>     2/3: do B\n>     3/3: do C, building on A and B\n>\n> This is not:\n>\n>     0/3: I want to improve X, and for that I need to do C.\n>     1/3: I couldn't do C, and I did A instead.\n>     2/3: A was totally useless. I fix it to do B.\n>     3/3: B is not very useful, either. I fix it to do C.\n>\n\nI agree with Junio here,\n\"git rebase --interactive\" and then editing/squashing commits\nis your friend.\n\n(unrelated side note:)\nAt GitMerge facebook presented their improvements on mercurial\nand one of the things was \"hg absorb\". It would take the dirty hunks/lines\nof the working tree and amend them into the \"stack of commits\", i.e. into\nyour local unpublished history. So instead of making fixup commits\nand doing the whole interactive rebase thing, it would do it automatically\nfor you. I think that is a neat time saver.\n\nThanks,\nStefan\n"},{"id":"310899","messageId":"CA+P7+xp0QJZkiYzgBhPvYPsG7iqRDhRQUjcdgf_GHU-93bSO-g@mail.gmail.com","threadId":"45004","inReplyTo":"CAGZ79kY_1ELUZ2wZwNbQ+HrDnRBM3ngt9HKHKPmvaJEcoAFTtg@mail.gmail.com","subject":"Re: [PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2017-02-06T05:55:04Z","receivedAt":"2017-02-06T05:55:33Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Sun, Feb 5, 2017 at 8:23 PM, Stefan Beller <sbeller@google.com> wrote:\n>\n> (unrelated side note:)\n> At GitMerge facebook presented their improvements on mercurial\n> and one of the things was \"hg absorb\". It would take the dirty hunks/lines\n> of the working tree and amend them into the \"stack of commits\", i.e. into\n> your local unpublished history. So instead of making fixup commits\n> and doing the whole interactive rebase thing, it would do it automatically\n> for you. I think that is a neat time saver.\n>\n> Thanks,\n> Stefan\n\nHow exactly was it different from doing \"git  commit --fixup xyz\" and\n\"git rebase -i --autosquash\"? Like, what was the advantage to the user\nfacing workflow? Just curious to see if we could learn something from\nit.\n\nRegards,\nJake\n"},{"id":"310903","messageId":"CAGZ79kZyofKoAzFH7zU7DDndRPbiS1L+7d7Y6HqRZ+_4JoJ_zw@mail.gmail.com","threadId":"45004","inReplyTo":"CA+P7+xp0QJZkiYzgBhPvYPsG7iqRDhRQUjcdgf_GHU-93bSO-g@mail.gmail.com","subject":"Re: [PATCH 1/4] git-prompt.sh: add submodule indicator","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-02-06T10:13:23Z","receivedAt":"2017-02-06T10:13:30Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Sun, Feb 5, 2017 at 9:55 PM, Jacob Keller <jacob.keller@gmail.com> wrote:\n> On Sun, Feb 5, 2017 at 8:23 PM, Stefan Beller <sbeller@google.com> wrote:\n>>\n>> (unrelated side note:)\n>> At GitMerge facebook presented their improvements on mercurial\n>> and one of the things was \"hg absorb\". It would take the dirty hunks/lines\n>> of the working tree and amend them into the \"stack of commits\", i.e. into\n>> your local unpublished history. So instead of making fixup commits\n>> and doing the whole interactive rebase thing, it would do it automatically\n>> for you. I think that is a neat time saver.\n>>\n>> Thanks,\n>> Stefan\n>\n> How exactly was it different from doing \"git  commit --fixup xyz\" and\n> \"git rebase -i --autosquash\"? Like, what was the advantage to the user\n> facing workflow? Just curious to see if we could learn something from\n> it.\n\nMy impression is that all local changes were split up and the \"xyz\"\nwas determined based off a heuristic, e.g. blame(?) and then the\nrebase is run automatically after that, i.e. having just one command for\na complete workflow here, moving up a whole level in abstraction.\n"},{"id":"313397","messageId":"20170307034553.10770-1-sbeller@google.com","threadId":"45004","inReplyTo":"CAGZ79kZv=LoP+nG0GVtU_Zi+_SX8_98AXFqzXNh=xM6ASy+=Gw@mail.gmail.com","subject":"[RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-07T03:45:53Z","receivedAt":"2017-03-07T03:46:10Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n\nMarking this as RFC as documentation and tests are missing.\n\n builtin/rev-parse.c |  7 +++++\n submodule.c         | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n submodule.h         |  8 +++++\n 3 files changed, 102 insertions(+)\n\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex e08677e559..2549643267 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -12,6 +12,7 @@\n #include \"diff.h\"\n #include \"revision.h\"\n #include \"split-index.h\"\n+#include \"submodule.h\"\n \n #define DO_REVS\t\t1\n #define DO_NOREV\t2\n@@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tputs(work_tree);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(arg, \"--show-superproject-working-tree\")) {\n+\t\t\t\tconst char *superproject = get_superproject_working_tree();\n+\t\t\t\tif (superproject)\n+\t\t\t\t\tputs(superproject);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-prefix\")) {\n \t\t\t\tif (prefix)\n \t\t\t\t\tputs(prefix);\ndiff --git a/submodule.c b/submodule.c\nindex 3b98766a6b..a63aef2c6b 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1514,3 +1514,90 @@ void absorb_git_dir_into_superproject(const char *prefix,\n \t\tstrbuf_release(&sb);\n \t}\n }\n+\n+static int superproject_exists(void)\n+{\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tconst char *one_up = real_path_if_valid(\"../\");\n+\tconst char *dirname;\n+\tint code, has_superproject = 0;\n+\n+\tif (!one_up)\n+\t\t/* At the root of the file system. */\n+\t\treturn 0;\n+\n+\tdirname = relative_path(xgetcwd(), one_up, &sb);\n+\tprepare_submodule_repo_env(&cp.env_array);\n+\targv_array_pop(&cp.env_array);\n+\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n+\t\t\t\"ls-tree\", \"HEAD\", \"--\", dirname, NULL);\n+\n+\tcp.no_stdin = 1;\n+\tcp.no_stderr = 1;\n+\tcp.out = -1;\n+\tcp.git_cmd = 1;\n+\n+\tif (start_command(&cp))\n+\t\tdie(_(\"could not start ls-tree in ..\"));\n+\n+\tstrbuf_read(&buf, cp.out, 7);\n+\tclose(cp.out);\n+\tif (starts_with(buf.buf, \"160000\"))\n+\t\t/* there is a superproject having this as a submodule */\n+\t\thas_superproject = 1;\n+\n+\tcode = finish_command(&cp);\n+\n+\tif (code == 128)\n+\t\t/* not a git repository */\n+\t\tgoto out;\n+\tif (code == 0 && !has_superproject)\n+\t\t/* there is an unrelated git repository */\n+\t\tgoto out;\n+\n+\tif (code)\n+\t\tdie(_(\"ls-tree returned unexpected return code\"));\n+\n+\treturn 1;\n+\n+out:\n+\tstrbuf_release(&sb);\n+\n+\treturn 0;\n+}\n+\n+const char *get_superproject_working_tree()\n+{\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\n+\tif (!superproject_exists())\n+\t\treturn NULL;\n+\n+\tprepare_submodule_repo_env(&cp.env_array);\n+\targv_array_pop(&cp.env_array);\n+\n+\targv_array_pushl(&cp.args, \"-C\", \"..\",\n+\t\t\t\"rev-parse\", \"--show-toplevel\", NULL);\n+\n+\tcp.no_stdin = 1;\n+\tcp.no_stderr = 1;\n+\tcp.out = -1;\n+\tcp.git_cmd = 1;\n+\n+\tif (start_command(&cp))\n+\t\tdie(_(\"could not start rev-parse in ..\"));\n+\n+\tstrbuf_reset(&sb);\n+\tstrbuf_read(&sb, cp.out, PATH_MAX);\n+\n+\t/* remove trailing new line */\n+\tstrbuf_rtrim(&sb);\n+\n+\tif (finish_command(&cp))\n+\t\tdie(_(\"rev-parse died unexpectedly\"));\n+\n+\treturn strbuf_detach(&sb, NULL);\n+}\ndiff --git a/submodule.h b/submodule.h\nindex 05ab674f06..f207bb8d5f 100644\n--- a/submodule.h\n+++ b/submodule.h\n@@ -93,4 +93,12 @@ extern void prepare_submodule_repo_env(struct argv_array *out);\n extern void absorb_git_dir_into_superproject(const char *prefix,\n \t\t\t\t\t     const char *path,\n \t\t\t\t\t     unsigned flags);\n+\n+/*\n+ * Return the absolute path of the working tree of the superproject, which this\n+ * project is a submodule of. If this repository is not a submodule of\n+ * another repository, return NULL.\n+ */\n+extern const char *get_superproject_working_tree();\n+\n #endif\n-- \n2.12.0.189.g3bc53220cb.dirty\n\n"},{"id":"313398","messageId":"xmqqvarly8hn.fsf@junio-linux.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170307034553.10770-1-sbeller@google.com","subject":"Re: [RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T05:13:40Z","receivedAt":"2017-03-07T05:15:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> diff --git a/submodule.c b/submodule.c\n> index 3b98766a6b..a63aef2c6b 100644\n> --- a/submodule.c\n> +++ b/submodule.c\n> @@ -1514,3 +1514,90 @@ void absorb_git_dir_into_superproject(const char *prefix,\n>  \t\tstrbuf_release(&sb);\n>  \t}\n>  }\n\nPlease have a comment here what this function expects (e.g. it is\ncalled after we ran repository discovery and $cwd is at the root of\nthe working tree of the current project, we _know_ we have a working\ntree, etc.).\n\n> +\n> +static int superproject_exists(void)\n> +{\n> +\tstruct child_process cp = CHILD_PROCESS_INIT;\n> +\tstruct strbuf sb = STRBUF_INIT;\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tconst char *one_up = real_path_if_valid(\"../\");\n> +\tconst char *dirname;\n> +\tint code, has_superproject = 0;\n> +\n> +\tif (!one_up)\n> +\t\t/* At the root of the file system. */\n> +\t\treturn 0;\n\nHmph.  I would have expected that \"/../\" would be the same as \"/\".\n\n> +\tdirname = relative_path(xgetcwd(), one_up, &sb);\n\nSo, the idea is we start at the root level of the current project's\nworking tree, and we go up one level, then we know the last component\nof the path our submodule is bound at in the superproject.\n\n> +\tprepare_submodule_repo_env(&cp.env_array);\n> +\targv_array_pop(&cp.env_array);\n> +\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n> +\t\t\t\"ls-tree\", \"HEAD\", \"--\", dirname, NULL);\n\nThis would ask our superproject what is at the \"dirname\" in its\nHEAD.  Two possible issues:\n\n - Shouldn't that be looking at its index instead?  It would be more\n   correct for unborn branch case, and new or moved submodule case.\n\n - If our submodule is bound at path sub/dir in the superproject,\n   the relative-path thing above would get \"dir\" and this ls-tree\n   ends up asking what is at \"dir\", but the question you really want\n   to ask is what is at \"sub/dir\", isn't it?\n\n> +const char *get_superproject_working_tree()\n\nconst char *get_superproject_working_tree(void)\n"},{"id":"313399","messageId":"xmqqr329y2sm.fsf@junio-linux.mtv.corp.google.com","threadId":"45004","inReplyTo":"xmqqvarly8hn.fsf@junio-linux.mtv.corp.google.com","subject":"Re: [RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T07:16:41Z","receivedAt":"2017-03-07T07:18:25Z","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>> +\tdirname = relative_path(xgetcwd(), one_up, &sb);\n>\n> So, the idea is we start at the root level of the current project's\n> working tree, and we go up one level, then we know the last component\n> of the path our submodule is bound at in the superproject.\n>\n>> +\tprepare_submodule_repo_env(&cp.env_array);\n>> +\targv_array_pop(&cp.env_array);\n>> +\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n>> +\t\t\t\"ls-tree\", \"HEAD\", \"--\", dirname, NULL);\n>\n> This would ask our superproject what is at the \"dirname\" in its\n> HEAD.  Two possible issues:\n>\n>  - Shouldn't that be looking at its index instead?  It would be more\n>    correct for unborn branch case, and new or moved submodule case.\n>\n>  - If our submodule is bound at path sub/dir in the superproject,\n>    the relative-path thing above would get \"dir\" and this ls-tree\n>    ends up asking what is at \"dir\", but the question you really want\n>    to ask is what is at \"sub/dir\", isn't it?\n\nIOW, the basic ontline of the idea may be OK, but I think you would\nwant to do something along this line:\n\n    - chdir to .. from the root of your submodule working tree;\n    - in that .. directory, ask what prefix it is (you'd get\n      \"sub/dir\", or \"not a git\" if you are not a submodule);\n    - in that .. directory, ask ls-files what sub/dir is;\n    - if it is 160000, you're happy.\n\n"},{"id":"313400","messageId":"xmqqh935y2hc.fsf@junio-linux.mtv.corp.google.com","threadId":"45004","inReplyTo":"xmqqr329y2sm.fsf@junio-linux.mtv.corp.google.com","subject":"Re: [RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T07:23:27Z","receivedAt":"2017-03-07T07:59: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>>  - If our submodule is bound at path sub/dir in the superproject,\n>>    the relative-path thing above would get \"dir\" and this ls-tree\n>>    ends up asking what is at \"dir\", but the question you really want\n>>    to ask is what is at \"sub/dir\", isn't it?\n>\n> IOW, the basic ontline of the idea may be OK, but I think you would\n> want to do something along this line:\n>\n>     - chdir to .. from the root of your submodule working tree;\n>     - in that .. directory, ask what prefix it is (you'd get\n>       \"sub/dir\", or \"not a git\" if you are not a submodule);\n>     - in that .. directory, ask ls-files what sub/dir is;\n>     - if it is 160000, you're happy.\n\nNah, that wouldn't be necessary and would not work.  --prefix would\nbe \"sub\" in that case, and you'd need to concatenate the \"dir\" that\nis the basename of the path to the submodule to get \"sub/dir\".  \n\nBesides, output from \"ls-files\" by default is relative to cwd, so if\nyou did ls-files or ls-tree HEAD in \"sub/\", you'll find where you\ncame from as \"dir\", not \"sub/dir\", so the original code happens to\nwork even from a subdirectory of a superproject, but the reason why\nit works is a bit subtle.  Perhaps it deserves in-code comment to\nexplain it.\n\n\n"},{"id":"313439","messageId":"xmqq8toh7wqu.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170307034553.10770-1-sbeller@google.com","subject":"Re: [RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T18:44:09Z","receivedAt":"2017-03-07T18:45:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> +const char *get_superproject_working_tree()\n\nconst char *get_superproject_working_tree(void)\n\nThe same for the *.h file declaration.\n\n> +{\n> +\tstruct child_process cp = CHILD_PROCESS_INIT;\n> +\tstruct strbuf sb = STRBUF_INIT;\n> +\n> +\tif (!superproject_exists())\n> +\t\treturn NULL;\n> + ...\n> +\treturn strbuf_detach(&sb, NULL);\n\nHaving reviewed it, I somehow think you do not want to have a\nseparate superproject_exists() that grabs some part of the\ninformation this caller needs and then discards it.\n\nThe helper already does these things:\n\n    - xgetcwd(), which may give you \"/local/repo/super/sub/dir\"\n\n    - relative_path() with the result and \"..\", which may give you\n      \"dir\"\n\n    - ls-tree HEAD \"dir\" to see what is in \"sub/dir\" of the\n      repository that governs \"..\"; if \"sub/dir\" is a gitlink,\n      you know you started in a working tree of a repository\n      different from the one that governs \"..\".\n\nAnd the caller is trying to figure out where the root of the\nsuperproject is, i.e. \"/local/repo/super\", and the helper has half\nof the answer to that already.  If you ask the \"ls-tree HEAD\" (as I\nsaid, I think it should be \"ls-files\") to give you not \"dir\" but\n\"sub/dir\", you can subtract it from the result of xgetcwd() you did\nat the beginning of the helper, and that gives what this caller of\nthe helper wants.\n\nSo perhaps your superproject_exists() helper can be eliminated and\ninstead coded in get_superproject_working_tree() in place to do:\n\n\t- xgetcwd() to get \"/local/repo/super/sub/dir\".\n\n\t- relative_path() to get \"dir\".\n\n\t- ask \"ls-{tree,files} --full-name HEAD dir\" to get \"160000\"\n          and \"sub/dir\".\n\n\t- subtract \"sub/dir\" from the tail of the \"/local/repo/super/sub/dir\"\n\t  you got from xgetcwd() earlier.\n\n\t- return the result.\n\nwith a failure/unmet expectations (like not finding 160000) from any\nstep returning an error, or something like that.\n\n"},{"id":"313450","messageId":"CAGZ79kYMZk3sNNjWgp9acQG6z5Q5CnsJi+n7Bvr3EkfbSHasMA@mail.gmail.com","threadId":"45004","inReplyTo":"xmqq8toh7wqu.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-07T20:40:54Z","receivedAt":"2017-03-07T20:41:27Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Mar 7, 2017 at 10:44 AM, Junio C Hamano <gitster@pobox.com> wrote:\n\n> So perhaps your superproject_exists() helper can be eliminated\n\nThat is what I had originally, but I assumed a strict helper function\nfor \"existence of the superproject\" would be interesting in the future,\ne.g. for get_superproject_git_dir, or on its own. There was an attempt\nto have the shell prompt indicate if you are in a submodule,\nwhich would not need to know the worktree or git dir of the\nsuperproject, but only its existence.\n\n> instead coded in get_superproject_working_tree() in place to do:\n>\n>         - xgetcwd() to get \"/local/repo/super/sub/dir\".\n\nDid you mean .../super/dir/sub ?\n\nIf not and we run this command from a directory inside the\nsubmodule, the usual prefix mechanics should go to the\nroot of the submodule, such that the \"..\" will be just enough\nto break out of that submodule repo.\n\nThe interesting part is in the superproject, to see if we are\nin a directory (and where the root of the superproject is).\n\n>         - relative_path() to get \"dir\".\n\nok.\n\n>         - ask \"ls-{tree,files} --full-name HEAD dir\" to get \"160000\"\n>           and \"sub/dir\".\n\n\"ls-files --stage --full-name\" to get\n160000 ... dir/sub\n\n>\n>         - subtract \"sub/dir\" from the tail of the \"/local/repo/super/sub/dir\"\n>           you got from xgetcwd() earlier.\n\nmakes sense.\n\n>\n>         - return the result.\n>\n> with a failure/unmet expectations (like not finding 160000) from any\n> step returning an error, or something like that.\n\nThat seems better as we only need to spawn one process.\n\n(This could also mean I am bad at reading our own man pages)\n\nThanks,\nStefan\n"},{"id":"313470","messageId":"xmqq7f4066t9.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"CAGZ79kYMZk3sNNjWgp9acQG6z5Q5CnsJi+n7Bvr3EkfbSHasMA@mail.gmail.com","subject":"Re: [RFC PATCH] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T22:49:38Z","receivedAt":"2017-03-08T00:44:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> On Tue, Mar 7, 2017 at 10:44 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n>> So perhaps your superproject_exists() helper can be eliminated\n>\n> That is what I had originally, but I assumed a strict helper function\n> for \"existence of the superproject\" would be interesting in the future,\n> e.g. for get_superproject_git_dir, or on its own. There was an attempt\n> to have the shell prompt indicate if you are in a submodule,\n> which would not need to know the worktree or git dir of the\n> superproject, but only its existence.\n>\n>> instead coded in get_superproject_working_tree() in place to do:\n>>\n>>         - xgetcwd() to get \"/local/repo/super/sub/dir\".\n>\n> Did you mean .../super/dir/sub ?\n\nI meant \"/local/repo/super/sub/dir\".  I am using this case to\nillustrate: the root of the superproject is at /local/repo/super,\nits submodule we are interested in is at sub/dir, and the function\nis working inside the submodule--after the repository discovery\nmoves the cwd, xgetcwd() would give the root of the working tree of\nthe submodule, which is at \"/local/repo/super/sub/dir\".\n\nAnd that would give us \"dir\" by taking that as relative to its \"../\"\n\n>>         - relative_path() to get \"dir\".\n>\n> ok.\n\nindeed.\n\n>>         - ask \"ls-{tree,files} --full-name HEAD dir\" to get \"160000\"\n>>           and \"sub/dir\".\n>\n> \"ls-files --stage --full-name\" to get\n> 160000 ... dir/sub\n\nYeah, also when usihng ls-files you obviously do not give HEAD but\nyou do give \"dir\" as the pathspec.  And you get \"sub/dir\" as the\nresult.\n"},{"id":"313472","messageId":"20170308005615.20321-1-sbeller@google.com","threadId":"45004","inReplyTo":"xmqq7f4066t9.fsf@gitster.mtv.corp.google.com","subject":"[PATCHv2] rev-parse: add --show-superproject-working-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-08T00:56:15Z","receivedAt":"2017-03-08T01:05:43Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"In some situations it is useful to know if the given repository\nis a submodule of another repository.\n\nAdd the flag --show-superproject-working-tree to git-rev-parse\nto make it easy to find out if there is a superproject.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n\n* not RFC anymore, but for real this time; including a test and docs :)\n\n* Following Junios advice: there is only one function\n  (superproject_exists was dropped) using ls-files.\n  (the test actually tests for a staged submodule) \n  \nThanks,\nStefan\n\n\n Documentation/git-rev-parse.txt |  5 +++\n builtin/rev-parse.c             |  7 ++++\n submodule.c                     | 83 +++++++++++++++++++++++++++++++++++++++++\n submodule.h                     |  8 ++++\n t/t1500-rev-parse.sh            | 14 +++++++\n 5 files changed, 117 insertions(+)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 91c02b8c85..b841bad7c7 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -261,6 +261,11 @@ print a message to stderr and exit with nonzero status.\n --show-toplevel::\n \tShow the absolute path of the top-level directory.\n \n+--show-superproject-working-tree\n+\tShow the absolute path of the top-level directory of\n+\tthe superproject. A superproject is a repository that records\n+\tthis repository as a submodule.\n+\n --shared-index-path::\n \tShow the path to the shared index file in split index mode, or\n \tempty if not in split-index mode.\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex e08677e559..2549643267 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -12,6 +12,7 @@\n #include \"diff.h\"\n #include \"revision.h\"\n #include \"split-index.h\"\n+#include \"submodule.h\"\n \n #define DO_REVS\t\t1\n #define DO_NOREV\t2\n@@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tputs(work_tree);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(arg, \"--show-superproject-working-tree\")) {\n+\t\t\t\tconst char *superproject = get_superproject_working_tree();\n+\t\t\t\tif (superproject)\n+\t\t\t\t\tputs(superproject);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-prefix\")) {\n \t\t\t\tif (prefix)\n \t\t\t\t\tputs(prefix);\ndiff --git a/submodule.c b/submodule.c\nindex 3b98766a6b..06473d3646 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1514,3 +1514,86 @@ void absorb_git_dir_into_superproject(const char *prefix,\n \t\tstrbuf_release(&sb);\n \t}\n }\n+\n+const char *get_superproject_working_tree(void)\n+{\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tconst char *one_up = real_path_if_valid(\"../\");\n+\tconst char *cwd = xgetcwd();\n+\tconst char *ret = NULL;\n+\tconst char *subpath;\n+\tint code;\n+\tssize_t len;\n+\n+\tif (!is_inside_work_tree())\n+\t\t/*\n+\t\t * FIXME:\n+\t\t * We might have a superproject, but it is harder\n+\t\t * to determine.\n+\t\t */\n+\t\treturn NULL;\n+\n+\tif (!one_up)\n+\t\treturn NULL;\n+\n+\tsubpath = relative_path(cwd, one_up, &sb);\n+\n+\tprepare_submodule_repo_env(&cp.env_array);\n+\targv_array_pop(&cp.env_array);\n+\n+\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n+\t\t\t\"ls-files\", \"--stage\", \"--full-name\", \"--\", subpath, NULL);\n+\tstrbuf_reset(&sb);\n+\n+\tcp.no_stdin = 1;\n+\tcp.no_stderr = 1;\n+\tcp.out = -1;\n+\tcp.git_cmd = 1;\n+\n+\tif (start_command(&cp))\n+\t\tdie(_(\"could not start ls-files in ..\"));\n+\n+\tlen = strbuf_read(&sb, cp.out, PATH_MAX);\n+\tclose(cp.out);\n+\n+\tif (starts_with(sb.buf, \"160000\")) {\n+\t\tint super_sub_len;\n+\t\tint cwd_len = strlen(cwd);\n+\t\tchar *super_sub, *super_wt;\n+\n+\t\t/*\n+\t\t * There is a superproject having this repo as a submodule.\n+\t\t * The format is <mode> SP <hash> SP <stage> TAB <full name> LF,\n+\t\t * First remove LF, then skip up to \\t.\n+\t\t */\n+\t\tstrbuf_rtrim(&sb);\n+\t\tsuper_sub = strchr(sb.buf, '\\t') + 1;\n+\n+\t\tsuper_sub_len = sb.buf + sb.len - super_sub;\n+\t\tif (super_sub_len > cwd_len ||\n+\t\t    strcmp(&cwd[cwd_len - super_sub_len], super_sub))\n+\t\t\tdie (_(\"BUG: returned path string doesn't match cwd?\"));\n+\n+\t\tsuper_wt = xstrdup(cwd);\n+\t\tsuper_wt[cwd_len - super_sub_len] = '\\0';\n+\n+\t\tret = real_path(super_wt);\n+\n+\t\tfree(super_wt);\n+\t}\n+\tstrbuf_release(&sb);\n+\n+\tcode = finish_command(&cp);\n+\n+\tif (code == 128)\n+\t\t/* '../' is not a git repository */\n+\t\treturn NULL;\n+\tif (code == 0 && len == 0)\n+\t\t/* There is an unrelated git repository at '../' */\n+\t\treturn NULL;\n+\tif (code)\n+\t\tdie(_(\"ls-tree returned unexpected return code %d\"), code);\n+\n+\treturn ret;\n+}\ndiff --git a/submodule.h b/submodule.h\nindex 05ab674f06..c8a0c9cb29 100644\n--- a/submodule.h\n+++ b/submodule.h\n@@ -93,4 +93,12 @@ extern void prepare_submodule_repo_env(struct argv_array *out);\n extern void absorb_git_dir_into_superproject(const char *prefix,\n \t\t\t\t\t     const char *path,\n \t\t\t\t\t     unsigned flags);\n+\n+/*\n+ * Return the absolute path of the working tree of the superproject, which this\n+ * project is a submodule of. If this repository is not a submodule of\n+ * another repository, return NULL.\n+ */\n+extern const char *get_superproject_working_tree(void);\n+\n #endif\ndiff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh\nindex 9ed8b8ccba..03d3c7f6d6 100755\n--- a/t/t1500-rev-parse.sh\n+++ b/t/t1500-rev-parse.sh\n@@ -116,4 +116,18 @@ test_expect_success 'git-path inside sub-dir' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'showing the superproject correctly' '\n+\tgit rev-parse --show-superproject-working-tree >out &&\n+\ttest_must_be_empty out &&\n+\n+\ttest_create_repo super &&\n+\ttest_commit -C super test_commit &&\n+\ttest_create_repo sub &&\n+\ttest_commit -C sub test_commit &&\n+\tgit -C super submodule add ../sub dir/sub &&\n+\techo $(pwd)/super >expect  &&\n+\tgit -C super/dir/sub rev-parse --show-superproject-working-tree >out &&\n+\ttest_cmp expect out\n+'\n+\n test_done\n-- \n2.12.0.190.g6a12a61b77.dirty\n\n"},{"id":"313484","messageId":"xmqq60jk488v.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170308005615.20321-1-sbeller@google.com","subject":"Re: [PATCHv2] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-08T06:01:36Z","receivedAt":"2017-03-08T06:08:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> +\t\t\tif (!strcmp(arg, \"--show-superproject-working-tree\")) {\n> +\t\t\t\tconst char *superproject = get_superproject_working_tree();\n> +\t\t\t\tif (superproject)\n> +\t\t\t\t\tputs(superproject);\n> +\t\t\t\tcontinue;\n> +\t\t\t}\n\nReturning the exact string of the path from the API function is\nabsolutely the right thing. I however have to wonder if rev-parse\nneed to do the c-quoting unless it is told to show pathnames in its\noutput without quoting (perhaps with \"-z\").  Paths from \"rev-parse\"\n(like \"--git-dir\", \"--show-toplevel\", etc.) already are excempt from\nthe usual quoting rules, so doing puts() and nothing else is fine to\nbe consistent with the existing practice, but in the longer term, I\nam sure we would need to revisit so that scripts can handle paths\nwith funny characters sensibly, but that would be a different topic\nif existing ones like \"--git-dir\" are already unsafe.\n\n>  \t\t\tif (!strcmp(arg, \"--show-prefix\")) {\n>  \t\t\t\tif (prefix)\n>  \t\t\t\t\tputs(prefix);\n> diff --git a/submodule.c b/submodule.c\n> index 3b98766a6b..06473d3646 100644\n> --- a/submodule.c\n> +++ b/submodule.c\n> @@ -1514,3 +1514,86 @@ void absorb_git_dir_into_superproject(const char *prefix,\n>  \t\tstrbuf_release(&sb);\n>  \t}\n>  }\n> +\n> +const char *get_superproject_working_tree(void)\n> +{\n> +...\n> +\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n> +\t\t\t\"ls-files\", \"--stage\", \"--full-name\", \"--\", subpath, NULL);\n> +\tstrbuf_reset(&sb);\n> +...\n> +\tif (starts_with(sb.buf, \"160000\")) {\n> +\t\tint super_sub_len;\n> +\t\tint cwd_len = strlen(cwd);\n> +\t\tchar *super_sub, *super_wt;\n> +\n> +\t\t/*\n> +\t\t * There is a superproject having this repo as a submodule.\n> +\t\t * The format is <mode> SP <hash> SP <stage> TAB <full name> LF,\n> +\t\t * First remove LF, then skip up to \\t.\n> +\t\t */\n\nLooks more or less right but invoke \"ls-files -z\" and reading the \\0\ndelimited output would be easier; otherwise you would have to worry\nabout c-unquoting the pathname when the submodule is bound at a path\nwith funny character (like a double-quote) in it.\n"},{"id":"313486","messageId":"CAPc5daWph1wPMqo_GEjixbY=t36MMaRaQ-mt3herWwxp0qHqcA@mail.gmail.com","threadId":"45004","inReplyTo":"20170308005615.20321-1-sbeller@google.com","subject":"Re: [PATCHv2] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-08T01:30:41Z","receivedAt":"2017-03-08T07:25:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Looks more or less right but invoke \"ls-files -z\" and reading the \\0\ndelimited output would be easier; otherwise you would have to worry\nabout c-unquoting the pathname when the submodule is bound at a path\nwith funny character (like a double-quote) in it.\n\nAlso, returning the exact string of the path from the API function is\nabsolutely the right thing. I however have to wonder if rev-parse need\nto do the c-quoting unless it is told to show pathnames in its output\nwithout quoting (perhaps with \"-z\")? Or are paths from \"rev-parse\"\n(like \"--git-dir\", \"--show-toplevel\", etc.) already excempt from the\nusual quoting rules---if so, doing puts() and nothing else is fine to\nbe consistent with the existing practice (in the longer term, I am\nsure we would need to revisit so that scripts can handle paths with\nfunny characters sensibly, but that would be a different topic if\nexisting ones like \"--git-dir\" are already unsafe).\n\nSorry for top-posting (I am not on a terminal right now).\n\nOn Tue, Mar 7, 2017 at 4:56 PM, Stefan Beller <sbeller@google.com> wrote:\n> In some situations it is useful to know if the given repository\n> is a submodule of another repository.\n>\n> Add the flag --show-superproject-working-tree to git-rev-parse\n> to make it easy to find out if there is a superproject.\n>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> ---\n>\n> * not RFC anymore, but for real this time; including a test and docs :)\n>\n> * Following Junios advice: there is only one function\n>   (superproject_exists was dropped) using ls-files.\n>   (the test actually tests for a staged submodule)\n>\n> Thanks,\n> Stefan\n>\n>\n>  Documentation/git-rev-parse.txt |  5 +++\n>  builtin/rev-parse.c             |  7 ++++\n>  submodule.c                     | 83 +++++++++++++++++++++++++++++++++++++++++\n>  submodule.h                     |  8 ++++\n>  t/t1500-rev-parse.sh            | 14 +++++++\n>  5 files changed, 117 insertions(+)\n>\n> diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\n> index 91c02b8c85..b841bad7c7 100644\n> --- a/Documentation/git-rev-parse.txt\n> +++ b/Documentation/git-rev-parse.txt\n> @@ -261,6 +261,11 @@ print a message to stderr and exit with nonzero status.\n>  --show-toplevel::\n>         Show the absolute path of the top-level directory.\n>\n> +--show-superproject-working-tree\n> +       Show the absolute path of the top-level directory of\n> +       the superproject. A superproject is a repository that records\n> +       this repository as a submodule.\n> +\n>  --shared-index-path::\n>         Show the path to the shared index file in split index mode, or\n>         empty if not in split-index mode.\n> diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\n> index e08677e559..2549643267 100644\n> --- a/builtin/rev-parse.c\n> +++ b/builtin/rev-parse.c\n> @@ -12,6 +12,7 @@\n>  #include \"diff.h\"\n>  #include \"revision.h\"\n>  #include \"split-index.h\"\n> +#include \"submodule.h\"\n>\n>  #define DO_REVS                1\n>  #define DO_NOREV       2\n> @@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n>                                         puts(work_tree);\n>                                 continue;\n>                         }\n> +                       if (!strcmp(arg, \"--show-superproject-working-tree\")) {\n> +                               const char *superproject = get_superproject_working_tree();\n> +                               if (superproject)\n> +                                       puts(superproject);\n> +                               continue;\n> +                       }\n>                         if (!strcmp(arg, \"--show-prefix\")) {\n>                                 if (prefix)\n>                                         puts(prefix);\n> diff --git a/submodule.c b/submodule.c\n> index 3b98766a6b..06473d3646 100644\n> --- a/submodule.c\n> +++ b/submodule.c\n> @@ -1514,3 +1514,86 @@ void absorb_git_dir_into_superproject(const char *prefix,\n>                 strbuf_release(&sb);\n>         }\n>  }\n> +\n> +const char *get_superproject_working_tree(void)\n> +{\n> +       struct child_process cp = CHILD_PROCESS_INIT;\n> +       struct strbuf sb = STRBUF_INIT;\n> +       const char *one_up = real_path_if_valid(\"../\");\n> +       const char *cwd = xgetcwd();\n> +       const char *ret = NULL;\n> +       const char *subpath;\n> +       int code;\n> +       ssize_t len;\n> +\n> +       if (!is_inside_work_tree())\n> +               /*\n> +                * FIXME:\n> +                * We might have a superproject, but it is harder\n> +                * to determine.\n> +                */\n> +               return NULL;\n> +\n> +       if (!one_up)\n> +               return NULL;\n> +\n> +       subpath = relative_path(cwd, one_up, &sb);\n> +\n> +       prepare_submodule_repo_env(&cp.env_array);\n> +       argv_array_pop(&cp.env_array);\n> +\n> +       argv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n> +                       \"ls-files\", \"--stage\", \"--full-name\", \"--\", subpath, NULL);\n> +       strbuf_reset(&sb);\n> +\n> +       cp.no_stdin = 1;\n> +       cp.no_stderr = 1;\n> +       cp.out = -1;\n> +       cp.git_cmd = 1;\n> +\n> +       if (start_command(&cp))\n> +               die(_(\"could not start ls-files in ..\"));\n> +\n> +       len = strbuf_read(&sb, cp.out, PATH_MAX);\n> +       close(cp.out);\n> +\n> +       if (starts_with(sb.buf, \"160000\")) {\n> +               int super_sub_len;\n> +               int cwd_len = strlen(cwd);\n> +               char *super_sub, *super_wt;\n> +\n> +               /*\n> +                * There is a superproject having this repo as a submodule.\n> +                * The format is <mode> SP <hash> SP <stage> TAB <full name> LF,\n> +                * First remove LF, then skip up to \\t.\n> +                */\n> +               strbuf_rtrim(&sb);\n> +               super_sub = strchr(sb.buf, '\\t') + 1;\n> +\n> +               super_sub_len = sb.buf + sb.len - super_sub;\n> +               if (super_sub_len > cwd_len ||\n> +                   strcmp(&cwd[cwd_len - super_sub_len], super_sub))\n> +                       die (_(\"BUG: returned path string doesn't match cwd?\"));\n> +\n> +               super_wt = xstrdup(cwd);\n> +               super_wt[cwd_len - super_sub_len] = '\\0';\n> +\n> +               ret = real_path(super_wt);\n> +\n> +               free(super_wt);\n> +       }\n> +       strbuf_release(&sb);\n> +\n> +       code = finish_command(&cp);\n> +\n> +       if (code == 128)\n> +               /* '../' is not a git repository */\n> +               return NULL;\n> +       if (code == 0 && len == 0)\n> +               /* There is an unrelated git repository at '../' */\n> +               return NULL;\n> +       if (code)\n> +               die(_(\"ls-tree returned unexpected return code %d\"), code);\n> +\n> +       return ret;\n> +}\n> diff --git a/submodule.h b/submodule.h\n> index 05ab674f06..c8a0c9cb29 100644\n> --- a/submodule.h\n> +++ b/submodule.h\n> @@ -93,4 +93,12 @@ extern void prepare_submodule_repo_env(struct argv_array *out);\n>  extern void absorb_git_dir_into_superproject(const char *prefix,\n>                                              const char *path,\n>                                              unsigned flags);\n> +\n> +/*\n> + * Return the absolute path of the working tree of the superproject, which this\n> + * project is a submodule of. If this repository is not a submodule of\n> + * another repository, return NULL.\n> + */\n> +extern const char *get_superproject_working_tree(void);\n> +\n>  #endif\n> diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh\n> index 9ed8b8ccba..03d3c7f6d6 100755\n> --- a/t/t1500-rev-parse.sh\n> +++ b/t/t1500-rev-parse.sh\n> @@ -116,4 +116,18 @@ test_expect_success 'git-path inside sub-dir' '\n>         test_cmp expect actual\n>  '\n>\n> +test_expect_success 'showing the superproject correctly' '\n> +       git rev-parse --show-superproject-working-tree >out &&\n> +       test_must_be_empty out &&\n> +\n> +       test_create_repo super &&\n> +       test_commit -C super test_commit &&\n> +       test_create_repo sub &&\n> +       test_commit -C sub test_commit &&\n> +       git -C super submodule add ../sub dir/sub &&\n> +       echo $(pwd)/super >expect  &&\n> +       git -C super/dir/sub rev-parse --show-superproject-working-tree >out &&\n> +       test_cmp expect out\n> +'\n> +\n>  test_done\n> --\n> 2.12.0.190.g6a12a61b77.dirty\n>\n"},{"id":"313538","messageId":"20170308192037.21847-1-sbeller@google.com","threadId":"45004","inReplyTo":"xmqq60jk488v.fsf@gitster.mtv.corp.google.com","subject":"[PATCHv3] rev-parse: add --show-superproject-working-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-08T19:20:37Z","receivedAt":"2017-03-08T19:21:15Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"In some situations it is useful to know if the given repository\nis a submodule of another repository.\n\nAdd the flag --show-superproject-working-tree to git-rev-parse\nto make it easy to find out if there is a superproject.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n> Looks more or less right but invoke \"ls-files -z\" and reading the \\0\n> delimited output would be easier;\n\ndone\n\n> otherwise you would have to worry\n> about c-unquoting the pathname when the submodule is bound at a path\n> with funny character (like a double-quote) in it.\n \npaths from \"rev-parse\" (like \"--git-dir\", \"--show-toplevel\", etc.) already\nare excempt from quoting rules, apparently.\n\n  $ git rev-parse --show-toplevel\n/usr/local/google/home/sbeller/OSS/git/t/trash directory.t1500-rev-parse\n\n\ninterdiff to v2:\n  #diff --git a/submodule.c b/submodule.c\n  #index 06473d3646..bb405653fd 100644\n  #--- a/submodule.c\n  #+++ b/submodule.c\n  #@@ -1543,7 +1543,8 @@ const char *get_superproject_working_tree(void)\n  # \targv_array_pop(&cp.env_array);\n  # \n  # \targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n  #-\t\t\t\"ls-files\", \"--stage\", \"--full-name\", \"--\", subpath, NULL);\n  #+\t\t\t\"ls-files\", \"-z\", \"--stage\", \"--full-name\", \"--\",\n  #+\t\t\tsubpath, NULL);\n  # \tstrbuf_reset(&sb);\n  # \n  # \tcp.no_stdin = 1;\n  #@@ -1564,13 +1565,12 @@ const char *get_superproject_working_tree(void)\n  # \n  # \t\t/*\n  # \t\t * There is a superproject having this repo as a submodule.\n  #-\t\t * The format is <mode> SP <hash> SP <stage> TAB <full name> LF,\n  #-\t\t * First remove LF, then skip up to \\t.\n  #+\t\t * The format is <mode> SP <hash> SP <stage> TAB <full name> \\0,\n  #+\t\t * We're only interested in the name after the tab.\n  # \t\t */\n  #-\t\tstrbuf_rtrim(&sb);\n  # \t\tsuper_sub = strchr(sb.buf, '\\t') + 1;\n  #+\t\tsuper_sub_len = sb.buf + sb.len - super_sub - 1;\n  # \n  #-\t\tsuper_sub_len = sb.buf + sb.len - super_sub;\n  # \t\tif (super_sub_len > cwd_len ||\n  # \t\t    strcmp(&cwd[cwd_len - super_sub_len], super_sub))\n  # \t\t\tdie (_(\"BUG: returned path string doesn't match cwd?\"));\n  #@@ -1579,7 +1579,6 @@ const char *get_superproject_working_tree(void)\n  # \t\tsuper_wt[cwd_len - super_sub_len] = '\\0';\n  # \n  # \t\tret = real_path(super_wt);\n  #-\n  # \t\tfree(super_wt);\n  # \t}\n  # \tstrbuf_release(&sb);\n  \n  Thanks,\n  Stefan\n  \n\n Documentation/git-rev-parse.txt |  5 +++\n builtin/rev-parse.c             |  7 ++++\n submodule.c                     | 82 +++++++++++++++++++++++++++++++++++++++++\n submodule.h                     |  8 ++++\n t/t1500-rev-parse.sh            | 14 +++++++\n 5 files changed, 116 insertions(+)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 91c02b8c85..b841bad7c7 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -261,6 +261,11 @@ print a message to stderr and exit with nonzero status.\n --show-toplevel::\n \tShow the absolute path of the top-level directory.\n \n+--show-superproject-working-tree\n+\tShow the absolute path of the top-level directory of\n+\tthe superproject. A superproject is a repository that records\n+\tthis repository as a submodule.\n+\n --shared-index-path::\n \tShow the path to the shared index file in split index mode, or\n \tempty if not in split-index mode.\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex e08677e559..2549643267 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -12,6 +12,7 @@\n #include \"diff.h\"\n #include \"revision.h\"\n #include \"split-index.h\"\n+#include \"submodule.h\"\n \n #define DO_REVS\t\t1\n #define DO_NOREV\t2\n@@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tputs(work_tree);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(arg, \"--show-superproject-working-tree\")) {\n+\t\t\t\tconst char *superproject = get_superproject_working_tree();\n+\t\t\t\tif (superproject)\n+\t\t\t\t\tputs(superproject);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-prefix\")) {\n \t\t\t\tif (prefix)\n \t\t\t\t\tputs(prefix);\ndiff --git a/submodule.c b/submodule.c\nindex 3b98766a6b..bb405653fd 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1514,3 +1514,85 @@ void absorb_git_dir_into_superproject(const char *prefix,\n \t\tstrbuf_release(&sb);\n \t}\n }\n+\n+const char *get_superproject_working_tree(void)\n+{\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tconst char *one_up = real_path_if_valid(\"../\");\n+\tconst char *cwd = xgetcwd();\n+\tconst char *ret = NULL;\n+\tconst char *subpath;\n+\tint code;\n+\tssize_t len;\n+\n+\tif (!is_inside_work_tree())\n+\t\t/*\n+\t\t * FIXME:\n+\t\t * We might have a superproject, but it is harder\n+\t\t * to determine.\n+\t\t */\n+\t\treturn NULL;\n+\n+\tif (!one_up)\n+\t\treturn NULL;\n+\n+\tsubpath = relative_path(cwd, one_up, &sb);\n+\n+\tprepare_submodule_repo_env(&cp.env_array);\n+\targv_array_pop(&cp.env_array);\n+\n+\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n+\t\t\t\"ls-files\", \"-z\", \"--stage\", \"--full-name\", \"--\",\n+\t\t\tsubpath, NULL);\n+\tstrbuf_reset(&sb);\n+\n+\tcp.no_stdin = 1;\n+\tcp.no_stderr = 1;\n+\tcp.out = -1;\n+\tcp.git_cmd = 1;\n+\n+\tif (start_command(&cp))\n+\t\tdie(_(\"could not start ls-files in ..\"));\n+\n+\tlen = strbuf_read(&sb, cp.out, PATH_MAX);\n+\tclose(cp.out);\n+\n+\tif (starts_with(sb.buf, \"160000\")) {\n+\t\tint super_sub_len;\n+\t\tint cwd_len = strlen(cwd);\n+\t\tchar *super_sub, *super_wt;\n+\n+\t\t/*\n+\t\t * There is a superproject having this repo as a submodule.\n+\t\t * The format is <mode> SP <hash> SP <stage> TAB <full name> \\0,\n+\t\t * We're only interested in the name after the tab.\n+\t\t */\n+\t\tsuper_sub = strchr(sb.buf, '\\t') + 1;\n+\t\tsuper_sub_len = sb.buf + sb.len - super_sub - 1;\n+\n+\t\tif (super_sub_len > cwd_len ||\n+\t\t    strcmp(&cwd[cwd_len - super_sub_len], super_sub))\n+\t\t\tdie (_(\"BUG: returned path string doesn't match cwd?\"));\n+\n+\t\tsuper_wt = xstrdup(cwd);\n+\t\tsuper_wt[cwd_len - super_sub_len] = '\\0';\n+\n+\t\tret = real_path(super_wt);\n+\t\tfree(super_wt);\n+\t}\n+\tstrbuf_release(&sb);\n+\n+\tcode = finish_command(&cp);\n+\n+\tif (code == 128)\n+\t\t/* '../' is not a git repository */\n+\t\treturn NULL;\n+\tif (code == 0 && len == 0)\n+\t\t/* There is an unrelated git repository at '../' */\n+\t\treturn NULL;\n+\tif (code)\n+\t\tdie(_(\"ls-tree returned unexpected return code %d\"), code);\n+\n+\treturn ret;\n+}\ndiff --git a/submodule.h b/submodule.h\nindex 05ab674f06..c8a0c9cb29 100644\n--- a/submodule.h\n+++ b/submodule.h\n@@ -93,4 +93,12 @@ extern void prepare_submodule_repo_env(struct argv_array *out);\n extern void absorb_git_dir_into_superproject(const char *prefix,\n \t\t\t\t\t     const char *path,\n \t\t\t\t\t     unsigned flags);\n+\n+/*\n+ * Return the absolute path of the working tree of the superproject, which this\n+ * project is a submodule of. If this repository is not a submodule of\n+ * another repository, return NULL.\n+ */\n+extern const char *get_superproject_working_tree(void);\n+\n #endif\ndiff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh\nindex 9ed8b8ccba..03d3c7f6d6 100755\n--- a/t/t1500-rev-parse.sh\n+++ b/t/t1500-rev-parse.sh\n@@ -116,4 +116,18 @@ test_expect_success 'git-path inside sub-dir' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'showing the superproject correctly' '\n+\tgit rev-parse --show-superproject-working-tree >out &&\n+\ttest_must_be_empty out &&\n+\n+\ttest_create_repo super &&\n+\ttest_commit -C super test_commit &&\n+\ttest_create_repo sub &&\n+\ttest_commit -C sub test_commit &&\n+\tgit -C super submodule add ../sub dir/sub &&\n+\techo $(pwd)/super >expect  &&\n+\tgit -C super/dir/sub rev-parse --show-superproject-working-tree >out &&\n+\ttest_cmp expect out\n+'\n+\n test_done\n-- \n2.12.0.190.g6e60aba09d.dirty\n\n"},{"id":"313566","messageId":"xmqqmvcv1jz9.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170308192037.21847-1-sbeller@google.com","subject":"Re: [PATCHv3] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-08T22:28:42Z","receivedAt":"2017-03-08T22:28:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> +--show-superproject-working-tree\n> +\tShow the absolute path of the top-level directory of\n> +\tthe superproject. A superproject is a repository that records\n> +\tthis repository as a submodule.\n\nThe top-level directory of the superproject's working tree?\n\nDescribe error conditions, like \"you get an error if there is no\nsuch project\"?\n\n> diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\n> index e08677e559..2549643267 100644\n> --- a/builtin/rev-parse.c\n> +++ b/builtin/rev-parse.c\n> @@ -12,6 +12,7 @@\n>  #include \"diff.h\"\n>  #include \"revision.h\"\n>  #include \"split-index.h\"\n> +#include \"submodule.h\"\n>  \n>  #define DO_REVS\t\t1\n>  #define DO_NOREV\t2\n> @@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n>  \t\t\t\t\tputs(work_tree);\n>  \t\t\t\tcontinue;\n>  \t\t\t}\n> +\t\t\tif (!strcmp(arg, \"--show-superproject-working-tree\")) {\n> +\t\t\t\tconst char *superproject = get_superproject_working_tree();\n> +\t\t\t\tif (superproject)\n> +\t\t\t\t\tputs(superproject);\n> +\t\t\t\tcontinue;\n\nWhen is superproject NULL?  Shouldn't we die with \"there is no\nsuperproject that uses us as a submodule\"?\n\nI can accept \"it is not an error to ask for the root of the\nsuperproject's working tree when we do not have any---that is one\nway to ask if we have a superproject or not\".  But if that is the\ncase, the code can stay the same, but the documentation should say\nso, something like...\n\n\tShow the absolute path of the root of the superproject's\n\tworking tree (if exists) that uses the current repository as\n\tits submodule.  Outputs nothing if the current repository is\n\tnot used as a submodule by any project.\n\n"},{"id":"313573","messageId":"20170308230742.5185-1-sbeller@google.com","threadId":"45004","inReplyTo":"xmqqmvcv1jz9.fsf@gitster.mtv.corp.google.com","subject":"[PATCHv4] rev-parse: add --show-superproject-working-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-08T23:07:42Z","receivedAt":"2017-03-08T23:33:15Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"In some situations it is useful to know if the given repository\nis a submodule of another repository.\n\nAdd the flag --show-superproject-working-tree to git-rev-parse\nto make it easy to find out if there is a superproject. When no\nsuperproject exists, the output will be empty.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n\n> I can accept \"it is not an error to ask for the root of the\n> superproject's working tree when we do not have any---that is one\n> way to ask if we have a superproject or not\".  But if that is the\n> case, the code can stay the same, but the documentation should say\n> so, something like...\n\n *this patch*\n \n* Documentation shamelessly stolen from Junio.\n\nThanks,\nStefan\n\n Documentation/git-rev-parse.txt |  6 +++\n builtin/rev-parse.c             |  7 ++++\n submodule.c                     | 82 +++++++++++++++++++++++++++++++++++++++++\n submodule.h                     |  8 ++++\n t/t1500-rev-parse.sh            | 14 +++++++\n 5 files changed, 117 insertions(+)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 91c02b8c85..c40c470448 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -261,6 +261,12 @@ print a message to stderr and exit with nonzero status.\n --show-toplevel::\n \tShow the absolute path of the top-level directory.\n \n+--show-superproject-working-tree\n+\tShow the absolute path of the root of the superproject's\n+\tworking tree (if exists) that uses the current repository as\n+\tits submodule.  Outputs nothing if the current repository is\n+\tnot used as a submodule by any project.\n+\n --shared-index-path::\n \tShow the path to the shared index file in split index mode, or\n \tempty if not in split-index mode.\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex e08677e559..2549643267 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -12,6 +12,7 @@\n #include \"diff.h\"\n #include \"revision.h\"\n #include \"split-index.h\"\n+#include \"submodule.h\"\n \n #define DO_REVS\t\t1\n #define DO_NOREV\t2\n@@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tputs(work_tree);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(arg, \"--show-superproject-working-tree\")) {\n+\t\t\t\tconst char *superproject = get_superproject_working_tree();\n+\t\t\t\tif (superproject)\n+\t\t\t\t\tputs(superproject);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-prefix\")) {\n \t\t\t\tif (prefix)\n \t\t\t\t\tputs(prefix);\ndiff --git a/submodule.c b/submodule.c\nindex 3b98766a6b..bb405653fd 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1514,3 +1514,85 @@ void absorb_git_dir_into_superproject(const char *prefix,\n \t\tstrbuf_release(&sb);\n \t}\n }\n+\n+const char *get_superproject_working_tree(void)\n+{\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tconst char *one_up = real_path_if_valid(\"../\");\n+\tconst char *cwd = xgetcwd();\n+\tconst char *ret = NULL;\n+\tconst char *subpath;\n+\tint code;\n+\tssize_t len;\n+\n+\tif (!is_inside_work_tree())\n+\t\t/*\n+\t\t * FIXME:\n+\t\t * We might have a superproject, but it is harder\n+\t\t * to determine.\n+\t\t */\n+\t\treturn NULL;\n+\n+\tif (!one_up)\n+\t\treturn NULL;\n+\n+\tsubpath = relative_path(cwd, one_up, &sb);\n+\n+\tprepare_submodule_repo_env(&cp.env_array);\n+\targv_array_pop(&cp.env_array);\n+\n+\targv_array_pushl(&cp.args, \"--literal-pathspecs\", \"-C\", \"..\",\n+\t\t\t\"ls-files\", \"-z\", \"--stage\", \"--full-name\", \"--\",\n+\t\t\tsubpath, NULL);\n+\tstrbuf_reset(&sb);\n+\n+\tcp.no_stdin = 1;\n+\tcp.no_stderr = 1;\n+\tcp.out = -1;\n+\tcp.git_cmd = 1;\n+\n+\tif (start_command(&cp))\n+\t\tdie(_(\"could not start ls-files in ..\"));\n+\n+\tlen = strbuf_read(&sb, cp.out, PATH_MAX);\n+\tclose(cp.out);\n+\n+\tif (starts_with(sb.buf, \"160000\")) {\n+\t\tint super_sub_len;\n+\t\tint cwd_len = strlen(cwd);\n+\t\tchar *super_sub, *super_wt;\n+\n+\t\t/*\n+\t\t * There is a superproject having this repo as a submodule.\n+\t\t * The format is <mode> SP <hash> SP <stage> TAB <full name> \\0,\n+\t\t * We're only interested in the name after the tab.\n+\t\t */\n+\t\tsuper_sub = strchr(sb.buf, '\\t') + 1;\n+\t\tsuper_sub_len = sb.buf + sb.len - super_sub - 1;\n+\n+\t\tif (super_sub_len > cwd_len ||\n+\t\t    strcmp(&cwd[cwd_len - super_sub_len], super_sub))\n+\t\t\tdie (_(\"BUG: returned path string doesn't match cwd?\"));\n+\n+\t\tsuper_wt = xstrdup(cwd);\n+\t\tsuper_wt[cwd_len - super_sub_len] = '\\0';\n+\n+\t\tret = real_path(super_wt);\n+\t\tfree(super_wt);\n+\t}\n+\tstrbuf_release(&sb);\n+\n+\tcode = finish_command(&cp);\n+\n+\tif (code == 128)\n+\t\t/* '../' is not a git repository */\n+\t\treturn NULL;\n+\tif (code == 0 && len == 0)\n+\t\t/* There is an unrelated git repository at '../' */\n+\t\treturn NULL;\n+\tif (code)\n+\t\tdie(_(\"ls-tree returned unexpected return code %d\"), code);\n+\n+\treturn ret;\n+}\ndiff --git a/submodule.h b/submodule.h\nindex 05ab674f06..c8a0c9cb29 100644\n--- a/submodule.h\n+++ b/submodule.h\n@@ -93,4 +93,12 @@ extern void prepare_submodule_repo_env(struct argv_array *out);\n extern void absorb_git_dir_into_superproject(const char *prefix,\n \t\t\t\t\t     const char *path,\n \t\t\t\t\t     unsigned flags);\n+\n+/*\n+ * Return the absolute path of the working tree of the superproject, which this\n+ * project is a submodule of. If this repository is not a submodule of\n+ * another repository, return NULL.\n+ */\n+extern const char *get_superproject_working_tree(void);\n+\n #endif\ndiff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh\nindex 9ed8b8ccba..03d3c7f6d6 100755\n--- a/t/t1500-rev-parse.sh\n+++ b/t/t1500-rev-parse.sh\n@@ -116,4 +116,18 @@ test_expect_success 'git-path inside sub-dir' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'showing the superproject correctly' '\n+\tgit rev-parse --show-superproject-working-tree >out &&\n+\ttest_must_be_empty out &&\n+\n+\ttest_create_repo super &&\n+\ttest_commit -C super test_commit &&\n+\ttest_create_repo sub &&\n+\ttest_commit -C sub test_commit &&\n+\tgit -C super submodule add ../sub dir/sub &&\n+\techo $(pwd)/super >expect  &&\n+\tgit -C super/dir/sub rev-parse --show-superproject-working-tree >out &&\n+\ttest_cmp expect out\n+'\n+\n test_done\n-- \n2.12.0.190.g6e60aba09d.dirty\n\n"},{"id":"313577","messageId":"xmqqr327z5rn.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170308230742.5185-1-sbeller@google.com","subject":"Re: [PATCHv4] rev-parse: add --show-superproject-working-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-08T23:51:40Z","receivedAt":"2017-03-08T23:52:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n>  *this patch*\n>  \n> * Documentation shamelessly stolen from Junio.\n\nYou stole it, and then ...\n\n> +test_expect_success 'showing the superproject correctly' '\n> +\tgit rev-parse --show-superproject-working-tree >out &&\n> +\ttest_must_be_empty out &&\n\n... made sure that the newly documented behaviour is tested as a\nfeature.  Good.\n\n> +\ttest_create_repo super &&\n> +\ttest_commit -C super test_commit &&\n> +\ttest_create_repo sub &&\n> +\ttest_commit -C sub test_commit &&\n> +\tgit -C super submodule add ../sub dir/sub &&\n> +\techo $(pwd)/super >expect  &&\n> +\tgit -C super/dir/sub rev-parse --show-superproject-working-tree >out &&\n> +\ttest_cmp expect out\n> +'\n> +\n"},{"id":"314401","messageId":"20170317222842.GP26789@aiede.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170308230742.5185-1-sbeller@google.com","subject":"Re: [PATCHv4] rev-parse: add --show-superproject-working-tree","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-03-17T22:28:42Z","receivedAt":"2017-03-17T22:28:50Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nStefan Beller wrote:\n\n> Add the flag --show-superproject-working-tree to git-rev-parse\n> to make it easy to find out if there is a superproject. When no\n> superproject exists, the output will be empty.\n\nI'm a little late for this, but think it's better to comment late than\nnever.\n\nAfter this patch, git rev-parse has two options relating to the working\ntree:\n\n\tgit rev-parse --is-inside-work-tree\n\tgit rev-parse --show-superproject-working-tree\n\nIs this inconsistency necessary?  Now that there is a \"git worktree\"\ncommand that allows making a second working tree for the same\nrepository, I would have thought we had standardized on work tree as\nthe name in UI.\n\nThoughts?\nJonathan\n"},{"id":"314411","messageId":"20170317225110.13417-1-sbeller@google.com","threadId":"45004","inReplyTo":"20170317222842.GP26789@aiede.mtv.corp.google.com","subject":"[PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-17T22:51:10Z","receivedAt":"2017-03-17T23:00:37Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"If I recall correctly, \"worktree\" is the feature/command, and\n\"working tree\" is an instance in the file system, even when you only\nhave one working tree.\n\nUsing that mental model, the documentation for 'git worktree list'\nclearly talks about working trees, so fix it.\n\nReflow the lines as well.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n\n Duy, this is my instant-make-a-apatch-to-fix-the-world reaction\n in reply to Jonathan.\n \n Thanks,\n Stefan\n\n Documentation/git-worktree.txt | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 553cf8413f..e080007ed0 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -58,10 +58,10 @@ as if `-b $(basename <path>)` was specified.\n \n list::\n \n-List details of each worktree.  The main worktree is listed first, followed by\n-each of the linked worktrees.  The output details include if the worktree is\n-bare, the revision currently checked out, and the branch currently checked out\n-(or 'detached HEAD' if none).\n+List details of each working tree.  The main working tree is listed first,\n+followed by each of the linked working trees.  The output details include if\n+the working tree is bare, the revision currently checked out, and the branch\n+currently checked out (or 'detached HEAD' if none).\n \n lock::\n \n-- \n2.12.0.306.g4a9b9b32d4.dirty\n\n"},{"id":"314421","messageId":"CAGZ79kaL=mHsqURqrnUMav8W=Hr960PHw6WDoBncVZA4AjmsJA@mail.gmail.com","threadId":"45004","inReplyTo":"20170317225532.GR26789@aiede.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-17T23:04:09Z","receivedAt":"2017-03-17T23:29:31Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Fri, Mar 17, 2017 at 3:55 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Hi,\n>\n> Stefan Beller wrote:\n>\n>> If I recall correctly, \"worktree\" is the feature/command, and\n>> \"working tree\" is an instance in the file system, even when you only\n>> have one working tree.\n>\n> I'm not sure I agree with this distinction.  \"worktree\" is just a\n> short name for \"working tree\".\n>\n> Unfortunately gitglossary(7) doesn't make this clear at all --- it\n> uses the term worktree a few times (and appears to mean \"working tree\"\n> when it does --- e.g.\n>\n>         Pathspecs are used on the command line of [...] and many other\n>         commands to limit the scope of operations to some subset of\n>         the tree or worktree.\n>\n> ) but never defines it.\n>\n\nSo maybe it's time to look for volunteers for a cleanup patch. ;)\nI tried finding the discussion on worktree vs \"working tree\"\nand did not succeed. :/\n\nMaybe Duy has a better memory there.\n\nThanks,\nStefan\n"},{"id":"314429","messageId":"20170317225532.GR26789@aiede.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170317225110.13417-1-sbeller@google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-03-17T22:55:32Z","receivedAt":"2017-03-18T00:06:27Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nStefan Beller wrote:\n\n> If I recall correctly, \"worktree\" is the feature/command, and\n> \"working tree\" is an instance in the file system, even when you only\n> have one working tree.\n\nI'm not sure I agree with this distinction.  \"worktree\" is just a\nshort name for \"working tree\".\n\nUnfortunately gitglossary(7) doesn't make this clear at all --- it\nuses the term worktree a few times (and appears to mean \"working tree\"\nwhen it does --- e.g.\n\n\tPathspecs are used on the command line of [...] and many other\n\tcommands to limit the scope of operations to some subset of\n\tthe tree or worktree.\n\n) but never defines it.\n\n[...]\n> --- a/Documentation/git-worktree.txt\n> +++ b/Documentation/git-worktree.txt\n> @@ -58,10 +58,10 @@ as if `-b $(basename <path>)` was specified.\n>  \n>  list::\n>  \n> -List details of each worktree.  The main worktree is listed first, followed by\n> -each of the linked worktrees.  The output details include if the worktree is\n> -bare, the revision currently checked out, and the branch currently checked out\n> -(or 'detached HEAD' if none).\n> +List details of each working tree.  The main working tree is listed first,\n> +followed by each of the linked working trees.  The output details include if\n> +the working tree is bare, the revision currently checked out, and the branch\n> +currently checked out (or 'detached HEAD' if none).\n\nThe patch itself looks good.\n\nThanks,\nJonathan\n"},{"id":"314436","messageId":"xmqq1stv5pam.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170317225532.GR26789@aiede.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-18T01:47:29Z","receivedAt":"2017-03-18T01:48:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> I'm not sure I agree with this distinction.  \"worktree\" is just a\n> short name for \"working tree\".\n\nThat is probably primarily my fault.  Loooooooooong before the \"git\nworktree\" that is meant to replace the \"workdir\" thing in contrib/\nwas invented, some people said \"working tree\" while some other\npeople called the same thing \"worktree\", simply because it is\nshorter.  Unfortunately I was among the latter, and wrote quite a\nlot of documents and in-code comments, so it got stuck.  But later\nwe somehow ended up deciding on using \"working tree\" to refer to the\nhierarchy of files that are checked out from a $GIT_DIR.\n\nSo if you see a message in the list archive, or an in-tree document\nor in-code comment that was written way before that \"let's call the\nthing non-bare repositories have 'working tree'\" decision was made\nand have not been updated since, you are likely to find \"worktree\"\nused to refer to \"working tree\".\n\nAnd then relatively recently, Duy's feature started calling itself\n\"worktree\".  The mention of \"worktree\" in git-worktree.txt, by\ndefinition, is a lot newer than the \"let's call the thing a non-bare\nrepository has 'working tree'\" and was written after the word\n\"worktree\" gained the new meaning, and it refers to that \"different\nthings that can be referred to by setting your $GIT_DIR at them\".\n\n\n\n"},{"id":"314457","messageId":"xmqq60j75psk.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170317225110.13417-1-sbeller@google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-18T01:36:43Z","receivedAt":"2017-03-18T02:14:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> -List details of each worktree.  The main worktree is listed first, followed by\n> -each of the linked worktrees.  The output details include if the worktree is\n> -bare, the revision currently checked out, and the branch currently checked out\n> -(or 'detached HEAD' if none).\n> +List details of each working tree.  The main working tree is listed first,\n> +followed by each of the linked working trees.  The output details include if\n> +the working tree is bare, the revision currently checked out, and the branch\n> +currently checked out (or 'detached HEAD' if none).\n\nI do not think this is correct.\n\nThink of a \"worktree\" something that roughly corresponds to\ndifferent location you can refer to with $GIT_DIR.\n\nA $GIT_DIR may be a true repository.  Or it may be borrowing many of\nthe things from its primary repository.  Even though \"git worktree\"\nPorcelain may not currently be equipped to create a \"bare\" $GIT_DIR,\nthere is no fundamental reason that a secondary \"worktree\" must have\na working tree, i.e. a \"worktree\" could be a \"bare\" one (it would be\nthe first use of per-worktree config; a secondary worktree that is a\nbare can be made by borrowing from the primary worktree that has a\nworking tree).\n\nNow, what does \"git worktree list\" enumearate?  It does not list\n\"working trees\"; its output are list of things, each of which you\ncould point at with $GIT_DIR and work with.\n\n"},{"id":"314509","messageId":"xmqqo9wy4hxa.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"CAGZ79kaL=mHsqURqrnUMav8W=Hr960PHw6WDoBncVZA4AjmsJA@mail.gmail.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-18T17:24:17Z","receivedAt":"2017-03-18T17:24:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n>> Unfortunately gitglossary(7) doesn't make this clear at all --- it\n>> uses the term worktree a few times (and appears to mean \"working tree\"\n>> when it does --- e.g.\n>>\n>>         Pathspecs are used on the command line of [...] and many other\n>>         commands to limit the scope of operations to some subset of\n>>         the tree or worktree.\n>>\n>> ) but never defines it.\n>\n> So maybe it's time to look for volunteers for a cleanup patch. ;)\n> I tried finding the discussion on worktree vs \"working tree\"\n> and did not succeed. :/\n\nA rough rule of thumb.  Anything that was written before 2014 or\nback when nobody knew df0b6cfb (\"worktree: new place for \"git prune\n--worktrees\"\", 2015-06-29) was coming that says \"worktree\" is using\nthe term to refer to what we call \"working tree\" these days.\n\nWhat Jonathan quoted above came from 3bd2bcfa (\"glossary: define\npathspec\", 2010-12-15) and certainly predates the one that replaced\ncontrib/workdir, so we should update it to read \"working tree\".\n\n"},{"id":"314689","messageId":"CAGZ79kayeSxFTJr3Q1atFgOyR74PzQyCLiejuZxh7+wTGGb=ww@mail.gmail.com","threadId":"45004","inReplyTo":"xmqq60j75psk.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-20T17:29:56Z","receivedAt":"2017-03-20T17:37:59Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Fri, Mar 17, 2017 at 6:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Stefan Beller <sbeller@google.com> writes:\n>\n>> -List details of each worktree.  The main worktree is listed first, followed by\n>> -each of the linked worktrees.  The output details include if the worktree is\n>> -bare, the revision currently checked out, and the branch currently checked out\n>> -(or 'detached HEAD' if none).\n>> +List details of each working tree.  The main working tree is listed first,\n>> +followed by each of the linked working trees.  The output details include if\n>> +the working tree is bare, the revision currently checked out, and the branch\n>> +currently checked out (or 'detached HEAD' if none).\n>\n> I do not think this is correct.\n>\n> Think of a \"worktree\" something that roughly corresponds to\n> different location you can refer to with $GIT_DIR.\n>\n> A $GIT_DIR may be a true repository.  Or it may be borrowing many of\n> the things from its primary repository.  Even though \"git worktree\"\n> Porcelain may not currently be equipped to create a \"bare\" $GIT_DIR,\n> there is no fundamental reason that a secondary \"worktree\" must have\n> a working tree, i.e. a \"worktree\" could be a \"bare\" one (it would be\n> the first use of per-worktree config; a secondary worktree that is a\n> bare can be made by borrowing from the primary worktree that has a\n> working tree).\n\nWhile it may be true that you can have bare worktrees; I would question\nwhy anyone wants to do this, as the only thing it provides is an\nadditional HEAD (plus its reflog).\n\n> Now, what does \"git worktree list\" enumearate?  It does not list\n> \"working trees\"; its output are list of things, each of which you\n> could point at with $GIT_DIR and work with.\n\n$ git worktree list\n/.../git                   0b47ebba82 [status-short]\n/.../git_origin_master     5588dbffbd (detached HEAD)\n/.../submodule_remote_dot  3d9025bd69 (detached HEAD)\n\nThis looks to me as if it is listing actual working trees. But looking\nat the actual code, I confirm we list worktrees here, even bare\nworktrees are taken care of.\n\nThat said, \"worktree prune\" (as well as (un)lock) are operating\non \"worktrees\" as you defined above:\n\n$ git worktree add test\n$ git worktree list\n# see the \"test\" worktree listed by its working tree\nrm -rf test # remove the working tree attached to the test worktree\n$ git worktree list\n# see the \"test\" worktree listed by its working tree, still there\n$ git worktree prune\n$ git worktree list\n# the \"test\" worktree is gone.\n\nSo maybe we need a patch that is s/working tree/worktree/\nin the prune section?\n\nThanks,\nStefan\n"},{"id":"314698","messageId":"xmqqbmsvx1ey.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"CAGZ79kayeSxFTJr3Q1atFgOyR74PzQyCLiejuZxh7+wTGGb=ww@mail.gmail.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-20T18:12:37Z","receivedAt":"2017-03-20T18:14:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> While it may be true that you can have bare worktrees; I would question\n> why anyone wants to do this, as the only thing it provides is an\n> additional HEAD (plus its reflog).\n\nA more plausible situation is you start with a bare one as the\nprimary and used to make local clones to do your work in the world\nbefore \"git worktree\".  It would be a natural extension to your\nworkflow to instead create worktrees of of that bare one as the\nprimary worktree with secondaries with working trees.\n"},{"id":"314708","messageId":"20170320185038.GU26789@aiede.mtv.corp.google.com","threadId":"45004","inReplyTo":"xmqqbmsvx1ey.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-03-20T18:50:38Z","receivedAt":"2017-03-20T18:51:01Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n> Stefan Beller <sbeller@google.com> writes:\n\n>> While it may be true that you can have bare worktrees; I would question\n>> why anyone wants to do this, as the only thing it provides is an\n>> additional HEAD (plus its reflog).\n>\n> A more plausible situation is you start with a bare one as the\n> primary and used to make local clones to do your work in the world\n> before \"git worktree\".  It would be a natural extension to your\n> workflow to instead create worktrees of of that bare one as the\n> primary worktree with secondaries with working trees.\n\nFor what it's worth, this conversation makes me think it was a mistake\nto call this construct a worktree.\n\nIt's fine for the command to have one name and the documentation to\nuse a longer, clearer name to explain it.  What should that longer,\nclearer name be?\n\nThanks,\nJonathan\n"},{"id":"314712","messageId":"20170320192225.18928-1-sbeller@google.com","threadId":"45004","inReplyTo":"20170320185038.GU26789@aiede.mtv.corp.google.com","subject":"[PATCH 0/2] use \"working trees\" instead of \"worktree\" in our API","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-20T19:22:23Z","receivedAt":"2017-03-20T19:22:48Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"> For what it's worth, this conversation makes me think it was a mistake\n> to call this construct a worktree.\n\nSo the way forward is to purge the use of \"worktree\" meaning actual working trees?\n\nThanks,\nStefan\n\nStefan Beller (2):\n  git.c: introduce --working-tree superseding --work-tree\n  revparse: introduce --is-inside-working-tree\n\n Documentation/git-rev-parse.txt |  4 ++--\n Documentation/git.txt           | 12 ++++++------\n builtin/rev-parse.c             |  3 ++-\n git.c                           |  5 +++--\n 4 files changed, 13 insertions(+), 11 deletions(-)\n\n-- \n2.12.0.306.g4a9b9b32d4.dirty\n\n"},{"id":"314713","messageId":"20170320192225.18928-3-sbeller@google.com","threadId":"45004","inReplyTo":"20170320192225.18928-1-sbeller@google.com","subject":"[PATCH 2/2] revparse: introduce --is-inside-working-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-20T19:22:25Z","receivedAt":"2017-03-20T19:22:50Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This behaves the same as 'is-inside-worktree' and supersedes it.\nSee prior patch for discussion of \"working tree\" vs. \"worktree\"\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n Documentation/git-rev-parse.txt | 4 ++--\n builtin/rev-parse.c             | 3 ++-\n 2 files changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex c40c470448..55ee3bde55 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -228,8 +228,8 @@ print a message to stderr and exit with nonzero status.\n \tWhen the current working directory is below the repository\n \tdirectory print \"true\", otherwise \"false\".\n \n---is-inside-work-tree::\n-\tWhen the current working directory is inside the work tree of the\n+--is-inside-working-tree::\n+\tWhen the current working directory is inside the working tree of the\n \trepository print \"true\", otherwise \"false\".\n \n --is-bare-repository::\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 2549643267..04da518058 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -851,7 +851,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\n-\t\t\tif (!strcmp(arg, \"--is-inside-work-tree\")) {\n+\t\t\tif (!strcmp(arg, \"--is-inside-work-tree\") ||\n+\t\t\t    !strcmp(arg, \"--is-inside-working-tree\")) {\n \t\t\t\tprintf(\"%s\\n\", is_inside_work_tree() ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n-- \n2.12.0.306.g4a9b9b32d4.dirty\n\n"},{"id":"314714","messageId":"20170320192225.18928-2-sbeller@google.com","threadId":"45004","inReplyTo":"20170320192225.18928-1-sbeller@google.com","subject":"[PATCH 1/2] git.c: introduce --working-tree superseding --work-tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-20T19:22:24Z","receivedAt":"2017-03-20T19:23:22Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Discussion on bf0231c661 (rev-parse: add --show-superproject-working-tree,\n2017-03-08) pointed out we are inconsistent with the naming of \"working\ntree\" and \"worktree\" even in user facing commands and documentation[1].\n\nIntroduce the new --working-tree option, which is the same as\n--work-tree. As --work-tree is considered slightly incorrect[2], stop\nmentioning it in the documentation.  But we need to keep its functionality\nas it is plumbing.\n\nAn alternative was considered off list to rename the newly added option\n'--show-superproject-working-tree' by dropping the part mentioning the\nworking tree to side step this discussion. However we need to make sure\nthat option still refers to the working tree, as a new option\n'show-superproject-git-dir' might be considered useful in the future,\nand we do not want to take the canonical '--show-superproject' now.\n\n[1] https://public-inbox.org/git/20170317222842.GP26789@aiede.mtv.corp.google.com/\n[2] https://public-inbox.org/git/xmqqo9wy4hxa.fsf@gitster.mtv.corp.google.com/\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n Documentation/git.txt | 12 ++++++------\n git.c                 |  5 +++--\n 2 files changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex df0941d456..763f3b5563 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -12,7 +12,7 @@ SYNOPSIS\n 'git' [--version] [--help] [-C <path>] [-c <name>=<value>]\n     [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n     [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n-    [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n+    [--git-dir=<path>] [--working-tree=<path>] [--namespace=<name>]\n     [--super-prefix=<path>]\n     <command> [<args>]\n \n@@ -551,12 +551,12 @@ help ...`.\n \t<path>`.\n +\n This option affects options that expect path name like `--git-dir` and\n-`--work-tree` in that their interpretations of the path names would be\n+`--working-tree` in that their interpretations of the path names would be\n made relative to the working directory caused by the `-C` option. For\n example the following invocations are equivalent:\n \n-    git --git-dir=a.git --work-tree=b -C c status\n-    git --git-dir=c/a.git --work-tree=c/b status\n+    git --git-dir=a.git --working-tree=b -C c status\n+    git --git-dir=c/a.git --working-tree=c/b status\n \n -c <name>=<value>::\n \tPass a configuration parameter to the command. The value\n@@ -602,7 +602,7 @@ foo.bar= ...`) sets `foo.bar` to the empty string.\n \tsetting the `GIT_DIR` environment variable. It can be an absolute\n \tpath or relative path to current working directory.\n \n---work-tree=<path>::\n+--working-tree=<path>::\n \tSet the path to the working tree. It can be an absolute path\n \tor a path relative to the current working directory.\n \tThis can also be controlled by setting the GIT_WORK_TREE\n@@ -892,7 +892,7 @@ Git so take care if using a foreign front-end.\n \n `GIT_WORK_TREE`::\n \tSet the path to the root of the working tree.\n-\tThis can also be controlled by the `--work-tree` command-line\n+\tThis can also be controlled by the `--working-tree` command-line\n \toption and the core.worktree configuration variable.\n \n `GIT_NAMESPACE`::\ndiff --git a/git.c b/git.c\nindex 33f52acbcc..a76ff97232 100644\n--- a/git.c\n+++ b/git.c\n@@ -149,9 +149,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)\n \t\t\tsetenv(GIT_NAMESPACE_ENVIRONMENT, cmd, 1);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n-\t\t} else if (!strcmp(cmd, \"--work-tree\")) {\n+\t\t} else if (!strcmp(cmd, \"--work-tree\") ||\n+\t\t\t   !strcmp(cmd, \"--working-tree\")) {\n \t\t\tif (*argc < 2) {\n-\t\t\t\tfprintf(stderr, \"No directory given for --work-tree.\\n\" );\n+\t\t\t\tfprintf(stderr, \"No directory given for %s.\\n\", cmd);\n \t\t\t\tusage(git_usage_string);\n \t\t\t}\n \t\t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);\n-- \n2.12.0.306.g4a9b9b32d4.dirty\n\n"},{"id":"314716","messageId":"xmqqy3vzvixm.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170320192225.18928-1-sbeller@google.com","subject":"Re: [PATCH 0/2] use \"working trees\" instead of \"worktree\" in our API","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-20T19:37:09Z","receivedAt":"2017-03-20T19:39:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n>> For what it's worth, this conversation makes me think it was a mistake\n>> to call this construct a worktree.\n>\n> So the way forward is to purge the use of \"worktree\" meaning actual working trees?\n\nGIT_WORK_TREE environment would have be a victim of this clean-up,\nso is setup_work_tree(), together with numerous in-code comment\nabout \"work tree\".\n\nWhile I would say that we would certainly pick one and stick to it\nif we were inventing Git from scratch today and just started caring\nthe distinction between core.bare and not, I am not sure how far we\nwould want to go, and what's the expected payoff of doing this\nclean-up would be, given that we are starting from today's world.\n\nSo, I dunno.  If the response and list concensus to Jonathan's\nearlier comment came up with a better name for the newer \"worktree\"\nconcept, we may not have to even worry about this and instead can\njust declare \"these are used interchangeably\".\n"},{"id":"314719","messageId":"20170320195818.GV26789@aiede.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170320192225.18928-2-sbeller@google.com","subject":"Re: [PATCH 1/2] git.c: introduce --working-tree superseding --work-tree","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-03-20T19:58:18Z","receivedAt":"2017-03-20T19:59:27Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nStefan Beller wrote:\n\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> ---\n>  Documentation/git.txt | 12 ++++++------\n>  git.c                 |  5 +++--\n>  2 files changed, 9 insertions(+), 8 deletions(-)\n\nI think this is a step in the right direction.  Thanks for writing it.\n\nNits:\n\n- tests are still using --work-tree --- this patch didn't add any tests\n  for --working-tree.  If --working-tree is what we prefer, it may make\n  sense to update tests to use --working-tree and add a test or two to\n  make sure the existing --work-tree synonym still works.\n\n- this patch updated the argv[i] == \"--work-tree\" case but forgot to\n  update the argv[i].has_prefix(\"--work-tree=\") case\n\n- since this is a feature used for scripting, I don't think we can\n  pretend the name change never happened.  We think we need to\n  document both option names and say what version introduced the new\n  one so script authors can make an informed decision about which to\n  use.  Later we can make the --work-tree synonym more obscure, but in\n  the short term I suspect it is what most script authors will still\n  want to use.\n\n> --- a/Documentation/git.txt\n> +++ b/Documentation/git.txt\n[...]\n> @@ -892,7 +892,7 @@ Git so take care if using a foreign front-end.\n>  \n>  `GIT_WORK_TREE`::\n>  \tSet the path to the root of the working tree.\n> -\tThis can also be controlled by the `--work-tree` command-line\n> +\tThis can also be controlled by the `--working-tree` command-line\n>  \toption and the core.worktree configuration variable.\n\nI suspect we don't want to rename GIT_WORK_TREE --- it's not\nuser-facing in the same way as --work-tree is, scripts make direct use\nof it (and they unset it when appropriate!), and dealing with the\npermutations of what to do if some subset of environment variables is\nset seems very complicated.\n\nFor comparison, core.worktree is user-facing.  Is it also in scope for\nthis change?\n\nThanks and hope that helps,\nJonathan\n"},{"id":"314723","messageId":"20170320200052.GW26789@aiede.mtv.corp.google.com","threadId":"45004","inReplyTo":"20170320192225.18928-3-sbeller@google.com","subject":"Re: [PATCH 2/2] revparse: introduce --is-inside-working-tree","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-03-20T20:00:52Z","receivedAt":"2017-03-20T20:07:46Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nStefan Beller wrote:\n\n> This behaves the same as 'is-inside-worktree' and supersedes it.\n> See prior patch for discussion of \"working tree\" vs. \"worktree\"\n>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> ---\n>  Documentation/git-rev-parse.txt | 4 ++--\n>  builtin/rev-parse.c             | 3 ++-\n>  2 files changed, 4 insertions(+), 3 deletions(-)\n\nThis is less invasive than the previous patch and can probably stand\nalone.  Some of the same nits apply:\n\n* tests?\n\n* documentation would need to warn people that this option is new, for\n  now. In fact it's even tempting to make --is-inside-working-tree\n  the hidden/discouraged one for a while, until script authors can\n  count on git having had it available for a while, and only then\n  encourage its use.\n\nThanks and hope that helps,\nJonathan\n"},{"id":"314786","messageId":"CACsJy8CBmfj8wY+LQzEshJT0Ya+nmAGs=K8b1Nyr3qinvCo4kA@mail.gmail.com","threadId":"45004","inReplyTo":"20170320185038.GU26789@aiede.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-03-21T10:37:08Z","receivedAt":"2017-03-21T10:37:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Mar 21, 2017 at 1:50 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Junio C Hamano wrote:\n>> Stefan Beller <sbeller@google.com> writes:\n>\n>>> While it may be true that you can have bare worktrees; I would question\n>>> why anyone wants to do this, as the only thing it provides is an\n>>> additional HEAD (plus its reflog).\n>>\n>> A more plausible situation is you start with a bare one as the\n>> primary and used to make local clones to do your work in the world\n>> before \"git worktree\".  It would be a natural extension to your\n>> workflow to instead create worktrees of of that bare one as the\n>> primary worktree with secondaries with working trees.\n>\n> For what it's worth, this conversation makes me think it was a mistake\n> to call this construct a worktree.\n\nFor the record, I am totally confused with Junio's last line, with two\n\"with\"s, \"worktree\" and \"working trees\" in the same phrase :D\n\n> It's fine for the command to have one name and the documentation to\n> use a longer, clearer name to explain it.  What should that longer,\n> clearer name be?\n\nNo comments from me. I'll let you know that if Eric (or Junio?) didn't\nstop me, we would have had $GIT_DIR/repos now instead of\n$GIT_DIR/worktrees, just some extra confusion toppings.\n-- \nDuy\n"},{"id":"314813","messageId":"xmqqvar2ska7.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"CACsJy8CBmfj8wY+LQzEshJT0Ya+nmAGs=K8b1Nyr3qinvCo4kA@mail.gmail.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-21T15:48:32Z","receivedAt":"2017-03-21T15:50:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Duy Nguyen <pclouds@gmail.com> writes:\n\n> On Tue, Mar 21, 2017 at 1:50 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>> Junio C Hamano wrote:\n>>> Stefan Beller <sbeller@google.com> writes:\n>>\n>>>> While it may be true that you can have bare worktrees; I would question\n>>>> why anyone wants to do this, as the only thing it provides is an\n>>>> additional HEAD (plus its reflog).\n>>>\n>>> A more plausible situation is you start with a bare one as the\n>>> primary and used to make local clones to do your work in the world\n>>> before \"git worktree\".  It would be a natural extension to your\n>>> workflow to instead create worktrees of of that bare one as the\n>>> primary worktree with secondaries with working trees.\n>>\n>> For what it's worth, this conversation makes me think it was a mistake\n>> to call this construct a worktree.\n>\n> For the record, I am totally confused with Junio's last line, with two\n> \"with\"s, \"worktree\" and \"working trees\" in the same phrase :D\n\nIn case this wasn't just a tangential note, what I meant was:\n\n - In the old world, you may have had a single bare repository and\n   then made clones, each of which has a working tree (i.e. non-bare\n   clones), and worked inside these clones.\n\n - In the \"git worktree\" world, you can start from that same single\n   bare repository, but instead of cloning it, use \"git worktree\" to\n   create \"worktree\"s, each of which has a working tree, and work\n   inside these \"worktree\"s.\n\nand the latter would be a natural extension to the workflow the\nformer wanted to use.\n\n>> It's fine for the command to have one name and the documentation to\n>> use a longer, clearer name to explain it.  What should that longer,\n>> clearer name be?\n>\n> No comments from me. I'll let you know that if Eric (or Junio?) didn't\n> stop me, we would have had $GIT_DIR/repos now instead of\n> $GIT_DIR/worktrees, just some extra confusion toppings.\n\nI forgot about that part of the history, but you are saying you\nwanted to call these \"repos\", not \"worktrees\"?  I can see why\nsomebody (or me?) would stop that by fearing \"repo\" is a bit too\nconfusing with a \"repository\", in the same way that we are now\nrealizing that \"worktree\" is too similar to an old synonym we used\nto call \"working tree\".\n\n"},{"id":"315116","messageId":"3c16aea8-be53-ef41-d43f-7b4e8ca15d7d@drmicha.warpmail.net","threadId":"45004","inReplyTo":"xmqqvar2ska7.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2017-03-23T17:06:23Z","receivedAt":"2017-03-23T17:06:34Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 21.03.2017 16:48:\n> Duy Nguyen <pclouds@gmail.com> writes:\n> \n>> On Tue, Mar 21, 2017 at 1:50 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>>> Junio C Hamano wrote:\n>>>> Stefan Beller <sbeller@google.com> writes:\n>>>\n>>>>> While it may be true that you can have bare worktrees; I would question\n>>>>> why anyone wants to do this, as the only thing it provides is an\n>>>>> additional HEAD (plus its reflog).\n>>>>\n>>>> A more plausible situation is you start with a bare one as the\n>>>> primary and used to make local clones to do your work in the world\n>>>> before \"git worktree\".  It would be a natural extension to your\n>>>> workflow to instead create worktrees of of that bare one as the\n>>>> primary worktree with secondaries with working trees.\n>>>\n>>> For what it's worth, this conversation makes me think it was a mistake\n>>> to call this construct a worktree.\n>>\n>> For the record, I am totally confused with Junio's last line, with two\n>> \"with\"s, \"worktree\" and \"working trees\" in the same phrase :D\n> \n> In case this wasn't just a tangential note, what I meant was:\n> \n>  - In the old world, you may have had a single bare repository and\n>    then made clones, each of which has a working tree (i.e. non-bare\n>    clones), and worked inside these clones.\n> \n>  - In the \"git worktree\" world, you can start from that same single\n>    bare repository, but instead of cloning it, use \"git worktree\" to\n>    create \"worktree\"s, each of which has a working tree, and work\n>    inside these \"worktree\"s.\n> \n> and the latter would be a natural extension to the workflow the\n> former wanted to use.\n> \n>>> It's fine for the command to have one name and the documentation to\n>>> use a longer, clearer name to explain it.  What should that longer,\n>>> clearer name be?\n>>\n>> No comments from me. I'll let you know that if Eric (or Junio?) didn't\n>> stop me, we would have had $GIT_DIR/repos now instead of\n>> $GIT_DIR/worktrees, just some extra confusion toppings.\n> \n> I forgot about that part of the history, but you are saying you\n> wanted to call these \"repos\", not \"worktrees\"?  I can see why\n> somebody (or me?) would stop that by fearing \"repo\" is a bit too\n> confusing with a \"repository\", in the same way that we are now\n> realizing that \"worktree\" is too similar to an old synonym we used\n> to call \"working tree\".\n> \n\nI would say the new thing is really a \"checkout\", but that opens another\ncan of worms. On the other hand, \"git checkout\" already does:\n- switching of branches\n- creation of branches\n- detaching of head\n- partial updates of the working tree\nSo why shouldn't it manage worktrees, as well?\n\nWhile that may sound a bit sarcastic it indicates that we may want to\nrethink some things at some point rather than adding up to the\nconflation. The discussion in this thread seems to show that \"worktree\"\nis just as a good a name for the new feature, while \"workbase\" or\n\"workroot\" (or \"workdir\") or so could have been for the old one.\n\nAre we at a point where we can still rename the new feature at least? If\nyes, and keeping everything else is mandatory, than \"workspace\" or\n\"working space\" may be a serious contender for naming the new thing.\n\nMichael\n"},{"id":"315131","messageId":"xmqqd1d7ev2q.fsf@gitster.mtv.corp.google.com","threadId":"45004","inReplyTo":"3c16aea8-be53-ef41-d43f-7b4e8ca15d7d@drmicha.warpmail.net","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-23T17:55:57Z","receivedAt":"2017-03-23T17:56:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Are we at a point where we can still rename the new feature at least? If\n> yes, and keeping everything else is mandatory, than \"workspace\" or\n> \"working space\" may be a serious contender for naming the new thing.\n\nI do not have a good answer to the first question, but workspace\ndoes sound like a good name for what this feature is trying to\nachieve.\n\n"},{"id":"315385","messageId":"CACsJy8D-+uO2GabNGLcTvfs7k8NrG1x200j3nOx11u8uUdzZVw@mail.gmail.com","threadId":"45004","inReplyTo":"xmqqvar2ska7.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-03-25T12:05:11Z","receivedAt":"2017-03-25T12:05:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Mar 21, 2017 at 10:48 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Duy Nguyen <pclouds@gmail.com> writes:\n>\n>> On Tue, Mar 21, 2017 at 1:50 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>>> Junio C Hamano wrote:\n>>>> Stefan Beller <sbeller@google.com> writes:\n>>>\n>>>>> While it may be true that you can have bare worktrees; I would question\n>>>>> why anyone wants to do this, as the only thing it provides is an\n>>>>> additional HEAD (plus its reflog).\n>>>>\n>>>> A more plausible situation is you start with a bare one as the\n>>>> primary and used to make local clones to do your work in the world\n>>>> before \"git worktree\".  It would be a natural extension to your\n>>>> workflow to instead create worktrees of of that bare one as the\n>>>> primary worktree with secondaries with working trees.\n>>>\n>>> For what it's worth, this conversation makes me think it was a mistake\n>>> to call this construct a worktree.\n>>\n>> For the record, I am totally confused with Junio's last line, with two\n>> \"with\"s, \"worktree\" and \"working trees\" in the same phrase :D\n>\n> In case this wasn't just a tangential note, what I meant was:\n>\n>  - In the old world, you may have had a single bare repository and\n>    then made clones, each of which has a working tree (i.e. non-bare\n>    clones), and worked inside these clones.\n>\n>  - In the \"git worktree\" world, you can start from that same single\n>    bare repository, but instead of cloning it, use \"git worktree\" to\n>    create \"worktree\"s, each of which has a working tree, and work\n>    inside these \"worktree\"s.\n>\n> and the latter would be a natural extension to the workflow the\n> former wanted to use.\n\nYes I really want that, and even the ability to convert a normal one\nrepo (with one working tree) to the latter, moving the repository to\nsomewhere safe.\n\n>>> It's fine for the command to have one name and the documentation to\n>>> use a longer, clearer name to explain it.  What should that longer,\n>>> clearer name be?\n>>\n>> No comments from me. I'll let you know that if Eric (or Junio?) didn't\n>> stop me, we would have had $GIT_DIR/repos now instead of\n>> $GIT_DIR/worktrees, just some extra confusion toppings.\n>\n> I forgot about that part of the history, but you are saying you\n> wanted to call these \"repos\", not \"worktrees\"?\n\nFrom $GIT_DIR perspective (which points to\n$GIT_COMMON_DIR/worktrees/blah) then they do look like a repository\nwith lots of part borrowed from $GIT_COMMON_DIR. I was simply saying\nI'm bad at naming things. \"worktrees\" is a better name than \"repos\".\n\n> I can see why\n> somebody (or me?) would stop that by fearing \"repo\" is a bit too\n> confusing with a \"repository\", in the same way that we are now\n> realizing that \"worktree\" is too similar to an old synonym we used\n> to call \"working tree\".\n-- \nDuy\n"},{"id":"315386","messageId":"CACsJy8BNYmYarZqnERhsO8LDxdsMsviUMs3Co6C4Ed7W9OvDJQ@mail.gmail.com","threadId":"45004","inReplyTo":"xmqqd1d7ev2q.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-03-25T12:07:28Z","receivedAt":"2017-03-25T12:08:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Mar 24, 2017 at 12:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n>\n>> Are we at a point where we can still rename the new feature at least? If\n>> yes, and keeping everything else is mandatory, than \"workspace\" or\n>> \"working space\" may be a serious contender for naming the new thing.\n>\n> I do not have a good answer to the first question, but workspace\n> does sound like a good name for what this feature is trying to\n> achieve.\n>\n\nNow is not too late to rename the command from worktree to workspace\n(and keep \"worktree\" as an alias that will be eventually deleted).\nShould we do it? I would keep file names, function names... unchanged\nthough, not worth the amount of new conflicts.\n-- \nDuy\n"},{"id":"316351","messageId":"ee8e8671-066b-311e-8cad-31a1ab22eec7@grubix.eu","threadId":"45004","inReplyTo":"CACsJy8BNYmYarZqnERhsO8LDxdsMsviUMs3Co6C4Ed7W9OvDJQ@mail.gmail.com","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Michael J Gruber","fromEmail":"git@grubix.eu","sentAt":"2017-04-07T13:59:57Z","receivedAt":"2017-04-07T14:00:10Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Duy Nguyen venit, vidit, dixit 25.03.2017 13:07:\n> On Fri, Mar 24, 2017 at 12:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Michael J Gruber <git@drmicha.warpmail.net> writes:\n>>\n>>> Are we at a point where we can still rename the new feature at least? If\n>>> yes, and keeping everything else is mandatory, than \"workspace\" or\n>>> \"working space\" may be a serious contender for naming the new thing.\n>>\n>> I do not have a good answer to the first question, but workspace\n>> does sound like a good name for what this feature is trying to\n>> achieve.\n>>\n> \n> Now is not too late to rename the command from worktree to workspace\n> (and keep \"worktree\" as an alias that will be eventually deleted).\n> Should we do it? I would keep file names, function names... unchanged\n> though, not worth the amount of new conflicts.\n\nI guess I would go for a full change. Our technical documentation often\nmerely consists of the source code, so we should reduce potential\nconfusion there, too.\n\nMichael\n"},{"id":"316362","messageId":"CA+P7+xotTt3e=yCp=ajHM7pV6Am_MZj5+e71-vCV1+utOa1XJg@mail.gmail.com","threadId":"45004","inReplyTo":"ee8e8671-066b-311e-8cad-31a1ab22eec7@grubix.eu","subject":"Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2017-04-07T16:14:05Z","receivedAt":"2017-04-07T16:14:33Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Fri, Apr 7, 2017 at 6:59 AM, Michael J Gruber <git@grubix.eu> wrote:\n> Duy Nguyen venit, vidit, dixit 25.03.2017 13:07:\n>> On Fri, Mar 24, 2017 at 12:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Michael J Gruber <git@drmicha.warpmail.net> writes:\n>>>\n>>>> Are we at a point where we can still rename the new feature at least? If\n>>>> yes, and keeping everything else is mandatory, than \"workspace\" or\n>>>> \"working space\" may be a serious contender for naming the new thing.\n>>>\n>>> I do not have a good answer to the first question, but workspace\n>>> does sound like a good name for what this feature is trying to\n>>> achieve.\n>>>\n>>\n>> Now is not too late to rename the command from worktree to workspace\n>> (and keep \"worktree\" as an alias that will be eventually deleted).\n>> Should we do it? I would keep file names, function names... unchanged\n>> though, not worth the amount of new conflicts.\n>\n> I guess I would go for a full change. Our technical documentation often\n> merely consists of the source code, so we should reduce potential\n> confusion there, too.\n>\n> Michael\n\nYes, changing the command name but not all the code would cause more\nconfusion in the long run.\n\nHowever, personally I never confused \"worktree\" and \"working trees\"\nmyself. I fee like they are related concepts anyways, in that a fresh\nclone has one worktree which its its working tree. Renaming it all to\nworkspace doesn't bother me either.\n\nThanks,\nJake\n"}]}