git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH/RFC 5/5] add tests for checking the behaviour of "unset.variable"

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 3, 2014, 18:25 UTC
Message-ID
<xmqq1tqpm2na.fsf@gitster.dls.corp.google.com>
In-Reply-To
<vpqeguptz5k.fsf@anie.imag.fr>
Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
> Junio C Hamano <gitster@pobox.com> writes:
> ...
>> Off the top of my head, from an end-user's point of view, something
>> like this would give a behaviour that is at least understandable:

Let's make sure we have the same starting point (i.e. understanding of the limitation of the current code) in mind.

The "git config [--add] section.var value" UI, which does not give the user any control over where the new definition goes in the resulting file, and the current implementation, which finds the last existing "section" and adds the "var = value" definition at the end (or adds a "section" at the end and then adds the definition there), are adequate for ordinary variables.

It is fine for single-valued ones that follow "the last one wins" semantics; "git config" would add the new definition at the end and that definition will win.

It is manageable for multi-valued variables, too. For uses of a multi-valued variable to track unordered set of values, by definition the order does not matter.

	Side note.  Otherwise, the scripter needs to read the
	existing ones, --unset-all them, and then add the elements
	of the final list in desired order.  It is cumbersome, but
	for a single multi-valued variable it is manageable.

But the "unset.variable" by nature wants a lot finer-grained control over the order in which other ordinary variables are defined and it itself is placed. No matter what improvements you attempt to make to the implementation, because the UI is not getting enough information from the user to learn where exactly the user wants to add a new variable or "unset.variable", it would not give you enough flexibility to do the job.

Show 6 quoted lines
>>  (1) forbid "git config" command line from touching "unset.var", as
>>      there is no way for a user to control where a new unset.var
>>      goes.  And
>
> Well, the normal use-case for unset.variable is to put it in a local
> config file, to unset a variable set in another, lower-priority file.
I agree that is one major use case.
> This common use-case works with the command-line "git config", and it
> would be a pity to forbid the common use-case because of a particular,
> unusual case.

Either you are being incoherent or I am not reading you right. If you said "If this common use-case worked with the command-line 'git config', it would be nice, but it would be a pity because it does not", I would understand.

If you use the command line 'git config', i.e.
	git config unset.variable xyzzy.frotz

in a repository whose .git/config does not have any unset.variable, you will add that _at the end_, which would undo what you did in your configuration file, not just what came before yours. Even if you ignore more exotic cases, the command line is *not* working.

That is why I said "unset.variable" is unworkable with existing "git config" command line. Always appending at the end is usable for ordinary variables, but for unset.variable, it is most likely the least useful thing to do. You can explain "among 47 different things it could do, we chose to do the most useless thing, because that is _consistent_ with how the ordinary variables are placed in the cofiguration file" in the documentation but it forgets to question if unset.variable should be treated the same way as ordinary variables in the first place.

Another use case would be to override what includes gave us.  I.e.
	[unset]
        	variable = ... nullify some /etc/gitconfig values ...
	[include]
        	path = ~/.gitcommon
	[unset]
		variable = ... nullify some ~/.gitcommon values ...
	[xyzzy]
		frotz = nitfol

Special-casing unset.variable and always adding them at the beginning of the output *might* turn it from totally useless to slightly usable. At least it supports the "nullify previous ones", even though it does not help "nullify after include".

I doubt if such a change to add unset.variable always at the top is worth it, though.

Show 7 quoted lines
>>  (2) When adding or appending section.var (it may also apply to
>>      removing one--you need to think about it deeper), ignore
>>      everything that comes before the last appearance of "unset.var"
>>      that unsets the "section.var" variable.
>
> That would probably be the best option from a user's point of view, but
> I'd say the implementation complexity is not worth the trouble.

test_expect_success declares a particular behaviour as "the right thing to happen" in order to protect that right behaviour from future changes. It is OK for you to illustrate what illogical thing the implementation does as a caveat, and admit that the behaviour comes because we consider the change is not worth the trouble and we punted. But pretending as if that is the right behaviour and the system has to promise that the broken behaviour will be kept forever by casting it in stone is the worst thing you can do, I am afraid.

Unfortunately, as I already said, there is no sensible behaviour to add "unset.variable" from the command line with the current "git config" UI, so it is not even feasible to define "the right thing to happen" and to document it as something other people may want to fix later, e.g.

	test_expect_failure 'natural but not working yet' '
		git config xyzzy.frotz 1
                git config --add xyzzy.frotz 2
                git config --add xyzzy.frotz 3
                : a magic command to add
                :  [unset] variable = xyzzy.frotz 
                : between 2 and 3
		git config xyzzy.frotz >actual
                echo 3 >expect
                test_expect_success expect actual
	'

However, you should be able to arrange in the test to do the following sequence:

    - Define "[xyzzy] frotz 1" in $HOME/.gitconfig (I think $HOME
      defaults to your trash directory).
    - Verify that "git config xyzzy.frotz" gives "1".
    - Define "[unset] variable = xyzzy.frotz" in .git/config (it is
      OK to use "git config unset.variable xyzzy.frotz" here).
    - Verify that "git config xyzzy.frotz" does not find anything.
    - Define "[xyzzy] frotz 2" in .git/config (again, it is OK to
      use "git config xyzzy.frotz 2" here).
    - Verify that "git config xyzzy.frotz" gives "2".

I think we can agree that the above sequence is something we would want to support, regardless of how we will change/fix the underlying config-writer implementation. Which means that something like the above can safely be cast in stone with test_expect_success.

Previous: Matthieu MoyNext: Junio C Hamano
Message 13 of 30 in “add "unset.variable" for unsetting previously set variables”
  1. 0/5 add "unset.variable" for unsetting previously set variablesTanay Abhra, Oct 2, 2014
  2. 1/5 config.c : move configset_iter() to an appropriate positionTanay Abhra, Oct 2, 2014
  3. 2/5 make git_config_with_options() to use a configsetTanay Abhra, Oct 2, 2014
  4. 3/5 add "unset.variable" for unsetting previously set variablesTanay Abhra, Oct 2, 2014
  5. 4/5 document the new "unset.variable" variableTanay Abhra, Oct 2, 2014
  6. 5/5 add tests for checking the behaviour of "unset.variable"Tanay Abhra, Oct 2, 2014
  7. Junio C HamanoOct 2, 2014
  8. Tanay AbhraOct 2, 2014
  9. Junio C HamanoOct 2, 2014
  10. Tanay AbhraOct 2, 2014
  11. Junio C HamanoOct 2, 2014
  12. Matthieu MoyOct 3, 2014
  13. Junio C HamanoOct 3, 2014
  14. Junio C HamanoOct 3, 2014
  15. Matthieu MoyOct 3, 2014
  16. Junio C HamanoOct 3, 2014
  17. Tanay AbhraOct 6, 2014
  18. Junio C HamanoOct 6, 2014
  19. Tanay AbhraOct 6, 2014
  20. Junio C HamanoOct 2, 2014
  21. Jeff KingOct 2, 2014
  22. Junio C HamanoOct 2, 2014
  23. Jakub NarębskiOct 7, 2014
  24. Junio C HamanoOct 7, 2014
  25. Matthieu MoyOct 8, 2014
  26. Junio C HamanoOct 8, 2014
  27. Matthieu MoyOct 8, 2014
  28. Junio C HamanoOct 8, 2014
  29. Jeff KingOct 10, 2014
  30. Junio C HamanoOct 13, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.