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

jj git colocate #4833

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

jj git colocate #4833

wants to merge 2 commits into from

Conversation

cormacrelf
Copy link

Fixes #4624

Open to bikesheds on what to call the inverse command. jj git delocate?

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

@joyously
Copy link

Open to bikesheds on what to call the inverse command. jj git delocate?

Would it be isolate?

@cormacrelf cormacrelf force-pushed the git-colocate branch 2 times, most recently from 14df9e7 to c5ad1b8 Compare November 11, 2024 15:58
@neongreen
Copy link
Contributor

jj git dismantle? jj git purify?

@cormacrelf
Copy link
Author

cormacrelf commented Nov 11, 2024

If you're turning off git, you are really turning a page on what once was. One might type it with a renewed sense of purpose, confidence in your knowledge of the JJ way, and independence of the crutch you once needed. In that vein I suggest

  • jj git renounce, my favourite; or
  • jj git disavow

(Also like jj git dismantle.)

@martinvonz
Copy link
Member

jj git internalize might be okay. I think of the operation as making the .git/ dir internal to .jj/. But it's not as cheeky as some of the other options :)

@emilazy
Copy link
Contributor

emilazy commented Nov 11, 2024

jj git conceal keeps everything nicely under a co‐ namespace. (Not serious. Or am I?)

@joyously
Copy link

separate comes to mind.
Or jj git colocate --reverse
I think of most of the git subcommands as actual Git commands, but this is not, so it seems a bit different. (both colocate and its reverse)

lib/src/workspace.rs Outdated Show resolved Hide resolved
We need this to differentiate primary/secondary workspaces when choosing
how to colocate them (and for now, doing nothing for workspaces as
worktrees have not landed).
@cormacrelf cormacrelf force-pushed the git-colocate branch 2 times, most recently from c510233 to 335ac54 Compare November 12, 2024 09:43
@cormacrelf cormacrelf requested a review from yuja November 12, 2024 09:58
@essiene
Copy link
Contributor

essiene commented Nov 12, 2024

separate comes to mind. Or jj git colocate --reverse I think of most of the git subcommands as actual Git commands, but this is not, so it seems a bit different. (both colocate and its reverse)

I really like colocate --reverse since unlike other suggestions, I don't have to think about what this does.

If there must be a command under jj git, a close second of colocate --reverse would be jj git decolocate, which is not a real word to be sure, but also communicates intent clearly.

fwiw ;-)

Comment on lines 83 to 114
let old_path = workspace_command.repo_path().join("store").join("git");
let new_path = workspace.workspace_root().join(".git");
fs::rename(&old_path, &new_path).context(old_path)?;
Copy link
Author

Choose a reason for hiding this comment

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

Ah, sorry, we have to check that old_path exists (and is a directory, and is not a symlink, and also that git_target points to it) before we commit to writing out core.bare=false.

As long as we check this, I don't think we need to handle the large variety of git_target scenarios outside of this, because there will soon be an alternative, which is to just add a worktree. Which will work in many more scenarios. git_target can point into outer space for all we care.

The idea is to have --prefer-worktree switch to using worktrees in the primary workspace, as well as secondary ones.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@cormacrelf cormacrelf force-pushed the git-colocate branch 3 times, most recently from 60c3272 to db0a1eb Compare November 12, 2024 14:26
Initially, we can only colocate the primary workspace.

See <https://martinvonz.github.io/jj/latest/git-compatibility/#converting-a-repo-into-a-co-located-repo> for the steps.

Adds a Workspace::reload() function to reload the workspace from the
file system, which is technically not necessary for this diff, but will
become necessary soon, when we make the GitBackend colocation-aware.
@PhilipMetzger
Copy link
Contributor

Open to bikesheds on what to call the inverse command. jj git delocate?

I'd like to have the inverse in the native backend with something like adopt but that can wait. Otherwise internalize is a fine name.

}

let git_repo = git_backend.git_repo();
if workspace.is_primary_workspace() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we detect this somehow by caller or git layer?

I don't think "is primary workspace" can be a common concept across working-copy/workspace-loader backends.


if workspace_command.working_copy_shared_with_git() {
return Err(user_error(format!(
"Workspace '{}' is already colocated.",
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: error message doesn't usually contain period

let old_path_canon = old_path.canonicalize().ok();

let mut config =
gix::config::File::from_git_dir(common_dir.to_path_buf()).map_err(internal_error)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe this should be a user error (assuming it would do some I/O)?

BTW, the gix' fetch/clone implementation might help understand their config API. I'm not familiar with that.
https://github.com/GitoxideLabs/gitoxide/blob/main/gix/src/clone/fetch/util.rs

//
// This way we end up with a git HEAD written immediately, rather than
// next time @ moves. And you can immediately start running git commands.
let workspace = workspace
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can use command.workspace_helper_no_snapshot()?


git::reset_head(tx.repo_mut(), &git2_repo, &wc_commit)?;

tx.finish(ui, format!("Colocated existing workspace {name}"))?;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Colocated -> colocate

Comment on lines +88 to +89
if old_path.is_symlink()
|| !old_path.is_dir()
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: use .symlink_metadata() instead of stat()ing twice?

@yuja
Copy link
Contributor

yuja commented Nov 15, 2024

jj git colocate --reverse

I don't like the name --reverse, but it's nice that we don't have to add two separate commands which would be rarely used.

@camsteffen
Copy link

subsume?

@bryango
Copy link

bryango commented Dec 18, 2024

I would suggest jj git relocate with flags --colocate and the reverse, perhaps --conceal or whatever. The --colocate flag then coincides with the flag for jj git init.

@KingMob
Copy link
Contributor

KingMob commented Dec 18, 2024

Open to bikesheds on what to call the inverse command

As joyously pointed out, many of the existing jj git * commands mirror existing git commands, and colocate is an oddball. If we wanted to strengthen the perception that jj git is for existing git commands, what about moving colocation under util?

It could be jj util dotgit --colocate or jj util dotgit --decolocate (or show/hide/conceal/relocate/etc). Just my $.02.


Otherwise, I agree that such a rare operation shouldn't have a dedicated word. I'm in favor of jj git colocate --reverse.

@PhilipMetzger
Copy link
Contributor

If we wanted to strengthen the perception that jj git is for existing git commands, what about moving colocation under util?

I disagree on that, as colocating a Git repo should be visible to many users. The util namespace is for our utilities.

It could be jj util dotgit --colocate or jj util dotgit --decolocate (or show/hide/conceal/relocate/etc). Just my $.02.

If there were a transparent .git mode, then it also could have a place there. But that only came up once a while ago in the Discord.

@tim-janik
Copy link
Contributor

Wouldn't it be simplest to just have:

jj git init --colocate
jj git init --bare

And instead of throwing an error if the repo exists, ensure it becomes bare/colocated?

@jennings
Copy link
Contributor

jennings commented Dec 19, 2024

Maybe this is a dumb suggestion, but what if we called this jj git reinit instead?

  • jj git reinit --colocate - Convert to colocated
  • jj git reinit --no-colocate - Convert to non-colocated

I suggest --no-colocate because we simply don't have a natural antonym for "colocate".

Or, if we're feeling really wild, we could overload jj git init to do this if we're already in a repo. (Update: Ha, @tim-janik suggested essentially this while I was typing).

jj git init --bare

I think --bare would create a false association with git init --bare, which is a different concept.

@KingMob
Copy link
Contributor

KingMob commented Dec 20, 2024

A new user might worry that running jj git reinit or rerunning jj git init would do other, destructive things that maybe they didn't want, like erasing all history and resetting the repo. I think init implies too many other things.

@nrbray
Copy link

nrbray commented Dec 20, 2024

jj git colocate --reverse

I don't like the name --reverse, but it's nice that we don't have to add two separate commands which would be rarely used.

jj git colocate --remove would be my suggestion, as it removes the presence of git from any existing git aware tooling and is the most significant effect from my point of view

@nrbray
Copy link

nrbray commented Dec 20, 2024

I really like colocate --reverse since unlike other suggestions, I don't have to think about what this does.

@essiene I think you made the most relevant comment. Also the effect is to remove the presence of git from the perspective of legacy tools. So you inspired me to suggest:

jj git locate --legacy
jj git locate --internal

@samueltardieu
Copy link
Contributor

Back in October, I had a need to colocate/"uncolocate" a lot of repos, so I wrote a half-backed implementation of it which does not deal with workspaces (more exactly which hasn't checked if it works or not in secondary workspaces), so I haven't finished or submitted it.

I chose jj git colocate and jj git colocate --undo which seemed clear enough to me.

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.

FR: Add a jj git colocate command