Skip to content

Config has no VCS-neutral checkout target or drift/dirty policy for sync #577

Description

@tony

Summary

A repo entry can pin options.rev, list git remotes and worktrees, and (after #576) set git_options, but it cannot say what vcspull sync should do when the checkout on disk is on a different ref than configured, or has uncommitted changes. Git-only keys sit beside VCS-neutral ones, and Mercurial and Subversion have no place for their own settings. This proposes one entry shape for every VCS: five VCS-neutral keys plus one block per VCS named after the URL scheme. Depends on libvcs#554. Sized for one evening once that lands.

Problem

Prompt

Give every entry the same VCS-neutral core, move VCS-specific keys into one block per VCS, and make drift and dirty handling explicit policy.

These must hold; everything after them is open:

  • VCS-neutral keys are identical for git+, hg+, and svn+ entries. VCS-specific keys live in exactly one block named after the URL scheme, and a block for the wrong VCS fails at load, naming the entry.
  • The main checkout and each worktree describe their target the same way: exactly one of branch, tag, commit, or rev.
  • sync policy is explicit and VCS-neutral: what to do when the checkout is on a different ref than configured, and what to do with uncommitted changes. Discarding changes still requires the caller's confirmation, and setting them aside uses each VCS's own mechanism through libvcs.
  • Every existing config keeps loading. Old locations warn, vcspull migrate rewrites them in one pass, and add, discover, import, and fmt write the new layout.
  • The published JSON Schema and the loader accept and reject the same entries, extending the agreement test from Config cannot request partial clones (git clone --filter) #576.

Direction, non-binding. Target shape:

# yaml-language-server: $schema=https://vcspull.git-pull.com/_static/schemas/vcspull.schema.json
~/code/:
  git:
    repo: git+https://github.com/git/git.git
    working_copy:
      tag: v2.55.0
      remote: upstream
      sync:
        drift: follow
        dirty: preserve
    remotes:
      upstream: git+https://github.com/git/git.git
    worktrees:
      - dir: ../git-maint
        branch: maint
    git:
      depth: 50
      filter: blob:none
    pin:
      import: true
    pin_reason: URL managed manually
  docutils:
    repo: svn+http://svn.code.sf.net/p/docutils/code/trunk
    working_copy:
      rev: 9500
    svn:
      depth: immediates
  • working_copy holds the target ref, the remote pulls come from (default: the repo URL), and sync. drift is one of keep (leave the checkout where it is), follow (move it to the configured ref), or warn (report in vcspull status, touch nothing). dirty is one of abort (skip the entry and report), preserve (set changes aside, then restore), or discard (needs --yes).
  • Each <vcs>: block is exactly the option set of the matching libvcs class, so adding a knob is one libvcs field plus one TypedDict field, and a test can check the two agree by introspection.
  • pin and pin_reason move to the entry level; options then has nothing left in it.
  • Worktree items keep their shape and gain working_copy's sync; whether to rename worktrees to working_copies is open.
  • Schema: post-process the generated schema with an if on the repo scheme that forbids the other VCS blocks, and a oneOf on the ref keys.
  • Migration in one vcspull migrate pass: options.rev to working_copy.rev; git_options.* to git.*, which can be folded into Config cannot request partial clones (git clone --filter) #576 before it ships; options.pin, options.pin_reason, and options.allow_overwrite to the entry level.

Details that cost time to rediscover:

  • "Working copy" is the word three of the six tools use (jj, Subversion, CVS). git says "working tree" (glossary at v2.55.0), got says "work tree" (got(1)), Mercurial says "working directory" (glossary at 7.2.4). rev is the word Mercurial, Subversion, CVS, and gitrevisions share; branch and tag exist in all six; commit fits git, got, and jj.
  • Drift means "the configured ref resolves to what is checked out", not "the same string". git records a branch name, got a branch plus a base commit, jj only the "working-copy commit" @ with "no concept of an active/current/checked-out bookmark" (bookmarks at v0.45.1), and Subversion and CVS record positions per directory or file, so mixed-revision working copies exist there. detach can be derived from the ref kind: a branch is followed, a tag or commit is pinned; jj is always detached and got never is.
  • preserve resolves per VCS: git stash, Mercurial shelve, Subversion a patch file because x-shelve is experimental, jj nothing because changes are already a commit (FAQ at v0.45.1), got and CVS a patch file. Naming the policy rather than the mechanism is what keeps a key like backup-to-stash from being git-only.
  • Fetch and push targets are separate in git, Mercurial, jj, and got. remotes entries keep fetch_url and push_url; the working_copy.remote is only where pulls come from.
  • Subversion's branch is part of the URL (svn switch is "Update the working copy to a different URL within the same repository.", svn.c at 1.14.5), so its working_copy is a rev plus the entry URL, not a branch name.

Not doing:

Alternatives

Weighed and set aside:

  • Flat git_options, hg_options, svn_options keys: also avoid the depth collision, but grow one top-level key per VCS and give VCS-neutral policy no home.
  • Keeping options as a catch-all: the mixed audiences and the collision above are what it produces.
  • Nesting working_copy inside the VCS block, as first sketched: puts a concept every VCS has into a per-VCS namespace, and Subversion and Mercurial would each need their own copy.

References

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions