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

Re: [PATCH v3] Expand ~ and ~user in core.excludesfile, commit.template

From
Jeff King <peff@peff.net>
Date
Aug 29, 2008, 03:26 UTC
Message-ID
<20080829032630.GA7024@coredump.intra.peff.net>
In-Reply-To
<quack.20080828T0209.lthmyixjyjx_-_@roar.cs.berkeley.edu>
On Thu, Aug 28, 2008 at 02:09:38AM -0700, Karl Chen wrote:
Show 5 quoted lines
>  builtin-commit.c |    2 +-
>  cache.h          |    2 +
>  config.c         |   13 +++++++-
>  path.c           |   88 +++++++++++++++++++++++++++++++++--------------------
>  4 files changed, 69 insertions(+), 36 deletions(-)
Documentation?
>  	if (!strcmp(k, "commit.template"))
> -		return git_config_string(&template_file, k, v);
> +		return git_config_userdir(&template_file, k, v);
I like this.
Show 7 quoted lines
> +int git_config_userdir(const char **dest, const char *var, const char *value) {
> +	if (!value)
> +		return config_error_nonbool(var);
> +	*dest = expand_user_path(NULL, value, 0);
> +	if (!*dest || !**dest) die("Failed to expand user dir in: '%s'", value);
> +	return 0;
> +}

I am not sure about !**dest here. This precludes somebody from using "". While it might not matter here, if there are other users of git_config_userdir(), they might want to allow a blank entry.

Also, style: there should be a newline after conditional but before executed code. IOW, replace

  if (cond) code;
with
  if (cond)
          code;
> +static inline struct passwd *getpw_strspan(const char *begin_username,
> +										   const char *end_username) 
1. There seem to be extra tabs in the second line, pushing the
   end_username argument way too far to the right.
2. I'm not sure "strspan" is a good name for this helper, since it calls
   to mind the strspn C function, which is not really related to this at
   all.
3. Usually helper functions that take a non-terminated string like this
   in git use the combination of (char *begin, int len) instead of two
   pointers. While you are currently the only user of the helper, I
   think it makes sense to follow that convention for future users.
> +	if (begin_username == end_username) {
> +		return getpwuid(getuid());
> +	} else {
Style: omit braces on one-liner conditionals:
  if (begin_username == end_username)
          return getwpuid(getuid());

Also, you do a lot of early returns in your code. I think this is good, because it makes it more readable. But that means you don't have to worry about "else"ing the other half of the conditional, because you have already returned. Which makes it even easier to read.

> +		size_t username_len = end_username - begin_username;

See, here you end up converting back from two pointers to a pointer and a length. Which is why I think we tend to use the other representation.

> +		char *username = alloca(username_len + 1);

I don't think we use alloca() anywhere else. I don't know if there are portability issues.

Show 10 quoted lines
> +static inline char *concatstr(char *buf, const char *str1, const char *str2,
> +							  size_t bufsz)
> +{
> +	size_t len1 = strlen(str1);
> +	size_t len2 = strlen(str2);
> +	size_t needbuflen = len1 + len2 + 1;
> +	if (buf) {
> +		if (needbuflen > bufsz) return NULL;
> +	} else {
> +		buf = xmalloc(needbuflen);
Style: more braces which can be omitted.

This function seems a little superfluous, since its semantics are so specific to this usage. I am all for splitting into little functions, but I think it would be quite confusing for somebody to try reusing this. Perhaps it at least needs a comment explaining the semantics of buf?

Show 5 quoted lines
> +static inline const char *strchr_or_end(const char *str, char c)
> +{
> +	while (*str && *str != c) ++str;
> +	return str;
> +}

This really seems like premature optimization to me. The only advantage this has over

  p = strchr(s);
  if (!p)
    p = s + strlen(s);

is that we avoid traversing the string once. But balance that against an assembler-optimized strchr provided by your libc. And then wonder if it is even worth it, since this is not even remotely a critical path.

Show 11 quoted lines
> +{
> +	if (path == NULL) {
>  		return NULL;
> [...]
> +	} else if (path[0] != '~') {
> +		if (buf == NULL) {
> +			return xstrdup(path);
> +		} else {
> +			if (strlen(path)+1 > sz) return NULL;
> +			return strcpy(buf, path);
> +		}
More early returns which can be removed from conditionals.

Also, some of this code seems duplicated with concatstr. Wouldn't it just be simpler to let concatstr take a NULL for one of the arguments, and then just use it again here? IOW, something like:

  if (!path)
    return NULL;
  if (path[0] != '~')
    return concatstr(path, NULL);
> -			if (!user_path(used_path, path, PATH_MAX))
> +			if (!expand_user_path(used_path, path, PATH_MAX))

But these functions don't have the same semantics, do they? user_path used to return NULL if the path didn't start with ~, right?

-Peff
Previous: Karl ChenNext: Junio C Hamano
Message 34 of 45 in “Support "core.excludesfile = ~/.gitignore"”
  1. Support "core.excludesfile = ~/.gitignore"Karl Chen, Aug 22, 2008
  2. Eric RaibleAug 22, 2008
  3. Bert WesargAug 22, 2008
  4. Junio C HamanoAug 22, 2008
  5. Karl ChenAug 24, 2008
  6. Junio C HamanoAug 24, 2008
  7. Jeff KingAug 24, 2008
  8. Junio C HamanoAug 24, 2008
  9. Jeff KingAug 24, 2008
  10. Junio C HamanoAug 24, 2008
  11. limiting relationship of git dir and worktree (was Re: [PATCH] Support "core.excludesfile = ~/.gitignore")Jeff King, Aug 24, 2008
  12. Dropping core.worktree and GIT_WORK_TREE support (was Re: limiting relationship of git dir and worktree)Junio C Hamano, Aug 25, 2008
  13. Miklos VajnaAug 25, 2008
  14. Junio C HamanoAug 25, 2008
  15. Miklos VajnaAug 25, 2008
  16. Nguyen Thai Ngoc DuyAug 25, 2008
  17. git diff/diff-index/diff-files: call setup_work_tree()Miklos Vajna, Aug 25, 2008
  18. Nguyen Thai Ngoc DuyAug 25, 2008
  19. Miklos VajnaAug 25, 2008
  20. git diff/diff-index/diff-files: call setup_work_tree()Miklos Vajna, Aug 25, 2008
  21. Nguyen Thai Ngoc DuyAug 25, 2008
  22. Junio C HamanoAug 26, 2008
  23. diff*: fix worktree setupNguyễn Thái Ngọc Duy, Aug 28, 2008
  24. Junio C HamanoAug 25, 2008
  25. Miklos VajnaAug 25, 2008
  26. Michael J GruberAug 26, 2008
  27. Jeff KingAug 27, 2008
  28. Support "core.excludesfile = ~/.gitignore"Karl Chen, Aug 25, 2008
  29. Johannes SixtAug 26, 2008
  30. Jeff KingAug 27, 2008
  31. Karl ChenAug 27, 2008
  32. Junio C HamanoAug 27, 2008
  33. Expand ~ and ~user in core.excludesfile, commit.templateKarl Chen, Aug 28, 2008
  34. Jeff KingAug 29, 2008
  35. Junio C HamanoAug 29, 2008
  36. Expand ~ and ~user in core.excludesfile, commit.templateKarl Chen, Aug 29, 2008
  37. Junio C HamanoAug 29, 2008
  38. Karl ChenAug 29, 2008
  39. Junio C HamanoAug 29, 2008
  40. Karl ChenAug 29, 2008
  41. Junio C HamanoAug 30, 2008
  42. Jeff KingAug 30, 2008
  43. Johannes SixtAug 29, 2008
  44. Karl ChenAug 27, 2008
  45. Junio C HamanoAug 27, 2008

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.