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: warn if destination doesn't contain path separator #4128

Merged
merged 2 commits into from
Jul 26, 2024

Conversation

scott2000
Copy link
Contributor

@scott2000 scott2000 commented Jul 20, 2024

Users may try to run jj workspace add <name> without specifying a path, which results in the workspace being created in the current directory. This can be confusing, since the workspace contents will also be snapshotted in the original workspace if it is not sparse. Adding a warning should reduce confusion in this case.

Resolves #865.

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

@thoughtpolice
Copy link
Member

I never saw the original ticket. I actually do use this feature. I keep a work/ root directory in the top level of some of my projects so I can put workspaces there and then test them individually. It works nice combined with jj sparse. I'll include the description from my internal notes below, but broadly speaking it would be nice if this could be gated or allowed with an extra flag of some kind. I'd be happy for a flag that only can be used with workspace add since creating them isn't so common.


This empty directory is a convenient "workspace root" to place your various
different jj workspaces. The idea is something like this — while you are
in a clean, empty working copy commit, execute the following:

cd $(jj workspace root) # go to the root of the default workspace
jj sparse set --clear --add work # only leave work/ in in the working copy

This removes all files except the top-level work/ directory, which is empty,
but it retains all the historical content of the repository. That's ideal. Now:

jj workspace add work/new-feature # create first new workspace
jj workspace add work/fix-bug-123 # create second new workspace

Now, your working copy is empty, but the the directory work/new-feature has a
copy of the whole repository instead, "linked" with the sparse copy above it.
work/fix-bug-123 also is a copy of the repository, and they both share the
same root-level .jj directory. You can run jj log in either workspace and
see it connected to the top level repository, and work on the two workspaces
independently. You can run jj workspace add many more times to keep creating
entirely new build directories that are all sharing the root .jj repo.

This kind of workflow is useful for scenarios where you want to e.g. execute
some long running test or other tool while having another set of commits being
worked on separately. It also conceptually can replace any workflow where you
might have multiple copies of a repository checked out in different directories
for some reason.

In a sense, this turns the Git model for change management on its head, since
instead of branches you are just using whole checkouts in subdirectories.
Instead it looks more like the way Darcs works, where every branch of a
project was its own separate repository entirely.

Run jj workspace forget work/new-feature when you are done with a workspace,
and the commits will still exist in the top level repository, but the workspace
is gone. You can delete the directories after that.

@scott2000
Copy link
Contributor Author

That's an interesting workflow! I hadn't considered that, but that does seem useful. Perhaps it would be better to just require there be a path separator somewhere in the path or something like that? That way you couldn't accidentally create a workspace inside another one with jj workspace add <name>, but it would still be possible to do it explicitly with jj workspace add ./<name> if it's really what's intended.

@joyously
Copy link

Instead it looks more like the way Darcs works, where every branch of a project was its own separate repository entirely.

Actually, it looks more like Bazaar(Breezy) in the default mode, where the repo is shared.

@scott2000 scott2000 force-pushed the current-workspace-check branch from cfbac96 to cf3e74e Compare July 21, 2024 00:24
@scott2000
Copy link
Contributor Author

I updated the PR to just produce an error if there's no path separators in the destination, since this seems like a simple way to avoid spurious errors. So it would look like this:

$ jj workspace add new-workspace
Error: Refusing to create workspace at "./new-workspace", since it is likely a mistake.
Hint: If that's what you intended, explicitly use "./new-workspace" instead to silence this error.

$ jj workspace add ./new-workspace
Created workspace in "new-workspace"
Working copy now at: tytvkxlw f3ad074f (empty) (no description set)
Parent commit      : zzzzzzzz 00000000 (empty) (no description set)

@scott2000 scott2000 changed the title workspace: don't allow adding workspace inside current workspace workspace: require path separator when adding workspace Jul 21, 2024
@scott2000 scott2000 force-pushed the current-workspace-check branch from cf3e74e to dc0bcff Compare July 21, 2024 00:35
@yuja
Copy link
Contributor

yuja commented Jul 21, 2024

It's inconsistent that workspace add requires ./ which the other commands don't. I personally don't think workspace add <name> is a mistake, but if that's common, maybe we can show warning (instead of erroring out)?

@scott2000
Copy link
Contributor Author

I personally think it's an easy mistake to make, since jj workspace add seems to break a pattern followed by other commands. For instance, while creating/forgetting branches, you use the name of the branch for both operations. But for workspaces, you have to use the path for creating it but the name for forgetting it. So I think it's easy to accidentally use the name instead of the path if you're not really thinking about where you want the workspace to be located on disk.

I do agree that only requiring a path separator for one command seems inconsistent though, so I'll look into making it a warning instead. I think it's good to have a warning at least, because having a workspace inside of another workspace can be confusing, so a warning explaining what happened would be useful.

@martinvonz
Copy link
Member

But for workspaces, you have to use the path for creating it but the name for forgetting it.

Good point. Do you think we should change the syntax for creating a workspace to jj workspace create --path/location/destination=<path> [<name>] instead? The current syntax is similar to jj git clone <url> [<location/destination>], so we may also want to consider changing that too in that case.

@scott2000
Copy link
Contributor Author

Another option could be something like this:

# Create workspace at <path> with basename as name
jj workspace add --at <path>

# Create workspace <name> at <path>
jj workspace add <name> --at <path>

# Create workspace <name> at <path>/<name>
jj workspace add <name> --in <path>

# Create workspace <name> at ../<name>
jj workspace add <name>

I don't mind the way it currently works though.

@yuja
Copy link
Contributor

yuja commented Jul 21, 2024

I don't think jj git clone <source> <dest> is analogous to jj workspace add, but we'll need to keep jj git remote add <name> <url> in sync with jj workspace add. Both commands take <name> <value> arguments.

@scott2000 scott2000 force-pushed the current-workspace-check branch from dc0bcff to 1680bc0 Compare July 25, 2024 21:43
@scott2000 scott2000 changed the title workspace: require path separator when adding workspace workspace: warn if destination doesn't contain path separator Jul 25, 2024
@scott2000
Copy link
Contributor Author

Ok, I updated it to just show a warning with instructions on how to remove the workspace if it was unintentional. Do you think it's clear enough?

Copy link
Contributor

@yuja yuja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks.

Copy link
Contributor

@PhilipMetzger PhilipMetzger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A warning should be good enough as it also preserves @thoughtpolice workflow.

cli/src/commands/workspace.rs Outdated Show resolved Hide resolved
This test case was creating "workspace1" as a sub-directory of the
default workspace, which seems like a mistake.
Users may try to run `jj workspace add <name>` without specifying a
path, which results in the workspace being created in the current
directory. This can be confusing, since the workspace contents will also
be snapshotted in the original workspace if it is not sparse. Adding a
warning should reduce confusion in this case.
@scott2000 scott2000 force-pushed the current-workspace-check branch from 1680bc0 to 71114c4 Compare July 26, 2024 23:13
@scott2000 scott2000 merged commit 304f6df into jj-vcs:main Jul 26, 2024
17 checks passed
@scott2000 scott2000 deleted the current-workspace-check branch July 26, 2024 23:37
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.

Do not allow creation of workspaces inside working copy
6 participants