{"thread":{"id":"65386","subject":"[GSoC] Draft Proposal: Enhancing the 'git repo' command","startedAt":"2026-03-30T13:14:52Z","lastAt":"2026-03-30T13:14:52Z","messageCount":1,"participants":["Mahmoud Samy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"540368","messageId":"CAC5WPUdUqAkjmO+rw9hGZ9O1d3y1+HvbA87sYmKw=Q7YFpxkmg@mail.gmail.com","threadId":"65386","inReplyTo":null,"subject":"[GSoC] Draft Proposal: Enhancing the 'git repo' command","fromName":"Mahmoud Samy","fromEmail":"mahmoudsamymahmoud01@gmail.com","sentAt":"2026-03-30T13:14:40Z","receivedAt":"2026-03-30T13:14:52Z","isPatch":false,"sender":{"key":"mahmoudsamymahmoud01@gmail.com","avatar":null},"body":"Hello Git community,\nI am Mahmoud Samy, a fourth-year computer science student. I am\nwriting to share a draft of my proposal for GSoC 2026 for \"Improve the\nnew git repo command\". I would really appreciate any feedback,\ncorrections, enhancements from the community and mentors to refine my\nplan.\n\nBelow you will find my implementation plan, testing plan, and\ntimeline. I am particularly interested in hearing your thoughts about:\n1. Using lower-bound binary search for optimal category-based prefix lookups.\n2. Defaulting to absolute paths for new path.* keys while offering a\n--path-format=(absolute|relative) toggle.\n3. Adding a --assess flag to `git repo structure` to display git-sizer\nstyle concern markers.\n\nThank you for your time and guidance. I look forward to hearing from you.\n\nAs well I have finished the microproject that I have previously sent\nto you \"Fix Improper Pluralization to Use ngettext()\" in `add-patch.c`\nand just waiting for the confirmation to open a PR.\n\n# **Git Repo Info Improvement**\n\n# **Personal Information**\n\n**Name**: Mahmoud Samy\n**University**: Cairo University, Faculty of Computers and Artificial\nIntelligence\n**Email**: mahmoudsamymahmoud01@gmail.com\n**Phone Number**: \\+20 01157196641\n**GitHub**: https://github.com/mahmoudsamyhamed\n**LinkedIn**: https://linkedin.com/in/mahmoud-samy-133355258\n**Country of Residence**: Egypt\n**Timezone**: EET (GMT+2)\n\nMy name is Mahmoud Samy, and I am a fourth-year Computer Science\nstudent at Cairo University. I am deeply interested in version control\nsystems and software architecture. I am eager to contribute to Git\nthrough the Google Summer of Code program by working on the **\"git\nrepo info improvement\"** project. My goal is to enhance the diagnostic\ncapabilities and structural modularity of Git’s repository reporting\ntools while actively engaging with the community's design.\n\n# **Project Motivation**\n\nThe current implementation of `git repo info` serves as a foundation\nfor inspecting repository state, but there is significant room for\nmodernization. By migrating features currently residing in `git\nrev-parse` and integrating advanced statistics similar to `git-sizer`,\nwe can provide users and automated tools with a more comprehensive,\ncentralized interface for repository metadata. Furthermore, this\nproject presents an opportunity to contribute to the ongoing effort of\nrefactoring Git's codebase to be more library-like by reducing\nreliance on global state.\n\n# **Implementation Plan**\n\n# **Enhancing git repo**\n\nThis implementation plan outlines the technical approach to expanding\nthe capabilities of the git repo command. The project is divided into\nfive core phases: addressing technical debt, improving query\nergonomics, expanding metadata retrieval, establishing path formatting\nstandards, and integrating deep repository analytics.\n\n## **Phase 1: Removing Global State Dependency (the\\_repository)**\n\n**Objective:** Eliminate the reliance on the global `the_repository`\nvariable within `builtin/repo.c` to align with Git's ongoing effort to\nremove global state.\n**Implementation Details:**\n\n1. **Refactor get\\_layout\\_bare():** Currently, this relies on the\nglobal `is_bare_repository()`. I will update this to use the passed\n`struct repository *repo` parameter by checking\n`repo_get_work_tree(repo)`. If it returns NULL, the repository is\nbare.\n2. **Update Callback Data Structures:** The `count_objects()` callback\ncurrently falls back to `the_repository` when parsing object buffers\nbecause it lacks context. I will add a `struct repository *repo`\npointer to `struct count_objects_data`.\n3. **Inject Repository Context:** In `structure_count_objects()`, I\nwill initialize the new `data.repo` field with the current repository\ninstance.\n4. **Update the Parsing Call:** I will modify the\n`parse_object_buffer()` call at the site of `count_objects()` to use\n`data->repo` instead of `the_repository`.\n5. **Remove the Macro:** Finally, I will delete `#define\nUSE_THE_REPOSITORY_VARIABLE` from the top of the file, ensuring the\ncompiler catches any future regressions.\n\n## **Phase 2: Category-Based Key Lookups**\n\n**Objective:** Allow users to query an entire category of metadata\n(e.g., git repo info layout) rather than fetching keys one by one,\nwhile maintaining optimal lookup performance.\n**Implementation Details:**\n**Retain O(log N) Efficiency:** Because the repo\\_info\\_field registry\nis maintained as a sorted array, falling back to an O(N) linear scan\nis unnecessary. We will utilize binary search to locate prefixes\nefficiently.\n **Implement a Lower-Bound Binary Search:** Standard C library\nbsearch() is insufficient for category lookups because, when multiple\nmatching prefixes exist (e.g., layout.bare and layout.shallow), it\ndoes not guarantee returning the *first* occurrence. I will implement\na custom lower-bound binary search to pinpoint the exact starting\nindex of the first matching prefix.\n**Forward Scanning & Boundary Checks:** Starting from the discovered\nlower-bound index, the loop will scan forward. For each key, it will\nuse strncmp() to ensure the prefix matches. To prevent erroneous\npartial matches (e.g., a query for layout.b matching layout.bare), the\ncode will verify that the character immediately following the matched\nprefix length is either \\\\0 (an exact match) or . (a valid category\nprefix).\n **Early Termination:** The forward scan will efficiently break the\nmoment it encounters a key that no longer matches the requested\nprefix, ensuring we only evaluate the relevant slice of the array.\n\n## **Phase 3: Expanding Repository Metadata (Path-Related Values)**\n\n**Objective:** Port critical path-querying functionality from `git\nrev-parse` into the structured `git repo info` command.\n**Implementation Details:**\nI will add new entries to the `repo_info_field` registry, ensuring\nlexicographical order is maintained.\n\n1. **Core Directory Paths:**\n   * `path.git-dir`: Implemented using `repo_get_git_dir(repo)`.\n   * `path.common-dir`: Implemented using `repo_get_common_dir(repo)`\n(crucial for linked worktrees).\n   * `path.toplevel`: Implemented using `repo_get_work_tree(repo)`,\nreturning an error if run in a bare repository.\n   * `path.superproject-working-tree`: Implemented using\n`get_superproject_working_tree()`.\n2. **git-path Derived Values:**\n   * `path.graft-file`: Implemented using `repo_get_graft_file(repo)`.\n   * `path.index-file`: Implemented using `repo_get_index_file(repo)`.\n   * `path.objects-dir`: Implemented using `repo_get_object_directory(repo)`.\n   * `path.hooks-dir`: Implemented by checking\n`repo_settings_get_hooks_path(repo)`, falling back to the default\nhooks path if unconfigured.\n   * `path.prefix`: Implemented by reading `startup_info->prefix` to\nget the subdirectory path relative to the working tree root.\n3. **Paths Adjusted by update\\_common\\_dir():** Add keys like\n`path.shallow-file` and `path.config-file` utilizing the internal\ncached paths of the repository struct.\n\n## **Phase 4: Path Formatting Architecture**\n\n**Objective:** Resolve the design decision between absolute and\nrelative paths, ensuring robustness for script consumption (especially\nwith `--format=nul`).\n**Implementation Details:**\n\n1. **Canonical Absolute Defaults:** All internal `get_path_*`\nfunctions will return absolute paths by default. This is critical for\nNUL-delimited script consumers to prevent silent path-resolution bugs\nwhen changing directories.\n2. **CLI Option Integration:** I will introduce a\n`--path-format=(absolute|relative)` argument to the `git repo info`\ncommand, defaulting to absolute.\n3. **Output-Layer Formatting:** Rather than complicating the\n`get_value_fn` signatures, formatting will be applied at the output\nlayer (e.g., inside `print_field`).\n4. **Relative Conversion:** If the user specifies\n`--path-format=relative`, the program will pass the retrieved absolute\npath through `relative_path()` (using the current working directory\nprefix) just before printing.\n\n## **Phase 5: Deep Analytics (git-sizer Functionality)**\n\n**Objective:** Bring high-value repository health metrics natively\ninto `git repo structure` without requiring external Go binaries.\n**Implementation Details:**\n\n1. **History Depth Calculation:** I will tap into the `commit-graph`\noptimization. During the `count_objects` walk, when encountering\n`OBJ_COMMIT`, I will check `commit_graph_generation(commit)`. If a\ncommit graph exists, the maximum generation number effectively yields\nthe history depth in O(1) time per commit. If no graph exists, it will\ngracefully fallback or skip to avoid expensive traversals.\n2. **Path Depth and Length Tracking:** The `count_objects()` callback\nalready receives a path parameter for trees. I will implement\nlightweight trackers:\n   * *Max Path Depth:* Count the number of `/` characters in the path string.\n   * *Max Path Length:* Track the maximum `strlen(path)`.\n3. **Total Disk Size Approximation:** Instead of shelling out to `du`,\nI will sum the already-calculated `disk_size` values across all four\nobject types (Commits, Trees, Blobs, Tags) to provide a highly\naccurate total disk footprint.\n4. **Community Discussion (Concern Levels):** As part of the community\ninteraction requirement, I will draft a discussion for the mailing\nlist regarding an optional `--assess` flag. This flag would apply\ngit-sizer-style heuristics to flag concerning metrics (e.g., \\>500k\ncommits) directly in the output table.\n\n# **Testing Plan**\n\nTesting will be heavily integrated into `t1900-repo-info.sh` and\n`t1901-repo-structure.sh`. The focus is on logical validation, edge\ncases, and ensuring strict parity with rev-parse.\n\n* **Regression Tracking (the\\_repository removal)**\n  * Verify compilation succeeds with 0 errors after macro removal.\nEnsure the entire existing `t1900` and `t1901` test suites pass\ncompletely unchanged.\n* **Path Keys Output**\n  * Validate expected path strings for normal repos, bare repos, and\nlinked worktrees. Ensure `path.toplevel` accurately tracks the working\ntree root from deeply nested subdirectories.\n* **Category Prefix Lookups**\n  * Test that querying a category (e.g., `layout`) successfully\nreturns all child keys. Verify that invalid categories or partial\nstrings (e.g., `layout.b`) correctly return a \"not found\" error.\n* **Path Formatting Flag**\n  * Assert that all paths default to absolute. Test\n`--path-format=relative` from various subdirectory depths to ensure\naccurate path calculation back to the Git directory.\n* **Layout and Object Keys**\n  * Assert that `layout.inside-git-dir` and `layout.inside-work-tree`\noutput the correct boolean depending on where the command is executed.\n* **rev-parse Consistency**\n  * Programmatically compare the outputs of `git repo info <key>`\ndirectly against their `git rev-parse` counterparts to guarantee\nidentical behavior.\n* **Structure Metrics (git-sizer)**\n  * Validate history depth calculations on both linear and highly\nbranched/merged histories. Assert that max path length/depth correctly\nidentifies deeply nested mock directories.\n* **Output Formats**\n  * Verify all new keys format correctly across `--format=lines`,\n`--format=nul`, and `-z`.\n* **Edge Cases**\n  * Validate safe error handling for missing commit-graphs, duplicate\nkey queries, and setups using `sha256` or `reftable` formats.\n\n# **Deliverables**\n\nThe key deliverables for this project align with the core objectives:\n\n* Implementation of repo info logic without dependency on the\n`the_repository` global variable.\n* A new category-based key system for improved output readability and parsing.\n* Consolidated access to path-related values from `git rev-parse`\nwithin `git repo info`.\n* Integration of `git-sizer`\\-inspired deep analysis and structural statistics.\n\n# **3\\. Project Timeline (12 Weeks)**\n\n* **Community Bonding Period (May 1 \\- May 31):**\n  * Engage with the mailing list to finalize the design decision\nregarding `--path-format`.\n  * Draft a discussion on adding `--assess` risk thresholds (git-sizer\nheuristics) to gather community consensus.\n* **Week 1-2 (June 1 \\- June 14):**\n  * Remove `the_repository` global dependency.\n  * Implement category-based prefix lookups.\n  * Write and submit Category 1 and 3 test suites.\n* **Week 3-5 (June 15 \\- July 5):**\n  * Implement all new `path.*`, `layout.*`, and `object.*` keys.\n  * Write and submit Category 2 and 5 test suites.\n* **Week 6-7 (July 6 \\- July 19):**\n  * Implement the `--path-format=(absolute|relative)` option and\noutput-layer relative conversion logic.\n  * Write and submit Category 4 and 6 tests.\n  * **Midterm Evaluation.**\n* **Week 8-10 (July 20 \\- August 9):**\n  *  Implement git-sizer structure metrics (history depth, path depth,\npath length, total disk size).\n  * Write and submit Category 7 test suite.\n* **Week 11-12 (August 10 \\- August 23):**\n  * Address final mailing list feedback and code reviews.\n  * Ensure Category 8 and 9 edge-case test coverage is complete.\n  * Finalize documentation and submit the final GSoC report.\n\nBest regards,\nMahmoud Samy\nGithub: @mahmoudsamyhamed | https://github.com/mahmoudsamyhamed\n"}]}