From: K Jayatheerth Date: Wed, 24 Jun 2026 03:37:45 GMT Subject: [GSoC Patch v8 0/3] teach git repo info to handle path keys Message-ID: <20260624033748.108281-1-jayatheerthkulkarni2005@gmail.com> In-Reply-To: <20260601151950.30686-1-jayatheerthkulkarni2005@gmail.com> Hi! This series teaches `git repo info` to handle `path.*` keys, allowing scripts to reliably discover core repository paths without resorting to `git rev-parse`. The patches are structured as follows: 1. path: Extract the localized path-formatting logic out of `rev-parse` and expose it globally via `path.h` using clear append semantics. 2. repo: Introduce `path.commondir.absolute` and `path.commondir.relative` alongside a robust, isolated test helper. 3. repo: Introduce `path.gitdir.absolute` and `path.gitdir.relative` using the same standardized formatting rules. Changes since v7: * Renamed the helper to format_path() and changed semantics to replace/reset the destination buffer instead of appending (Junio). * Eliminated wasteful intermediate strbuf allocations (e.g., canonical_buf) by passing the destination buffer directly where safe (Junio). * Refactored the print_path() switch logic in rev-parse.c to evaluate FORMAT_DEFAULT first for better readability and future-proofing (Junio). Keeping the name as format_path() made sense to me. I understand we already had a discussion stating format_path() wasn't a good name back then because we were clearly appending to the buffer. I believe it is a good name now. Although, if there are any other name suggestions, I am happy to change it. P.S: I have thought of: replace_formatted_path strbuf_format_path populate_formatted_path In the end, I came to the conclusion that format_path() is simply better. Tagging Justin Tobler, Lucas Seiki Oshiro, Junio, Phillip Wood, brian m. carlson, and Ayush Jha. Thanks for helping improve this series! K Jayatheerth (3): path: extract format_path() and use in rev-parse repo: add path.commondir with absolute and relative suffix formatting repo: add path.gitdir with absolute and relative suffix formatting Documentation/git-repo.adoc | 15 +++++++ builtin/repo.c | 50 +++++++++++++++++++++++ builtin/rev-parse.c | 79 +++++++++++++++++-------------------- path.c | 69 ++++++++++++++++++++++++++++++++ path.h | 30 ++++++++++++++ t/t1900-repo-info.sh | 58 +++++++++++++++++++++++++++ 6 files changed, 258 insertions(+), 43 deletions(-) Range-diff against v7: 1: bb1d3fd06f ! 1: 287281935e path: extract append_formatted_path() and use in rev-parse @@ Metadata Author: K Jayatheerth ## Commit message ## - path: extract append_formatted_path() and use in rev-parse + path: extract format_path() and use in rev-parse Path formatting logic in builtin/rev-parse.c writes directly to stdout. Other builtins cannot reuse it. - Extract this logic into append_formatted_path() in path.c and expose + Extract this logic into format_path() in path.c and expose a path_format enum in path.h. Convert rev-parse to use the new helper in the same step to validate @@ builtin/rev-parse.c: enum default_type { + struct strbuf sb = STRBUF_INIT; + enum path_format fmt; + -+ if (format == FORMAT_RELATIVE) { -+ fmt = PATH_FORMAT_RELATIVE; -+ } else if (format == FORMAT_CANONICAL) { -+ fmt = PATH_FORMAT_CANONICAL; -+ } else /* FORMAT_DEFAULT */ { ++ if (format == FORMAT_DEFAULT) { + switch (def) { + case DEFAULT_RELATIVE: + fmt = PATH_FORMAT_RELATIVE; @@ builtin/rev-parse.c: enum default_type { - struct strbuf buf = STRBUF_INIT; - puts(relative_path(path, prefix, &buf)); - strbuf_release(&buf); -- } else { + } else { - struct strbuf buf = STRBUF_INIT; - strbuf_realpath_forgiving(&buf, path, 1); - puts(buf.buf); - strbuf_release(&buf); ++ switch (format) { ++ case FORMAT_RELATIVE: ++ fmt = PATH_FORMAT_RELATIVE; ++ break; ++ case FORMAT_CANONICAL: ++ fmt = PATH_FORMAT_CANONICAL; ++ break; ++ default: ++ fmt = PATH_FORMAT_UNMODIFIED; ++ break; ++ } } - free(cwd); + -+ append_formatted_path(&sb, path, prefix, fmt); ++ format_path(&sb, path, prefix, fmt); + puts(sb.buf); + + strbuf_release(&sb); @@ path.c: char *xdg_cache_home(const char *filename) return NULL; } -+void append_formatted_path(struct strbuf *dest, const char *path, -+ const char *prefix, enum path_format format) ++void format_path(struct strbuf *dest, const char *path, ++ const char *prefix, enum path_format format) +{ ++ strbuf_reset(dest); ++ + switch (format) { + case PATH_FORMAT_UNMODIFIED: + strbuf_addstr(dest, path); @@ path.c: char *xdg_cache_home(const char *filename) + break; + } + -+ case PATH_FORMAT_CANONICAL: { -+ struct strbuf canonical_buf = STRBUF_INIT; -+ -+ strbuf_realpath_forgiving(&canonical_buf, path, 1); -+ strbuf_addbuf(dest, &canonical_buf); -+ -+ strbuf_release(&canonical_buf); ++ case PATH_FORMAT_CANONICAL: ++ /* ++ * strbuf_realpath_forgiving inherently resets the destination ++ * buffer, safely aligning with our replace semantics. ++ */ ++ strbuf_realpath_forgiving(dest, path, 1); + break; -+ } + + default: + BUG("unknown path_format value %d", format); @@ path.h: enum scld_error safe_create_leading_directories_no_share(char *path); +}; + +/** -+ * Format a path according to the specified formatting strategy and append -+ * the result to the given strbuf. ++ * Format a path according to the specified formatting strategy and store ++ * the result in the given strbuf, replacing any existing contents. + * -+ * `dest` : The string buffer to append the formatted path to. ++ * `dest` : The string buffer to store the formatted path into. + * `path` : The path string that needs to be formatted. + * `prefix` : The directory prefix to calculate relative offsets against. + * Pass NULL to default to the current working directory where applicable. + * `format` : The formatting behavior rule to execute. + */ -+void append_formatted_path(struct strbuf *dest, const char *path, -+ const char *prefix, enum path_format format); ++void format_path(struct strbuf *dest, const char *path, ++ const char *prefix, enum path_format format); + # ifdef USE_THE_REPOSITORY_VARIABLE # include "strbuf.h" 2: d2414bee58 ! 2: 69517f1a08 repo: add path.commondir with absolute and relative suffix formatting @@ builtin/repo.c: static int get_object_format(struct repository *repo, struct str + if (!common_dir) + return error(_("unable to get common directory")); + -+ append_formatted_path(buf, common_dir, startup_info->prefix, PATH_FORMAT_CANONICAL); ++ format_path(buf, common_dir, startup_info->prefix, PATH_FORMAT_CANONICAL); + return 0; +} + @@ builtin/repo.c: static int get_object_format(struct repository *repo, struct str + if (!common_dir) + return error(_("unable to get common directory")); + -+ append_formatted_path(buf, common_dir, startup_info->prefix, PATH_FORMAT_RELATIVE); ++ format_path(buf, common_dir, startup_info->prefix, PATH_FORMAT_RELATIVE); + return 0; +} + 3: 9962c7d530 ! 3: ce43453975 repo: add path.gitdir with absolute and relative suffix formatting @@ builtin/repo.c: static int get_path_commondir_relative(struct repository *repo, + if (!git_dir) + return error(_("unable to get git directory")); + -+ append_formatted_path(buf, git_dir, startup_info->prefix, PATH_FORMAT_CANONICAL); ++ format_path(buf, git_dir, startup_info->prefix, PATH_FORMAT_CANONICAL); + return 0; +} + @@ builtin/repo.c: static int get_path_commondir_relative(struct repository *repo, + if (!git_dir) + return error(_("unable to get git directory")); + -+ append_formatted_path(buf, git_dir, startup_info->prefix, PATH_FORMAT_RELATIVE); ++ format_path(buf, git_dir, startup_info->prefix, PATH_FORMAT_RELATIVE); + return 0; +} + -- 2.55.0-rc1