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

FR: workspaces should also be collocated in --colocate mode #4436

Open
cormacrelf opened this issue Sep 11, 2024 · 5 comments
Open

FR: workspaces should also be collocated in --colocate mode #4436

cormacrelf opened this issue Sep 11, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@cormacrelf
Copy link
Collaborator

cormacrelf commented Sep 11, 2024

Is your feature request related to a problem? Please describe.

From #4424 (reply in thread)

Currently if you create a workspace in a collocated repo, the new workspace is not recognisable as a Git repository by any git tools. It does not have a .git directory.

The most painful tool, as usual, is Nix flakes, which silently drops back to "no git repo" mode and stops looking at your .gitignore file, and then just repeatedly copies your enormous build artifacts folder into the nix store. I actually only discovered this issue because Nix caused my computer to run out of space. (As usual this Nix's fault!)

Describe the solution you'd like

I think we should be able to create a corresponding git worktree for each workspace. (We might consider supporting importing worktrees you created with git, but not a priority really.)

Git worktrees are pretty simple and really just involve a couple of files and a ref. So I don't think it'll be that hard.

Unfortunately I don't think you can use libgit2 for this because there are no APIs that don't also do a full checkout into a newly created worktree directory. There are no options that prevent checkout. Nor does gitoxide help, it has some worktree code but not useful either (search docs.rs for gix-worktree).

So I recommend just copying roughly these bits of libgit2's git_worktree_add function (unless you think that much would violate GPL, in which case just read https://git-scm.com/docs/git-worktree sections Refs, and Details):

https://github.com/libgit2/libgit2/blob/main/src/libgit2/worktree.c#L355-L366

https://github.com/libgit2/libgit2/blob/main/src/libgit2/worktree.c#L389-L409

All it really needs to do is write a couple of files in the .git directory in the main workspace and in the newly created worktree, and then set an appropriate HEAD on the new worktree. It may be easier to add this in gitoxide, but this is a pretty niche use case.

Describe alternatives you've considered

None, but see the linked discussion

@yuja
Copy link
Collaborator

yuja commented Sep 11, 2024

We'll also need to track Git HEAD per jj's workspace.

jj/lib/src/op_store.rs

Lines 275 to 278 in 8314046

/// The commit the Git HEAD points to.
// TODO: Support multiple Git worktrees?
// TODO: Do we want to store the current branch name too?
pub git_head: RefTarget,

@yuja yuja added the enhancement New feature or request label Sep 11, 2024
@cormacrelf
Copy link
Collaborator Author

Ok, done. PR soon.

@cormacrelf
Copy link
Collaborator Author

Well, a few questions, what do we call the new heads? If you have two workspaces "default" and "hotfix", should they be called HEAD@default and HEAD@hotfix? Do we resolve HEAD@git to the one in the current workspace for backwards-compatibility reasons?

@yuja
Copy link
Collaborator

yuja commented Sep 12, 2024

If you have two workspaces "default" and "hotfix", should they be called HEAD@default and HEAD@hotfix? Do we resolve HEAD@git to the one in the current workspace for backwards-compatibility reasons?

Good question. Because the current syntax is <name>@<remote> (where remote = "git") or <workspace_name>@, the canonical form might be <workspace_name>@HEAD@git. It looks weird and the revset parser can't handle double @s.

Maybe we can instead map HEAD of the current workspace to HEAD@git, and hide everything else? We'll need to pass the current workspace id around to a few more places (e.g. git::import_head()), and HEAD@git might have to be translated earlier in revset (to e.g. RevsetCommitRef::GitHead(WorkspaceId).)

@cormacrelf
Copy link
Collaborator Author

If the parser could handle it, I think maybe HEAD@workspace@ would make slightly more sense. But no matter, we can just make a function that can resolve a HEAD from another workspace.

I have started making HEAD@git use the current workspace id. It seems right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants