Re: [PATCH v3 3/3] core: convert build-time USE_NSEC into runtime core.useNanosec

Junio C Hamano <[email protected]>
Newsgroups org.kernel.vger.git
Message-ID <[email protected]>
"D. Ben Knoble" <[email protected]> writes:

> diff --git a/environment.c b/environment.c
> index 6676e6f5ae..c7f6b801f4 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -571,6 +571,13 @@ int git_default_core_config(const char *var, const char *value,
>  		return 0;
>  	}
>  
> +#ifndef NO_NSEC
> +	if (!strcmp(var, "core.usenanosec")) {
> +		cfg->use_nanosec = git_config_bool(var, value);
> +		return 0;
> +	}
> +#endif

What this hunk tells us: At build time, you could choose to ignore
core.usenanosec configuration variable, preventing cfg->use_nanosec
from getting flipped to true by the configured value.

> @@ -769,6 +776,9 @@ void repo_config_values_init(struct repo_config_values *cfg)
>  	cfg->ignore_case = 0;
>  	cfg->trust_executable_bit = 1;
>  	cfg->has_symlinks = platform_has_symlinks();
> +#ifndef NO_NSEC
> +	cfg->use_nanosec = 0;
> +#endif

I think we want to unconditionally initialize it to 0, unless the
definition of the .use_nanosec member itself in the structure is
conditional on NO_NSEC.  And ...

>  
>  	/* section "sparse" config values */
>  	cfg->sparse_expect_files_outside_of_patterns = 0;
> diff --git a/environment.h b/environment.h
> index e7ec5b0437..a35534afe5 100644
> --- a/environment.h
> +++ b/environment.h
> @@ -139,6 +139,7 @@ struct repo_config_values {
>  	int ignore_case;
>  	int trust_executable_bit;
>  	int has_symlinks;
> +	int use_nanosec;

... that is not the case.  

Which means that git_default_core_config() does keep the initial
value of the member without getting affected by the configuration,
but it does not necessarily be keeping "false".  It may be keeping
the uninitialized state instead ;-).

> diff --git a/read-cache.c b/read-cache.c
> index 6c449f393d..31888f77ee 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -353,12 +353,18 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
>  static int is_racy_stat(const struct index_state *istate,
>  			const struct stat_data *sd)
>  {
> +#ifndef NO_NSEC
> +	int use_nsec = repo_config_values(istate->repo)->use_nanosec;
> +#endif
> +
>  	return (istate->timestamp.sec &&
> -#ifdef USE_NSEC
> -		 /* nanosecond timestamped files can also be racy! */
> -		(istate->timestamp.sec < sd->sd_mtime.sec ||
> -		 (istate->timestamp.sec == sd->sd_mtime.sec &&
> -		  istate->timestamp.nsec <= sd->sd_mtime.nsec))
> +#ifndef NO_NSEC
> +		/* nanosecond timestamped files can also be racy! */
> +		use_nsec
> +		? (istate->timestamp.sec < sd->sd_mtime.sec ||
> +		   (istate->timestamp.sec == sd->sd_mtime.sec &&
> +		    istate->timestamp.nsec <= sd->sd_mtime.nsec))
> +		: istate->timestamp.sec <= sd->sd_mtime.sec
>  #else
>  		istate->timestamp.sec <= sd->sd_mtime.sec
>  #endif

Ugly.  How about getting rid of the latter #ifndef/#else/#endif and
instead keeping the "if use_nsec, pay attention to nsec, otherwise
only the seconds part" ternary?  As to the early part, as you can
arrange cfg's '.use_nanosec' to always hold a sensible value, the
function can become

        return (istate->timestamp.sec &&
                (repo_config_values(istate->repo)->use_nanosec
                 ? (istate->timestamp.sec < sd->sd_mtime.sec ||
                   (istate->timestamp.sec == sd->sd_mtime.sec &&
                    istate->timestamp.nsec <= sd->sd_mtime.nsec))
                 : istate->timestamp.sec <= sd->sd_mtime.sec));

I think.

The code you presented here for is_racy_stat() sprinkled with
#ifndef/#else/#endif would be sensible if repo_config_values struct
defined the '.use_nanosec' member conditionally.  But that is not
what is happening here.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.