microsoft / microsoft/FluidFramework

Duplicate Code: GitRest routes repeat repo open + fsManager setup + soft-delete check

Open
#26,929 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4.9k
Forks
586
Avg merge
1d 15h
Merged PRs (30d)
146

Description

🔍 Duplicate Code Detected: GitRest “open repo + fsManager + soft-delete check”

Analysis of commit dbc4aa3808cc965a74f77bd5ff9a7a40d55a104e

Assignee: @copilot

Summary

Multiple GitRest route handlers repeat the same sequence to:

  1. derive repoManagerParams, 2) open a repo manager (or via write API), 3) create a filesystem manager via getFilesystemManagerFactory, and 4) call checkSoftDeleted.

This is substantial copy/paste logic across many endpoints; any future change to soft-delete semantics, filesystem manager selection, or error handling must be repeated consistently.

Duplication Details

Pattern: “create fsManager for repo + checkSoftDeleted”
  • Severity: Medium (server request-path logic; consistency/bug-risk)

  • Occurrences: 18 blocks (14+ lines each)

  • Locations (representative; all are exact duplicate/near-duplicate blocks):

    • server/gitrest/packages/gitrest-base/src/routes/git/blobs.ts (lines 37-50, 67-80)
    • server/gitrest/packages/gitrest-base/src/routes/git/commits.ts (lines 40-53, 64-80)
    • server/gitrest/packages/gitrest-base/src/routes/git/refs.ts (lines 48-61, 74-87, 107-120, 137-150, 167-180)
    • server/gitrest/packages/gitrest-base/src/routes/git/tags.ts (lines 40-53, 66-79)
    • server/gitrest/packages/gitrest-base/src/routes/git/trees.ts (lines 38-51, 64-77)
    • server/gitrest/packages/gitrest-base/src/routes/repository/contents.ts (lines 33-46)
    • server/gitrest/packages/gitrest-base/src/routes/repository/commits.ts (lines 41-54)
    • server/gitrest/packages/gitrest-base/src/routes/summaries.ts (lines 293-306, 370-385, 427-443)
  • Code Sample (example from git/blobs.ts):

    const fileSystemManagerFactory = getFilesystemManagerFactory(
      fileSystemManagerFactories,
      repoManagerParams.isEphemeralContainer ?? false,
    );
    const fsManager = fileSystemManagerFactory.create({
      ...repoManagerParams.fileSystemManagerParams,
      rootDir: repoManager.path,
    });
    await checkSoftDeleted(
      fsManager,
      repoManager.path,
      repoManagerParams,
      repoPerDocEnabled,
    );
    

Impact Analysis

  • Maintainability: Changes to filesystem selection (getFilesystemManagerFactory), soft-delete rules (checkSoftDeleted), or parameter plumbing must be updated in many handlers.
  • Bug Risk: High risk of inconsistent behavior across endpoints if one copy diverges (e.g., missing checkSoftDeleted, differing rootDir, different handling for repo-per-doc / initial summary optimizations).
  • Code Bloat: Adds repeated boilerplate to every new route.

Refactoring Recommendations

  1. Extract a shared helper in GitRest utils

    • Suggested location: server/gitrest/packages/gitrest-base/src/utils/helpers.ts (already exports getFilesystemManagerFactory, checkSoftDeleted, etc.)
    • Shape idea (pseudo-signature):
      • async function withFsManager(repoManager, repoManagerParams, fileSystemManagerFactories, repoPerDocEnabled, fn)
      • Or async function openRepoAndFsManager(request, repoManagerFactory, fileSystemManagerFactories, repoPerDocEnabled, { skipSoftDeleteCheck?: boolean }, fn)
    • Benefits: single source of truth for fsManager creation, rootDir wiring, and soft-delete gate.
  2. Unify read vs write pathways

    • Several handlers use repoManagerFactory.open(...) while others use getRepoManagerFromWriteAPI(...).
    • Consider passing a “repoManager getter” callback into the helper so route handlers can share the remainder of the logic.

Implementation Checklist

  • Identify exact common block variants (read open vs write API; optional soft-delete skip in optimized initial summary)
  • Add helper + typed return ({ repoManager, fsManager })
  • Update all GitRest routes in server/gitrest/packages/gitrest-base/src/routes/** to use helper
  • Ensure behavior parity (especially summaries.ts optimized initial summary path)
  • Run existing server/unit tests for gitrest-base

Analysis Metadata

  • Analyzed Files: 10+ (GitRest routes + utils)
  • Detection Method: Serena semantic code analysis + duplicate-block scanning
  • Commit: dbc4aa3808cc965a74f77bd5ff9a7a40d55a104e
  • Analysis Date: 2026-04-02T21:50:21.913Z

Generated by Duplicate Code Detector ·

To install this agentic workflow, run

gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in server/gitrest/packages/gitrest-base/src/utils/helpers.ts, then compare the repeated setup blocks in the listed GitRest route files, especially summaries.ts. Identify the read, write-API, and optimized-summary variants before choosing the shared helper shape. Run the existing gitrest-base server and unit tests; done means all listed routes use the helper with behavior parity.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.