Skip to content

Work Unit 008: Remove Legacy Git/File Refs System #130

Description

@jmgilman

Work Unit 008: Remove Legacy Git/File Refs System

Status: Specification
Estimated Effort: 2-3 days
Dependencies: Work Unit 003 (libs/refs OCI Backend), Work Unit 006 (Ref Installation), Work Unit 007 (CLI Integration)


Behavioral Goal

As a sow maintainer,
I need to remove the legacy git-based and file-based refs implementations after the OCI refs system is complete,
So that the codebase is simplified, maintenance burden is reduced, and users have a single, consistent refs mechanism (OCI) without lingering dead code or confusion about which system to use.

Success Criteria

  1. All files implementing GitType and FileType are deleted
  2. The legacy type registry pattern (registry.go) is removed
  3. Legacy URL parsing functions for git/file schemes are removed from CLI (replaced by libs/refs/url.go)
  4. github.com/jmgilman/go/git dependency is removed from cli/go.mod (unless still needed by other code)
  5. cli/internal/refs/manager.go works exclusively with the new OCI-only system via libs/refs
  6. All CLI commands function correctly with only OCI refs
  7. go build ./... succeeds after removal
  8. go test ./... passes with no references to deleted code
  9. No orphaned imports or references to deleted files remain (verified via grep)
  10. Documentation referencing git/file refs is updated or removed

Existing Code Context

Explanatory Context

The current refs system in cli/internal/refs/ implements a type registry pattern where multiple ref types (git, file) can be registered and used interchangeably. The RefType interface (types.go:23-79) defines the contract that each type must implement, and registry.go provides a global registry for type lookup.

With the OCI refs implementation (Work Units 002-007), this multi-type architecture becomes unnecessary. The new system uses libs/refs exclusively for OCI operations, and the CLI will only support OCI refs going forward. This is a "clean break" decision - no migration tooling, no deprecation period, no backward compatibility.

The CacheManager in manager.go and Manager in index_manager.go currently depend on the legacy type system via InferTypeFromURL(), GetType(), and the RefType interface. After OCI migration, these managers will delegate to libs/refs instead of calling type-specific implementations.

The git dependency github.com/jmgilman/go/git is used by GitType in git.go for repository caching. After removal, this dependency should be removed from cli/go.mod unless other CLI code still requires it (e.g., worktree commands via go-git/go-git/v5).

Key Files to Delete

File Lines Purpose
cli/internal/refs/git.go 1-226 GitType implementation using github.com/jmgilman/go/git/cache
cli/internal/refs/git_test.go full Unit tests for GitType
cli/internal/refs/file.go 1-165 FileType implementation using filesystem symlinks
cli/internal/refs/file_test.go full Unit tests for FileType
cli/internal/refs/types.go 1-100 Legacy RefType interface and RefTypeInfo struct
cli/internal/refs/registry.go 1-116 Type registry pattern (global map, Register, GetType, etc.)
cli/internal/refs/registry_test.go full Unit tests for registry
cli/internal/refs/url.go 1-199 Legacy URL parsing (InferTypeFromURL, NormalizeGitURL, etc.)
cli/internal/refs/url_test.go full Unit tests for URL parsing

Key Files to Update

File Lines Required Changes
cli/internal/refs/manager.go 1-239 Replace type inference/dispatch with libs/refs client calls
cli/internal/refs/index_manager.go 1-599 Remove type-based logic, use libs/refs for all operations
cli/cmd/refs/add.go full Update to use OCI-only flow, remove git/file-specific flags
cli/cmd/refs/update.go full Update to use libs/refs for OCI update operations
cli/cmd/refs/remove.go full Ensure compatibility with OCI-only cache structure
cli/cmd/refs/status.go full Update status display for OCI refs
cli/cmd/refs/init.go full Initialize OCI refs only
cli/go.mod 14 Remove github.com/jmgilman/go/git if no longer needed

Existing Documentation Context

ADR-003 (Decision Rationale)

ADR-003 (.sow/knowledge/adrs/003-oci-refs-distribution.md) documents the decision to replace git-based refs with OCI packages. This is a strategic architectural decision, not incremental improvement. The ADR's "Alternatives Rejected" section explicitly notes "Keep git - doesn't solve pain points" as rejected.

The decision includes "Migration effort (tooling provided)" as a trade-off, but the task description specifies "No backward compatibility or deprecation period - this is a clean break." Users with existing git refs will need to manually re-add them as OCI refs.

Discovery Analysis (Current State)

Section 1 of the discovery analysis (.sow/project/discovery/analysis.md) documents the existing refs architecture:

  • Type Registry Pattern (lines 18-32): RefType interface with Name(), IsEnabled(), Cache(), Update(), etc.
  • Current Implementations (line 35-37): GitType uses github.com/jmgilman/go/git/cache, FileType uses filesystem symlinks
  • Cache Structure (lines 130-139): ~/.cache/sow/refs/git/checkouts/ and ~/.cache/sow/refs/file/

The analysis recommends (Section 10.3) that OCI implementation go in libs/refs/ following recent patterns, which Work Units 003-006 implement. The removal of legacy code follows naturally.

Design Document (OCI Architecture)

The OCI Refs Design Document (.sow/knowledge/designs/oci-refs/oci-refs-design.md) describes the new architecture that replaces the legacy system:

  • Single Cache Structure (lines 182-186): ~/.cache/sow/refs/{id}-{short-digest}/ (no subdirectories per type)
  • URL Detection (lines 351-358): OCI URLs detected via oci:// prefix or known registry patterns
  • No Type Registry: The design doesn't mention multiple types - OCI is the only mechanism

Detailed Requirements

Phase 1: Delete Legacy Type Implementations

Delete the following files completely:

cli/internal/refs/
├── git.go          # DELETE
├── git_test.go     # DELETE
├── file.go         # DELETE
├── file_test.go    # DELETE
├── types.go        # DELETE
├── registry.go     # DELETE
├── registry_test.go # DELETE
├── url.go          # DELETE
└── url_test.go     # DELETE

After deletion, cli/internal/refs/ should contain only:

  • manager.go (updated)
  • index_manager.go (updated)
  • options.go (if still needed for functional options)
  • ref.go (if still needed for Ref wrapper)

Phase 2: Update Manager to Use libs/refs

CacheManager Updates (manager.go)

Current CacheManager.Install() flow (lines 53-91):

  1. InferTypeFromURL(ref.Source) → type name
  2. TypeForScheme(ctx, typeName)RefType implementation
  3. refType.ValidateConfig(ref.Config)
  4. refType.Cache(ctx, m.cacheDir, ref) → cache path
  5. Create workspace symlink

New flow using libs/refs:

  1. Call libs/refs.IsOCIRef(ref.Source) to validate
  2. Create libs/refs.Installer via libs/refs.NewInstaller()
  3. Call installer.Install(ctx, ref.Source, opts...)InstallResult
  4. Create workspace symlink from result.CachePath

The Update() and Remove() methods need similar updates.

Manager Updates (index_manager.go)

The Manager orchestrates refs operations at a higher level. Updates needed:

  • Add() (lines 28-142): Remove type inference, use libs/refs.IsOCIRef() for validation
  • normalizeURLForType() (lines 318-367): Remove git/file-specific logic, normalize OCI URLs only
  • generateRefID() (lines 370-414): Simplify for OCI URL pattern only
  • InitRefs() (lines 269-313): Install using libs/refs.Installer instead of type-based loop

Remove any imports of deleted files and replace with libs/refs imports.

Phase 3: Update CLI Commands

Each command in cli/cmd/refs/ needs review:

add.go:

  • Remove --branch flag (git-specific)
  • Keep --path flag (repurposed for OCI selective extraction globs)
  • Update validation to require OCI URL format
  • Update help text to reflect OCI-only support

update.go:

  • Update to use libs/refs.Installer for digest comparison and re-pull
  • Remove any git-specific update logic

remove.go:

  • Update cache cleanup to use libs/refs cache structure
  • Remove git/file-specific cleanup paths

status.go:

  • Update to show OCI-specific status (digest, selective extraction info)
  • Remove git staleness checks

init.go:

  • Update to initialize OCI refs only
  • Remove type enumeration logic

Phase 4: Clean Up Dependencies

Check if github.com/jmgilman/go/git is still needed:

# Search for remaining uses
grep -r "jmgilman/go/git" cli/

# Expected matches (keep):
# - cli/cmd/worktree.go (uses go-git/go-git, not jmgilman/go/git)

# If no matches besides deleted files, remove from go.mod

Note: go-git/go-git/v5 is different from jmgilman/go/git. The former is used for worktree commands and should remain.

Phase 5: Update Documentation

Review and update any documentation referencing git/file refs:

  • Remove examples showing git+https:// URLs
  • Remove examples showing file:// URLs
  • Update command help text
  • Update any README or user guides

Testing Requirements

Build Verification

  1. After all deletions and updates:

    cd cli && go build ./...

    Must succeed with no errors.

  2. Verify no orphaned imports:

    grep -r "internal/refs/git" cli/
    grep -r "internal/refs/file" cli/
    grep -r "internal/refs/types" cli/
    grep -r "internal/refs/registry" cli/
    grep -r "internal/refs/url" cli/

    All should return empty.

Test Verification

  1. Run all tests:

    cd cli && go test ./...

    Must pass with no failures.

  2. Run specific refs tests:

    cd cli && go test ./internal/refs/... -v
    cd cli && go test ./cmd/refs/... -v

Functional Verification

  1. Add OCI ref: sow refs add ghcr.io/org/ref:v1.0.0 --link myref --description "Test"
  2. List refs: sow refs list (should show only OCI refs)
  3. Update ref: sow refs update myref
  4. Remove ref: sow refs remove myref
  5. Init refs: Clone repo with refs, run sow refs init

Regression Verification

Ensure that attempting to add non-OCI URLs fails gracefully:

  • sow refs add git+https://github.com/org/repo → Error: "OCI URL required"
  • sow refs add /local/path → Error: "OCI URL required"

Implementation Notes

Dependency Order

This work unit MUST be executed AFTER Work Units 003, 006, and 007 are complete:

  1. Work Unit 003 provides libs/refs module with OCI client
  2. Work Unit 006 provides libs/refs.Installer for installation
  3. Work Unit 007 provides CLI integration and OCIType adapter

Only after these are complete and functioning can the legacy code be safely removed.

Clean Break Strategy

Per the task description, this is a "clean break":

  • No migration tooling
  • No deprecation warnings
  • No backward compatibility
  • Users with existing git/file refs must manually re-add as OCI

This simplifies implementation significantly - we delete code without providing alternatives for legacy formats.

Cache Cleanup

The old cache directories (~/.cache/sow/refs/git/ and ~/.cache/sow/refs/file/) are NOT automatically deleted. Users can manually clean these up. The new OCI cache uses ~/.cache/sow/refs/oci/ (or flat ~/.cache/sow/refs/{id}-{digest}/ per design).

Consider adding a note to release notes: "Run rm -rf ~/.cache/sow/refs/git ~/.cache/sow/refs/file to clean up legacy cache."

Error Messages

Update error messages to reflect OCI-only support:

  • "Invalid URL: OCI registry URL required (e.g., ghcr.io/org/ref:tag)"
  • "Unknown URL format. Use oci://registry/path:tag or a known registry like ghcr.io"

Out of Scope

  • Migration tooling: No tools to convert git refs to OCI refs
  • Deprecation period: No warnings before removal
  • Backward compatibility shims: No code to read legacy index formats
  • Automatic cache cleanup: Users manually clean old cache
  • Git/file support as plugins: Complete removal, not modularization

Implementation Standards

All code produced in this work unit MUST adhere to the following standards:

Code Quality Standards

  • STYLE.md Compliance: All Go code modifications must follow the conventions documented in .standards/STYLE.md
  • TESTING.md Compliance: All tests must follow the patterns documented in .standards/TESTING.md
  • golangci-lint: Code must pass golangci-lint run with zero errors after removal

Verification Checklist

Before marking this work unit complete, verify:

  • golangci-lint run ./cli/... passes with zero errors
  • go build ./... succeeds with no errors
  • go test ./... passes with no failures
  • No orphaned imports or references to deleted files (grep verification)

Acceptance Criteria

  • cli/internal/refs/git.go deleted
  • cli/internal/refs/git_test.go deleted
  • cli/internal/refs/file.go deleted
  • cli/internal/refs/file_test.go deleted
  • cli/internal/refs/types.go deleted
  • cli/internal/refs/registry.go deleted
  • cli/internal/refs/registry_test.go deleted
  • cli/internal/refs/url.go deleted
  • cli/internal/refs/url_test.go deleted
  • cli/internal/refs/manager.go updated to use libs/refs
  • cli/internal/refs/index_manager.go updated to use libs/refs
  • cli/cmd/refs/*.go commands updated for OCI-only
  • github.com/jmgilman/go/git removed from cli/go.mod (if unused elsewhere)
  • go build ./... succeeds
  • go test ./... passes
  • grep verification shows no orphaned references
  • CLI commands work with OCI refs only
  • Error messages updated for OCI-only support
  • Documentation updated to remove git/file examples

Metadata

Metadata

Assignees

No one assigned

    Labels

    sowIssues managed by sow breakdown workflow

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions