repo info: add category/path keys and --path-format#2208
repo info: add category/path keys and --path-format#2208eslam-reda-div wants to merge 6 commits intogit:masterfrom
Conversation
Welcome to GitGitGadgetHi @eslam-reda-div, and welcome to GitGitGadget, the GitHub App to send patch series to the Git mailing list from GitHub Pull Requests. Please make sure that either:
You can CC potential reviewers by adding a footer to the PR description with the following syntax: NOTE: DO NOT copy/paste your CC list from a previous GGG PR's description, Also, it is a good idea to review the commit messages one last time, as the Git project expects them in a quite specific form:
It is in general a good idea to await the automated test ("Checks") in this Pull Request before contributing the patches, e.g. to avoid trivial issues such as unportable code. Contributing the patchesBefore you can contribute the patches, your GitHub username needs to be added to the list of permitted users. Any already-permitted user can do that, by adding a comment to your PR of the form Both the person who commented An alternative is the channel Once on the list of permitted usernames, you can contribute the patches to the Git mailing list by adding a PR comment If you want to see what email(s) would be sent for a After you submit, GitGitGadget will respond with another comment that contains the link to the cover letter mail in the Git mailing list archive. Please make sure to monitor the discussion in that thread and to address comments and suggestions (while the comments and suggestions will be mirrored into the PR by GitGitGadget, you will still want to reply via mail). If you do not want to subscribe to the Git mailing list just to be able to respond to a mail, you can download the mbox from the Git mailing list archive (click the curl -g --user "<EMailAddress>:<Password>" \
--url "imaps://imap.gmail.com/INBOX" -T /path/to/raw.txtTo iterate on your change, i.e. send a revised patch or patch series, you will first want to (force-)push to the same branch. You probably also want to modify your Pull Request description (or title). It is a good idea to summarize the revision by adding something like this to the cover letter (read: by editing the first comment on the PR, i.e. the PR description): To send a new iteration, just add another PR comment with the contents: Need help?New contributors who want advice are encouraged to join git-mentoring@googlegroups.com, where volunteers who regularly contribute to Git are willing to answer newbie questions, give advice, or otherwise provide mentoring to interested contributors. You must join in order to post or view messages, but anyone can join. You may also be able to find help in real time in the developer IRC channel, |
|
There are issues in commit 0d44f60:
|
|
/allow |
|
User eslam-reda-div is now allowed to use GitGitGadget. WARNING: eslam-reda-div has no public email address set on GitHub; GitGitGadget needs an email address to Cc: you on your contribution, so that you receive any feedback on the Git mailing list. Go to https://github.com/settings/profile to make your preferred email public to let GitGitGadget know which email address to use. |
There was a problem hiding this comment.
Pull request overview
This PR enhances git repo info and git repo structure commands with improved path reporting and deeper repository statistics inspired by git-sizer.
Changes:
- Removes reliance on global repository state in
git repo infoby introducing arepo_infostructure that explicitly passes repository context - Adds category key support (e.g.,
layout,path) and new path-related keys with--path-format=(absolute|relative)option - Extends
git repo structurewith comprehensive metrics including max object sizes, max commit parent count, max tree entries, max blob path length/depth, and max annotated tag chain depth
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| builtin/repo.c | Refactors info command to remove global state, adds path keys and formatting, implements new structure statistics computation |
| t/t1900-repo.sh | Adds comprehensive tests for path keys, category keys, and path format options |
| t/t1901-repo-structure.sh | Adds test helpers and expectations for new structure metrics |
| Documentation/git-repo.adoc | Documents new path keys, category key syntax, and extended structure metrics |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
builtin/repo.c
Outdated
| if ((uintmax_t)disk > max_disk) | ||
| max_disk = disk; |
There was a problem hiding this comment.
The cast to uintmax_t at line 1005 is inconsistent with the comparison at line 1003. The variable disk is of type off_t (which is typically signed) and max_disk is of type size_t (unsigned). The cast appears to be an attempt to handle potential sign issues, but it's inconsistent with how inflated (unsigned long) is handled at line 1003.
For consistency and correctness, either both comparisons should use casts, or neither should. Since disk sizes should never be negative, consider either: (1) casting disk to size_t directly for the comparison, or (2) removing the cast if off_t and size_t comparison is safe on all platforms.
| if ((uintmax_t)disk > max_disk) | |
| max_disk = disk; | |
| if ((size_t)disk > max_disk) | |
| max_disk = (size_t)disk; |
0d44f60 to
daeb338
Compare
|
Could you please review this when you have time? |
daeb338 to
9f2b3a4
Compare
Thank you for reaching out. I do not really have time to do a proper review and as explained in #2208 (comment), the process of the Git project is completely outside of GitHub. Reviews happen on the Git mailing list. As such, I would encourage you to just There's just one thing that immediately jumped to my eye and that's in the sign-off by it line. You use not your real name but a handle before the email address. The Git project is very very particular about this and wants the real name to appear there. You might want to write it out. For the record, I always enjoy seeing names the require Unicode; The Git project has a massive over-representation of people whose names can be written in plain 7-bit ASCII (like mine). |
|
dscho
left a comment
There was a problem hiding this comment.
@eslam-reda-div okay, I just stumbled over the CI failures and cannot help it, I've gotta assist you. The Git project could be a lot friendlier to newcomers by providing excellent error message in the CI build failures. Essentially there are two classes of problems here.
One is the hard coding of the SHA-1, where SHA-256 is slated to become the default in Git v3.0:
@@ -1,3 +1,3 @@
-object.format=sha1
+object.format=sha256
layout.bare=false
layout.shallow=false
error: last command exited with $?=1
not ok 28 - mixed key/category requests preserve request order
The other one is a subtle issue on macOS where the wc tool deviates from the GNU variant of the same tool. The BSD variant, which is used on MacOS, adds some white space:
@@ -25,7 +25,7 @@
objects.blobs.max_disk_size=20
objects.tags.max_disk_size=127
objects.commits.max_parent_count=1
-objects.trees.max_entry_count= 42
+objects.trees.max_entry_count=42
objects.blobs.max_path_length=4
objects.blobs.max_path_depth=1
objects.tags.max_chain_depth=1
error: last command exited with $?=1
t/t1900-repo.sh
Outdated
|
|
||
| test_expect_success 'mixed key/category requests preserve request order' ' | ||
| cat >expect <<-\EOF && | ||
| object.format=sha1 |
There was a problem hiding this comment.
You will want to replace this with $(test_oid algo) (need to remove the backslash from \EOF for that), just like e.g. https://github.com/git/git/blob/v2.53.0/t/t1050-large.sh#L179
t/t1901-repo-structure.sh
Outdated
| test "$entries" -gt "$max" && max=$entries | ||
| done | ||
|
|
||
| echo "$max" |
There was a problem hiding this comment.
You will want to lose the quotes, to avoid running into the extra white-space produced by the BSD variant of wc (which is used on macOS).
|
Thank you for the feedback. Thanks again for your time and guidance. |
You're welcome!
Please take your time, there's no rush. And please just force-push the branch, do not open a new Pull Request (it's unnecessary). |
|
/submit |
|
Submitted as pull.2208.git.git.1771784936.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
| @@ -8,7 +8,7 @@ git-repo - Retrieve information about the repository | |||
| SYNOPSIS | |||
There was a problem hiding this comment.
Lucas Seiki Oshiro wrote on the Git mailing list (how to reply to this email):
> and additional git-path based locations.
This statement is too vague. Each one of the covered key-value pairs
needs to be mentioned and discussed about why they are being added.
> Extend git repo structure with deeper repository metrics inspired by
> git-sizer, including per-type maximum inflated and on-disk object sizes,
> maximum commit parent count, maximum tree entry count, longest/deepest
> blob path, and deepest annotated tag chain.
This patch is doing too much. It needs to be broken, at least, into 20
smaller patches, one per git-repo-info and git-repo-structure key.
There was a problem hiding this comment.
Thank you for the detailed feedback.
I will start right away on preparing a thorough and detailed explanation for each key that was added, clearly describing what it does and the specific reason for introducing it. I’ll make sure every addition is properly justified and documented.
Regarding the patch structure, would it be acceptable to keep it as a single series without splitting it into many smaller patches? I completely understand the concern, but since the changes are closely related, I’m hoping it might still be reasonable to keep them grouped.
That said, I’m fully prepared to follow the recommended approach if splitting is strictly required. I’m ready to put in the work and will begin refining the explanations immediately.
Thank you again for your guidance.
There was a problem hiding this comment.
@eslam-reda-div please note that this reply should not be sent as a PR comment, but instead as an email.
| git init category-layout && | ||
| git -C category-layout repo info layout >actual && | ||
| test_cmp expect actual | ||
| ' |
There was a problem hiding this comment.
Lucas Seiki Oshiro wrote on the Git mailing list (how to reply to this email):
> From: Eslam reda ragheb <eslam.reda.div@gmail.com>
>
> Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
Missing patch message.
> test_expect_success 'mixed key/category requests preserve request order' '
> - cat >expect <<-\EOF &&
> - object.format=sha1
> + cat >expect <<-EOF &&
> + object.format=$(test_oid algo)
Don't send patches fixing the code you have just added. Instead, rewrite
the history applying the fix to the original patch.
|
Junio C Hamano wrote on the Git mailing list (how to reply to this email): "eslam reda via GitGitGadget" <gitgitgadget@gmail.com> writes:
> Eslam reda ragheb (2):
> t1900,t1901: make repo tests hash-agnostic and wc-portable
> t1900,t1901: fix test portability issues
>
> eslam-reda-div (1):
> repo: extend info paths and structure statistics
I do not think you meant to send a patch seriees with these two same
but different looking folks claiming authorship.
I'll let the main change 1/3 reviewed and commented on those who are
more invested into "git repo", but both [2/3] and [3/3] need to sell
themselves with a more meaningful proposed log messages.
I think the test updates in [2/3] are all good things to do---they
make the test more robust against changes in the hash algorithm
used, what the history left by the previous test steps exactly have,
etc., by avoiding hardcoded constants in the expectation. And in
light of that, I do not think [3/3] is a good change, especially
without explanation of why we may want to use hardcoded numbres.
Thanks.
|
| @@ -8,7 +8,7 @@ git-repo - Retrieve information about the repository | |||
| SYNOPSIS | |||
There was a problem hiding this comment.
Justin Tobler wrote on the Git mailing list (how to reply to this email):
On 26/02/22 06:28PM, eslam-reda-div via GitGitGadget wrote:
> From: eslam-reda-div <eslam.reda.div@gmail.com>
>
> Improve git repo info by adding path-oriented keys that match values
> users currently obtain from git rev-parse, including common directory,
> git directory, top-level, superproject working tree, and additional
> git-path based locations.
>
> Teach git repo info to accept category keys like layout and path,
> and add --path-format=(absolute|relative) so scripts can request the
> desired path style explicitly. The command now uses repository context
> passed to the command path instead of relying on global state.
>
> Extend git repo structure with deeper repository metrics inspired by
> git-sizer, including per-type maximum inflated and on-disk object sizes,
> maximum commit parent count, maximum tree entry count, longest/deepest
> blob path, and deepest annotated tag chain.
Hello,
Just FYI, there is already a series on the list I'm currently working on
that is extending the "structure" output for git-repo [1] similar to
what is being done here. This series collects largest inflated object
info, max commit parents, and max tree entries. It does look like this
series is collecting a couple of other data points too, but maybe we
could do so it a separate followup series to the one I'm working on? :)
Thanks,
-Justin
[1]: https://lore.kernel.org/git/20260203221758.1164434-1-jltobler@gmail.com/3c656bf to
c9973b4
Compare
|
There is an issue in commit 2afb987:
|
|
There is an issue in commit 0239b23:
|
|
There is an issue in commit 0a43ed7:
|
|
There is an issue in commit 983659f:
|
|
There is an issue in commit e327700:
|
|
/submit |
|
Error: a2a6768 was already submitted |
|
Hi @dscho, First of all, I’d like to warmly welcome you and apologize for any inconvenience I might have caused—I hope I haven’t been a bother. I’ve made all the requested changes and improvements, and I’ve resubmitted everything. All the adjustments should now be included. I just wanted to kindly ask what the expected timeframe might be for receiving feedback or a decision, as I truly hope my contribution will be accepted. I’m fully ready to make any further updates if needed. Thank you very much for your time and guidance. |
|
It's common for contributors to reply on the list with a gentle "ping" after 2-4 weeks... |
a2a6768 to
1bc100d
Compare
|
/submit |
|
Submitted as pull.2208.v4.git.git.1772140487.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
| @@ -22,7 +22,12 @@ static const char *const repo_usage[] = { | |||
| NULL | |||
There was a problem hiding this comment.
Junio C Hamano wrote on the Git mailing list (how to reply to this email):
"Eslam reda ragheb via GitGitGadget" <gitgitgadget@gmail.com>
writes:
> From: Eslam reda ragheb <eslam.reda.div@gmail.com>
>
> Introduce an explicit repo_info context for the repo info codepath
> and thread it through value lookups and field printing.
>
> This removes direct coupling from these helpers to ad-hoc
> repository globals and makes key retrieval logic easier to extend
> safely.
The above makes it sound as if you are improving existing code where
existing helper functions are already making ad-hoc and unsafe
access to global variables, but I somehow doubt that is what is
happening here.
What does "these helpers" exactly refer to in this sentence? The
ones you will introduce in patch 02/10?
Currently helper functions of get_value_fn type receives the
output buffer and repository instance as parameters, but we are
about to teach "repo info" to retrieve information that requires
to know more than just the repository (e.g., the prefix given
when the command was invoked). Introduce a new "repo_info"
structure and update get_value_fn to take it as a parameter.
or something?
> Also teach git repo info to accept category names (for example,
> layout) and expand them to matching key.* entries in request
> order.
That smells like an unrelated change. Wouldn't it better to do so
in a subsequent patch, so that each step will concentrate on doing
one thing and one thing well?There was a problem hiding this comment.
Thank you for the detailed feedback.
You are right: that wording is imprecise. In the next reroll I will rewrite the commit message to describe the change mechanically and explicitly (introducing a repo_info context so get_value_fn can access more than the repository, such as invocation prefix), without implying existing unsafe global usage.
You are also right that category expansion should be separated. I will split it into its own patch so each commit does one focused thing.
| @@ -1,10 +1,12 @@ | |||
| #define USE_THE_REPOSITORY_VARIABLE | |||
There was a problem hiding this comment.
Junio C Hamano wrote on the Git mailing list (how to reply to this email):
"Eslam reda ragheb via GitGitGadget" <gitgitgadget@gmail.com>
writes:
> From: Eslam reda ragheb <eslam.reda.div@gmail.com>
>
> Add a path category to git repo info with key-value pairs that
> mirror repository paths users commonly retrieve via rev-parse and
> git-path lookups.
> ...
> +static int get_path_git_prefix(struct repo_info *info, struct strbuf *buf)
> +{
> + if (info->prefix)
> + strbuf_addstr(buf, info->prefix);
> + return 0;
> +}
Can (info->prefix && info->prefix[0] == '\0') be possible? If so,
"repo info path.git-prefix" would not be able to help users who want
to know between (info->prefix == NULL) and info->prefix being an
empty string.
There was a problem hiding this comment.
Thank you, good catch.
I updated this so prefix handling is normalized in the context setup, and path.prefix now has stable behavior instead of depending on nullable handling in the getter. This avoids ambiguity in behavior around absent prefix vs empty prefix and makes the output contract clearer.
| @@ -1,10 +1,12 @@ | |||
| #define USE_THE_REPOSITORY_VARIABLE | |||
There was a problem hiding this comment.
Phillip Wood wrote on the Git mailing list (how to reply to this email):
Hi Eslam
On 26/02/2026 21:14, Eslam reda ragheb via GitGitGadget wrote:
> From: Eslam reda ragheb <eslam.reda.div@gmail.com>
> > Add a path category to git repo info with key-value pairs that
> mirror repository paths users commonly retrieve via rev-parse and
> git-path lookups.
I think that makes sense, I'm not sure about some of the paths though, see below.
> This makes scripting against repo metadata more direct and avoids
> shelling out to multiple commands for related paths.
You can get more than one path at a time from "git rev-parse" so I'm not sure what this is saying.
It would be helpful to include the tests and Documentation for the new keys in this patch.
> The new keys are introduced as explicit path.* entries in
> repo_info_fields and are resolved through dedicated helpers.
> > This keeps lookup behavior predictable and makes future path
> additions straightforward.
> > Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
> ---
> @@ -74,6 +197,20 @@ static const struct field repo_info_fields[] = {
> { "layout.bare", get_layout_bare },
> { "layout.shallow", get_layout_shallow },
> { "object.format", get_object_format },
> + { "path.common-dir", get_path_common_dir },
> + { "path.config-file", get_path_config_file },
> + { "path.git-dir", get_path_git_dir },
> + { "path.git-prefix", get_path_git_prefix },
I'm not sure about calling this 'git-prefix', 'prefix' might be more appropriate as it is about prefixing paths in the worktree rather than the git_dir.
> + { "path.grafts-file", get_path_grafts_file },
> + { "path.hooks-directory", get_path_hooks_directory },
> + { "path.index-file", get_path_index_file },
> + { "path.logs-directory", get_path_logs_directory },
We're moving away from file based refs and reflogs so I'm not sure adding this, pick-refs-file or refs-directory is a good idea as we should not be encouraging people to access these files directly.
> + { "path.objects-directory", get_path_objects_directory },
> + { "path.packed-refs-file", get_path_packed_refs_file },
> + { "path.refs-directory", get_path_refs_directory },
> + { "path.shallow-file", get_path_shallow_file },
> + { "path.superproject-working-tree", get_path_superproject_working_tree },
> + { "path.toplevel", get_path_toplevel },
'path.toplevel' matches the git-rev-parse option but 'path.work-tree' might be more descriptive?
What happens if 'path.toplevel' is requested in a bare repository?
Thanks
Phillip
> { "references.format", get_references_format },
> };
> There was a problem hiding this comment.
Thank you for the careful review — this is very helpful.
I addressed your points in the next reroll:
renamed path.git-prefix to path.prefix,
added path.work-tree (alias of path.toplevel) for clearer naming,
dropped path.logs-directory, path.packed-refs-file, and path.refs-directory to avoid encouraging direct access to refs/reflog file layout.
I also kept tests and documentation in sync in the same update.
Regarding bare repositories: path.toplevel returns an empty value there (and I added/kept test coverage for that behavior). path.work-tree follows the same behavior since it is an alias.
Thanks again for the suggestions.
There was a problem hiding this comment.
@eslam-reda-div please note: communication with the Git mailing list is not bidirectional: gitgitgadget/gitgitgadget#154. Meaning: your replies will need to be sent as per the guidance in the "reply to this" links.
There was a problem hiding this comment.
Junio C Hamano wrote on the Git mailing list (how to reply to this email):
Phillip Wood <phillip.wood123@gmail.com> writes:
>> + { "path.common-dir", get_path_common_dir },
>> + { "path.config-file", get_path_config_file },
>> + { "path.git-dir", get_path_git_dir },
>> + { "path.git-prefix", get_path_git_prefix },
>
> I'm not sure about calling this 'git-prefix', 'prefix' might be more
> appropriate as it is about prefixing paths in the worktree rather than
> the git_dir.
True.
>> + { "path.grafts-file", get_path_grafts_file },
>> + { "path.hooks-directory", get_path_hooks_directory },
>> + { "path.index-file", get_path_index_file },
>> + { "path.logs-directory", get_path_logs_directory },
>
> We're moving away from file based refs and reflogs so I'm not sure
> adding this, pick-refs-file or refs-directory is a good idea as we
> should not be encouraging people to access these files directly.
>
>> + { "path.objects-directory", get_path_objects_directory },
>> + { "path.packed-refs-file", get_path_packed_refs_file },
>> + { "path.refs-directory", get_path_refs_directory },
The same comment applies to these entries as well, as the pluggable
object database support is just beyond the horizon if I understand
correctly.
>> + { "path.shallow-file", get_path_shallow_file },
>> + { "path.superproject-working-tree", get_path_superproject_working_tree },
>> + { "path.toplevel", get_path_toplevel },
>
> 'path.toplevel' matches the git-rev-parse option but 'path.work-tree'
> might be more descriptive?
I think the "git repo" thrust comes primarily from being unfamiliar
with "rev-parse" (and I wouldn't particularly encourage new people
to become familiar with it---it grew pretty much organically driven
by scripting needs without taking UI cleanliness into consideration
very much), so not many folks would find it disturbing that
"--toplevel" corresponds to "topOfTheWorkingTree". Given that we
have a token to ask for superproject's working tree, giving a name
made after the same phrasing philosophy for the current project's
working tree would be a good thing, i.e., "path.working-tree".
> What happens if 'path.toplevel' is requested in a bare repository?
FWIW "git rev-parse --show-toplevel" dies with "must be run in a
work tree". Better or worse,
rm -fr new
git init new
cd new/.git && git rev-parse --show-toplevel
also dies the same way, which I am not sure we want to inherit when
we are making a new interrogator command.
Thanks.
There was a problem hiding this comment.
Phillip Wood wrote on the Git mailing list (how to reply to this email):
On 27/02/2026 19:51, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
> >>> + { "path.objects-directory", get_path_objects_directory },
>>> + { "path.packed-refs-file", get_path_packed_refs_file },
>>> + { "path.refs-directory", get_path_refs_directory },
> > The same comment applies to these entries as well, as the pluggable
> object database support is just beyond the horizon if I understand
> correctly.
Good point. Also what is the "shallow file" below and should scripts be poking it directly?
>>> + { "path.shallow-file", get_path_shallow_file },
>>> + { "path.superproject-working-tree", get_path_superproject_working_tree },
>>> + { "path.toplevel", get_path_toplevel },
>>
>> 'path.toplevel' matches the git-rev-parse option but 'path.work-tree'
>> might be more descriptive?
> > I think the "git repo" thrust comes primarily from being unfamiliar
> with "rev-parse" (and I wouldn't particularly encourage new people
> to become familiar with it---it grew pretty much organically driven
> by scripting needs without taking UI cleanliness into consideration
> very much), so not many folks would find it disturbing that
> "--toplevel" corresponds to "topOfTheWorkingTree". Given that we
> have a token to ask for superproject's working tree, giving a name
> made after the same phrasing philosophy for the current project's
> working tree would be a good thing, i.e., "path.working-tree".
That's a good idea
>> What happens if 'path.toplevel' is requested in a bare repository?
> > FWIW "git rev-parse --show-toplevel" dies with "must be run in a
> work tree". Better or worse,
> > rm -fr new
> git init new
> cd new/.git && git rev-parse --show-toplevel
> > also dies the same way, which I am not sure we want to inherit when
> we are making a new interrogator command.
Yes, I think printing an empty value after the key would be better - I don't think there are any paths where we care about the distinction between NULL and ""
Thanks
PhillipThere was a problem hiding this comment.
Junio C Hamano wrote on the Git mailing list (how to reply to this email):
Phillip Wood <phillip.wood123@gmail.com> writes:
>> FWIW "git rev-parse --show-toplevel" dies with "must be run in a
>> work tree". Better or worse,
>>
>> rm -fr new
>> git init new
>> cd new/.git && git rev-parse --show-toplevel
>>
>> also dies the same way, which I am not sure we want to inherit when
>> we are making a new interrogator command.
>
> Yes, I think printing an empty value after the key would be better - I
> don't think there are any paths where we care about the distinction
> between NULL and ""
If the new and safer variant of the command should signal "error" by
giving an empty string, it would work with its "--show-toplevel"
equivalent run in a bare repository. In a working tree, it would
give a full/absolute path, and never be an empty string. I am still
unsure what that new and safer one should do from inside the .git
directory. "rev-parse --show-toplevel" dies. $(cd .. && pwd) may
be another plausible and arguably more useful answer.
Your idea of equiating NULL and "", I do not think it would work
well with "git rev-parse --show-cdup" equivalent. The command will
give us an empty string from the top-level of the working tree.
Curiously, in this sequence
rm -fr new
git init new
cd new/.git && git rev-parse --show-cdup
cd objects && git rev-parse --show-cdup
two "rev-parse" do not die with "must be run in a work tree", and
worse yet, they do not give you ".." or "../../", either.
It seems that one rule of "rev-parse --show-<some-path>" is that
"when you are inside .git directory of a non-bare repository, we'd
behave as if you are in a bare repository as if its working tree
does not exist", and the above is consistent with that rule.
"--show-cdup" does not fail but gives an empty string when run
anywhere in a bare repository.
But among "rev-parse --show-<anything>" that are about working tree
paths, there seems no unifying rule on what to do when in a bare
repsitory. As we already saw, "--show-toplevel" dies without a
working tree. This reflects the history of rev-parse that grew
organizally without a grand design.
If we are adding new and safer interface to these pieces of
information to "repo info", we may want to straighten these rules.
|
User |
|
/submit |
|
Submitted as pull.2208.v5.git.git.1772220640.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
| @@ -22,7 +22,12 @@ static const char *const repo_usage[] = { | |||
| NULL | |||
There was a problem hiding this comment.
Lucas Seiki Oshiro wrote on the Git mailing list (how to reply to this email):
> Also teach git repo info to accept category names (for example,
> layout) and expand them to matching key.* entries in request
> order.
If you have a patch where its description says "Do A. Also do B"
when A and B are unrelated, there are good chances that it should
be splitted into two commits. This patch is an example of that.|
User |
|
Lucas Seiki Oshiro wrote on the Git mailing list (how to reply to this email): > * No git repo structure feature changes.
Patch 4/11 changes git repo structure
> * No t1901 structure test changes.
Patch 8/11 changes t1901
> * No structure metrics/docs additions.
Patch 9/11 changes git-repo.adoc
> Commit structure
> ================
>
> * repo: teach info context and category keys
> * repo: add path keys to repo info
> * repo: add --path-format for info path output
> * t1900: cover repo info path keys and path-format
> * docs: describe repo info path keys
Only 5 commits are described here, while you sent 11 patches in this series. |
| `path.config-file`:: | ||
| The path to the `config` file in the git directory. | ||
|
|
||
| `path.git-dir`:: |
There was a problem hiding this comment.
Phillip Wood wrote on the Git mailing list (how to reply to this email):
Hi Eslam
On 27/02/2026 19:30, Eslam reda ragheb via GitGitGadget wrote:
> From: Eslam reda ragheb <eslam.reda.div@gmail.com>
> > Rename path.git-prefix to path.prefix, add path.work-tree as an alias
> for path.toplevel, and drop reflog/ref-file-oriented path keys.
> > This narrows the path surface to keys that are less tied to direct
> file access while keeping tests and documentation in sync.
> > Also normalize prefix handling in repo_info context so path.prefix has
> a stable empty-string behavior.
When you change a patch series based on a reviewer's feedback, you should use "git rebase -i" to edit or fixup the existing commits rather than adding new changes on top. That keeps the history cleaner as we don't need to know "I implemented it like this and than changed it to that". It also makes the patch series easier to review as reviewers don't waste their time commenting on changes in one patch that are then deleted in a later patch.
Thanks
Phillip
> Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
> ---
> Documentation/git-repo.adoc | 14 ++++-------
> builtin/repo.c | 45 ++++++++--------------------------
> t/t1900-repo.sh | 48 +++++++++++++++++--------------------
> 3 files changed, 36 insertions(+), 71 deletions(-)
> > diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc
> index b575977a4b..3d34c6edca 100644
> --- a/Documentation/git-repo.adoc
> +++ b/Documentation/git-repo.adoc
> @@ -114,7 +114,7 @@ Here's a list of the available keys and the values that they return:
> `path.git-dir`::
> The path to the git directory.
> > -`path.git-prefix`::
> +`path.prefix`::
> The path of the current working directory relative to the top-level
> directory.
> > @@ -127,18 +127,9 @@ Here's a list of the available keys and the values that they return:
> `path.index-file`::
> The path to the index file.
> > -`path.logs-directory`::
> - The path to the `logs` directory.
> -
> `path.objects-directory`::
> The path to the objects directory.
> > -`path.packed-refs-file`::
> - The path to the `packed-refs` file.
> -
> -`path.refs-directory`::
> - The path to the `refs` directory.
> -
> `path.shallow-file`::
> The path to the `shallow` file.
> > @@ -150,6 +141,9 @@ Here's a list of the available keys and the values that they return:
> The path to the top-level working tree directory, or an empty string
> for bare repositories.
> > +`path.work-tree`::
> + Alias for `path.toplevel`.
> +
> `references.format`::
> The reference storage format. The valid values are:
> +
> diff --git a/builtin/repo.c b/builtin/repo.c
> index ecd9d3aee5..9fbd13a358 100644
> --- a/builtin/repo.c
> +++ b/builtin/repo.c
> @@ -109,10 +109,9 @@ static int get_path_git_dir(struct repo_info *info, struct strbuf *buf)
> return 0;
> }
> > -static int get_path_git_prefix(struct repo_info *info, struct strbuf *buf)
> +static int get_path_prefix(struct repo_info *info, struct strbuf *buf)
> {
> - if (info->prefix)
> - strbuf_addstr(buf, info->prefix);
> + strbuf_addstr(buf, info->prefix);
> return 0;
> }
> > @@ -137,39 +136,12 @@ static int get_path_index_file(struct repo_info *info, struct strbuf *buf)
> return 0;
> }
> > -static int get_path_logs_directory(struct repo_info *info, struct strbuf *buf)
> -{
> - struct strbuf path = STRBUF_INIT;
> -
> - repo_info_add_path(info, buf, repo_git_path_replace(info->repo, &path, "logs"));
> - strbuf_release(&path);
> - return 0;
> -}
> -
> static int get_path_objects_directory(struct repo_info *info, struct strbuf *buf)
> {
> repo_info_add_path(info, buf, repo_get_object_directory(info->repo));
> return 0;
> }
> > -static int get_path_packed_refs_file(struct repo_info *info, struct strbuf *buf)
> -{
> - struct strbuf path = STRBUF_INIT;
> -
> - repo_info_add_path(info, buf, repo_git_path_replace(info->repo, &path, "packed-refs"));
> - strbuf_release(&path);
> - return 0;
> -}
> -
> -static int get_path_refs_directory(struct repo_info *info, struct strbuf *buf)
> -{
> - struct strbuf path = STRBUF_INIT;
> -
> - repo_info_add_path(info, buf, repo_git_path_replace(info->repo, &path, "refs"));
> - strbuf_release(&path);
> - return 0;
> -}
> -
> static int get_path_shallow_file(struct repo_info *info, struct strbuf *buf)
> {
> struct strbuf path = STRBUF_INIT;
> @@ -201,6 +173,11 @@ static int get_path_toplevel(struct repo_info *info, struct strbuf *buf)
> return 0;
> }
> > +static int get_path_work_tree(struct repo_info *info, struct strbuf *buf)
> +{
> + return get_path_toplevel(info, buf);
> +}
> +
> static int get_references_format(struct repo_info *info, struct strbuf *buf)
> {
> struct repository *repo = info->repo;
> @@ -217,17 +194,15 @@ static const struct field repo_info_fields[] = {
> { "path.common-dir", get_path_common_dir },
> { "path.config-file", get_path_config_file },
> { "path.git-dir", get_path_git_dir },
> - { "path.git-prefix", get_path_git_prefix },
> { "path.grafts-file", get_path_grafts_file },
> { "path.hooks-directory", get_path_hooks_directory },
> { "path.index-file", get_path_index_file },
> - { "path.logs-directory", get_path_logs_directory },
> { "path.objects-directory", get_path_objects_directory },
> - { "path.packed-refs-file", get_path_packed_refs_file },
> - { "path.refs-directory", get_path_refs_directory },
> + { "path.prefix", get_path_prefix },
> { "path.shallow-file", get_path_shallow_file },
> { "path.superproject-working-tree", get_path_superproject_working_tree },
> { "path.toplevel", get_path_toplevel },
> + { "path.work-tree", get_path_work_tree },
> { "references.format", get_references_format },
> };
> > @@ -378,7 +353,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,
> enum output_format format = FORMAT_KEYVALUE;
> struct repo_info info = {
> .repo = repo,
> - .prefix = prefix,
> + .prefix = prefix ? prefix : "",
> .path_format = PATH_FORMAT_ABSOLUTE,
> };
> int all_keys = 0;
> diff --git a/t/t1900-repo.sh b/t/t1900-repo.sh
> index dcacf84cc3..2351b772b2 100755
> --- a/t/t1900-repo.sh
> +++ b/t/t1900-repo.sh
> @@ -13,17 +13,15 @@ REPO_INFO_KEYS='
> path.common-dir
> path.config-file
> path.git-dir
> - path.git-prefix
> path.grafts-file
> path.hooks-directory
> path.index-file
> - path.logs-directory
> path.objects-directory
> - path.packed-refs-file
> - path.refs-directory
> + path.prefix
> path.shallow-file
> path.superproject-working-tree
> path.toplevel
> + path.work-tree
> references.format
> '
> > @@ -31,17 +29,15 @@ REPO_INFO_PATH_KEYS='
> path.common-dir
> path.config-file
> path.git-dir
> - path.git-prefix
> path.grafts-file
> path.hooks-directory
> path.index-file
> - path.logs-directory
> path.objects-directory
> - path.packed-refs-file
> - path.refs-directory
> + path.prefix
> path.shallow-file
> path.superproject-working-tree
> path.toplevel
> + path.work-tree
> '
> > # Test whether a key-value pair is correctly returned
> @@ -172,12 +168,12 @@ test_expect_success 'path.toplevel is empty in bare repository' '
> test_cmp expect actual
> '
> > -test_expect_success 'path.git-prefix matches rev-parse --show-prefix' '
> +test_expect_success 'path.prefix matches rev-parse --show-prefix' '
> git init path-prefix &&
> mkdir -p path-prefix/a/b &&
> expected_value=$(git -C path-prefix/a/b rev-parse --show-prefix) &&
> - echo "path.git-prefix=$expected_value" >expect &&
> - git -C path-prefix/a/b repo info path.git-prefix >actual &&
> + echo "path.prefix=$expected_value" >expect &&
> + git -C path-prefix/a/b repo info path.prefix >actual &&
> test_cmp expect actual
> '
> > @@ -209,27 +205,27 @@ test_expect_success 'git-path style keys match rev-parse --git-path' '
> git -C path-git-path repo info path.config-file >actual &&
> test_cmp expect actual &&
> > - expected_value=$(git -C path-git-path rev-parse --path-format=absolute --git-path logs) &&
> - echo "path.logs-directory=$expected_value" >expect &&
> - git -C path-git-path repo info path.logs-directory >actual &&
> - test_cmp expect actual &&
> -
> - expected_value=$(git -C path-git-path rev-parse --path-format=absolute --git-path packed-refs) &&
> - echo "path.packed-refs-file=$expected_value" >expect &&
> - git -C path-git-path repo info path.packed-refs-file >actual &&
> - test_cmp expect actual &&
> -
> - expected_value=$(git -C path-git-path rev-parse --path-format=absolute --git-path refs) &&
> - echo "path.refs-directory=$expected_value" >expect &&
> - git -C path-git-path repo info path.refs-directory >actual &&
> - test_cmp expect actual &&
> -
> expected_value=$(git -C path-git-path rev-parse --path-format=absolute --git-path shallow) &&
> echo "path.shallow-file=$expected_value" >expect &&
> git -C path-git-path repo info path.shallow-file >actual &&
> test_cmp expect actual
> '
> > +test_expect_success 'path.work-tree matches path.toplevel' '
> + git init path-work-tree &&
> + expected_value=$(git -C path-work-tree rev-parse --show-toplevel) &&
> + echo "path.work-tree=$expected_value" >expect &&
> + git -C path-work-tree repo info path.work-tree >actual &&
> + test_cmp expect actual
> +'
> +
> +test_expect_success 'path.work-tree is empty in bare repository' '
> + git init --bare bare-path-work-tree &&
> + echo "path.work-tree=" >expect &&
> + git -C bare-path-work-tree repo info path.work-tree >actual &&
> + test_cmp expect actual
> +'
> +
> test_expect_success 'path.superproject-working-tree is empty when not a submodule' '
> git init path-superproject &&
> echo "path.superproject-working-tree=" >expect &&ae908e7 to
5205c82
Compare
Introduce a repo_info context and thread it through get_value_fn, field lookup, and value-printing helpers. This prepares repo info for fields that need invocation-specific context in addition to the repository handle. Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
Teach repo info to accept category names (for example, layout) and expand them to matching key.* entries in request order. Explicit keys keep their existing behavior; unknown keys or categories still report clear errors. Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
Add a path category to git repo info with key-value pairs that mirror repository paths users commonly retrieve via rev-parse and git-path lookups. This makes scripting against repo metadata more direct and avoids shelling out to multiple commands for related paths. The new keys are introduced as explicit path.* entries in repo_info_fields and are resolved through dedicated helpers. This keeps lookup behavior predictable and makes future path additions straightforward. Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
Teach git repo info to accept --path-format=(absolute|relative) so scripts can request stable path style explicitly. This aligns path.* output behavior with existing rev-parse usage patterns and reduces ad-hoc path conversion in callers. The option is wired through repo_info context and used by repo_info_add_path(), so path formatting remains centralized and consistent across all path.* keys. Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
Extend t1900 to validate category-key expansion, path.* key behavior, and --path-format handling for git repo info. The tests compare repo info output to equivalent rev-parse values. This ensures behavior remains aligned with existing plumbing semantics. Also keep mixed key/category ordering coverage so callers can rely on deterministic output order when combining explicit keys with category requests. Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
5205c82 to
02c8fa2
Compare
Document repo info category requests, path.* keys, and --path-format behavior. Signed-off-by: Eslam reda ragheb <eslam.reda.div@gmail.com>
02c8fa2 to
b98490a
Compare
|
/submit |
|
Submitted as pull.2208.v6.git.git.1772428548.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
This series now focuses only on
git repo infoimprovements.It introduces category-aware key requests, adds path-oriented keys (
path.*), and adds--path-format=(absolute|relative)so scripts can request stable path rendering behavior.What this PR does
For
git repo info, this series:repo_infocontext plumbing,layoutexpands tolayout.*),path.*) for common repository locations,--path-format=(absolute|relative)to control path output style.Tests and documentation are updated accordingly.
What this PR does NOT do
git repo structurefeature changes.t1901structure test changes.Key naming/scope adjustments from review
path.git-prefixtopath.prefix,path.working-tree(alias forpath.toplevel),path.logs-directorypath.packed-refs-filepath.refs-directorypath.shallow-fileCommit structure
All commits are signed off with the same real-name identity.
Changes since previous revision
repo structurecode/tests/docs from this branch,Validation
Focused (Linux Docker):
make -C t test T=t1900-repo.sh→ passed (53/53)cc: Phillip Wood phillip.wood123@gmail.com
cc: Lucas Seiki Oshiro lucasseikioshiro@gmail.com