Git development
 help / color / mirror / Atom feed
* Re: [PATCH v2 3/5] completion: add and use __git_compute_first_level_config_vars_for_section
From: Philippe Blain @ 2024-02-10 17:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Patrick Steinhardt, Philippe Blain via GitGitGadget, git
In-Reply-To: <xmqqwmrcb5q8.fsf@gitster.g>

Hi Junio,

Le 2024-02-10 à 12:15, Junio C Hamano a écrit :
> Philippe Blain <levraiphilippeblain@gmail.com> writes:
> 
>>>> +	__git_compute_config_vars
>>>> +	local this_section="__git_first_level_config_vars_for_section_${section}"
>>>> +	test -n "${!this_section}" ||
>>>> +	printf -v "__git_first_level_config_vars_for_section_${section}" %s "$(echo "$__git_config_vars" | grep -E "^${section}\.[a-z]" | awk -F. '{print $2}')"
>>>> +}
> 
> A silly question (primarily because I do not much use the indirect
> reference construct ${!name}).  Does the assignment with printf need
> to spell out the long variable name with "_${section}"?  Can it be
> 
>     printf -v "$this_section" ...
> 
> instead, as we already have the short-hand for it?

No, unfortunately neither "$this_section" nor "${!this_section}"
work, so we must use the long name.

> 
>> finds also others. I think the idea is to cache these lists to avoid 
>> computing them everytime they are needed (probably most useful on Windows 
>> where process creation is longer). I'll mention that in the 
>> commit message.
> 
> Yup, as long as the contents of the list stays stable (e.g., list of
> Git subcommands, list of options a Git subcommand takes, list of
> configuration variable names that do not have end-user customization
> part, etc.), it is a viable optimization technique.  The available
> <slot> for color.branch.<slot> and color.diff.<slot> do not change
> (unless you talk about new version of Git adding support for more
> slots) and is a good idea to cache.  remote.<name>.url takes its
> <name> component out of an unbound set of end-user controlled names,
> so unless we somehow have a method to invalidate cached values, the
> list can go stale as remotes are added and removed.

Indeed. Here I'm caching Git config variables, not any user-defined names,
so these are stable.

Thanks,

Philippe.
 

^ permalink raw reply

* Re: [L10N] Kickoff for Git 2.44.0 round #1
From: Junio C Hamano @ 2024-02-10 17:21 UTC (permalink / raw)
  To: Jiang Xin
  Cc: Git List, Git l10n discussion group, Alexander Shopov, Jordi Mas,
	Ralf Thielow, Jimmy Angelakos, Christopher Díaz,
	Jean-Noël Avila, Bagas Sanjaya, Alessandro Menti,
	Gwan-gyeong Mun, Arusekk, Daniel Santos, Dimitriy Ryazantcev,
	Peter Krefting, Emir SARI, Arkadii Yakovets,
	Trần Ngọc Quân, Teng Long, Yi-Jyun Pan,
	Patrick Steinhardt
In-Reply-To: <20240210104321.3303-1-worldhello.net@gmail.com>

Jiang Xin <worldhello.net@gmail.com> writes:

> Git v2.44.0-rc0 has been released, and it's time to start new round of
> git l10n.  This time there are 52 updated messages need to be translated
> since last release. Please send your pull request to the l10n coordinator's
> repository below before this update window closes on Sun, 18 Feb 2024. 

Thanks.

^ permalink raw reply

* [BUG] git 2.44.0-rc0 t0080.1 Breaks on NonStop x86 and ia64
From: rsbecker @ 2024-02-10 18:14 UTC (permalink / raw)
  To: git

I encountered a new problem on git 2.44.0-rc0 for test t0080.1. Run very
verbose (--verbose -x):

++ cat
++ /home/randall/git/t/unit-tests/bin/t-basic
++ test_cmp expect actual
++ test 2 -ne 2
++ eval 'diff -u' '"$@"'
+++ diff -u expect actual
--- expect      2024-02-10 18:04:28 +0000
+++ actual      2024-02-10 18:04:28 +0000
@@ -1,43 +1,43 @@
 ok 1 - passing test
 ok 2 - passing test and assertion return 1
-# check "1 == 2" failed at t/unit-tests/t-basic.c:76
+# check "1 == 2" failed at /home/randall/git/t/unit-tests/t-basic.c:76
 #    left: 1
 #   right: 2
 not ok 3 - failing test
 ok 4 - failing test and assertion return 0
 not ok 5 - passing TEST_TODO() # TODO
 ok 6 - passing TEST_TODO() returns 1
-# todo check 'check(x)' succeeded at t/unit-tests/t-basic.c:25
+# todo check 'check(x)' succeeded at
/home/randall/git/t/unit-tests/t-basic.c:25
 not ok 7 - failing TEST_TODO()
 ok 8 - failing TEST_TODO() returns 0
-# check "0" failed at t/unit-tests/t-basic.c:30
+# check "0" failed at /home/randall/git/t/unit-tests/t-basic.c:30
 # skipping test - missing prerequisite
-# skipping check '1' at t/unit-tests/t-basic.c:32
+# skipping check '1' at /home/randall/git/t/unit-tests/t-basic.c:32
 ok 9 - test_skip() # SKIP
 ok 10 - skipped test returns 1
 # skipping test - missing prerequisite
 ok 11 - test_skip() inside TEST_TODO() # SKIP
 ok 12 - test_skip() inside TEST_TODO() returns 1
-# check "0" failed at t/unit-tests/t-basic.c:48
+# check "0" failed at /home/randall/git/t/unit-tests/t-basic.c:48
 not ok 13 - TEST_TODO() after failing check
 ok 14 - TEST_TODO() after failing check returns 0
-# check "0" failed at t/unit-tests/t-basic.c:56
+# check "0" failed at /home/randall/git/t/unit-tests/t-basic.c:56
 not ok 15 - failing check after TEST_TODO()
 ok 16 - failing check after TEST_TODO() returns 0
-# check "!strcmp("\thello\\", "there\"\n")" failed at
t/unit-tests/t-basic.c:61
+# check "!strcmp("\thello\\", "there\"\n")" failed at
/home/randall/git/t/unit-tests/t-basic.c:61
 #    left: "\011hello\\"
 #   right: "there\"\012"
-# check "!strcmp("NULL", NULL)" failed at t/unit-tests/t-basic.c:62
+# check "!strcmp("NULL", NULL)" failed at
/home/randall/git/t/unit-tests/t-basic.c:62
 #    left: "NULL"
 #   right: NULL
-# check "'a' == '\n'" failed at t/unit-tests/t-basic.c:63
+# check "'a' == '\n'" failed at /home/randall/git/t/unit-tests/t-basic.c:63
 #    left: 'a'
 #   right: '\012'
-# check "'\\' == '\''" failed at t/unit-tests/t-basic.c:64
+# check "'\\' == '\''" failed at
/home/randall/git/t/unit-tests/t-basic.c:64
 #    left: '\\'
 #   right: '\''
 not ok 17 - messages from failing string and char comparison
-# BUG: test has no checks at t/unit-tests/t-basic.c:91
+# BUG: test has no checks at /home/randall/git/t/unit-tests/t-basic.c:91
 not ok 18 - test with no checks
 ok 19 - test with no checks returns 0
 1..19
error: last command exited with $?=1

The diff appears to have failed because of an assumption of how paths are
resolved during compilation. The assumption is that files remain partially
qualified, which is not the case in all C compilers. This is c99. My
experience with gcc is that it qualifies names differently than other
compilers. It might be useful to pipe to sed to strip ${HOME}/ when building
the actual file, something like:

sed -i "1,\$s/${HOME}\//g" actual    # Not that that will actually work
because sed will process /. A different delimiter would work.

Randall

--
Randall S. Becker
NSGit Chief Architect
Nexbridge Inc.
+1.416.984.9826



^ permalink raw reply

* [PATCH v3 1/4] completion: add space after config variable names also in Bash 3
From: Philippe Blain via GitGitGadget @ 2024-02-10 18:32 UTC (permalink / raw)
  To: git; +Cc: Patrick Steinhardt, Philippe Blain, Philippe Blain,
	Philippe Blain
In-Reply-To: <pull.1660.v3.git.git.1707589943.gitgitgadget@gmail.com>

From: Philippe Blain <levraiphilippeblain@gmail.com>

In be6444d1ca (completion: bash: add correct suffix in variables,
2021-08-16), __git_complete_config_variable_name was changed to use
"${sfx- }" instead of "$sfx" as the fourth argument of _gitcomp_nl and
_gitcomp_nl_append, such that this argument evaluates to a space if sfx
is unset. This was to ensure that e.g.

	git config branch.autoSetupMe[TAB]

correctly completes to 'branch.autoSetupMerge ' with the trailing space.
This commits notes that the fix only works in Bash 4 because in Bash 3
the 'local sfx' construct at the beginning of
__git_complete_config_variable_name creates an empty string.

Make the fix also work for Bash 3 by using the "unset or null' parameter
expansion syntax ("${sfx:- }"), such that the parameter is also expanded
to a space if it is set but null, as is the behaviour of 'local sfx' in
Bash 3.

Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
---
 contrib/completion/git-completion.bash | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 6662db221df..159a4fd8add 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2750,7 +2750,7 @@ __git_complete_config_variable_name ()
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
 		__gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
-		__gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "${sfx- }"
+		__gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	guitool.*.*)
@@ -2784,7 +2784,7 @@ __git_complete_config_variable_name ()
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
 		__git_compute_all_commands
-		__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx- }"
+		__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	remote.*.*)
@@ -2800,7 +2800,7 @@ __git_complete_config_variable_name ()
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
 		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
-		__gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx- }"
+		__gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	url.*.*)
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH v3 0/4] completion: remove hardcoded config variable names
From: Philippe Blain via GitGitGadget @ 2024-02-10 18:32 UTC (permalink / raw)
  To: git; +Cc: Patrick Steinhardt, Philippe Blain, Philippe Blain
In-Reply-To: <pull.1660.v2.git.git.1706534881.gitgitgadget@gmail.com>

Changes since v2:

 * Moved the addition of the tests to 2/4, and tweaked 3/4 and 4/4 so they
   simply adjust the test names
 * Added a test for user-defined submodule names, as suggested by Patrick
 * Added more details in the commit message of 3/4 around the use of global
   variables as caches
 * Slightly improved commit message wording and fixed typos
 * Added 'local' where suggested
 * Dropped 4/5 which modified 'git help', since it's not needed (thanks
   Patrick!)

Changes since v1:

 * Corrected my email in PATCH 2/5 (sorry for the noise)

v1: This series removes hardcoded config variable names in the
__git_complete_config_variable_name function, partly by adding a new mode to
'git help'. It also adds completion for 'submodule.*' config variables,
which were previously missing.

I think it makes sense to do that in the same series since it's closely
related, and splitting it would result in textual conflicts between both
series if one does not build on top of the other, but I'm open to other
suggestions.

Thanks,

Philippe.

Philippe Blain (4):
  completion: add space after config variable names also in Bash 3
  completion: complete 'submodule.*' config variables
  completion: add and use
    __git_compute_first_level_config_vars_for_section
  completion: add and use
    __git_compute_second_level_config_vars_for_section

 contrib/completion/git-completion.bash | 90 +++++++++++++-------------
 t/t9902-completion.sh                  | 29 +++++++++
 2 files changed, 75 insertions(+), 44 deletions(-)


base-commit: b50a608ba20348cb3dfc16a696816d51780e3f0f
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1660%2Fphil-blain%2Fcompletion-submodule-config-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1660/phil-blain/completion-submodule-config-v3
Pull-Request: https://github.com/git/git/pull/1660

Range-diff vs v2:

 1:  837d92a6c27 = 1:  837d92a6c27 completion: add space after config variable names also in Bash 3
 2:  426374ff9b3 ! 2:  6b75582ee35 completion: complete 'submodule.*' config variables
     @@ Commit message
          Add the appropriate branches to the case statement, making use of the
          in-tree '.gitmodules' to list relevant submodules.
      
     +    Add corresponding tests in t9902-completion.sh, making sure we complete
     +    both first level submodule config variables as well as second level
     +    variables involving submodule names.
     +
          Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
      
       ## contrib/completion/git-completion.bash ##
     @@ contrib/completion/git-completion.bash: __git_complete_config_variable_name ()
       	url.*.*)
       		local pfx="${cur_%.*}."
       		cur_="${cur_##*.}"
     +
     + ## t/t9902-completion.sh ##
     +@@ t/t9902-completion.sh: test_expect_success 'git config - variable name include' '
     + 	EOF
     + '
     + 
     ++test_expect_success 'setup for git config submodule tests' '
     ++	test_create_repo sub &&
     ++	test_commit -C sub initial &&
     ++	git submodule add ./sub
     ++'
     ++
     ++test_expect_success 'git config - variable name - submodule' '
     ++	test_completion "git config submodule." <<-\EOF
     ++	submodule.active Z
     ++	submodule.alternateErrorStrategy Z
     ++	submodule.alternateLocation Z
     ++	submodule.fetchJobs Z
     ++	submodule.propagateBranches Z
     ++	submodule.recurse Z
     ++	submodule.sub.Z
     ++	EOF
     ++'
     ++
     ++test_expect_success 'git config - variable name - submodule names' '
     ++	test_completion "git config submodule.sub." <<-\EOF
     ++	submodule.sub.url Z
     ++	submodule.sub.update Z
     ++	submodule.sub.branch Z
     ++	submodule.sub.fetchRecurseSubmodules Z
     ++	submodule.sub.ignore Z
     ++	submodule.sub.active Z
     ++	EOF
     ++'
     ++
     + test_expect_success 'git config - value' '
     + 	test_completion "git config color.pager " <<-\EOF
     + 	false Z
 3:  838aabf2858 ! 3:  fb210325394 completion: add and use __git_compute_first_level_config_vars_for_section
     @@ Commit message
      
          The function __git_complete_config_variable_name in the Bash completion
          script hardcodes several config variable names. These variables are
     -    those in config section where user-defined names can appear, such as
     +    those in config sections where user-defined names can appear, such as
          "branch.<name>". These sections are treated first by the case statement,
          and the two last "catch all" cases are used for other sections, making
          use of the __git_compute_config_vars and __git_compute_config_sections
     @@ Commit message
          like 'branch.autoSetupMerge, 'remote.pushDefault', etc.  Use this
          function and the variables it defines in the 'branch.*', 'remote.*' and
          'submodule.*' switches of the case statement instead of hardcoding the
     -    corresponding config variables.  Note that we use indirect expansion
     -    instead of associative arrays because those are not supported in Bash 3,
     -    on which macOS is stuck for licensing reasons.
     +    corresponding config variables.  Note that we use indirect expansion to
     +    create a variable for each section, instead of using a single
     +    associative array indexed by section names, because associative arrays
     +    are not supported in Bash 3, on which macOS is stuck for licensing
     +    reasons.
      
     -    Add a test to make sure the new function works correctly by verfying it
     -    lists all 'submodule' config variables. This has the downside that this
     -    test must be updated when new 'submodule' configuration are added, but
     -    this should be a small burden since it happens infrequently.
     +    Use the existing pattern in the completion script of using global
     +    variables to cache the list of config variables for each section. The
     +    rationale for such caching is explained in eaa4e6ee2a (Speed up bash
     +    completion loading, 2009-11-17), and the current approach to using and
     +    defining them via 'test -n' is explained in cf0ff02a38 (completion: work
     +    around zsh option propagation bug, 2012-02-02).
     +
     +    Adjust the name of one of the tests added in the previous commit,
     +    reflecting that it now also tests the new function.
      
          Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
      
     @@ contrib/completion/git-completion.bash: __git_compute_config_vars ()
       
      +__git_compute_first_level_config_vars_for_section ()
      +{
     -+	section="$1"
     ++	local section="$1"
      +	__git_compute_config_vars
      +	local this_section="__git_first_level_config_vars_for_section_${section}"
      +	test -n "${!this_section}" ||
     @@ contrib/completion/git-completion.bash: __git_complete_config_variable_name ()
       	url.*.*)
      
       ## t/t9902-completion.sh ##
     -@@ t/t9902-completion.sh: test_expect_success 'git config - variable name include' '
     - 	EOF
     +@@ t/t9902-completion.sh: test_expect_success 'setup for git config submodule tests' '
     + 	git submodule add ./sub
       '
       
     -+test_expect_success 'git config - variable name - __git_compute_first_level_config_vars_for_section' '
     -+	test_completion "git config submodule." <<-\EOF
     -+	submodule.active Z
     -+	submodule.alternateErrorStrategy Z
     -+	submodule.alternateLocation Z
     -+	submodule.fetchJobs Z
     -+	submodule.propagateBranches Z
     -+	submodule.recurse Z
     -+	EOF
     -+'
     -+
     - test_expect_success 'git config - value' '
     - 	test_completion "git config color.pager " <<-\EOF
     - 	false Z
     +-test_expect_success 'git config - variable name - submodule' '
     ++test_expect_success 'git config - variable name - submodule and __git_compute_first_level_config_vars_for_section' '
     + 	test_completion "git config submodule." <<-\EOF
     + 	submodule.active Z
     + 	submodule.alternateErrorStrategy Z
 4:  d442a039b27 < -:  ----------- builtin/help: add --config-all-for-completion
 5:  a2e792c911e ! 4:  69fc02bb6b4 completion: add an use __git_compute_second_level_config_vars_for_section
     @@ Metadata
      Author: Philippe Blain <levraiphilippeblain@gmail.com>
      
       ## Commit message ##
     -    completion: add an use __git_compute_second_level_config_vars_for_section
     +    completion: add and use __git_compute_second_level_config_vars_for_section
      
          In a previous commit we removed some hardcoded config variable names from
          function __git_complete_config_variable_name in the completion script by
     @@ Commit message
          configuration variables, meaning 'branch.<name>.upstream',
          'remote.<name>.url', etc. where <name> is a user-defined name.
      
     -    Making use of the new --config-all-for-completion flag to 'git help'
     -    introduced in the previous commit, add a new function,
     -    __git_compute_second_level_config_vars_for_section. This function takes
     -    as argument a config section name and computes the corresponding
     -    second-level config variables, i.e. those that contain a '<' which
     -    indicates the start of a placeholder. Note that as in
     +    Making use of the new existing --config flag to 'git help', add a new
     +    function, __git_compute_second_level_config_vars_for_section. This
     +    function takes as argument a config section name and computes the
     +    corresponding second-level config variables, i.e. those that contain a
     +    '<' which indicates the start of a placeholder. Note that as in
          __git_compute_first_level_config_vars_for_section added previsouly, we
          use indirect expansion instead of associative arrays to stay compatible
          with Bash 3 on which macOS is stuck for licensing reasons.
      
     +    As explained in the previous commit, we use the existing pattern in the
     +    completion script of using global variables to cache the list of
     +    variables for each section.
     +
          Use this new function and the variables it defines in
          __git_complete_config_variable_name to remove hardcoded config
          variables, and add a test to verify the new function.  Use a single
          'case' for all sections with second-level variables names, since the
          code for each of them is now exactly the same.
      
     +    Adjust the name of a test added in a previous commit to reflect that it
     +    now tests the added function.
     +
          Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
      
       ## contrib/completion/git-completion.bash ##
     @@ contrib/completion/git-completion.bash: __git_compute_config_vars ()
      +__git_compute_config_vars_all ()
      +{
      +	test -n "$__git_config_vars_all" ||
     -+	__git_config_vars_all="$(git help --config-all-for-completion)"
     ++	__git_config_vars_all="$(git --no-pager help --config)"
      +}
      +
       __git_compute_first_level_config_vars_for_section ()
       {
     - 	section="$1"
     + 	local section="$1"
      @@ contrib/completion/git-completion.bash: __git_compute_first_level_config_vars_for_section ()
       	printf -v "__git_first_level_config_vars_for_section_${section}" %s "$(echo "$__git_config_vars" | grep -E "^${section}\.[a-z]" | awk -F. '{print $2}')"
       }
       
      +__git_compute_second_level_config_vars_for_section ()
      +{
     -+	section="$1"
     ++	local section="$1"
      +	__git_compute_config_vars_all
      +	local this_section="__git_second_level_config_vars_for_section_${section}"
      +	test -n "${!this_section}" ||
     @@ contrib/completion/git-completion.bash: __git_complete_config_variable_name ()
       		__gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
      
       ## t/t9902-completion.sh ##
     -@@ t/t9902-completion.sh: test_expect_success 'git config - variable name - __git_compute_first_level_conf
     - 	submodule.recurse Z
     +@@ t/t9902-completion.sh: test_expect_success 'git config - variable name - submodule and __git_compute_fi
       	EOF
       '
     -+test_expect_success 'git config - variable name - __git_compute_second_level_config_vars_for_section' '
     -+	test_completion "git config branch.main." <<-\EOF
     -+	branch.main.description Z
     -+	branch.main.remote Z
     -+	branch.main.pushRemote Z
     -+	branch.main.merge Z
     -+	branch.main.mergeOptions Z
     -+	branch.main.rebase Z
     -+	EOF
     -+'
       
     - test_expect_success 'git config - value' '
     - 	test_completion "git config color.pager " <<-\EOF
     +-test_expect_success 'git config - variable name - submodule names' '
     ++test_expect_success 'git config - variable name - __git_compute_second_level_config_vars_for_section' '
     + 	test_completion "git config submodule.sub." <<-\EOF
     + 	submodule.sub.url Z
     + 	submodule.sub.update Z

-- 
gitgitgadget

^ permalink raw reply

* [PATCH v3 2/4] completion: complete 'submodule.*' config variables
From: Philippe Blain via GitGitGadget @ 2024-02-10 18:32 UTC (permalink / raw)
  To: git; +Cc: Patrick Steinhardt, Philippe Blain, Philippe Blain,
	Philippe Blain
In-Reply-To: <pull.1660.v3.git.git.1707589943.gitgitgadget@gmail.com>

From: Philippe Blain <levraiphilippeblain@gmail.com>

In the Bash completion script, function
__git_complete_config_variable_name completes config variables and has
special logic to deal with config variables involving user-defined
names, like branch.<name>.* and remote.<name>.*.

This special logic is missing for submodule-related config variables.
Add the appropriate branches to the case statement, making use of the
in-tree '.gitmodules' to list relevant submodules.

Add corresponding tests in t9902-completion.sh, making sure we complete
both first level submodule config variables as well as second level
variables involving submodule names.

Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
---
 contrib/completion/git-completion.bash | 13 ++++++++++++
 t/t9902-completion.sh                  | 29 ++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 159a4fd8add..8af9bc3f4e1 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2803,6 +2803,19 @@ __git_complete_config_variable_name ()
 		__gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
+	submodule.*.*)
+		local pfx="${cur_%.*}."
+		cur_="${cur_##*.}"
+		__gitcomp "url update branch fetchRecurseSubmodules ignore active" "$pfx" "$cur_" "$sfx"
+		return
+		;;
+	submodule.*)
+		local pfx="${cur_%.*}."
+		cur_="${cur_#*.}"
+		__gitcomp_nl "$(__git config -f "$(__git rev-parse --show-toplevel)/.gitmodules" --get-regexp 'submodule.*.path' | awk -F. '{print $2}')" "$pfx" "$cur_" "."
+		__gitcomp_nl_append $'alternateErrorStrategy\nfetchJobs\nactive\nalternateLocation\nrecurse\npropagateBranches' "$pfx" "$cur_" "${sfx:- }"
+		return
+		;;
 	url.*.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_##*.}"
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 35eb534fdda..23d0e71324c 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2583,6 +2583,35 @@ test_expect_success 'git config - variable name include' '
 	EOF
 '
 
+test_expect_success 'setup for git config submodule tests' '
+	test_create_repo sub &&
+	test_commit -C sub initial &&
+	git submodule add ./sub
+'
+
+test_expect_success 'git config - variable name - submodule' '
+	test_completion "git config submodule." <<-\EOF
+	submodule.active Z
+	submodule.alternateErrorStrategy Z
+	submodule.alternateLocation Z
+	submodule.fetchJobs Z
+	submodule.propagateBranches Z
+	submodule.recurse Z
+	submodule.sub.Z
+	EOF
+'
+
+test_expect_success 'git config - variable name - submodule names' '
+	test_completion "git config submodule.sub." <<-\EOF
+	submodule.sub.url Z
+	submodule.sub.update Z
+	submodule.sub.branch Z
+	submodule.sub.fetchRecurseSubmodules Z
+	submodule.sub.ignore Z
+	submodule.sub.active Z
+	EOF
+'
+
 test_expect_success 'git config - value' '
 	test_completion "git config color.pager " <<-\EOF
 	false Z
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH v3 3/4] completion: add and use __git_compute_first_level_config_vars_for_section
From: Philippe Blain via GitGitGadget @ 2024-02-10 18:32 UTC (permalink / raw)
  To: git; +Cc: Patrick Steinhardt, Philippe Blain, Philippe Blain,
	Philippe Blain
In-Reply-To: <pull.1660.v3.git.git.1707589943.gitgitgadget@gmail.com>

From: Philippe Blain <levraiphilippeblain@gmail.com>

The function __git_complete_config_variable_name in the Bash completion
script hardcodes several config variable names. These variables are
those in config sections where user-defined names can appear, such as
"branch.<name>". These sections are treated first by the case statement,
and the two last "catch all" cases are used for other sections, making
use of the __git_compute_config_vars and __git_compute_config_sections
function, which omit listing any variables containing wildcards or
placeholders. Having hardcoded config variables introduces the risk of
the completion code becoming out of sync with the actual config
variables accepted by Git.

To avoid these hardcoded config variables, introduce a new function,
__git_compute_first_level_config_vars_for_section, making use of the
existing __git_config_vars variable. This function takes as argument a
config section name and computes the matching "first level" config
variables for that section, i.e. those _not_ containing any placeholder,
like 'branch.autoSetupMerge, 'remote.pushDefault', etc.  Use this
function and the variables it defines in the 'branch.*', 'remote.*' and
'submodule.*' switches of the case statement instead of hardcoding the
corresponding config variables.  Note that we use indirect expansion to
create a variable for each section, instead of using a single
associative array indexed by section names, because associative arrays
are not supported in Bash 3, on which macOS is stuck for licensing
reasons.

Use the existing pattern in the completion script of using global
variables to cache the list of config variables for each section. The
rationale for such caching is explained in eaa4e6ee2a (Speed up bash
completion loading, 2009-11-17), and the current approach to using and
defining them via 'test -n' is explained in cf0ff02a38 (completion: work
around zsh option propagation bug, 2012-02-02).

Adjust the name of one of the tests added in the previous commit,
reflecting that it now also tests the new function.

Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
---
 contrib/completion/git-completion.bash | 24 +++++++++++++++++++++---
 t/t9902-completion.sh                  |  2 +-
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 8af9bc3f4e1..57a8da7ca1a 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2596,6 +2596,15 @@ __git_compute_config_vars ()
 	__git_config_vars="$(git help --config-for-completion)"
 }
 
+__git_compute_first_level_config_vars_for_section ()
+{
+	local section="$1"
+	__git_compute_config_vars
+	local this_section="__git_first_level_config_vars_for_section_${section}"
+	test -n "${!this_section}" ||
+	printf -v "__git_first_level_config_vars_for_section_${section}" %s "$(echo "$__git_config_vars" | grep -E "^${section}\.[a-z]" | awk -F. '{print $2}')"
+}
+
 __git_config_sections=
 __git_compute_config_sections ()
 {
@@ -2749,8 +2758,11 @@ __git_complete_config_variable_name ()
 	branch.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
+		local section="${pfx%.}"
 		__gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
-		__gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "${sfx:- }"
+		__git_compute_first_level_config_vars_for_section "${section}"
+		local this_section="__git_first_level_config_vars_for_section_${section}"
+		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	guitool.*.*)
@@ -2799,8 +2811,11 @@ __git_complete_config_variable_name ()
 	remote.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
+		local section="${pfx%.}"
 		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
-		__gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx:- }"
+		__git_compute_first_level_config_vars_for_section "${section}"
+		local this_section="__git_first_level_config_vars_for_section_${section}"
+		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	submodule.*.*)
@@ -2812,8 +2827,11 @@ __git_complete_config_variable_name ()
 	submodule.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
+		local section="${pfx%.}"
 		__gitcomp_nl "$(__git config -f "$(__git rev-parse --show-toplevel)/.gitmodules" --get-regexp 'submodule.*.path' | awk -F. '{print $2}')" "$pfx" "$cur_" "."
-		__gitcomp_nl_append $'alternateErrorStrategy\nfetchJobs\nactive\nalternateLocation\nrecurse\npropagateBranches' "$pfx" "$cur_" "${sfx:- }"
+		__git_compute_first_level_config_vars_for_section "${section}"
+		local this_section="__git_first_level_config_vars_for_section_${section}"
+		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	url.*.*)
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 23d0e71324c..8600b9e0dd9 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2589,7 +2589,7 @@ test_expect_success 'setup for git config submodule tests' '
 	git submodule add ./sub
 '
 
-test_expect_success 'git config - variable name - submodule' '
+test_expect_success 'git config - variable name - submodule and __git_compute_first_level_config_vars_for_section' '
 	test_completion "git config submodule." <<-\EOF
 	submodule.active Z
 	submodule.alternateErrorStrategy Z
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH v3 4/4] completion: add and use __git_compute_second_level_config_vars_for_section
From: Philippe Blain via GitGitGadget @ 2024-02-10 18:32 UTC (permalink / raw)
  To: git; +Cc: Patrick Steinhardt, Philippe Blain, Philippe Blain,
	Philippe Blain
In-Reply-To: <pull.1660.v3.git.git.1707589943.gitgitgadget@gmail.com>

From: Philippe Blain <levraiphilippeblain@gmail.com>

In a previous commit we removed some hardcoded config variable names from
function __git_complete_config_variable_name in the completion script by
introducing a new function,
__git_compute_first_level_config_vars_for_section.

The remaining hardcoded config variables are "second level"
configuration variables, meaning 'branch.<name>.upstream',
'remote.<name>.url', etc. where <name> is a user-defined name.

Making use of the new existing --config flag to 'git help', add a new
function, __git_compute_second_level_config_vars_for_section. This
function takes as argument a config section name and computes the
corresponding second-level config variables, i.e. those that contain a
'<' which indicates the start of a placeholder. Note that as in
__git_compute_first_level_config_vars_for_section added previsouly, we
use indirect expansion instead of associative arrays to stay compatible
with Bash 3 on which macOS is stuck for licensing reasons.

As explained in the previous commit, we use the existing pattern in the
completion script of using global variables to cache the list of
variables for each section.

Use this new function and the variables it defines in
__git_complete_config_variable_name to remove hardcoded config
variables, and add a test to verify the new function.  Use a single
'case' for all sections with second-level variables names, since the
code for each of them is now exactly the same.

Adjust the name of a test added in a previous commit to reflect that it
now tests the added function.

Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
---
 contrib/completion/git-completion.bash | 71 ++++++++------------------
 t/t9902-completion.sh                  |  2 +-
 2 files changed, 22 insertions(+), 51 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 57a8da7ca1a..87678a5bb36 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2596,6 +2596,13 @@ __git_compute_config_vars ()
 	__git_config_vars="$(git help --config-for-completion)"
 }
 
+__git_config_vars_all=
+__git_compute_config_vars_all ()
+{
+	test -n "$__git_config_vars_all" ||
+	__git_config_vars_all="$(git --no-pager help --config)"
+}
+
 __git_compute_first_level_config_vars_for_section ()
 {
 	local section="$1"
@@ -2605,6 +2612,15 @@ __git_compute_first_level_config_vars_for_section ()
 	printf -v "__git_first_level_config_vars_for_section_${section}" %s "$(echo "$__git_config_vars" | grep -E "^${section}\.[a-z]" | awk -F. '{print $2}')"
 }
 
+__git_compute_second_level_config_vars_for_section ()
+{
+	local section="$1"
+	__git_compute_config_vars_all
+	local this_section="__git_second_level_config_vars_for_section_${section}"
+	test -n "${!this_section}" ||
+	printf -v "__git_second_level_config_vars_for_section_${section}" %s "$(echo "$__git_config_vars_all" | grep -E "^${section}\.<" | awk -F. '{print $3}')"
+}
+
 __git_config_sections=
 __git_compute_config_sections ()
 {
@@ -2749,10 +2765,13 @@ __git_complete_config_variable_name ()
 	done
 
 	case "$cur_" in
-	branch.*.*)
+	branch.*.*|guitool.*.*|difftool.*.*|man.*.*|mergetool.*.*|remote.*.*|submodule.*.*|url.*.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_##*.}"
-		__gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx"
+		local section="${pfx%.*.}"
+		__git_compute_second_level_config_vars_for_section "${section}"
+		local this_section="__git_second_level_config_vars_for_section_${section}"
+		__gitcomp "${!this_section}" "$pfx" "$cur_" "$sfx"
 		return
 		;;
 	branch.*)
@@ -2765,33 +2784,6 @@ __git_complete_config_variable_name ()
 		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
-	guitool.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "
-			argPrompt cmd confirm needsFile noConsole noRescan
-			prompt revPrompt revUnmerged title
-			" "$pfx" "$cur_" "$sfx"
-		return
-		;;
-	difftool.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
-		return
-		;;
-	man.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
-		return
-		;;
-	mergetool.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx"
-		return
-		;;
 	pager.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
@@ -2799,15 +2791,6 @@ __git_complete_config_variable_name ()
 		__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
-	remote.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "
-			url proxy fetch push mirror skipDefaultUpdate
-			receivepack uploadpack tagOpt pushurl
-			" "$pfx" "$cur_" "$sfx"
-		return
-		;;
 	remote.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
@@ -2818,12 +2801,6 @@ __git_complete_config_variable_name ()
 		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
-	submodule.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "url update branch fetchRecurseSubmodules ignore active" "$pfx" "$cur_" "$sfx"
-		return
-		;;
 	submodule.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
@@ -2834,12 +2811,6 @@ __git_complete_config_variable_name ()
 		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
-	url.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx"
-		return
-		;;
 	*.*)
 		__git_compute_config_vars
 		__gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 8600b9e0dd9..64031a9eff8 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2601,7 +2601,7 @@ test_expect_success 'git config - variable name - submodule and __git_compute_fi
 	EOF
 '
 
-test_expect_success 'git config - variable name - submodule names' '
+test_expect_success 'git config - variable name - __git_compute_second_level_config_vars_for_section' '
 	test_completion "git config submodule.sub." <<-\EOF
 	submodule.sub.url Z
 	submodule.sub.update Z
-- 
gitgitgadget

^ permalink raw reply related

* Re: git status became very slow after upgrading git
From: Vijay Raghavan Aravamudhan @ 2024-02-10 18:42 UTC (permalink / raw)
  To: Sean Allred; +Cc: git
In-Reply-To: <m05xyw9r92.fsf@epic96565.epic.com>

Thanks for responding. I have run the command that you gave on an open
source repo so that its easy for you to replicate. The remote url is:
https://github.com/vraravam/ferdium-app

The output is:
    ~/d/o/ferdium  on   develop  GIT_TRACE=1 GIT_TRACE_SETUP=1
GIT_TRACE_PERFORMANCE=1 git status
00:08:15.548976 trace.c:314             setup: git_dir: .git
00:08:15.550590 trace.c:315             setup: git_common_dir: .git
00:08:15.550600 trace.c:316             setup: worktree:
/Users/vijay/dev/oss/ferdium
00:08:15.550604 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
00:08:15.550611 trace.c:318             setup: prefix: (null)
00:08:15.550707 chdir-notify.c:70       setup: chdir from
'/Users/vijay/dev/oss/ferdium' to '/Users/vijay/dev/oss/ferdium'
00:08:15.550723 git.c:463               trace: built-in: git status
00:08:15.552184 read-cache.c:2386       performance: 0.000183000 s:
read cache .git/index
00:08:15.555964 read-cache.c:1629       performance: 0.003696000 s:
refresh index
00:08:15.556442 diff-lib.c:273          performance: 0.000132000 s:  diff-files
00:08:15.558558 unpack-trees.c:2004     performance: 0.000019000 s:
traverse_trees
00:08:15.558801 unpack-trees.c:438      performance: 0.000003000 s:
check_updates
00:08:15.558813 unpack-trees.c:2096     performance: 0.000394000 s:
unpack_trees
00:08:15.558819 diff-lib.c:638          performance: 0.000524000 s:  diff-index
00:08:15.559166 name-hash.c:613         performance: 0.000148000 s:
initialize name hash
On branch develop
Your branch is up to date with 'origin/develop'.

00:08:15.567249 run-command.c:657       trace: run_command:
GIT_INDEX_FILE=.git/index git submodule summary --cached --for-status
--summary-limit -1 HEAD
00:08:15.833334 git.c:749               trace: exec: git-submodule
summary --cached --for-status --summary-limit -1 HEAD
00:08:15.834114 run-command.c:657       trace: run_command:
git-submodule summary --cached --for-status --summary-limit -1 HEAD
00:08:16.880778 trace.c:414             performance: 0.000013000 s:
git command: git --exec-path
00:08:18.216639 git.c:463               trace: built-in: git rev-parse --git-dir
00:08:18.218740 trace.c:414             performance: 0.002132000 s:
git command: git rev-parse --git-dir
00:08:18.489025 git.c:463               trace: built-in: git rev-parse
--git-path objects
00:08:18.490677 trace.c:414             performance: 0.001675000 s:
git command: git rev-parse --git-path objects
00:08:19.031080 git.c:463               trace: built-in: git rev-parse
--show-prefix
00:08:19.032882 trace.c:414             performance: 0.001827000 s:
git command: git rev-parse --show-prefix
00:08:19.296074 git.c:463               trace: built-in: git rev-parse
--show-toplevel
00:08:19.297559 trace.c:414             performance: 0.001504000 s:
git command: git rev-parse --show-toplevel
00:08:19.830285 trace.c:314             setup: git_dir: .git
00:08:19.830972 trace.c:315             setup: git_common_dir: .git
00:08:19.830981 trace.c:316             setup: worktree:
/Users/vijay/dev/oss/ferdium
00:08:19.830984 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
00:08:19.830990 trace.c:318             setup: prefix: (null)
00:08:19.830994 git.c:463               trace: built-in: git
submodule--helper summary --cached --for-status -n -1 -- HEAD
00:08:19.834629 read-cache.c:2386       performance: 0.000164000 s:
read cache .git/index
00:08:19.834914 unpack-trees.c:2004     performance: 0.000024000 s:
traverse_trees
00:08:19.834932 unpack-trees.c:438      performance: 0.000003000 s:
check_updates
00:08:19.834940 unpack-trees.c:2096     performance: 0.000157000 s:
unpack_trees
00:08:19.834958 diff-lib.c:638          performance: 0.000307000 s:  diff-index
00:08:19.834975 trace.c:414             performance: 0.005922000 s:
git command: git submodule--helper summary --cached --for-status -n -1
-- HEAD
00:08:19.836137 trace.c:414             performance: 4.003693000 s:
git command: /opt/homebrew/opt/git/libexec/git-core/git submodule
summary --cached --for-status --summary-limit -1 HEAD
00:08:19.836842 run-command.c:657       trace: run_command:
GIT_INDEX_FILE=.git/index git submodule summary --files --for-status
--summary-limit -1
00:08:20.106802 git.c:749               trace: exec: git-submodule
summary --files --for-status --summary-limit -1
00:08:20.107638 run-command.c:657       trace: run_command:
git-submodule summary --files --for-status --summary-limit -1
00:08:21.162243 trace.c:414             performance: 0.000006000 s:
git command: git --exec-path
00:08:22.496146 git.c:463               trace: built-in: git rev-parse --git-dir
00:08:22.497722 trace.c:414             performance: 0.001589000 s:
git command: git rev-parse --git-dir
00:08:22.764795 git.c:463               trace: built-in: git rev-parse
--git-path objects
00:08:22.766763 trace.c:414             performance: 0.001991000 s:
git command: git rev-parse --git-path objects
00:08:23.304626 git.c:463               trace: built-in: git rev-parse
--show-prefix
00:08:23.306436 trace.c:414             performance: 0.001833000 s:
git command: git rev-parse --show-prefix
00:08:23.575506 git.c:463               trace: built-in: git rev-parse
--show-toplevel
00:08:23.577138 trace.c:414             performance: 0.001656000 s:
git command: git rev-parse --show-toplevel
00:08:24.111335 trace.c:314             setup: git_dir: .git
00:08:24.112123 trace.c:315             setup: git_common_dir: .git
00:08:24.112138 trace.c:316             setup: worktree:
/Users/vijay/dev/oss/ferdium
00:08:24.112142 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
00:08:24.112149 trace.c:318             setup: prefix: (null)
00:08:24.112154 git.c:463               trace: built-in: git
submodule--helper summary --files --for-status -n -1 --
00:08:24.113679 read-cache.c:2386       performance: 0.000216000 s:
read cache .git/index
00:08:24.117811 diff-lib.c:273          performance: 0.004115000 s:  diff-files
00:08:24.117838 trace.c:414             performance: 0.007389000 s:
git command: git submodule--helper summary --files --for-status -n -1
--
00:08:24.118895 trace.c:414             performance: 4.013083000 s:
git command: /opt/homebrew/opt/git/libexec/git-core/git submodule
summary --files --for-status --summary-limit -1
nothing to commit, working tree clean
00:08:24.119646 trace.c:414             performance: 8.571954000 s:
git command: git status

Hope this helps. Also, I noticed that the same repo, same versions of
all tools, etc - this issue only occurs on my M2 mac, but works
without any slowness on the intel mac.

On Sat, Feb 10, 2024 at 10:43 PM Sean Allred <allred.sean@gmail.com> wrote:
>
>
> Vijay Raghavan Aravamudhan <avijayr@gmail.com> writes:
>
> > What did you do before the bug happened? (Steps to reproduce your issue)
> > 1. brew update which pulled in latest version of git
> > 2. git status in a repository (without submodules)
> >
> > What did you expect to happen? (Expected behavior)
> > git status should have been fast
> >
> > What happened instead? (Actual behavior)
> > git status takes almost 5s to complete.
>
> Thanks for the report. This isn't a whole lot of information to go on.
> At least, I'm not able to reproduce locally with a trivial repository:
>
>     git init
>     echo foo > file
>     git add file
>     git commit -mtest
>     git status
>
> If you're able to reproduce, can you re-run `git status` with tracing
> enabled and provide your output?
>
>     GIT_TRACE=1 GIT_TRACE_SETUP=1 GIT_TRACE_PERFORMANCE=1 git status
>
> If you can provide reproduction instructions that start with `git init`,
> that would also help. It may take some time for you, but it'll take less
> time than folks on this list taking shots in the dark :-)
>
> --
> Sean Allred



-- 
You can visit my Github Profile to get to know what I work on outside
of my day job

^ permalink raw reply

* Re: What's cooking in git.git (Feb 2024, #04; Thu, 8)
From: Philippe Blain @ 2024-02-10 18:49 UTC (permalink / raw)
  To: Junio C Hamano, git, mi.al.lohmann
In-Reply-To: <xmqqzfw9h7oy.fsf@gitster.g>

Hi Junio,

Le 2024-02-09 à 12:24, Junio C Hamano a écrit :
> * ml/log-merge-with-cherry-pick-and-other-pseudo-heads (2024-02-08) 2 commits
>  - revision: implement `git log --merge` also for rebase/cherry_pick/revert
>  - revision: ensure MERGE_HEAD is a ref in prepare_show_merge
> 
>  "git log --merge" learned to pay attention to CHERRY_PICK_HEAD and
>  other kinds of *_HEAD pseudorefs.
> 
>  Will merge to 'next'?
>  source: <20240117081405.14012-1-mi.al.lohmann@gmail.com>
>  source: <dfb582cf-b1e4-414d-bfe1-0f93d910ec54@kdbg.org>

I think this is a very nice addition, I've been meaning to do a similar
patch for quite some time.

I think the commit message of 2/2 should be improved, which was pointed out a few
times in the thread. I'll try to send a v4 with a more useful message, summarizing 
the discussion, so maybe hold off on merging to next.

Cheers,
Philippe.

^ permalink raw reply

* Re: GitGui tool - new local clone is missing commit(s) and missing a tag on master branch
From: Mark Levedahl @ 2024-02-10 19:10 UTC (permalink / raw)
  To: Allan Ford, git@vger.kernel.org
In-Reply-To: <MEYPR01MB6534B74E07CB2231EAE8D5C7A5452@MEYPR01MB6534.ausprd01.prod.outlook.com>

On 2/7/24 01:00, Allan Ford wrote:
> Dear Git devs,
> 
> GitGui tool local clone is missing commit(s) and missing a tag on master branch
>   
> As compared to using Visual Studio 2022 or Visual Studio Code ..
> Wondering if a bug somehow / somewhere ?
> Other colleague devs observe the same ..
> 
> If I switch to the remote master branch then I get right content ..   but I should be able to do a new clone of master and hold locally.

This is reminiscent of cloning issues some folks on my team raised 
nearly a decade ago. git-gui uses a custom/unique do_clone function 
written in tcl, rather than native git-clone, so problem diagnosis is 
difficult and updates infrequent. My "cure" was to make git-gui use 
git-clone. I still have that patch, have rebased it (some conflicts) 
onto current git-gui master, and it still works in my very limited testing.

But, git-gui currently has no active maintainer, and Junio is now in a 
release cycle, so the list's concern is not on new topics like this. For 
both reasons, I'll hold onto the patch until the release cycle completes.

Mark

^ permalink raw reply

* Re: git status became very slow after upgrading git
From: Sean Allred @ 2024-02-10 19:06 UTC (permalink / raw)
  To: Vijay Raghavan Aravamudhan; +Cc: Sean Allred, git
In-Reply-To: <CAK7MZG29+Cy-7SJnWayro_5GGEe3iZLysQqVaATLz8GLtEtA5A@mail.gmail.com>


Vijay Raghavan Aravamudhan <avijayr@gmail.com> writes:

> Thanks for responding. I have run the command that you gave on an open
> source repo so that its easy for you to replicate. The remote url is:
> https://github.com/vraravam/ferdium-app
>
> The output is:
>
>         [[ I took the liberty of cleaning this up; ]]
>         [[ let's hope formatting is preserved now. ]]
>
> ferdium-app.git:develop$ GIT_TRACE=1 GIT_TRACE_SETUP=1 GIT_TRACE_PERFORMANCE=1 git status
> 00:08:15.548976 trace.c:314             setup: git_dir: .git
> 00:08:15.550590 trace.c:315             setup: git_common_dir: .git
> 00:08:15.550600 trace.c:316             setup: worktree: /Users/vijay/dev/oss/ferdium
> 00:08:15.550604 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
> 00:08:15.550611 trace.c:318             setup: prefix: (null)
> 00:08:15.550707 chdir-notify.c:70       setup: chdir from '/Users/vijay/dev/oss/ferdium' to '/Users/vijay/dev/oss/ferdium'
> 00:08:15.550723 git.c:463               trace: built-in: git status
> 00:08:15.552184 read-cache.c:2386       performance: 0.000183000 s: read cache .git/index
> 00:08:15.555964 read-cache.c:1629       performance: 0.003696000 s: refresh index
> 00:08:15.556442 diff-lib.c:273          performance: 0.000132000 s:  diff-files
> 00:08:15.558558 unpack-trees.c:2004     performance: 0.000019000 s: traverse_trees
> 00:08:15.558801 unpack-trees.c:438      performance: 0.000003000 s: check_updates
> 00:08:15.558813 unpack-trees.c:2096     performance: 0.000394000 s: unpack_trees
> 00:08:15.558819 diff-lib.c:638          performance: 0.000524000 s:  diff-index
> 00:08:15.559166 name-hash.c:613         performance: 0.000148000 s: initialize name hash
> On branch develop
> Your branch is up to date with 'origin/develop'.
>
> 00:08:15.567249 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --cached --for-status --summary-limit -1 HEAD
> 00:08:15.833334 git.c:749               trace: exec: git-submodule summary --cached --for-status --summary-limit -1 HEAD
> 00:08:15.834114 run-command.c:657       trace: run_command: git-submodule summary --cached --for-status --summary-limit -1 HEAD
> 00:08:16.880778 trace.c:414             performance: 0.000013000 s: git command: git --exec-path
> 00:08:18.216639 git.c:463               trace: built-in: git rev-parse --git-dir
> 00:08:18.218740 trace.c:414             performance: 0.002132000 s: git command: git rev-parse --git-dir
> 00:08:18.489025 git.c:463               trace: built-in: git rev-parse --git-path objects
> 00:08:18.490677 trace.c:414             performance: 0.001675000 s: git command: git rev-parse --git-path objects
> 00:08:19.031080 git.c:463               trace: built-in: git rev-parse --show-prefix
> 00:08:19.032882 trace.c:414             performance: 0.001827000 s: git command: git rev-parse --show-prefix
> 00:08:19.296074 git.c:463               trace: built-in: git rev-parse --show-toplevel
> 00:08:19.297559 trace.c:414             performance: 0.001504000 s: git command: git rev-parse --show-toplevel
> 00:08:19.830285 trace.c:314             setup: git_dir: .git
> 00:08:19.830972 trace.c:315             setup: git_common_dir: .git
> 00:08:19.830981 trace.c:316             setup: worktree: /Users/vijay/dev/oss/ferdium
> 00:08:19.830984 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
> 00:08:19.830990 trace.c:318             setup: prefix: (null)
> 00:08:19.830994 git.c:463               trace: built-in: git submodule--helper summary --cached --for-status -n -1 -- HEAD
> 00:08:19.834629 read-cache.c:2386       performance: 0.000164000 s: read cache .git/index
> 00:08:19.834914 unpack-trees.c:2004     performance: 0.000024000 s: traverse_trees
> 00:08:19.834932 unpack-trees.c:438      performance: 0.000003000 s: check_updates
> 00:08:19.834940 unpack-trees.c:2096     performance: 0.000157000 s: unpack_trees
> 00:08:19.834958 diff-lib.c:638          performance: 0.000307000 s:  diff-index
> 00:08:19.834975 trace.c:414             performance: 0.005922000 s: git command: git submodule--helper summary --cached --for-status -n -1 -- HEAD
> 00:08:19.836137 trace.c:414             performance: 4.003693000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --cached --for-status --summary-limit -1 HEAD
> 00:08:19.836842 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --files --for-status --summary-limit -1
> 00:08:20.106802 git.c:749               trace: exec: git-submodule summary --files --for-status --summary-limit -1
> 00:08:20.107638 run-command.c:657       trace: run_command: git-submodule summary --files --for-status --summary-limit -1
> 00:08:21.162243 trace.c:414             performance: 0.000006000 s: git command: git --exec-path
> 00:08:22.496146 git.c:463               trace: built-in: git rev-parse --git-dir
> 00:08:22.497722 trace.c:414             performance: 0.001589000 s: git command: git rev-parse --git-dir
> 00:08:22.764795 git.c:463               trace: built-in: git rev-parse --git-path objects
> 00:08:22.766763 trace.c:414             performance: 0.001991000 s: git command: git rev-parse --git-path objects
> 00:08:23.304626 git.c:463               trace: built-in: git rev-parse --show-prefix
> 00:08:23.306436 trace.c:414             performance: 0.001833000 s: git command: git rev-parse --show-prefix
> 00:08:23.575506 git.c:463               trace: built-in: git rev-parse --show-toplevel
> 00:08:23.577138 trace.c:414             performance: 0.001656000 s: git command: git rev-parse --show-toplevel
> 00:08:24.111335 trace.c:314             setup: git_dir: .git
> 00:08:24.112123 trace.c:315             setup: git_common_dir: .git
> 00:08:24.112138 trace.c:316             setup: worktree: /Users/vijay/dev/oss/ferdium
> 00:08:24.112142 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
> 00:08:24.112149 trace.c:318             setup: prefix: (null)
> 00:08:24.112154 git.c:463               trace: built-in: git submodule--helper summary --files --for-status -n -1 --
> 00:08:24.113679 read-cache.c:2386       performance: 0.000216000 s: read cache .git/index
> 00:08:24.117811 diff-lib.c:273          performance: 0.004115000 s:  diff-files
> 00:08:24.117838 trace.c:414             performance: 0.007389000 s: git command: git submodule--helper summary --files --for-status -n -1 --
> 00:08:24.118895 trace.c:414             performance: 4.013083000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --files --for-status --summary-limit -1
> nothing to commit, working tree clean
> 00:08:24.119646 trace.c:414             performance: 8.571954000 s: git command: git status
>
> Hope this helps. Also, I noticed that the same repo, same versions of
> all tools, etc - this issue only occurs on my M2 mac, but works
> without any slowness on the intel mac.

Thanks, that info does help. It at least narrows it down to these two
subprocesses:

    git submodule--helper summary --cached --for-status -n -1 -- HEAD
    git submodule--helper summary --files --for-status -n -1 --

Unfortunately, I'm still not able to reproduce on my M2 (even with that
config set globally), so I wonder if there's something else at play.
I've probably reached the end of my usefulness (since the problem does
appear to be specific to submodules and cmd_submodule__helper seems to
be lacking documentation), but you might consider replying with your
output of

    git config --list --show-scope

after stripping any private information, of course.

I'll provide my info down below in the hopes that it's useful for
comparison by someone who knows more about this subsystem. It's worth
noting that I'm running the same submodule--helper command and it's
completing in a reasonable timeframe for me.

Configuration:

    ferdium-app.git:develop$ git --no-pager config --list --show-scope
    system	credential.helper=osxkeychain
    system	filter.lfs.clean=git-lfs clean -- %f
    system	filter.lfs.smudge=git-lfs smudge -- %f
    system	filter.lfs.process=git-lfs filter-process
    system	filter.lfs.required=true
    global	user.signingkey=/Users/sallred/.ssh/id_ed25519.pub
    global	pull.rebase=true
    global	push.default=current
    global	core.editor=mg
    global	core.excludesfile=/Users/sallred/.gitignore
    global	core.fsmonitor=true
    global	core.whitespace=trailing-space
    global	init.defaultbranch=main
    global	remote.pushdefault=origin
    global	branch.autosetupmerge=true
    global	rerere.enabled=true
    global	gpg.format=ssh
    global	maintenance.repo=/Users/sallred/a
    global	maintenance.repo=/Users/sallred/b
    global	maintenance.repo=/Users/sallred/c
    global	maintenance.repo=/Users/sallred/d
    global	commit.gpgsign=true
    global	diff.wserrorhighlight=old,new
    global	gpg.ssh.allowedsignersfile=/Users/sallred/.ssh/allowed_signers
    global	remote.origin.fetch=+refs/notes/*:refs/notes/*
    global	status.submodulesummary=true
    local	core.repositoryformatversion=0
    local	core.filemode=true
    local	core.bare=false
    local	core.logallrefupdates=true
    local	core.ignorecase=true
    local	core.precomposeunicode=true
    local	remote.origin.url=git@github.com:vraravam/ferdium-app
    local	remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
    local	branch.develop.remote=origin
    local	branch.develop.merge=refs/heads/develop

Performance data:

    ferdium-app.git:develop$ GIT_TRACE=1 GIT_TRACE_SETUP=1 GIT_TRACE_PERFORMANCE=1 git status
    13:29:32.879597 trace.c:314             setup: git_dir: .git
    13:29:32.880020 trace.c:315             setup: git_common_dir: .git
    13:29:32.880026 trace.c:316             setup: worktree: /Users/sallred/tmp/ferdium-app
    13:29:32.880029 trace.c:317             setup: cwd: /Users/sallred/tmp/ferdium-app
    13:29:32.880033 trace.c:318             setup: prefix: (null)
    13:29:32.880071 chdir-notify.c:70       setup: chdir from '/Users/sallred/tmp/ferdium-app' to '/Users/sallred/tmp/ferdium-app'
    13:29:32.880078 git.c:463               trace: built-in: git status
    13:29:32.880606 read-cache.c:2386       performance: 0.000118000 s:  read cache .git/index
    13:29:32.904888 read-cache.c:1629       performance: 0.000082000 s:  refresh index
    13:29:32.905983 diff-lib.c:273          performance: 0.000287000 s:  diff-files
    13:29:32.907393 unpack-trees.c:2004     performance: 0.000014000 s:    traverse_trees
    13:29:32.907403 unpack-trees.c:438      performance: 0.000002000 s:    check_updates
    13:29:32.907407 unpack-trees.c:2096     performance: 0.000109000 s:   unpack_trees
    13:29:32.907410 diff-lib.c:638          performance: 0.000163000 s:  diff-index
    13:29:32.907681 name-hash.c:613         performance: 0.000107000 s:  initialize name hash
    13:29:32.922245 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --cached --for-status --summary-limit -1 HEAD
    On branch develop
    Your branch is up to date with 'origin/develop'.

    13:29:32.928117 git.c:749               trace: exec: git-submodule summary --cached --for-status --summary-limit -1 HEAD
    13:29:32.928715 run-command.c:657       trace: run_command: git-submodule summary --cached --for-status --summary-limit -1 HEAD
    13:29:32.941067 trace.c:414             performance: 0.000002000 s: git command: git --exec-path
    13:29:32.961582 git.c:463               trace: built-in: git rev-parse --git-dir
    13:29:32.962376 trace.c:414             performance: 0.000802000 s: git command: git rev-parse --git-dir
    13:29:32.966772 git.c:463               trace: built-in: git rev-parse --git-path objects
    13:29:32.967437 trace.c:414             performance: 0.000673000 s: git command: git rev-parse --git-path objects
    13:29:32.976243 git.c:463               trace: built-in: git rev-parse --show-prefix
    13:29:32.976902 trace.c:414             performance: 0.000667000 s: git command: git rev-parse --show-prefix
    13:29:32.981157 git.c:463               trace: built-in: git rev-parse --show-toplevel
    13:29:32.981835 trace.c:414             performance: 0.000690000 s: git command: git rev-parse --show-toplevel
    13:29:32.989790 trace.c:314             setup: git_dir: .git
    13:29:32.990234 trace.c:315             setup: git_common_dir: .git
    13:29:32.990238 trace.c:316             setup: worktree: /Users/sallred/tmp/ferdium-app
    13:29:32.990242 trace.c:317             setup: cwd: /Users/sallred/tmp/ferdium-app
    13:29:32.990245 trace.c:318             setup: prefix: (null)
    13:29:32.990246 git.c:463               trace: built-in: git submodule--helper summary --cached --for-status -n -1 -- HEAD
    13:29:32.991301 read-cache.c:2386       performance: 0.000062000 s:  read cache .git/index
    13:29:33.002570 unpack-trees.c:2004     performance: 0.000009000 s:    traverse_trees
    13:29:33.002577 unpack-trees.c:438      performance: 0.000001000 s:    check_updates
    13:29:33.002580 unpack-trees.c:2096     performance: 0.000074000 s:   unpack_trees
    13:29:33.002585 diff-lib.c:638          performance: 0.000117000 s:  diff-index
    13:29:33.002591 trace.c:414             performance: 0.013037000 s: git command: git submodule--helper summary --cached --for-status -n -1 -- HEAD
    13:29:33.003099 trace.c:414             performance: 0.075293000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --cached --for-status --summary-limit -1 HEAD
    13:29:33.003446 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --files --for-status --summary-limit -1
    13:29:33.007530 git.c:749               trace: exec: git-submodule summary --files --for-status --summary-limit -1
    13:29:33.007926 run-command.c:657       trace: run_command: git-submodule summary --files --for-status --summary-limit -1
    13:29:33.017316 trace.c:414             performance: 0.000002000 s: git command: git --exec-path
    13:29:33.036544 git.c:463               trace: built-in: git rev-parse --git-dir
    13:29:33.037494 trace.c:414             performance: 0.000959000 s: git command: git rev-parse --git-dir
    13:29:33.041936 git.c:463               trace: built-in: git rev-parse --git-path objects
    13:29:33.042731 trace.c:414             performance: 0.000803000 s: git command: git rev-parse --git-path objects
    13:29:33.051651 git.c:463               trace: built-in: git rev-parse --show-prefix
    13:29:33.052320 trace.c:414             performance: 0.000678000 s: git command: git rev-parse --show-prefix
    13:29:33.056260 git.c:463               trace: built-in: git rev-parse --show-toplevel
    13:29:33.057043 trace.c:414             performance: 0.000793000 s: git command: git rev-parse --show-toplevel
    13:29:33.064488 trace.c:314             setup: git_dir: .git
    13:29:33.064860 trace.c:315             setup: git_common_dir: .git
    13:29:33.064862 trace.c:316             setup: worktree: /Users/sallred/tmp/ferdium-app
    13:29:33.064863 trace.c:317             setup: cwd: /Users/sallred/tmp/ferdium-app
    13:29:33.064866 trace.c:318             setup: prefix: (null)
    13:29:33.064867 git.c:463               trace: built-in: git submodule--helper summary --files --for-status -n -1 --
    13:29:33.065421 read-cache.c:2386       performance: 0.000085000 s:  read cache .git/index
    13:29:33.079310 diff-lib.c:273          performance: 0.000026000 s:  diff-files
    13:29:33.079330 trace.c:414             performance: 0.015094000 s: git command: git submodule--helper summary --files --for-status -n -1 --
    13:29:33.079947 trace.c:414             performance: 0.072649000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --files --for-status --summary-limit -1
    13:29:33.080290 trace.c:414             performance: 0.201218000 s: git command: git status
    nothing to commit, working tree clean

--
Sean Allred

^ permalink raw reply

* git gc changes ownerships of files linux
From: K_V @ 2024-02-10 19:52 UTC (permalink / raw)
  To: git

Hi team git

Running 'git -C /srv/mssioncontrol/.git gc' on linux from a user which
has access to another users files will occasionally change the
ownership of the file 'packed-refs'. I believe git actually overwrites
the file with a new one at the end af the gc command. But details
about this is not writen in the help text. Could it be a bug?

Use case: I'm using ansible to cleanup .git directories across
multible servers and this issue is starting to cause problems.

My solution is to make a variable containing the user and group id
before running gc command and then reapply it afterwards:
current_owner_uid_gid=$(stat -c "%u:%g" /srv/mssioncontrol/.git)
git -C /srv/mssioncontrol/.git gc
chown -R $current_owner_uid_gid "/srv/mssioncontrol/.git"

Details:
Debian GNU/Linux 12 (bookworm)
git version 2.39.2

Best:
zinen

^ permalink raw reply

* Re: git status became very slow after upgrading git
From: Vijay Raghavan Aravamudhan @ 2024-02-10 19:57 UTC (permalink / raw)
  To: Sean Allred; +Cc: git
In-Reply-To: <m0o7co8688.fsf@epic96565.epic.com>

Thanks for the quick response!
Here's the data requested:
system credential.helper=osxkeychain
global includeif.gitdir/i:~/.path=~/.gitconfig-oss.inc
global advice.detachedhead=true
global alias.dangling=fsck --no-reflog
global alias.ec=config --global -e
global alias.f=!git ls-files | grep -i
global alias.sci=!sh -c ' if $(git st | grep -q "have diverged"); then
echo "Diverged branches: aborting"; exit 1; elif ! $(git st | grep -q
"to unstage"); then echo "Nothing to commit: aborting"; else if $(git
st | grep -q "is ahead of"); then echo "Amending existing commit"; git
amq; else echo "Creating new commit"; echo $0; git ci "$0"; fi fi'
global alias.what=show -s --pretty='tformat:%h (%s, %ad)' --date=short
global alias.who=shortlog -s --
global alias.whois=log -i -1 --pretty=format:'%an <%ae>' --author
global alias.standup=log --since 1.week.ago --author
global alias.lg=log --color --graph
--pretty=format:'%C(yellow)%h%Creset -%C(bold blue)%d%Creset %s
%C(green) %an, %cr%Creset' --abbrev-commit
global alias.lga=log --color --graph --all
--pretty=format:'%C(yellow)%h%Creset -%C(bold blue)%d%Creset %s
%C(green) %an, %cr%Creset' --abbrev-commit
global alias.ll=log --decorate --graph --oneline --abbrev-commit
global alias.mn=merge --no-commit
global alias.cn=cherry-pick --no-commit
global alias.cr=cherry-pick
global alias.ci=commit -m
global alias.co=checkout
global alias.cl=clone
global alias.st=!git status --ahead-behind && git submodule summary
global alias.sts=status -sb
global alias.b=branch
global alias.d=diff
global alias.dc=diff --staged
global alias.undo=reset --soft HEAD^
global alias.wipe=!git add -A && git commit -qm 'WIPE SAVEPOINT if
needed later, can be resurrected using reflog' && git reset HEAD~1
--hard
global alias.amend=commit --amend --date=now
global alias.amq=amend --no-edit --quiet
global alias.unstage=restore --staged
global alias.large=!git ls-tree -r -t -l --full-name HEAD | sort -n -k
4 | tail -n 10
global alias.untrack=rm -rf --cached --
global alias.grep=grep -Ii
global alias.patch=!git --no-pager diff --no-color
global alias.track=rev-parse --abbrev-ref --symbolic-full-name @{u}
global alias.fo=!git fetch --all --tags && git dlb
global alias.repo=!basename `git remote get-url origin`
global alias.br=branch --show-current
global alias.upreb=!git branch -u origin/`git br` && git fo && ( git
remote | grep upstream 2>&1 >/dev/null ) && git rebase upstream/`git
br` --no-verify && git fetch upstream --tags && git push --no-verify
&& git push --tags --no-verify && git siu && git dlb
global alias.rpo=remote prune origin
global alias.in=log --reverse ..@{u} --stat --no-merges
global alias.inp=log -p --reverse ..@{u} --no-merges
global alias.inc=!git diff ..@{u}
global alias.new=!sh -c 'git log $1@{1}..$1@{0} $@'
global alias.ghpg-trim=!r() { days=${1:-19}; echo "Will clean beyond
$days days" && git checkout gh-pages && echo "Size before: $(du -sh
*reports)" && DIRECTORIES=$(find *-reports -mindepth 1 -maxdepth 1
-type d); for dir in ${DIRECTORIES}; do SHA_FROM_DIR="$(basename
$dir)"; COMMIT_DATE_IN_MILLIS=$(git show -s --format=%ct $SHA_FROM_DIR
2> /dev/null || echo 5000000000); COMMIT_DATE_IN_DAYS=$(echo
"$COMMIT_DATE_IN_MILLIS / (1000 * 60 * 60 * 24)" | bc -l); ((
${COMMIT_DATE_IN_DAYS%.*} > ${days%.*} )) && git rm -rf $dir; done;
git commit -m "Deleting reports older than $days days" && echo $(git
rev-parse HEAD) > .git/info/grafts && git config
advice.graftFileDeprecated false && FILTER_BRANCH_SQUELCH_WARNING=1
git filter-branch -f -- --all; rm -f .git/info/grafts; echo "Size
after: $(du -sh *reports)" done;}; r
global alias.out=log --reverse @{u}..
global alias.outp=log -p --reverse @{u}..
global alias.g=grep --break --heading --line-number
global alias.sf=submodule foreach
global alias.rfc=reflog expire --expire=now
global alias.cc=!echo "Size before: $(du -sh .git | cut -f1)"; git
remote prune origin; git repack; git prune-packed; git reflog expire
--all --expire=1.week.ago; git maintenance run --task=gc; echo "Size
after: $(du -sh .git | cut -f1)";
global alias.big=!git rev-list --objects --all | grep "$(git
verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -100 |
awk '{print $1}')"
global alias.dlb=!git branch -vv | GREP_OPTIONS= grep ': gone]' | awk
'{print $1}' | xargs -I {} git branch -D {}
global alias.old=!sh -c '[[ "`git log $0/$1 --since 10.days -1 | wc
-l`" -eq 0 ]] && echo "Will need to delete $0/$1"'
global alias.recentb=!r() { refbranch=$1 count=$2; git for-each-ref
--sort=-committerdate refs/remotes
--format='%(refname:short)|%(HEAD)%(color:yellow)%(refname:short)|%(color:bold
green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'
--color=always --count=${count:-20} | while read line; do
branch=$(echo "$line" | awk 'BEGIN { FS = "|" }; { print $1 }' | tr -d
'*'); ahead=$(git rev-list --count
"${refbranch:-origin/master}..${branch}"); behind=$(git rev-list
--count "${branch}..${refbranch:-origin/master}"); colorline=$(echo
"$line" | sed 's/^[^|]*|//'); echo "$ahead|$behind|$colorline" | awk
-F'|' -vOFS='|' '{$5=substr($5,1,70)}1' ; done | ( echo
"ahead|behind||branch|lastcommit|message|author\n" && cat) | column
-ts'|';}; r
global alias.oldestb=!r() { refbranch=$1 count=$2; git for-each-ref
--sort=committerdate refs/remotes
--format='%(refname:short)|%(HEAD)%(color:yellow)%(refname:short)|%(color:bold
green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'
--color=always --count=${count:-20} | while read line; do
branch=$(echo "$line" | awk 'BEGIN { FS = "|" }; { print $1 }' | tr -d
'*'); ahead=$(git rev-list --count
"${refbranch:-origin/master}..${branch}"); behind=$(git rev-list
--count "${branch}..${refbranch:-origin/master}"); colorline=$(echo
"$line" | sed 's/^[^|]*|//'); echo "$ahead|$behind|$colorline" | awk
-F'|' -vOFS='|' '{$5=substr($5,1,70)}1' ; done | ( echo
"ahead|behind||branch|lastcommit|message|author\n" && cat) | column
-ts'|';}; r
global alias.lc=!git branch -r --sort=-committerdate
--format="%(color:magenta)%(committerdate:relative)%(color:reset)
%(color:bold cyan)%(refname:short)%(color:reset) %(contents:subject)
%(color:bold blue) <%(authorname)> %(color:reset)"
global alias.lc2=!git branch -r --sort=-committerdate | egrep -v
'HEAD|master|main' | while read b; do git log --since 4.days --color
--format="%ci _%C(magenta)%cr %C(bold cyan)$b%Creset %s %C(bold
blue)<%an>%Creset" $b | head -n 1; done | sort -r | cut -d_ -f2-
global alias.se=!git rev-list --all | xargs git grep -F
global alias.siu=!git submodule update --init --recursive --remote
--rebase --force
global alias.pushsub=sf git push
global alias.pullsub=sf git pull
global alias.dcolor=diff --color-words
global branch.autosetupmerge=true
global branch.autosetuprebase=always
global branch.sort=committerdate
global checkout.defaultremote=origin
global checkout.workers=0
global color.diff.meta=yellow
global color.diff.frag=magenta bold
global color.diff.func=146 bold
global color.diff.commit=yellow bold
global color.diff.old=red bold
global color.diff.new=green bold
global color.diff.whitespace=red reverse
global core.pager=diff-so-fancy | less --tabs=2 -RFX
global core.editor=codium --wait
global core.autocrlf=input
global core.excludesfile=~/.gitignore_global
global core.commentchar=*
global core.whitespace=fix
global diff.compactionheuristic=true
global diff.renames=true
global diff.renamelimit=1000
global diff.colormoved=default
global diff.submodule=diff
global diff-so-fancy.markemptylines=false
global fetch.prune=true
global fetch.prunetags=true
global fetch.parallel=0
global fetch.showforcedupdates=true
global filter.lfs.required=true
global filter.lfs.clean=git-lfs clean -- %f
global filter.lfs.smudge=git-lfs smudge -- %f
global filter.lfs.process=git-lfs filter-process
global gc.auto=2000
global gc.pruneexpire=now
global gc.worktreepruneexpire=1.weeks.ago
global gc.reflogexpire=2.weeks.ago
global gc.reflogexpireunreachable=2.weeks.ago
global gc.rerereresolved=1.weeks.ago
global grep.column=true
global grep.extendedregexp=true
global grep.linenumber=true
global grep.fullname=true
global gui.pruneduringfetch=true
global gui.matchtrackingbranch=true
global gui.warndetachedcommit=true
global gui.tabsize=2
global help.autocorrect=1
global interactive.difffilter=diff-so-fancy --patch
global merge.defaulttoupstream=true
global merge.ff=only
global merge.renamelimit=15000
global merge.autostash=true
global pack.threads=0
global pack.writereverseindex=true
global pager.diff=diff-so-fancy | less --tabs=2 -RFX
global pull.rebase=true
global pull.autostash=true
global push.default=upstream
global push.followtags=true
global push.recursesubmodules=check
global rebase.autosquash=true
global rebase.autostash=true
global rebase.missingcommitscheck=error
global rebase.abbreviatecommands=true
global rerere.enabled=true
global rerere.autoupdate=true
global stash.untracked=true
global stash.showincludeuntracked=true
global stash.showpatch=true
global status.showstash=true
global submodule.fetchjobs=0
global tag.sort=version:refname
global transfer.fsckobjects=false
global http.postbuffer=786432000
global user.useconfigonly=true
global add.interactive.usebuiltin=false
global init.defaultbranch=master
local core.repositoryformatversion=0
local core.filemode=true
local core.bare=false
local core.logallrefupdates=true
local core.ignorecase=true
local core.precomposeunicode=true
local core.hookspath=.husky
local remote.origin.url=git@github.com:vraravam/ferdium-app
local remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
local branch.develop.remote=origin
local branch.develop.rebase=true
local branch.develop.merge=refs/heads/develop
local remote.upstream.url=git@github.com:ferdium/ferdium-app
local remote.upstream.fetch=+refs/heads/*:refs/remotes/upstream/*
local submodule.recipes.active=true
local submodule.recipes.url=https://github.com/ferdium/ferdium-recipes.git
local branch.nightly.remote=origin
local branch.nightly.rebase=true
local branch.nightly.merge=refs/heads/nightly
local branch.release.remote=origin
local branch.release.rebase=true
local branch.release.merge=refs/heads/release
local gui.wmstate=normal
local gui.geometry=1381x921+5+48 201 203

On Sun, Feb 11, 2024 at 1:03 AM Sean Allred <allred.sean@gmail.com> wrote:
>
>
> Vijay Raghavan Aravamudhan <avijayr@gmail.com> writes:
>
> > Thanks for responding. I have run the command that you gave on an open
> > source repo so that its easy for you to replicate. The remote url is:
> > https://github.com/vraravam/ferdium-app
> >
> > The output is:
> >
> >         [[ I took the liberty of cleaning this up; ]]
> >         [[ let's hope formatting is preserved now. ]]
> >
> > ferdium-app.git:develop$ GIT_TRACE=1 GIT_TRACE_SETUP=1 GIT_TRACE_PERFORMANCE=1 git status
> > 00:08:15.548976 trace.c:314             setup: git_dir: .git
> > 00:08:15.550590 trace.c:315             setup: git_common_dir: .git
> > 00:08:15.550600 trace.c:316             setup: worktree: /Users/vijay/dev/oss/ferdium
> > 00:08:15.550604 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
> > 00:08:15.550611 trace.c:318             setup: prefix: (null)
> > 00:08:15.550707 chdir-notify.c:70       setup: chdir from '/Users/vijay/dev/oss/ferdium' to '/Users/vijay/dev/oss/ferdium'
> > 00:08:15.550723 git.c:463               trace: built-in: git status
> > 00:08:15.552184 read-cache.c:2386       performance: 0.000183000 s: read cache .git/index
> > 00:08:15.555964 read-cache.c:1629       performance: 0.003696000 s: refresh index
> > 00:08:15.556442 diff-lib.c:273          performance: 0.000132000 s:  diff-files
> > 00:08:15.558558 unpack-trees.c:2004     performance: 0.000019000 s: traverse_trees
> > 00:08:15.558801 unpack-trees.c:438      performance: 0.000003000 s: check_updates
> > 00:08:15.558813 unpack-trees.c:2096     performance: 0.000394000 s: unpack_trees
> > 00:08:15.558819 diff-lib.c:638          performance: 0.000524000 s:  diff-index
> > 00:08:15.559166 name-hash.c:613         performance: 0.000148000 s: initialize name hash
> > On branch develop
> > Your branch is up to date with 'origin/develop'.
> >
> > 00:08:15.567249 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --cached --for-status --summary-limit -1 HEAD
> > 00:08:15.833334 git.c:749               trace: exec: git-submodule summary --cached --for-status --summary-limit -1 HEAD
> > 00:08:15.834114 run-command.c:657       trace: run_command: git-submodule summary --cached --for-status --summary-limit -1 HEAD
> > 00:08:16.880778 trace.c:414             performance: 0.000013000 s: git command: git --exec-path
> > 00:08:18.216639 git.c:463               trace: built-in: git rev-parse --git-dir
> > 00:08:18.218740 trace.c:414             performance: 0.002132000 s: git command: git rev-parse --git-dir
> > 00:08:18.489025 git.c:463               trace: built-in: git rev-parse --git-path objects
> > 00:08:18.490677 trace.c:414             performance: 0.001675000 s: git command: git rev-parse --git-path objects
> > 00:08:19.031080 git.c:463               trace: built-in: git rev-parse --show-prefix
> > 00:08:19.032882 trace.c:414             performance: 0.001827000 s: git command: git rev-parse --show-prefix
> > 00:08:19.296074 git.c:463               trace: built-in: git rev-parse --show-toplevel
> > 00:08:19.297559 trace.c:414             performance: 0.001504000 s: git command: git rev-parse --show-toplevel
> > 00:08:19.830285 trace.c:314             setup: git_dir: .git
> > 00:08:19.830972 trace.c:315             setup: git_common_dir: .git
> > 00:08:19.830981 trace.c:316             setup: worktree: /Users/vijay/dev/oss/ferdium
> > 00:08:19.830984 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
> > 00:08:19.830990 trace.c:318             setup: prefix: (null)
> > 00:08:19.830994 git.c:463               trace: built-in: git submodule--helper summary --cached --for-status -n -1 -- HEAD
> > 00:08:19.834629 read-cache.c:2386       performance: 0.000164000 s: read cache .git/index
> > 00:08:19.834914 unpack-trees.c:2004     performance: 0.000024000 s: traverse_trees
> > 00:08:19.834932 unpack-trees.c:438      performance: 0.000003000 s: check_updates
> > 00:08:19.834940 unpack-trees.c:2096     performance: 0.000157000 s: unpack_trees
> > 00:08:19.834958 diff-lib.c:638          performance: 0.000307000 s:  diff-index
> > 00:08:19.834975 trace.c:414             performance: 0.005922000 s: git command: git submodule--helper summary --cached --for-status -n -1 -- HEAD
> > 00:08:19.836137 trace.c:414             performance: 4.003693000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --cached --for-status --summary-limit -1 HEAD
> > 00:08:19.836842 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --files --for-status --summary-limit -1
> > 00:08:20.106802 git.c:749               trace: exec: git-submodule summary --files --for-status --summary-limit -1
> > 00:08:20.107638 run-command.c:657       trace: run_command: git-submodule summary --files --for-status --summary-limit -1
> > 00:08:21.162243 trace.c:414             performance: 0.000006000 s: git command: git --exec-path
> > 00:08:22.496146 git.c:463               trace: built-in: git rev-parse --git-dir
> > 00:08:22.497722 trace.c:414             performance: 0.001589000 s: git command: git rev-parse --git-dir
> > 00:08:22.764795 git.c:463               trace: built-in: git rev-parse --git-path objects
> > 00:08:22.766763 trace.c:414             performance: 0.001991000 s: git command: git rev-parse --git-path objects
> > 00:08:23.304626 git.c:463               trace: built-in: git rev-parse --show-prefix
> > 00:08:23.306436 trace.c:414             performance: 0.001833000 s: git command: git rev-parse --show-prefix
> > 00:08:23.575506 git.c:463               trace: built-in: git rev-parse --show-toplevel
> > 00:08:23.577138 trace.c:414             performance: 0.001656000 s: git command: git rev-parse --show-toplevel
> > 00:08:24.111335 trace.c:314             setup: git_dir: .git
> > 00:08:24.112123 trace.c:315             setup: git_common_dir: .git
> > 00:08:24.112138 trace.c:316             setup: worktree: /Users/vijay/dev/oss/ferdium
> > 00:08:24.112142 trace.c:317             setup: cwd: /Users/vijay/dev/oss/ferdium
> > 00:08:24.112149 trace.c:318             setup: prefix: (null)
> > 00:08:24.112154 git.c:463               trace: built-in: git submodule--helper summary --files --for-status -n -1 --
> > 00:08:24.113679 read-cache.c:2386       performance: 0.000216000 s: read cache .git/index
> > 00:08:24.117811 diff-lib.c:273          performance: 0.004115000 s:  diff-files
> > 00:08:24.117838 trace.c:414             performance: 0.007389000 s: git command: git submodule--helper summary --files --for-status -n -1 --
> > 00:08:24.118895 trace.c:414             performance: 4.013083000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --files --for-status --summary-limit -1
> > nothing to commit, working tree clean
> > 00:08:24.119646 trace.c:414             performance: 8.571954000 s: git command: git status
> >
> > Hope this helps. Also, I noticed that the same repo, same versions of
> > all tools, etc - this issue only occurs on my M2 mac, but works
> > without any slowness on the intel mac.
>
> Thanks, that info does help. It at least narrows it down to these two
> subprocesses:
>
>     git submodule--helper summary --cached --for-status -n -1 -- HEAD
>     git submodule--helper summary --files --for-status -n -1 --
>
> Unfortunately, I'm still not able to reproduce on my M2 (even with that
> config set globally), so I wonder if there's something else at play.
> I've probably reached the end of my usefulness (since the problem does
> appear to be specific to submodules and cmd_submodule__helper seems to
> be lacking documentation), but you might consider replying with your
> output of
>
>     git config --list --show-scope
>
> after stripping any private information, of course.
>
> I'll provide my info down below in the hopes that it's useful for
> comparison by someone who knows more about this subsystem. It's worth
> noting that I'm running the same submodule--helper command and it's
> completing in a reasonable timeframe for me.
>
> Configuration:
>
>     ferdium-app.git:develop$ git --no-pager config --list --show-scope
>     system      credential.helper=osxkeychain
>     system      filter.lfs.clean=git-lfs clean -- %f
>     system      filter.lfs.smudge=git-lfs smudge -- %f
>     system      filter.lfs.process=git-lfs filter-process
>     system      filter.lfs.required=true
>     global      user.signingkey=/Users/sallred/.ssh/id_ed25519.pub
>     global      pull.rebase=true
>     global      push.default=current
>     global      core.editor=mg
>     global      core.excludesfile=/Users/sallred/.gitignore
>     global      core.fsmonitor=true
>     global      core.whitespace=trailing-space
>     global      init.defaultbranch=main
>     global      remote.pushdefault=origin
>     global      branch.autosetupmerge=true
>     global      rerere.enabled=true
>     global      gpg.format=ssh
>     global      maintenance.repo=/Users/sallred/a
>     global      maintenance.repo=/Users/sallred/b
>     global      maintenance.repo=/Users/sallred/c
>     global      maintenance.repo=/Users/sallred/d
>     global      commit.gpgsign=true
>     global      diff.wserrorhighlight=old,new
>     global      gpg.ssh.allowedsignersfile=/Users/sallred/.ssh/allowed_signers
>     global      remote.origin.fetch=+refs/notes/*:refs/notes/*
>     global      status.submodulesummary=true
>     local       core.repositoryformatversion=0
>     local       core.filemode=true
>     local       core.bare=false
>     local       core.logallrefupdates=true
>     local       core.ignorecase=true
>     local       core.precomposeunicode=true
>     local       remote.origin.url=git@github.com:vraravam/ferdium-app
>     local       remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
>     local       branch.develop.remote=origin
>     local       branch.develop.merge=refs/heads/develop
>
> Performance data:
>
>     ferdium-app.git:develop$ GIT_TRACE=1 GIT_TRACE_SETUP=1 GIT_TRACE_PERFORMANCE=1 git status
>     13:29:32.879597 trace.c:314             setup: git_dir: .git
>     13:29:32.880020 trace.c:315             setup: git_common_dir: .git
>     13:29:32.880026 trace.c:316             setup: worktree: /Users/sallred/tmp/ferdium-app
>     13:29:32.880029 trace.c:317             setup: cwd: /Users/sallred/tmp/ferdium-app
>     13:29:32.880033 trace.c:318             setup: prefix: (null)
>     13:29:32.880071 chdir-notify.c:70       setup: chdir from '/Users/sallred/tmp/ferdium-app' to '/Users/sallred/tmp/ferdium-app'
>     13:29:32.880078 git.c:463               trace: built-in: git status
>     13:29:32.880606 read-cache.c:2386       performance: 0.000118000 s:  read cache .git/index
>     13:29:32.904888 read-cache.c:1629       performance: 0.000082000 s:  refresh index
>     13:29:32.905983 diff-lib.c:273          performance: 0.000287000 s:  diff-files
>     13:29:32.907393 unpack-trees.c:2004     performance: 0.000014000 s:    traverse_trees
>     13:29:32.907403 unpack-trees.c:438      performance: 0.000002000 s:    check_updates
>     13:29:32.907407 unpack-trees.c:2096     performance: 0.000109000 s:   unpack_trees
>     13:29:32.907410 diff-lib.c:638          performance: 0.000163000 s:  diff-index
>     13:29:32.907681 name-hash.c:613         performance: 0.000107000 s:  initialize name hash
>     13:29:32.922245 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --cached --for-status --summary-limit -1 HEAD
>     On branch develop
>     Your branch is up to date with 'origin/develop'.
>
>     13:29:32.928117 git.c:749               trace: exec: git-submodule summary --cached --for-status --summary-limit -1 HEAD
>     13:29:32.928715 run-command.c:657       trace: run_command: git-submodule summary --cached --for-status --summary-limit -1 HEAD
>     13:29:32.941067 trace.c:414             performance: 0.000002000 s: git command: git --exec-path
>     13:29:32.961582 git.c:463               trace: built-in: git rev-parse --git-dir
>     13:29:32.962376 trace.c:414             performance: 0.000802000 s: git command: git rev-parse --git-dir
>     13:29:32.966772 git.c:463               trace: built-in: git rev-parse --git-path objects
>     13:29:32.967437 trace.c:414             performance: 0.000673000 s: git command: git rev-parse --git-path objects
>     13:29:32.976243 git.c:463               trace: built-in: git rev-parse --show-prefix
>     13:29:32.976902 trace.c:414             performance: 0.000667000 s: git command: git rev-parse --show-prefix
>     13:29:32.981157 git.c:463               trace: built-in: git rev-parse --show-toplevel
>     13:29:32.981835 trace.c:414             performance: 0.000690000 s: git command: git rev-parse --show-toplevel
>     13:29:32.989790 trace.c:314             setup: git_dir: .git
>     13:29:32.990234 trace.c:315             setup: git_common_dir: .git
>     13:29:32.990238 trace.c:316             setup: worktree: /Users/sallred/tmp/ferdium-app
>     13:29:32.990242 trace.c:317             setup: cwd: /Users/sallred/tmp/ferdium-app
>     13:29:32.990245 trace.c:318             setup: prefix: (null)
>     13:29:32.990246 git.c:463               trace: built-in: git submodule--helper summary --cached --for-status -n -1 -- HEAD
>     13:29:32.991301 read-cache.c:2386       performance: 0.000062000 s:  read cache .git/index
>     13:29:33.002570 unpack-trees.c:2004     performance: 0.000009000 s:    traverse_trees
>     13:29:33.002577 unpack-trees.c:438      performance: 0.000001000 s:    check_updates
>     13:29:33.002580 unpack-trees.c:2096     performance: 0.000074000 s:   unpack_trees
>     13:29:33.002585 diff-lib.c:638          performance: 0.000117000 s:  diff-index
>     13:29:33.002591 trace.c:414             performance: 0.013037000 s: git command: git submodule--helper summary --cached --for-status -n -1 -- HEAD
>     13:29:33.003099 trace.c:414             performance: 0.075293000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --cached --for-status --summary-limit -1 HEAD
>     13:29:33.003446 run-command.c:657       trace: run_command: GIT_INDEX_FILE=.git/index git submodule summary --files --for-status --summary-limit -1
>     13:29:33.007530 git.c:749               trace: exec: git-submodule summary --files --for-status --summary-limit -1
>     13:29:33.007926 run-command.c:657       trace: run_command: git-submodule summary --files --for-status --summary-limit -1
>     13:29:33.017316 trace.c:414             performance: 0.000002000 s: git command: git --exec-path
>     13:29:33.036544 git.c:463               trace: built-in: git rev-parse --git-dir
>     13:29:33.037494 trace.c:414             performance: 0.000959000 s: git command: git rev-parse --git-dir
>     13:29:33.041936 git.c:463               trace: built-in: git rev-parse --git-path objects
>     13:29:33.042731 trace.c:414             performance: 0.000803000 s: git command: git rev-parse --git-path objects
>     13:29:33.051651 git.c:463               trace: built-in: git rev-parse --show-prefix
>     13:29:33.052320 trace.c:414             performance: 0.000678000 s: git command: git rev-parse --show-prefix
>     13:29:33.056260 git.c:463               trace: built-in: git rev-parse --show-toplevel
>     13:29:33.057043 trace.c:414             performance: 0.000793000 s: git command: git rev-parse --show-toplevel
>     13:29:33.064488 trace.c:314             setup: git_dir: .git
>     13:29:33.064860 trace.c:315             setup: git_common_dir: .git
>     13:29:33.064862 trace.c:316             setup: worktree: /Users/sallred/tmp/ferdium-app
>     13:29:33.064863 trace.c:317             setup: cwd: /Users/sallred/tmp/ferdium-app
>     13:29:33.064866 trace.c:318             setup: prefix: (null)
>     13:29:33.064867 git.c:463               trace: built-in: git submodule--helper summary --files --for-status -n -1 --
>     13:29:33.065421 read-cache.c:2386       performance: 0.000085000 s:  read cache .git/index
>     13:29:33.079310 diff-lib.c:273          performance: 0.000026000 s:  diff-files
>     13:29:33.079330 trace.c:414             performance: 0.015094000 s: git command: git submodule--helper summary --files --for-status -n -1 --
>     13:29:33.079947 trace.c:414             performance: 0.072649000 s: git command: /opt/homebrew/opt/git/libexec/git-core/git submodule summary --files --for-status --summary-limit -1
>     13:29:33.080290 trace.c:414             performance: 0.201218000 s: git command: git status
>     nothing to commit, working tree clean
>
> --
> Sean Allred



-- 
You can visit my Github Profile to get to know what I work on outside
of my day job

^ permalink raw reply

* Re: [PATCH 1/1] imap-send: include strbuf.h
From: Christian Hesse @ 2024-02-10 20:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Philippe Blain, Git Mailing List, Christian Hesse
In-Reply-To: <xmqqeddlckqa.fsf@gitster.g>

[-- Attachment #1: Type: text/plain, Size: 968 bytes --]

Junio C Hamano <gitster@pobox.com> on Fri, 2024/02/09 14:54:
> Junio C Hamano <gitster@pobox.com> writes:
> 
> > Christian Hesse <list@eworm.de> writes:
> >  
> >> From: Christian Hesse <mail@eworm.de>
> >>
> >> We had this fixed in 3307f7dde2ae8f5281d0782f7291a073c9b1cdc2,
> >> and it broke again in eea0e59ffbed6e33d171ace5be13cde9faa41639.  
> >
> > Thanks, already reported and fixed, I believe?  
> 
> Oops, missing link:
> 
> https://lore.kernel.org/git/pull.1664.git.git.1706833113569.gitgitgadget@gmail.com/

Sorry, missed that... Probably because the breakage went into 2.43.1, but the
upstream fix did not. So sorry for the noise.

Anyway... does it make sense to move the include into the condition?
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Best regards             my address:    */=0;b=c[a++];)
putchar(b-1/(/*    Chris            cc -ox -xc - && ./x    */b/42*2-3)*42);}

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* RE: [BUG] git 2.44.0-rc0 t0080.1 Breaks on NonStop x86 and ia64
From: rsbecker @ 2024-02-10 23:22 UTC (permalink / raw)
  To: rsbecker, git
In-Reply-To: <000401da5c4c$fd4ad260$f7e07720$@nexbridge.com>

On Saturday, February 10, 2024 1:14 PM, I wrote:
>I encountered a new problem on git 2.44.0-rc0 for test t0080.1. Run very
verbose
>(--verbose -x):
>
>++ cat
>++ /home/randall/git/t/unit-tests/bin/t-basic
>++ test_cmp expect actual
>++ test 2 -ne 2
>++ eval 'diff -u' '"$@"'
>+++ diff -u expect actual
>--- expect      2024-02-10 18:04:28 +0000
>+++ actual      2024-02-10 18:04:28 +0000
>@@ -1,43 +1,43 @@
> ok 1 - passing test
> ok 2 - passing test and assertion return 1 -# check "1 == 2" failed at
t/unit-tests/t-
>basic.c:76
>+# check "1 == 2" failed at /home/randall/git/t/unit-tests/t-basic.c:76
> #    left: 1
> #   right: 2
> not ok 3 - failing test
> ok 4 - failing test and assertion return 0  not ok 5 - passing TEST_TODO()
# TODO
>ok 6 - passing TEST_TODO() returns 1 -# todo check 'check(x)' succeeded at
t/unit-
>tests/t-basic.c:25
>+# todo check 'check(x)' succeeded at
>/home/randall/git/t/unit-tests/t-basic.c:25
> not ok 7 - failing TEST_TODO()
> ok 8 - failing TEST_TODO() returns 0
>-# check "0" failed at t/unit-tests/t-basic.c:30
>+# check "0" failed at /home/randall/git/t/unit-tests/t-basic.c:30
> # skipping test - missing prerequisite
>-# skipping check '1' at t/unit-tests/t-basic.c:32
>+# skipping check '1' at /home/randall/git/t/unit-tests/t-basic.c:32
> ok 9 - test_skip() # SKIP
> ok 10 - skipped test returns 1
> # skipping test - missing prerequisite
> ok 11 - test_skip() inside TEST_TODO() # SKIP  ok 12 - test_skip() inside
>TEST_TODO() returns 1 -# check "0" failed at t/unit-tests/t-basic.c:48
>+# check "0" failed at /home/randall/git/t/unit-tests/t-basic.c:48
> not ok 13 - TEST_TODO() after failing check  ok 14 - TEST_TODO() after
failing check
>returns 0 -# check "0" failed at t/unit-tests/t-basic.c:56
>+# check "0" failed at /home/randall/git/t/unit-tests/t-basic.c:56
> not ok 15 - failing check after TEST_TODO()  ok 16 - failing check after
TEST_TODO()
>returns 0 -# check "!strcmp("\thello\\", "there\"\n")" failed at
>t/unit-tests/t-basic.c:61
>+# check "!strcmp("\thello\\", "there\"\n")" failed at
>/home/randall/git/t/unit-tests/t-basic.c:61
> #    left: "\011hello\\"
> #   right: "there\"\012"
>-# check "!strcmp("NULL", NULL)" failed at t/unit-tests/t-basic.c:62
>+# check "!strcmp("NULL", NULL)" failed at
>/home/randall/git/t/unit-tests/t-basic.c:62
> #    left: "NULL"
> #   right: NULL
>-# check "'a' == '\n'" failed at t/unit-tests/t-basic.c:63
>+# check "'a' == '\n'" failed at
>+/home/randall/git/t/unit-tests/t-basic.c:63
> #    left: 'a'
> #   right: '\012'
>-# check "'\\' == '\''" failed at t/unit-tests/t-basic.c:64
>+# check "'\\' == '\''" failed at
>/home/randall/git/t/unit-tests/t-basic.c:64
> #    left: '\\'
> #   right: '\''
> not ok 17 - messages from failing string and char comparison -# BUG: test
has no
>checks at t/unit-tests/t-basic.c:91
>+# BUG: test has no checks at
>+/home/randall/git/t/unit-tests/t-basic.c:91
> not ok 18 - test with no checks
> ok 19 - test with no checks returns 0
> 1..19
>error: last command exited with $?=1
>
>The diff appears to have failed because of an assumption of how paths are
resolved
>during compilation. The assumption is that files remain partially
qualified, which is
>not the case in all C compilers. This is c99. My experience with gcc is
that it qualifies
>names differently than other compilers. It might be useful to pipe to sed
to strip
>${HOME}/ when building the actual file, something like:
>
>sed -i "1,\$s/${HOME}\//g" actual    # Not that that will actually work
>because sed will process /. A different delimiter would work.
>
>Randall

Putting the sed command in, as follows:

diff --git a/t/t0080-unit-test-output.sh b/t/t0080-unit-test-output.sh
index 6657c114a3..eaf25f2ddc 100755
--- a/t/t0080-unit-test-output.sh
+++ b/t/t0080-unit-test-output.sh
@@ -52,7 +52,7 @@ test_expect_success 'TAP output from unit tests' '
        1..19
        EOF

-       ! "$GIT_BUILD_DIR"/t/unit-tests/bin/t-basic >actual &&
+       ! "$GIT_BUILD_DIR"/t/unit-tests/bin/t-basic | sed "s?/.*/t/?t/?"
>actual &&
        test_cmp expect actual
 '

still results in a problem. The ! in the above line is being interpreted
incorrectly:

diff expect actual
27c27
< # check "!strcmp("\thello\\", "there"\n")" failed at
t/unit-tests/t-basic.c:61
---
> # check "!strcmp("\thello\\", "there\"\n")" failed at
t/unit-tests/t-basic.c:61
29c29
< #   right: "there"\012"
---
> #   right: "there\"\012"

I am not convinced the test is working properly. The ! appears to be causing
/bin/ksh to be invoked instead of bash. If I remove !, the test works
correctly. Did we not have issues with using ! in the past?

--Randall

--
Brief whoami: NonStop&UNIX developer since approximately
UNIX(421664400)
NonStop(211288444200000000)
-- In real life, I talk too much.




^ permalink raw reply related

* [PATCH v4 1/2] revision: ensure MERGE_HEAD is a ref in prepare_show_merge
From: Philippe Blain @ 2024-02-10 23:35 UTC (permalink / raw)
  To: git
  Cc: Johannes Sixt, Elijah Newren, Michael Lohmann, Phillip Wood,
	Patrick Steinhardt, Michael Lohmann, Junio C Hamano
In-Reply-To: <20240210-ml-log-merge-with-cherry-pick-and-other-pseudo-heads-v4-0-3bc9e62808f4@gmail.com>

From: Michael Lohmann <mi.al.lohmann@gmail.com>

This is done to
(1) ensure MERGE_HEAD is a ref,
(2) obtain the oid without any prefixing by refs.c:repo_dwim_ref()
(3) error out when MERGE_HEAD is a symref.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Lohmann <mi.al.lohmann@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/revision.c b/revision.c
index 2424c9bd67..aa4c4dc778 100644
--- a/revision.c
+++ b/revision.c
@@ -1973,8 +1973,12 @@ static void prepare_show_merge(struct rev_info *revs)
 	if (repo_get_oid(the_repository, "HEAD", &oid))
 		die("--merge without HEAD?");
 	head = lookup_commit_or_die(&oid, "HEAD");
-	if (repo_get_oid(the_repository, "MERGE_HEAD", &oid))
+	if (read_ref_full("MERGE_HEAD",
+			RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+			&oid, NULL))
 		die("--merge without MERGE_HEAD?");
+	if (is_null_oid(&oid))
+		die("MERGE_HEAD is a symbolic ref???");
 	other = lookup_commit_or_die(&oid, "MERGE_HEAD");
 	add_pending_object(revs, &head->object, "HEAD");
 	add_pending_object(revs, &other->object, "MERGE_HEAD");

-- 
2.39.1


^ permalink raw reply related

* [PATCH v4 0/2] Implement `git log --merge` also for rebase/cherry-pick/revert
From: Philippe Blain @ 2024-02-10 23:35 UTC (permalink / raw)
  To: git
  Cc: Johannes Sixt, Elijah Newren, Michael Lohmann, Phillip Wood,
	Patrick Steinhardt, Michael Lohmann, Junio C Hamano,
	Philippe Blain
In-Reply-To: <20240117081405.14012-1-mi.al.lohmann@gmail.com>

Changes in v4:
- Added a commit message for 2/2 detailing the use case and summarizing the discussion in the thread
- Adjusted the documentation of the option

Link to v3: https://lore.kernel.org/r/20240117081405.14012-1-mi.al.lohmann@gmail.com

Range-diff vs v3:

1:  37405be1a3 = 1:  37405be1a3 revision: ensure MERGE_HEAD is a ref in prepare_show_merge
2:  de080a628c ! 2:  6ac1608809 revision: implement `git log --merge` also for rebase/cherry_pick/revert
    @@ Metadata
     Author: Michael Lohmann <mi.al.lohmann@gmail.com>

      ## Commit message ##
    -    revision: implement `git log --merge` also for rebase/cherry_pick/revert
    +    revision: implement `git log --merge` also for rebase/cherry-pick/revert

    +    'git log' learned in ae3e5e1ef2 (git log -p --merge [[--] paths...],
    +    2006-07-03) to show commits touching conflicted files in the range
    +    HEAD...MERGE_HEAD, an addition documented in d249b45547 (Document
    +    rev-list's option --merge, 2006-08-04).
    +
    +    It can be useful to look at the commit history to understand what lead
    +    to merge conflicts also for other mergy operations besides merges, like
    +    cherry-pick, revert and rebase.
    +
    +    For rebases, an interesting range to look at is HEAD...REBASE_HEAD,
    +    since the conflicts are usually caused by how the code changed
    +    differently on HEAD since REBASE_HEAD forked from it.
    +
    +    For cherry-picks and revert, it is less clear that
    +    HEAD...CHERRY_PICK_HEAD and HEAD...REVERT_HEAD are indeed interesting
    +    ranges, since these commands are about applying or unapplying a single
    +    (or a few, for cherry-pick) commit(s) on top of HEAD. However, conflicts
    +    encountered during these operations can indeed be caused by changes
    +    introduced in preceding commits on both sides of the history.
    +
    +    Adjust the code in prepare_show_merge so it constructs the range
    +    HEAD...$OTHER for each of OTHER={MERGE_HEAD, CHERRY_PICK_HEAD,
    +    REVERT_HEAD or REBASE_HEAD}. Note that we try these pseudorefs in order,
    +    so keep REBASE_HEAD last since the three other operations can be
    +    performed during a rebase. Note also that in the uncommon case where
    +    $OTHER and HEAD do not share a common ancestor, this will show the
    +    complete histories of both sides since their root commits, which is the
    +    same behaviour as currently happens in that case for HEAD and
    +    MERGE_HEAD.
    +
    +    Adjust the documentation of this option accordingly.
    +
    +    Co-authored-by: Philippe Blain <levraiphilippeblain@gmail.com>
         Co-authored-by: Johannes Sixt <j6t@kdbg.org>
    +    Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
         Signed-off-by: Michael Lohmann <mi.al.lohmann@gmail.com>
         [jc: tweaked in j6t's precedence fix that tries REBASE_HEAD last]
         Signed-off-by: Junio C Hamano <gitster@pobox.com>

    + ## Documentation/gitk.txt ##
    +@@ Documentation/gitk.txt: linkgit:git-rev-list[1] for a complete list.
    +
    + --merge::
    +
    +-	After an attempt to merge stops with conflicts, show the commits on
    +-	the history between two branches (i.e. the HEAD and the MERGE_HEAD)
    +-	that modify the conflicted files and do not exist on all the heads
    +-	being merged.
    ++	Show commits touching conflicted paths in the range `HEAD...$OTHER`,
    ++	where `$OTHER` is the first existing pseudoref in `MERGE_HEAD`,
    ++	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
    ++	when the index has unmerged entries.
    +
    + --left-right::
    +
    +
    + ## Documentation/rev-list-options.txt ##
    +@@ Documentation/rev-list-options.txt: See also linkgit:git-reflog[1].
    + Under `--pretty=reference`, this information will not be shown at all.
    +
    + --merge::
    +-	After a failed merge, show refs that touch files having a
    +-	conflict and don't exist on all heads to merge.
    ++	Show commits touching conflicted paths in the range `HEAD...$OTHER`,
    ++	where `$OTHER` is the first existing pseudoref in `MERGE_HEAD`,
    ++	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
    ++	when the index has unmerged entries.
    +
    + --boundary::
    + 	Output excluded boundary commits. Boundary commits are
    +
      ## revision.c ##
     @@ revision.c: static void add_pending_commit_list(struct rev_info *revs,
      	}

---
Michael Lohmann (2):
      revision: ensure MERGE_HEAD is a ref in prepare_show_merge
      revision: implement `git log --merge` also for rebase/cherry-pick/revert

 Documentation/gitk.txt             |  8 ++++----
 Documentation/rev-list-options.txt |  6 ++++--
 revision.c                         | 27 +++++++++++++++++++++++----
 3 files changed, 31 insertions(+), 10 deletions(-)
---
base-commit: 186b115d3062e6230ee296d1ddaa0c4b72a464b5
change-id: 20240210-ml-log-merge-with-cherry-pick-and-other-pseudo-heads-05bd8e8797db


^ permalink raw reply

* [PATCH v4 2/2] revision: implement `git log --merge` also for rebase/cherry-pick/revert
From: Philippe Blain @ 2024-02-10 23:35 UTC (permalink / raw)
  To: git
  Cc: Johannes Sixt, Elijah Newren, Michael Lohmann, Phillip Wood,
	Patrick Steinhardt, Michael Lohmann, Junio C Hamano,
	Philippe Blain
In-Reply-To: <20240210-ml-log-merge-with-cherry-pick-and-other-pseudo-heads-v4-0-3bc9e62808f4@gmail.com>

From: Michael Lohmann <mi.al.lohmann@gmail.com>

'git log' learned in ae3e5e1ef2 (git log -p --merge [[--] paths...],
2006-07-03) to show commits touching conflicted files in the range
HEAD...MERGE_HEAD, an addition documented in d249b45547 (Document
rev-list's option --merge, 2006-08-04).

It can be useful to look at the commit history to understand what lead
to merge conflicts also for other mergy operations besides merges, like
cherry-pick, revert and rebase.

For rebases, an interesting range to look at is HEAD...REBASE_HEAD,
since the conflicts are usually caused by how the code changed
differently on HEAD since REBASE_HEAD forked from it.

For cherry-picks and revert, it is less clear that
HEAD...CHERRY_PICK_HEAD and HEAD...REVERT_HEAD are indeed interesting
ranges, since these commands are about applying or unapplying a single
(or a few, for cherry-pick) commit(s) on top of HEAD. However, conflicts
encountered during these operations can indeed be caused by changes
introduced in preceding commits on both sides of the history.

Adjust the code in prepare_show_merge so it constructs the range
HEAD...$OTHER for each of OTHER={MERGE_HEAD, CHERRY_PICK_HEAD,
REVERT_HEAD or REBASE_HEAD}. Note that we try these pseudorefs in order,
so keep REBASE_HEAD last since the three other operations can be
performed during a rebase. Note also that in the uncommon case where
$OTHER and HEAD do not share a common ancestor, this will show the
complete histories of both sides since their root commits, which is the
same behaviour as currently happens in that case for HEAD and
MERGE_HEAD.

Adjust the documentation of this option accordingly.

Co-authored-by: Philippe Blain <levraiphilippeblain@gmail.com>
Co-authored-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Michael Lohmann <mi.al.lohmann@gmail.com>
[jc: tweaked in j6t's precedence fix that tries REBASE_HEAD last]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/gitk.txt             |  8 ++++----
 Documentation/rev-list-options.txt |  6 ++++--
 revision.c                         | 31 +++++++++++++++++++++++--------
 3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index c2213bb77b..80ff4e149a 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -63,10 +63,10 @@ linkgit:git-rev-list[1] for a complete list.
 
 --merge::
 
-	After an attempt to merge stops with conflicts, show the commits on
-	the history between two branches (i.e. the HEAD and the MERGE_HEAD)
-	that modify the conflicted files and do not exist on all the heads
-	being merged.
+	Show commits touching conflicted paths in the range `HEAD...$OTHER`,
+	where `$OTHER` is the first existing pseudoref in `MERGE_HEAD`,
+	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
+	when the index has unmerged entries.
 
 --left-right::
 
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 2bf239ff03..5b4672c346 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -341,8 +341,10 @@ See also linkgit:git-reflog[1].
 Under `--pretty=reference`, this information will not be shown at all.
 
 --merge::
-	After a failed merge, show refs that touch files having a
-	conflict and don't exist on all heads to merge.
+	Show commits touching conflicted paths in the range `HEAD...$OTHER`,
+	where `$OTHER` is the first existing pseudoref in `MERGE_HEAD`,
+	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
+	when the index has unmerged entries.
 
 --boundary::
 	Output excluded boundary commits. Boundary commits are
diff --git a/revision.c b/revision.c
index aa4c4dc778..36dc2f94f7 100644
--- a/revision.c
+++ b/revision.c
@@ -1961,11 +1961,31 @@ static void add_pending_commit_list(struct rev_info *revs,
 	}
 }
 
+static const char *lookup_other_head(struct object_id *oid)
+{
+	int i;
+	static const char *const other_head[] = {
+		"MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "REBASE_HEAD"
+	};
+
+	for (i = 0; i < ARRAY_SIZE(other_head); i++)
+		if (!read_ref_full(other_head[i],
+				RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+				oid, NULL)) {
+			if (is_null_oid(oid))
+				die("%s is a symbolic ref???", other_head[i]);
+			return other_head[i];
+		}
+
+	die("--merge without MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD or REBASE_HEAD?");
+}
+
 static void prepare_show_merge(struct rev_info *revs)
 {
 	struct commit_list *bases;
 	struct commit *head, *other;
 	struct object_id oid;
+	const char *other_name;
 	const char **prune = NULL;
 	int i, prune_num = 1; /* counting terminating NULL */
 	struct index_state *istate = revs->repo->index;
@@ -1973,15 +1993,10 @@ static void prepare_show_merge(struct rev_info *revs)
 	if (repo_get_oid(the_repository, "HEAD", &oid))
 		die("--merge without HEAD?");
 	head = lookup_commit_or_die(&oid, "HEAD");
-	if (read_ref_full("MERGE_HEAD",
-			RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
-			&oid, NULL))
-		die("--merge without MERGE_HEAD?");
-	if (is_null_oid(&oid))
-		die("MERGE_HEAD is a symbolic ref???");
-	other = lookup_commit_or_die(&oid, "MERGE_HEAD");
+	other_name = lookup_other_head(&oid);
+	other = lookup_commit_or_die(&oid, other_name);
 	add_pending_object(revs, &head->object, "HEAD");
-	add_pending_object(revs, &other->object, "MERGE_HEAD");
+	add_pending_object(revs, &other->object, other_name);
 	bases = repo_get_merge_bases(the_repository, head, other);
 	add_rev_cmdline_list(revs, bases, REV_CMD_MERGE_BASE, UNINTERESTING | BOTTOM);
 	add_pending_commit_list(revs, bases, UNINTERESTING | BOTTOM);

-- 
2.39.1


^ permalink raw reply related

* Re: [BUG] git 2.44.0-rc0 t0080.1 Breaks on NonStop x86 and ia64
From: Junio C Hamano @ 2024-02-11  2:05 UTC (permalink / raw)
  To: rsbecker; +Cc: git
In-Reply-To: <000401da5c4c$fd4ad260$f7e07720$@nexbridge.com>

<rsbecker@nexbridge.com> writes:

> The diff appears to have failed because of an assumption of how paths are
> resolved during compilation. The assumption is that files remain partially
> qualified, which is not the case in all C compilers. This is c99. My
> experience with gcc is that it qualifies names differently than other
> compilers.

I just found this bit of gem in t/unit-tests/test-lib.c.  I guess
Visual C falls into the same category as yours, while GCC and Clang
are from different camps?

The easiest way forward may be to build on top of it, perhaps like
so, to generalize the make_relative() to cover your case, too?

 t/unit-tests/test-lib.c | 63 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 15 deletions(-)

diff --git c/t/unit-tests/test-lib.c w/t/unit-tests/test-lib.c
index 7bf9dfdb95..69dbe1bbc7 100644
--- c/t/unit-tests/test-lib.c
+++ w/t/unit-tests/test-lib.c
@@ -21,45 +21,78 @@ static struct {
 	.result = RESULT_NONE,
 };
 
-#ifndef _MSC_VER
-#define make_relative(location) location
-#else
+#include "dir.h"
 /*
  * Visual C interpolates the absolute Windows path for `__FILE__`,
  * but we want to see relative paths, as verified by t0080.
+ * There are other compilers that do the same, and are not for
+ * Windows.
  */
-#include "dir.h"
-
 static const char *make_relative(const char *location)
 {
 	static char prefix[] = __FILE__, buf[PATH_MAX], *p;
 	static size_t prefix_len;
+	static int need_bs_to_fs = -1;
 
-	if (!prefix_len) {
+	/* one-time preparation */
+	if (need_bs_to_fs < 0) {
 		size_t len = strlen(prefix);
-		const char *needle = "\\t\\unit-tests\\test-lib.c";
+		char needle[] = "t\\unit-tests\\test-lib.c";
 		size_t needle_len = strlen(needle);
 
-		if (len < needle_len || strcmp(needle, prefix + len - needle_len))
+		if (len < needle_len)
+			die("unexpected prefix '%s'", prefix);
+
+		/*
+		 * The path could be relative (t/unit-tests/test-lib.c)
+		 * or full (/home/user/git/t/unit-tests/test-lib.c).
+		 * Check the slash between "t" and "unit-tests".
+		 */
+		prefix_len = len - needle_len;
+		if (prefix[prefix_len + 1] == '/') {
+			/* Oh, we're not Windows */
+			for (size_t i = 0; i < needle_len; i++)
+				if (needle[i] == '\\')
+					needle[i] = '/';
+			need_bs_to_fs = 0;
+		} else {
+			need_bs_to_fs = 1;
+		}
+
+		/* 
+		 * prefix_len == 0 if the compiler gives paths relative
+		 * to the root of the working tree.  Otherwise, we want
+		 * to see that we did find the needle[] at a directory
+		 * boundary.
+		 */
+		if (fspathcmp(needle, prefix + prefix_len) ||
+		    (prefix_len &&
+		     prefix[prefix_len - 1] != '/' &&
+		     prefix[prefix_len - 1] != '\\'))
 			die("unexpected suffix of '%s'", prefix);
 
-		/* let it end in a directory separator */
-		prefix_len = len - needle_len + 1;
 	}
 
+	/* 
+	 * If our compiler gives relative paths and we do not need
+	 * to munge directory separator, we can return location as-is.
+	 */
+	if (!prefix_len && !need_bs_to_fs)
+		return location;
+
 	/* Does it not start with the expected prefix? */
 	if (fspathncmp(location, prefix, prefix_len))
 		return location;
 
 	strlcpy(buf, location + prefix_len, sizeof(buf));
 	/* convert backslashes to forward slashes */
-	for (p = buf; *p; p++)
-		if (*p == '\\')
-			*p = '/';
-
+	if (need_bs_to_fs) {
+		for (p = buf; *p; p++)
+			if (*p == '\\')
+				*p = '/';
+	}
 	return buf;
 }
-#endif
 
 static void msg_with_prefix(const char *prefix, const char *format, va_list ap)
 {

^ permalink raw reply related

* Re: [PATCH 1/1] imap-send: include strbuf.h
From: Junio C Hamano @ 2024-02-11  2:42 UTC (permalink / raw)
  To: Christian Hesse; +Cc: Philippe Blain, Git Mailing List, Christian Hesse
In-Reply-To: <20240210210155.71fa163d@leda.eworm.net>

Christian Hesse <list@eworm.de> writes:

>> Oops, missing link:
>> 
>> https://lore.kernel.org/git/pull.1664.git.git.1706833113569.gitgitgadget@gmail.com/
>
> Sorry, missed that... Probably because the breakage went into 2.43.1, but the
> upstream fix did not. So sorry for the noise.

Please don't be.  Duplicated reports are much much better than no
reports due to "well, this must have been reported already by
somebody else".  Thanks for reporting.

> Anyway... does it make sense to move the include into the condition?

I do not think so.  The original breakage was because it implicitly
relied on the fact that http.h, which is included only when
USE_CURL_FOR_IMAP_SEND is defined, happens to include strbuf.h, even
though the code that does not rely on USE_CURL_FOR_IMAP_SEND do
unconditionally rely on the strbuf facility being available to them,
possibly combined with the fact that not too many people build
imap-send with USE_CURL_FOR_IMAP_SEND disabled.

So the conditional thing still rely on an implicit assumption you
are making, i.e. "http.h will forever be including strbuf.h", which
is fragile when people from time to time come and make sweeping
"header clean-up".  Which is a good thing.  But we need to be
careful, and one way to help us being careful against such a header
clean-up is to make sure you include what you use yourself, instead
of assuming that somebody else you include will keep doing so.


^ permalink raw reply

* RE: [BUG] git 2.44.0-rc0 t0080.1 Breaks on NonStop x86 and ia64
From: rsbecker @ 2024-02-11  2:47 UTC (permalink / raw)
  To: 'Junio C Hamano'; +Cc: git
In-Reply-To: <xmqqbk8nbvqy.fsf@gitster.g>

On Saturday, February 10, 2024 9:06 PM, Junio C Hamano wrote:
><rsbecker@nexbridge.com> writes:
>
>> The diff appears to have failed because of an assumption of how paths
>> are resolved during compilation. The assumption is that files remain
>> partially qualified, which is not the case in all C compilers. This is
>> c99. My experience with gcc is that it qualifies names differently
>> than other compilers.
>
>I just found this bit of gem in t/unit-tests/test-lib.c.  I guess Visual C
falls into the
>same category as yours, while GCC and Clang are from different camps?
>
>The easiest way forward may be to build on top of it, perhaps like so, to
generalize
>the make_relative() to cover your case, too?
>
> t/unit-tests/test-lib.c | 63
+++++++++++++++++++++++++++++++++++++---------
>---
> 1 file changed, 48 insertions(+), 15 deletions(-)
>
>diff --git c/t/unit-tests/test-lib.c w/t/unit-tests/test-lib.c index
>7bf9dfdb95..69dbe1bbc7 100644
>--- c/t/unit-tests/test-lib.c
>+++ w/t/unit-tests/test-lib.c
>@@ -21,45 +21,78 @@ static struct {
> 	.result = RESULT_NONE,
> };
>
>-#ifndef _MSC_VER
>-#define make_relative(location) location -#else
>+#include "dir.h"
> /*
>  * Visual C interpolates the absolute Windows path for `__FILE__`,
>  * but we want to see relative paths, as verified by t0080.
>+ * There are other compilers that do the same, and are not for
>+ * Windows.
>  */
>-#include "dir.h"
>-
> static const char *make_relative(const char *location)  {
> 	static char prefix[] = __FILE__, buf[PATH_MAX], *p;
> 	static size_t prefix_len;
>+	static int need_bs_to_fs = -1;
>
>-	if (!prefix_len) {
>+	/* one-time preparation */
>+	if (need_bs_to_fs < 0) {
> 		size_t len = strlen(prefix);
>-		const char *needle = "\\t\\unit-tests\\test-lib.c";
>+		char needle[] = "t\\unit-tests\\test-lib.c";
> 		size_t needle_len = strlen(needle);
>
>-		if (len < needle_len || strcmp(needle, prefix + len -
needle_len))
>+		if (len < needle_len)
>+			die("unexpected prefix '%s'", prefix);
>+
>+		/*
>+		 * The path could be relative (t/unit-tests/test-lib.c)
>+		 * or full (/home/user/git/t/unit-tests/test-lib.c).
>+		 * Check the slash between "t" and "unit-tests".
>+		 */
>+		prefix_len = len - needle_len;
>+		if (prefix[prefix_len + 1] == '/') {
>+			/* Oh, we're not Windows */
>+			for (size_t i = 0; i < needle_len; i++)
>+				if (needle[i] == '\\')
>+					needle[i] = '/';
>+			need_bs_to_fs = 0;
>+		} else {
>+			need_bs_to_fs = 1;
>+		}
>+
>+		/*
>+		 * prefix_len == 0 if the compiler gives paths relative
>+		 * to the root of the working tree.  Otherwise, we want
>+		 * to see that we did find the needle[] at a directory
>+		 * boundary.
>+		 */
>+		if (fspathcmp(needle, prefix + prefix_len) ||
>+		    (prefix_len &&
>+		     prefix[prefix_len - 1] != '/' &&
>+		     prefix[prefix_len - 1] != '\\'))
> 			die("unexpected suffix of '%s'", prefix);
>
>-		/* let it end in a directory separator */
>-		prefix_len = len - needle_len + 1;
> 	}
>
>+	/*
>+	 * If our compiler gives relative paths and we do not need
>+	 * to munge directory separator, we can return location as-is.
>+	 */
>+	if (!prefix_len && !need_bs_to_fs)
>+		return location;
>+
> 	/* Does it not start with the expected prefix? */
> 	if (fspathncmp(location, prefix, prefix_len))
> 		return location;
>
> 	strlcpy(buf, location + prefix_len, sizeof(buf));
> 	/* convert backslashes to forward slashes */
>-	for (p = buf; *p; p++)
>-		if (*p == '\\')
>-			*p = '/';
>-
>+	if (need_bs_to_fs) {
>+		for (p = buf; *p; p++)
>+			if (*p == '\\')
>+				*p = '/';
>+	}
> 	return buf;
> }
>-#endif
>
> static void msg_with_prefix(const char *prefix, const char *format,
va_list ap)  {

This looks like a good plan.

--Randall


^ permalink raw reply

* Re: [PATCH v2 3/8] rebase: update `--empty=ask` to `--empty=drop`
From: Brian Lyles @ 2024-02-11  4:54 UTC (permalink / raw)
  To: git; +Cc: newren, me, phillip.wood123, gitster
In-Reply-To: <20240210074859.552497-4-brianmlyles@gmail.com>

I just noticed that I incorrectly specified `--empty=drop` in the
subject of this commit. It should read "rebase: update `--empty=ask` to
`--empty=stop`". This will need to be corrected in a v3 reroll.

-- 
Thank you,
Brian Lyles

^ permalink raw reply

* Re: [PATCH v4 2/2] revision: implement `git log --merge` also for rebase/cherry-pick/revert
From: Johannes Sixt @ 2024-02-11  8:34 UTC (permalink / raw)
  To: Philippe Blain
  Cc: Elijah Newren, Michael Lohmann, Phillip Wood, Patrick Steinhardt,
	Michael Lohmann, Junio C Hamano, git
In-Reply-To: <20240210-ml-log-merge-with-cherry-pick-and-other-pseudo-heads-v4-2-3bc9e62808f4@gmail.com>

Thank you for stepping in and resubmitting with an extended commit
message and documentation!

Am 11.02.24 um 00:35 schrieb Philippe Blain:
> From: Michael Lohmann <mi.al.lohmann@gmail.com>
> 
> 'git log' learned in ae3e5e1ef2 (git log -p --merge [[--] paths...],
> 2006-07-03) to show commits touching conflicted files in the range
> HEAD...MERGE_HEAD, an addition documented in d249b45547 (Document
> rev-list's option --merge, 2006-08-04).
> 
> It can be useful to look at the commit history to understand what lead
> to merge conflicts also for other mergy operations besides merges, like
> cherry-pick, revert and rebase.
> 
> For rebases, an interesting range to look at is HEAD...REBASE_HEAD,
> since the conflicts are usually caused by how the code changed
> differently on HEAD since REBASE_HEAD forked from it.
> 
> For cherry-picks and revert, it is less clear that
> HEAD...CHERRY_PICK_HEAD and HEAD...REVERT_HEAD are indeed interesting
> ranges, since these commands are about applying or unapplying a single
> (or a few, for cherry-pick) commit(s) on top of HEAD. However, conflicts
> encountered during these operations can indeed be caused by changes
> introduced in preceding commits on both sides of the history.

I very much agree. Thank you for spelling it out!

> Adjust the code in prepare_show_merge so it constructs the range
> HEAD...$OTHER for each of OTHER={MERGE_HEAD, CHERRY_PICK_HEAD,
> REVERT_HEAD or REBASE_HEAD}. Note that we try these pseudorefs in order,
> so keep REBASE_HEAD last since the three other operations can be
> performed during a rebase. Note also that in the uncommon case where
> $OTHER and HEAD do not share a common ancestor, this will show the
> complete histories of both sides since their root commits, which is the
> same behaviour as currently happens in that case for HEAD and
> MERGE_HEAD.

Well explained!

> 
> Adjust the documentation of this option accordingly.
> 
> Co-authored-by: Philippe Blain <levraiphilippeblain@gmail.com>
> Co-authored-by: Johannes Sixt <j6t@kdbg.org>
> Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
> Signed-off-by: Michael Lohmann <mi.al.lohmann@gmail.com>
> [jc: tweaked in j6t's precedence fix that tries REBASE_HEAD last]
> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Signed-off-by trailers should occur in temporal order. Therefore, when
you pick up a commit and resend it, you should keep existing
Signed-off-by and add yours last.

> ---
>  Documentation/gitk.txt             |  8 ++++----
>  Documentation/rev-list-options.txt |  6 ++++--
>  revision.c                         | 31 +++++++++++++++++++++++--------
>  3 files changed, 31 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
> index c2213bb77b..80ff4e149a 100644
> --- a/Documentation/gitk.txt
> +++ b/Documentation/gitk.txt
> @@ -63,10 +63,10 @@ linkgit:git-rev-list[1] for a complete list.
>  
>  --merge::
>  
> -	After an attempt to merge stops with conflicts, show the commits on
> -	the history between two branches (i.e. the HEAD and the MERGE_HEAD)
> -	that modify the conflicted files and do not exist on all the heads
> -	being merged.
> +	Show commits touching conflicted paths in the range `HEAD...$OTHER`,
> +	where `$OTHER` is the first existing pseudoref in `MERGE_HEAD`,
> +	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
> +	when the index has unmerged entries.

Unfortunately, this patch does not help gitk. Gitk has its own logic to
treat --merge and needs its own patch. This hunk should not be part of
this patch.

>  
>  --left-right::
>  
> diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
> index 2bf239ff03..5b4672c346 100644
> --- a/Documentation/rev-list-options.txt
> +++ b/Documentation/rev-list-options.txt
> @@ -341,8 +341,10 @@ See also linkgit:git-reflog[1].
>  Under `--pretty=reference`, this information will not be shown at all.
>  
>  --merge::
> -	After a failed merge, show refs that touch files having a
> -	conflict and don't exist on all heads to merge.
> +	Show commits touching conflicted paths in the range `HEAD...$OTHER`,
> +	where `$OTHER` is the first existing pseudoref in `MERGE_HEAD`,
> +	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
> +	when the index has unmerged entries.

Good. I used --left-right to check that the direction is indeed
HEAD...$OTHER and not $OTHER...HEAD.

-- Hannes


^ permalink raw reply

* [PATCH] unit-tests: do show relative file paths on non-Windows, too
From: Junio C Hamano @ 2024-02-11  8:57 UTC (permalink / raw)
  To: git; +Cc: Phillip Wood, Johannes Schindelin, Randall S. Becker

There are compilers other than Visual C that want to show absolute
paths.  Generalize the helper introduced by a2c5e294 (unit-tests: do
show relative file paths, 2023-09-25) so that it can also work with
a path that uses slash as the directory separator, and becomes
almost no-op once one-time preparation finds out that we are using a
compiler that already gives relative paths.  Incidentally, this also
should do the right thing on Windows with a compiler that shows
relative paths but with backslash as the directory separator (if
such a thing exists and is used to build git).

Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * Another change I made, which is not described in the proposed
   commit log message, is that we now use fspathcmp() instead of
   strcmp() to precompute the prefix length using a known needle[]
   string, to be consistent with the runtime check done for each and
   every path.

   This is a belated follow-up on <f0b804129e8a21449cbb6f346473d3570182ddfa.1695640837.git.gitgitgadget@gmail.com>

 t/unit-tests/test-lib.c | 60 ++++++++++++++++++++++++++++++++---------
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/t/unit-tests/test-lib.c b/t/unit-tests/test-lib.c
index 7bf9dfdb95..83c9eb8c59 100644
--- a/t/unit-tests/test-lib.c
+++ b/t/unit-tests/test-lib.c
@@ -21,12 +21,11 @@ static struct {
 	.result = RESULT_NONE,
 };
 
-#ifndef _MSC_VER
-#define make_relative(location) location
-#else
 /*
  * Visual C interpolates the absolute Windows path for `__FILE__`,
  * but we want to see relative paths, as verified by t0080.
+ * There are other compilers that do the same, and are not for
+ * Windows.
  */
 #include "dir.h"
 
@@ -34,32 +33,67 @@ static const char *make_relative(const char *location)
 {
 	static char prefix[] = __FILE__, buf[PATH_MAX], *p;
 	static size_t prefix_len;
+	static int need_bs_to_fs = -1;
 
-	if (!prefix_len) {
+	/* one-time preparation */
+	if (need_bs_to_fs < 0) {
 		size_t len = strlen(prefix);
-		const char *needle = "\\t\\unit-tests\\test-lib.c";
+		char needle[] = "t\\unit-tests\\test-lib.c";
 		size_t needle_len = strlen(needle);
 
-		if (len < needle_len || strcmp(needle, prefix + len - needle_len))
+		if (len < needle_len)
+			die("unexpected prefix '%s'", prefix);
+
+		/*
+		 * The path could be relative (t/unit-tests/test-lib.c)
+		 * or full (/home/user/git/t/unit-tests/test-lib.c).
+		 * Check the slash between "t" and "unit-tests".
+		 */
+		prefix_len = len - needle_len;
+		if (prefix[prefix_len + 1] == '/') {
+			/* Oh, we're not Windows */
+			for (size_t i = 0; i < needle_len; i++)
+				if (needle[i] == '\\')
+					needle[i] = '/';
+			need_bs_to_fs = 0;
+		} else {
+			need_bs_to_fs = 1;
+		}
+
+		/*
+		 * prefix_len == 0 if the compiler gives paths relative
+		 * to the root of the working tree.  Otherwise, we want
+		 * to see that we did find the needle[] at a directory
+		 * boundary.
+		 */
+		if (fspathcmp(needle, prefix + prefix_len) ||
+		    (prefix_len &&
+		     prefix[prefix_len - 1] != '/' &&
+		     prefix[prefix_len - 1] != '\\'))
 			die("unexpected suffix of '%s'", prefix);
 
-		/* let it end in a directory separator */
-		prefix_len = len - needle_len + 1;
 	}
 
+	/*
+	 * If our compiler gives relative paths and we do not need
+	 * to munge directory separator, we can return location as-is.
+	 */
+	if (!prefix_len && !need_bs_to_fs)
+		return location;
+
 	/* Does it not start with the expected prefix? */
 	if (fspathncmp(location, prefix, prefix_len))
 		return location;
 
 	strlcpy(buf, location + prefix_len, sizeof(buf));
 	/* convert backslashes to forward slashes */
-	for (p = buf; *p; p++)
-		if (*p == '\\')
-			*p = '/';
-
+	if (need_bs_to_fs) {
+		for (p = buf; *p; p++)
+			if (*p == '\\')
+				*p = '/';
+	}
 	return buf;
 }
-#endif
 
 static void msg_with_prefix(const char *prefix, const char *format, va_list ap)
 {
-- 
2.44.0-rc0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox