worktree mutations - #2977
Draft
Sebastian Thiel (Byron) wants to merge 16 commits into
Draft
worktree mutations#2977Sebastian Thiel (Byron) wants to merge 16 commits into
Sebastian Thiel (Byron) wants to merge 16 commits into
Conversation
Sebastian Thiel (Byron)
force-pushed
the
worktree-create
branch
5 times, most recently
from
September 11, 2026 03:58
7c42198 to
520efea
Compare
Sebastian Thiel (Byron)
force-pushed
the
worktree-create
branch
10 times, most recently
from
September 14, 2026 13:18
55f423f to
614b5a4
Compare
<!-- agent --> Paths such as `C:repo` previously replaced the supplied base with the `C:` prefix and could remain relative. Resolve them against `cwd` when its drive matches, including verbatim drive prefixes, and otherwise ask Windows for the current directory on that drive. Resolve only the drive prefix so subsequent symlinks are followed before interpreting `..`. Document the base-directory rules and add regressions for bare drives, matching and different drives, verbatim bases, fully qualified paths, and symlink-sensitive parent traversal. Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
…e Git conformant <!-- agent --> Replace leading dots before stripping repeated `.lock` suffixes, matching Git so `.lock.lock` becomes `-lock` instead of losing its name. Handle empty sanitized output without indexing it. Keep `name_partial_or_sanitize()` returning `BString` and guarantee a nonempty valid partial reference name. Empty or slash-only input falls back to `-`; document this Gitoxide-specific behavior so callers need no empty-result handling. Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
<!-- agent --> Shared repository modes need more than adding or replacing permission bits: read-only files must stay read-only, executable files need execute access wherever sharing grants read access, and directories need search bits and Git's setgid defaults, including on macOS. Follow Git's `calc_shared_perm()` and `adjust_shared_perm()`. Add `set_shared_repository_permissions()` to apply the policy to an existing path, skipping unchanged permissions and avoiding filesystem access for a zero policy or on non-Unix platforms. Require an explicit parsed sharing policy in `dir::create::Iter::new()` and `dir::create::all()`. Apply it only to newly created directories, preserving existing directory permissions. Configure retry limits with `Iter::retries()`, which updates both the original and remaining counts. Tests cover file modes, directory search and setgid bits, preservation of existing directories, and retry limits reported in errors. BREAKING CHANGE: `Iter::new(target, policy)` and `dir::create::all(dir, retries, policy)` require a parsed sharing policy; pass `0` to retain the previous umask behavior. Replace `Iter::new_with_retries(target, retries)` with `Iter::new(target, policy).retries(retries)`. Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
<!-- agent --> Temporary files created in shared repositories can require new parent directories. Callers need those directories to honor the repository's sharing policy even when the process umask would make them private. Replace the tuple field of `ContainingDirectory::CreateAllRaceProof` with named `retries` and `shared_repository_permissions` fields, and pass the policy to directory creation in `gix_fs`. Setting the policy to `0` preserves the previous umask behavior. Adapt the existing tempfile tests to the new variant shape. Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
…ries <!-- agent --> Locks in shared repositories need consistent permissions on both the lock file and any parent directories created during acquisition. Adjusting only the file can leave those directories inaccessible to other repository users. Use one explicit parsed Git sharing policy for writable locks, markers, and newly created directories. Apply it after the process umask in the common acquisition path and forward it to `gix-tempfile` for directory creation. A policy of `0` keeps the umask behavior without permission metadata access. The adjusted file mode reaches the committed resource. Keep `boundary_directory` as `Option<PathBuf>` and pass the sharing policy separately. Replace custom-permission and symlink convenience methods with `File::acquire()` and its optional resource resolver. Tests cover lock, marker, and committed-resource modes, directory permissions, and rollback. BREAKING CHANGE: acquisition methods require a `shared_repository_permissions` argument; pass `0` for the previous umask behavior. `File::acquire()` takes it before the optional resolver and no longer accepts a permission callback. The `_with_permissions` and `_following_symlinks` convenience methods are removed. Use `File::acquire()` with `Some(&acquire::resolve_symlink)` to follow resource symlinks. Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
<!-- agent --> Add transactional linked-worktree administration with rollback, then compose it in gix with existing reference, checkout, index, progress, and interruption machinery. Support attached and detached worktrees from bare or non-bare repositories while rejecting occupied branches and destinations. Keep move, remove, repair, hooks, sparse checkout, and relative-link configuration out of scope. Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
Expose `Repository::add_worktree()` for existing local branches and detached commits. Prepare the links, initialize `HEAD` and its reflog, check out the commit, and write the index, rolling back created files on failure or interruption. Inherit worktree configuration and common attributes before checkout. Enumerate the main and linked repositories consistently so additions and branch deletion protect branches checked out or reserved by bisect and rebase, while matching Git's default namespace behavior. Support `worktree.useRelativePaths` with its repository-format upgrade and `extensions.relativeWorktrees` validation. Compare behavior with Git for bare parents, separate Git directories, moved relative links, configuration inheritance, invalid destinations, and rollback. Co-authored-by: Byron <sebastian.thiel@icloud.com>
Provide the `gix-worktree` plumbing needed to recursively remove a linked checkout and its private Git directory without following symbolic links or crossing Unix mount boundaries. Use `dua-core` for traversal and parallel deletion with progress reporting, bounded retries for directory-not-empty races, and errors distinguishing checkout and administration failures. Keep repository validation, dirty-state checks, lock policy, and branch decisions with higher-level callers. Include the opt-in crate feature, disposable-repository coverage, and the existing CLI adapter's required `dua-core` upgrade together so the workspace remains consistent. Co-authored-by: Byron <sebastian.thiel@icloud.com>
Expose safe linked-worktree removal through `gix`, using the `gix-worktree` removal plumbing. Validate the selected worktree, inspect dirty and locked states, and preserve the checkout unless the requested removal policy permits deleting it. Enable removal through `worktree-mutation` and report progress and cleanup outcomes to callers. Keep branch deletion explicit, adding compare-and-swap branch removal for callers that have already inspected a target so concurrent branch changes are not lost. Cover porcelain removal behavior and conditional branch deletion in disposable repositories. Co-authored-by: Byron <sebastian.thiel@icloud.com>
Reference, index, and linked-worktree metadata writes must apply the effective `core.sharedRepository` policy after the process umask so other users can access shared repository data. Cache the parsed policy in `gix`, refresh it after configuration changes, and pass it through loose and packed references, reflogs, clone checkout, status index updates, and the CLI and Tix index writers. Avoid redundant permission changes on already-shared reflogs owned by another user. Standalone index writers retain process-umask behavior by passing `0`. Apply the same policy when preparing linked-worktree directories and linking files, writing `HEAD` and the index, and copying worktree configuration. Keep the private Git directory and checked-out contents at ordinary filesystem permissions. Include Git-baseline coverage and the deliberate extension of sharing to worktree linking files. BREAKING CHANGE: `gix_index::File::write()` takes the signed sharing policy as its second argument, and `gix_worktree::add::Options` gains `shared_repository_permissions`. All workspace callers are adapted together; standalone callers can pass `0`. Co-authored-by: Byron <sebastian.thiel@icloud.com>
…and clone Deleting branch configuration and adopting a cloned remote's object format must preserve an existing configuration file's explicit permissions, even when `core.sharedRepository` is enabled. Use the existing `FileTransaction` for both updates. This preserves the configuration mode and follows the transaction's symlink and locking behavior while retaining branch deletion's partial-success error reporting. Regression coverage checks that an explicit `0600` config stays private, matching Git. BREAKING CHANGE: branch deletion and clone configuration failures expose `FileTransaction` errors instead of separate raw lock, read, write, and commit errors.
Initialization must resolve `core.sharedRepository` before it creates repository metadata; adjusting later writes leaves the Git directory, configuration, and template files inaccessible under a restrictive umask. Load the permitted configuration scopes first, apply the sharing policy to the Git root and its metadata, and persist active sharing as Git does. Destination ancestors and the configuration-independent creation entry point retain their ordinary umask behavior. Add a reusable subprocess helper for umask-sensitive tests, avoiding process-wide umask changes in concurrent tests. Compare initialized repositories and cloned metadata with Git under restrictive and ordinary umasks.
Shared refs are insufficient when loose objects remain private. Propagate the resolved repository policy through object-store initialization and each handle's loose-object writes, applying it before publishing objects and to newly created fanout directories. Keep objects read-only. Runtime configuration changes and reloads affect the next write through the current handle without changing other handles, including cloned and thread-safe round trips. Cover both object hash formats and update the existing repository-size guard for the measured Windows layout. BREAKING CHANGE: dynamic and loose object-store initialization options gain `shared_repository_permissions`. Standalone callers can retain umask behavior with `0`.
Fetching into a shared repository must make received packs, pack indices, and shallow boundaries accessible according to `core.sharedRepository`. Pass the repository policy through pack-writing and protocol-fetch options. Create immutable pack and index files with appropriate initial permissions, share new destination directories, and keep `.keep` markers private. Preserve pre-existing markers and their ownership so the receiver does not remove another operation's marker. A tempfile constructor accepts creation permissions without bypassing the process umask. BREAKING CHANGE: pack-writing and protocol-fetch options gain `shared_repository_permissions`. Repository callers pass their resolved policy; standalone callers pass `0`. The workspace adaptations and Git-baseline coverage are included together.
A multi-pack-index written into the selected repository must honor that repository's sharing policy. Leaving it at the process umask can make an otherwise shared object database inaccessible to other readers. Resolve sharing for the default MIDX destination only when the selected repository owns that path, and pass the policy into its output lock. Explicit standalone destinations retain process-umask behavior. Extend the CLI journey coverage for repository-owned and standalone output.
The query database and its SQLite sidecars must be accessible to the same users as other shared repository data. Apply `core.sharedRepository` immediately after opening the database, before SQLite creates journals, WALs, or shared-memory files that inherit its mode. Reapply the policy when schema-version changes recreate the database. Test initial creation, a live rollback journal, and recreation under ordinary and restrictive umasks.
Sebastian Thiel (Byron)
force-pushed
the
worktree-create
branch
from
September 16, 2026 14:50
614b5a4 to
ec2bc11
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tasks