Skip to content

Conversation

@jeremysprofile
Copy link

@jeremysprofile jeremysprofile commented Dec 18, 2025

Description

return the shorter (closer to cwd) path rather than preferring .git files to .git folders.

Motivation and Context

The previous method preferred finding .git files over .git/ directories. That doesn't work if, for some reason, the user a .git/ directory inside the repo with commitlint and that repo path is nested inside another git repo. Ignoring the fact that this isn't a standard use of git, it still works, and can be trivially supported by comparing the path lengths.

Fixed bug when running commitlint as part of pre-commit from git repo nested inside another git repo.

Usage examples

n/a

How Has This Been Tested?

Created unit test. Ran yarn test @commitlint/top-level

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

The previous method preferred finding `.git` files over `.git/` directories.
That doesn't work if, for some reason, the user a `.git/` directory inside
the repo with commitlint and that repo path is nested inside another git repo.
Ignoring the fact that this isn't a standard use of git, it still works, and
can be trivially supported by comparing the path lengths.

Priority: Low
Tests: None, but there were none in @commitlint before this, either.
Risk: Low
Add a unit test showing the previous change works as expected.
@codesandbox-ci
Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in the .git discovery logic to prefer the closer .git path when both a file and directory are found. This addresses an edge case where a git repository with commitlint is nested inside another git repository.

Key Changes:

  • Modified the searchDotGit function to compare path lengths when both .git file and directory are found
  • Added comprehensive test coverage for the new logic including edge cases for nested repositories and submodules

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
@commitlint/top-level/src/index.ts Added logic to compare path lengths and return the closer .git when both file and directory exist
@commitlint/top-level/src/index.test.ts Added comprehensive test suite with 4 tests covering basic functionality, nested repos, submodules, and missing .git scenarios
@commitlint/top-level/package.json Added @commitlint/test as a dev dependency for testing utilities

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +27 to +28
// Return whichever is deeper (closer to cwd) by comparing path lengths
return foundFile.length > foundDir.length ? foundFile : foundDir;
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While path length comparison works for determining proximity in typical cases, it's fragile and relies on filesystem conventions. Consider using path segment counting or explicit path comparison methods for more robust and maintainable code. For example, comparing foundFile.split(path.sep).length vs foundDir.split(path.sep).length would make the intent clearer and be more resilient to edge cases.

Suggested change
// Return whichever is deeper (closer to cwd) by comparing path lengths
return foundFile.length > foundDir.length ? foundFile : foundDir;
// Return whichever is deeper (closer to cwd) by comparing path segment counts
const fileDepth = path.resolve(foundFile).split(path.sep).length;
const dirDepth = path.resolve(foundDir).split(path.sep).length;
return fileDepth > dirDepth ? foundFile : foundDir;

Copilot uses AI. Check for mistakes.
const foundDir = await findUp(".git", { cwd, type: "directory" });

if (foundFile && foundDir) {
// Return whichever is deeper (closer to cwd) by comparing path lengths
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "whichever is deeper (closer to cwd)" but the code returns the longer path. In the context of file paths, "deeper" typically means more nested (more path segments), not a longer string. This mismatch between comment and implementation could be confusing.

Suggested change
// Return whichever is deeper (closer to cwd) by comparing path lengths
// Return whichever has the longer path string

Copilot uses AI. Check for mistakes.
@escapedcat
Copy link
Member

Hey, thanks!

Have a look at copilots feedback please.

And adjust your commit message ;)

✖ scope must be one of [commitlint-config-angular, commitlint-config-lerna-scopes, commitlint-config-nx-scopes, commitlint-config-patternplate, commitlint, cli, config-angular-type-enum, config-angular, config-conventional, config-lerna-scopes, config-nx-scopes, config-patternplate, config-pnpm-scopes, config-rush-scopes, config-validator, config-workspace-scopes, core, cz-commitlint, ensure, execute-rule, format, is-ignored, lint, load, message, parse, prompt-cli, prompt, read, resolve-extends, rules, to-lines, top-level, travis-cli, types, vitest-environment-commitlint, test, utils] [scope-enum]

✖ found 1 problems, 0 warnings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants