From: Jeff King <peff@peff.net>
To: Keith Cascio <keith@CS.UCLA.EDU>
Cc: Junio C Hamano <gitster@pobox.com>, git@vger.kernel.org
Subject: Re: [PATCH v2 1/2] Introduce config variable "diff.defaultOptions"
Date: Fri, 20 Mar 2009 03:01:48 -0400 [thread overview]
Message-ID: <20090320070148.GD27008@coredump.intra.peff.net> (raw)
In-Reply-To: <alpine.GSO.2.00.0903170825340.16242@kiwi.cs.ucla.edu>
On Tue, Mar 17, 2009 at 09:05:18AM -0700, Keith Cascio wrote:
> In order to answer your questions as convincingly as possible, I wrote up a
> one-page PDF document, downloadable here:
> http://preview.tinyurl.com/c769dd
Thanks for following up on this. And I appreciate that it is probably
nicer to compose in whatever you used to make this PDF due to enhanced
typography and linked footnotes, but posting a link to a PDF has a few
downsides:
- the text in the PDF does not become part of the list archive; if
your tinyurl or your hosted file ever goes away, the content of
your message is permanently lost
- it makes it very difficult for readers to reply inline to your
comments
So please just send text emails in the future.
This time, however, I converted your PDF to text so I could reply.
Your PDF said:
> No matter which implementation, we all agree the semantics are "pretend
> as if the options in [diff.defaultOptions] were prepended to the command
> line" [1]. That requirement is subject neither to confusion nor doubt.
> An implementation is acceptable only if it delivers exactly that
> behavior to the user.
OK, good, I think we are in agreement there.
> Git's diff options processing scheme is a mature[2], versatile
> instrument relied upon by at least 47 client codepaths. The API it
> provides for recording user intent to an instance of struct diff_options
> entails the following steps[3]:
>
> 1) to prepare the structure for recording, call diff_setup() once
>
> 2) to record user intention, write to the structure[4], calling
> diff_opt_parse() as needed
I think there is a step 1.5, where callers can record their own
"default" intentions -- things that this particular caller will default
to, but which users can override via command-line options. E.g., "git
log" tweaks several options in cmd_log_init, such as turning on
ALLOW_TEXTCONV and RECURSIVE.
> 3) to prepare the structure for "playback", call diff_setup_done() once
>
> 4) to test user intention, read from the structure
OK, makes sense.
> Git's code is already equipped to react to every kind of user intention
> during step 2.
More or less. I think in our past discussion, it came about that there
are some things the user cannot say, like undoing certain options. This
could be a problem if a caller defaults options to something un-doable.
For example, I don't think there is a way to turn off OPT_RECURSIVE in
git-log. In practice, this hasn't been a problem.
> An attractive (but hopelessly flawed) strategy is to pre-load the
> structure with defaultOptions before step 2. Step 1, diff_setup(), is
> the only place to do that, since the client starts overwriting as soon
> as diff_setup() returns.
I don't agree that it is hopelessly flawed. It requires a new call at
each callsite to say "I have set up my defaults, now take the user
defaults from the config, before I proceed to step 2 and parse the
user intentions". Which sounds awful to add a new call at each site,
but I am not sure that is not necessary anyway.
I don't know that all callsites will _want_ to respect such a config
option, especially not plumbing. So any callsite is going to have to opt
into this functionality anyway.
> Some aspects of user intention dictate whether or not to perform the
> pre-load at all, most notably: which Git command the user invoked (also
> switches). But at step 1, inside diff_setup(), we don't know the user's
> full intention yet, so we can't decide whether or not to perform the
> pre-load.
I think I suggested last time that the idea of whether or not to perform
the pre-load doesn't _have_ to come from the same set of user intention.
That is, in the call
git [git-options] diff [diff-options]
we actually parse [git-options] and [diff-options] at different times.
Pre-load intention can go into [git-options], which avoids this
dependency cycle.
> This could tempt an undisciplined programmer to try to peek ahead at
> part of the user's intention before the code sees it in its normal
> course. That would be a disaster because it would undermine the
> integrity, not to mention beauty, of Git's entire initialization scheme.
> It would be a cheap hack; an inelegant, fragile, ugly, and utterly
> half-baked attempt to bypass and circumvent the existing architecture.
Your poetry aside, I agree that way madness lies.
> My proposal:
>
> a) patiently accumulates user intention via Git's well-established
> initialization scheme, never needing to peek ahead or misbehave in any
> way, thus attaining harmony.
>
> b) postpones the decision whether or not to load defaultOptions until
> step 3, diff_setup_done(), after we've had every opportunity to examine
> user intention, but loads them effectively underneath any explicit
> command line options, thereby fulfilling the agreed upon semantic
> obligation.
>
> c) is inspired by a simple, powerful, easy-to-understand, and popular
> metaphor: layer flattening.
>
> Why, oh why do some people think there's an "easier" way[1]?!
Because I outlined it above?
Look, I am not opposed to layer flattening if that's what is required to
get it right. But consider the downside of layer flattening: we must
always record intent-to-change when making a change to the struct (i.e.,
the "mask" variable in your original patches). This is fine for members
hidden behind macros, but there are a lot of members that are assigned
to directly. We would need to:
1. Introduce new infrastructure for assigning to these members.
2. Fix existing locations by converting them to this infrastructure.
3. Introduce some mechanism to help future callers get it right (since
otherwise assigning directly is a subtle bug).
This is elementary encapsulation; in a language with better OO support,
you would hide all of your struct members behind accessors. But this is
C, and a dialect of C where that doesn't usually happen. So I think it
is going to introduce a lot of code changes, and the resulting code will
not look as much like the rest of git as it once did.
So what I am suggesting is that _if_ there is an easier way to do it,
then it is worth exploring.
-Peff
next prev parent reply other threads:[~2009-03-20 7:03 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1233598855-1088-1-git-send-email-keith@cs.ucla.edu>
2009-02-02 18:20 ` [PATCH v2 1/2] Introduce config variable "diff.primer" Keith Cascio
2009-02-02 18:20 ` [PATCH v2 2/2] Test functionality of new " Keith Cascio
2009-02-02 20:45 ` [PATCH v2 0/2] Introduce " Keith Cascio
2009-02-02 21:03 ` Keith Cascio
2009-02-03 7:15 ` [PATCH v2 1/2] " Jeff King
2009-02-03 17:55 ` Keith Cascio
2009-02-04 5:43 ` Junio C Hamano
2009-02-04 6:36 ` Keith Cascio
2009-02-06 16:54 ` Jeff King
2009-02-06 16:19 ` Jeff King
2009-02-07 21:45 ` Junio C Hamano
2009-02-09 17:24 ` Keith Cascio
2009-02-13 22:22 ` Jeff King
2009-02-14 6:03 ` Johannes Schindelin
2009-02-14 6:15 ` Jeff King
2009-02-14 6:24 ` Johannes Schindelin
2009-02-14 15:17 ` Jeff King
2009-02-15 23:26 ` Keith Cascio
2009-02-15 23:39 ` Junio C Hamano
2009-02-17 7:24 ` diff.defaultOptions implementation design [was diff.primer] Keith Cascio
2009-02-17 19:56 ` Jeff King
2009-03-17 16:05 ` [PATCH v2 1/2] Introduce config variable "diff.defaultOptions" Keith Cascio
2009-03-20 7:01 ` Jeff King [this message]
2009-03-20 17:11 ` Keith Cascio
2009-03-20 19:49 ` Jeff King
2009-03-21 2:00 ` [PATCH/RFC v3] Introduce config variable "diff.defaultoptions" Keith Cascio
2009-03-21 3:15 ` [PATCH] Allow setting default diff options via diff.defaultOptions Johannes Schindelin
2009-04-03 0:04 ` Keith Cascio
2009-04-09 8:45 ` Johannes Schindelin
2009-04-09 8:49 ` Jeff King
2009-04-09 10:43 ` Johannes Schindelin
2009-04-10 8:01 ` Jeff King
2009-04-13 22:37 ` [PATCH] Add the diff option --no-defaults Johannes Schindelin
2009-04-16 8:34 ` Jeff King
2009-04-16 9:25 ` Johannes Schindelin
2009-04-16 9:41 ` Jeff King
2009-04-16 16:52 ` Junio C Hamano
2009-04-16 17:36 ` Johannes Schindelin
2009-04-17 11:54 ` Jeff King
2009-04-17 13:15 ` Johannes Schindelin
2009-04-18 16:41 ` Keith Cascio
2009-04-18 17:40 ` Johannes Schindelin
2009-04-18 20:32 ` Keith Cascio
2009-04-18 21:15 ` Johannes Schindelin
2009-04-09 16:29 ` [PATCH] Allow setting default diff options via diff.defaultOptions Keith Cascio
2009-04-09 0:44 ` Keith Cascio
2009-04-09 8:29 ` Johannes Schindelin
2009-04-09 8:31 ` Jeff King
2009-02-03 18:56 ` [PATCH v2 1/2] Introduce config variable "diff.primer" Jakub Narebski
2009-02-03 19:13 ` Keith Cascio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090320070148.GD27008@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=keith@CS.UCLA.EDU \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).