microsoft / microsoft/FluidFramework

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

Open
#26,966 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

Analysis of commit 7c632a25e829687a7946711db1eb2978d5285464

Assignee: @copilot

Summary

Multiple GitRest route handlers repeat the same 15–20 line block to:

  1. open the repo manager,
  2. choose/create a filesystem manager,
  3. run checkSoftDeleted(...),
    then proceed with the endpoint-specific operation.

This is significant duplication across several routes and increases the chance of inconsistent behavior (e.g., if soft-delete semantics, ephemeral routing, or error handling needs to change).

Duplication Details

Pattern: Open repo + create FS manager + check soft-delete
  • Severity: Medium
  • Occurrences: 10+ blocks across 8 files (several files contain multiple routes repeating the same block)
  • Locations (examples):
    • server/gitrest/packages/gitrest-base/src/routes/repository/contents.ts (lines 29–49)
    • server/gitrest/packages/gitrest-base/src/routes/repository/commits.ts (around line 38–62)
    • server/gitrest/packages/gitrest-base/src/routes/git/blobs.ts (around lines 33–53, 63–86)
    • server/gitrest/packages/gitrest-base/src/routes/git/refs.ts (around lines 43–66, 69–95, 98–120, 129–151, 159–180)
    • server/gitrest/packages/gitrest-base/src/routes/git/tags.ts (around lines 35–58, 61–84)
    • server/gitrest/packages/gitrest-base/src/routes/git/trees.ts (around lines 33–56, 58–82)
    • server/gitrest/packages/gitrest-base/src/routes/git/commits.ts (around lines 35–55, 62–85)
    • server/gitrest/packages/gitrest-base/src/routes/summaries.ts (around lines 290–320, plus additional similar blocks around 370 and 427)

Representative code sample (server/gitrest/packages/gitrest-base/src/routes/repository/contents.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,
				);
				return repoManager.getContent(request.query.ref as string, request.params[0]);
			})
			.catch((error) => logAndThrowApiError(error, request, repoManagerParams));

Impact Analysis

  • Maintainability: Any change to soft-delete gating, ephemeral FS selection, or repo opening semantics must be applied in many places.
  • Bug Risk: High risk of subtle inconsistencies (e.g., missing a soft-delete check in a new route, different ordering, or different error handling).
  • Code Bloat: Repeated blocks across route files make endpoints harder to scan and review.

Refactoring Recommendations

  1. Extract a shared helper in server/gitrest/packages/gitrest-base/src/utils/helpers.ts

    • Example shape (name TBD):
      • openRepoAndFsManager(repoManagerFactory, fileSystemManagerFactories, repoManagerParams, repoPerDocEnabled)
      • returns { repoManager, fsManager } after running checkSoftDeleted(...).
    • Benefits: centralizes ephemeral/container FS selection, ensures soft-delete checks are consistently applied.
  2. Optional: build a small route wrapper for read APIs

    • Similar to existing getRepoManagerFromWriteAPI(...), but for common read-route setup.
    • Keeps each route focused on endpoint-specific logic.

Implementation Checklist

  • Identify the minimal shared helper signature (inputs/outputs) for routes
  • Update the 8 route files to use the helper
  • Ensure behavior is unchanged (same error wrapping via logAndThrowApiError, same soft-delete behavior)
  • Run existing GitRest/server tests (if present) and any linting required

Analysis Metadata

  • Detection Method: Serena pattern search + duplicated-block scanning (normalized 16-line windows)
  • Commit: 7c632a25e829687a7946711db1eb2978d5285464
  • Analysis Date: 2026-04-07

Note: the local checkout for this workflow appears shallow (limited history), so the analysis focused on duplication present in the current HEAD snapshot rather than new-vs-old comparisons.

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 and compare the repeated setup in repository/contents.ts, git/blobs.ts, git/refs.ts, git/tags.ts, git/trees.ts, git/commits.ts, repository/commits.ts, and summaries.ts. Define the minimal shared setup identified by the issue, update the listed routes, then run the existing GitRest/server tests and required linting. Done means behavior, soft-delete checks, and error wrapping remain unchanged across all affected routes.

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.