Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace colocate 2 #4678

Draft
wants to merge 13 commits into
base: workspace-colocate-minimal
Choose a base branch
from

Conversation

cormacrelf
Copy link

This is a draft, still cleaning up, but you can see how we create the worktrees. Follow-on from #4644

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added tests to cover my changes

A colocated workspace is one that also happens to have a valid .git file
or directory. To create a colocated workspace in an existing JJ repo, 
we need to add a corresponding git _worktree_.

JJ doesn't have the ability to create colocated workspaces yet. We want
to test a bunch of code around colocating worktrees with a workspace,
assuming we will build the functionality to actually create one in JJ
itself later. So here's a helper function to do it the really hacky
way with the `git` CLI, moving a .git file into place, and running
`git worktree repair`.
@cormacrelf cormacrelf mentioned this pull request Oct 20, 2024
4 tasks
Previously, only the default workspace could be colocated. This adds
logic to the colocation-detection code to support finding a worktree
with a "gitfile" as well as a full-on .git directory.

There are some new tests for what happens when you `jj git init
--git-repo=...` either in or pointing at an existing worktree. I do not
expect these to be common workflows, but there is new behaviour here
that we need to track.
…_head

This makes colocated workspaces independent. You can move @ in a
workspace and JJ will write HEAD = @- to the git worktree in that
workspace. And you can run mutating git commands in a workspace, and
JJ will import the new HEAD only in that workspace.

Previously, any imports and exports were against the git backing repo,
which is sometimes colocated with the default workspace. So colocated
workspaces were not independent, they all read and wrote from the same
HEAD in the backing repo.
…t worktree

Now that colocated workspaces exist, it is necessary to distinguish the
two kinds of git repository `jj` might open. There's the git backend
(which is either a bare repository or a colocated one) and the worktrees
for all the colocated workspaces. Both of these are a
`gix/git2::Repository`, the difference is just which path you opened. So
you have to distinguish them with names.

This rename mostly serves as an opportunity to review at least some of
the usages of explicit usage of the git backend repo.
This forms the basis of `jj workspace add --colocate`.

The libraries don't quite have the functionality we need
- gix doesn't do it at all
- git2 does (Repository::worktree(name, opts)), but it
  always has to check out a commit.

This implementation
- can create in an already-existing directory;
- writes a dummy HEAD and index; and
- does not check out any files.

JJ handles all three of those things (enabled in a later diff).
We need this for when we forget colocated workspaces, so that users
do not have to `git worktree remove` manually.

The validation / removal separation is so we can two-phase-commit the
removals during a multi-workspace forget operation, checking they're all
valid and able to be removed during the transaction and removing the
worktrees afterwards. Missing worktrees (like when the user has ALREADY
run `git worktree remove`) are ignored.
We need to include WorkspaceId in error messages more frequently now.
New flag: jj workspace add --colocate. This is hidden, because we will
be splitting the colocated workspaces code over a few PRs and it's
plausible a new JJ will be released before the feature is ready.

To implement, we add a worktree. And remove it during `workspace
forget`.
We're getting paths like this, I think.

    gitdir: \\?\C:\Users\runneradmin\AppData\Local\Temp\jj-test-fy26a2\second

But I don't know what git does, and I don't have access to a windows machine.
Adding this so the CI windows build can tell us what's wrong.
Before

    gitdir: \\?\C:\Users\runneradmin\AppData\Local\Temp\jj-test-fy26a2\second

After

    gitdir: C:/Users/runneradmin/AppData/Local/Temp/jj-test-fy26a2/second

And same for the other worktree bits and pieces. We also change the way
the tests run git commands, because of yet another error to do with
Git being unable to handle verbatim paths:

    command=`"git" "worktree" "add" "\\\\?\\C:\\Users\\runneradmin\\AppData\\Local\\Temp\\jj-test-ti0MHE\\second"`
    code=128
    stdout=""
    stderr=```
    Preparing worktree (new branch \'second\')
    fatal: could not create leading directories of \'//?/C:/Users/runneradmin/AppData/Local/Temp/jj-test-ti0MHE/second/.git\': Invalid argument
@cormacrelf cormacrelf force-pushed the workspace-colocate-2 branch from 23f8317 to 9a9034a Compare November 8, 2024 11:24
@cormacrelf cormacrelf force-pushed the workspace-colocate-minimal branch 15 times, most recently from 2dc282c to 7c1ea6a Compare November 13, 2024 10:15
@cormacrelf cormacrelf force-pushed the workspace-colocate-minimal branch 3 times, most recently from d23d59c to 2923211 Compare November 13, 2024 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant