🔍 Duplicate Code Detected: Gitrest route FS-manager setup
Analysis of commit 705e92735ec8ed44b6819739520bdd22d3c27f6d
Assignee: @copilot
Summary
Multiple Gitrest HTTP route handlers contain a near-identical block that:
- derives
repoManagerParams from the request,
- opens/gets a repo manager,
- creates a filesystem manager (
getFilesystemManagerFactory(...).create(...)), and
- runs
checkSoftDeleted(...).
This duplication increases the risk of inconsistent behavior when the soft-delete rules, FS manager creation, or ephemeral-container handling changes.
Note: this workflow environment has a shallow git history (no parent commit available), so “recently changed files” couldn’t be derived via git diff. A repo-wide scan of eligible .ts/.mjs/.cjs (excluding tests/workflows) was used, and the finding was validated by inspecting the matched blocks.
Duplication Details
Pattern: “open repo → create fsManager → checkSoftDeleted”
- Severity: Medium
- Occurrences: 8 (exact duplicate block; additional near-duplicates exist in the same files)
- Locations:
server/gitrest/packages/gitrest-base/src/routes/git/blobs.ts (lines 63–80)
server/gitrest/packages/gitrest-base/src/routes/git/refs.ts (lines 44–61)
server/gitrest/packages/gitrest-base/src/routes/git/refs.ts (lines 70–87)
server/gitrest/packages/gitrest-base/src/routes/git/refs.ts (lines 163–180)
server/gitrest/packages/gitrest-base/src/routes/git/tags.ts (lines 62–79)
server/gitrest/packages/gitrest-base/src/routes/git/trees.ts (lines 60–77)
server/gitrest/packages/gitrest-base/src/routes/repository/commits.ts (lines 37–54)
server/gitrest/packages/gitrest-base/src/routes/repository/contents.ts (lines 29–46)
Code sample (from blobs.ts):
const repoManagerParams = getRepoManagerParamsFromRequest(request);
const resultP = repoManagerFactory
.open(repoManagerParams)
.then(async (repoManager) => {
const fileSystemManagerFactory = getFilesystemManagerFactory(
fileSystemManagerFactories,
repoManagerParams.isEphemeralContainer ?? false,
);
const fsManager = fileSystemManagerFactory.create({
...repoManagerParams.fileSystemManagerParams,
rootDir: repoManager.path,
});
await checkSoftDeleted(
fsManager,
repoManager.path,
repoManagerParams,
repoPerDocEnabled,
);
// handler-specific repoManager call...
});
Impact Analysis
- Maintainability: Future changes to soft-delete semantics, repo-per-doc behavior, or FS manager options require editing many route handlers.
- Bug Risk: High likelihood of drift (one route updated, another missed), especially since some handlers use
repoManagerFactory.open(...) while others use getRepoManagerFromWriteAPI(...).
- Code Bloat: ~18 duplicated lines per occurrence (+ near-duplicates), spread across multiple route modules.
Refactoring Recommendations
-
Extract a shared helper in server/gitrest/packages/gitrest-base/src/utils
- Proposed shape (example):
async function openRepoAndGetFsManager(request, { repoManagerFactory, fileSystemManagerFactories, repoPerDocEnabled, write: boolean }): Promise<{ repoManagerParams, repoManager, fsManager }>
- Centralize:
getRepoManagerParamsFromRequest(request)
getFilesystemManagerFactory(...).create(...)
checkSoftDeleted(...)
- Keep
open vs getRepoManagerFromWriteAPI selection as a parameter.
-
Optional: wrap the error-handling/promise plumbing
- Consider a helper that returns the
resultP already wired with .catch((error) => logAndThrowApiError(...)) so route handlers become small and consistent.
Implementation Checklist
Analysis Metadata
- Analyzed Files: 2,835 eligible
.ts/.mjs/.cjs files (excluding tests/workflows)
- Detection Method: Exact clone scan + Serena-assisted inspection
- Commit:
705e92735ec8ed44b6819739520bdd22d3c27f6d
- Analysis Date: 2026-04-11
Generated by Duplicate Code Detector · ◷
To install this agentic workflow, run
gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4
🔍 Duplicate Code Detected: Gitrest route FS-manager setup
Analysis of commit
705e92735ec8ed44b6819739520bdd22d3c27f6dAssignee:
@copilotSummary
Multiple Gitrest HTTP route handlers contain a near-identical block that:
repoManagerParamsfrom the request,getFilesystemManagerFactory(...).create(...)), andcheckSoftDeleted(...).This duplication increases the risk of inconsistent behavior when the soft-delete rules, FS manager creation, or ephemeral-container handling changes.
Duplication Details
Pattern: “open repo → create fsManager → checkSoftDeleted”
server/gitrest/packages/gitrest-base/src/routes/git/blobs.ts(lines 63–80)server/gitrest/packages/gitrest-base/src/routes/git/refs.ts(lines 44–61)server/gitrest/packages/gitrest-base/src/routes/git/refs.ts(lines 70–87)server/gitrest/packages/gitrest-base/src/routes/git/refs.ts(lines 163–180)server/gitrest/packages/gitrest-base/src/routes/git/tags.ts(lines 62–79)server/gitrest/packages/gitrest-base/src/routes/git/trees.ts(lines 60–77)server/gitrest/packages/gitrest-base/src/routes/repository/commits.ts(lines 37–54)server/gitrest/packages/gitrest-base/src/routes/repository/contents.ts(lines 29–46)Code sample (from
blobs.ts):Impact Analysis
repoManagerFactory.open(...)while others usegetRepoManagerFromWriteAPI(...).Refactoring Recommendations
Extract a shared helper in
server/gitrest/packages/gitrest-base/src/utilsasync function openRepoAndGetFsManager(request, { repoManagerFactory, fileSystemManagerFactories, repoPerDocEnabled, write: boolean }): Promise<{ repoManagerParams, repoManager, fsManager }>getRepoManagerParamsFromRequest(request)getFilesystemManagerFactory(...).create(...)checkSoftDeleted(...)openvsgetRepoManagerFromWriteAPIselection as a parameter.Optional: wrap the error-handling/promise plumbing
resultPalready wired with.catch((error) => logAndThrowApiError(...))so route handlers become small and consistent.Implementation Checklist
server/gitrest/packages/gitrest-base/src/utilsAnalysis Metadata
.ts/.mjs/.cjsfiles (excluding tests/workflows)705e92735ec8ed44b6819739520bdd22d3c27f6d