jj
jj copied to clipboard
FR: `jj git import` local detached git objects by exact name
The josh-filter
tool from the Josh project can rewrite the current HEAD
of a Git repository into a new FILTERED_HEAD
reference i.e. the file .git/FILTERED_HEAD
is created and points to a new commit with its own history, which exists as its own tree independent of the existing history.
I would like to import this FILTERED_HEAD
reference to play with in jj
, however, to do that right now, you have to create a temporary branch, jj git import, then delete the branch. So something like:
git branch tmp-filtered FILTERED_HEAD
jj git import
jj branch forget tmp-filtered
Now I can:
jj workspace add ws/filtered -r $(cat .git/FILTERED_HEAD)
And get a workspace created for that reference to examine/test it. I can then jj abandon
the commits when I'm done or what have you.
Proposed UX
I would like to avoid the fiddling with the underlying Git repository and branch structure. So I would like something like this:
jj git import -r FILTERED_HEAD
Where the syntax -r <GITREF>
looks up and imports a commit, and possibly its ancestry, into jj
's view. GITREF
should more or less be treated as Git would interpret it, IMO. So you can refer to any commit ID or pointer to an ID; FILTERED_HEAD
, a prefix, etc.
It would also be reasonable to support multiple -r
options at once, the semantics resulting in an aggregate "import all of this in bulk", of course.
Where the syntax
-r <GITREF>
looks up and imports a commit, and possibly its ancestry, intojj
's view.GITREF
should more or less be treated as Git would interpret it, IMO. So you can refer to any commit ID or pointer to an ID;FILTERED_HEAD
, a prefix, etc.
It sounds like a low-level command (like jj git push-commit
discussed in #2098), and I think it's better to not overload jj git import
command.
Implementation-wise, maybe we can just git_backend.import_head_commits(new_heads); mut_repo.add_heads(new_heads);
. The existing git::import_refs()
machinery has complex logic to track (named) branch movement, which isn't needed to import new anonymous branches.
This is getting pretty annoying for two of us at work suddenly, because we're demoing Gerrit, and to download patches it encourages you to do something like the following (in Gitspeak):
git fetch $URL refs/changes/$CHANGENO/$CHANGENO/$PATCHNO
git checkout FETCH_HEAD
So, obviously having to do the whole branch-sync-delete dance is really tiring and explaining the workaround is annoying. I'll probably take a stab at fixing this shortly.
What do we think about the name? Maybe I can come up with something, but I wonder if changing the name around to jj git commit pull
instead is better? pull-commit
seems odd. We could also have a jj git commit push
and other various jj git commit
commands along the lines of #2098. (Even though #2845 obsoletes that particular change, and I plan on adding a simple jj gerrit receive
which would better address this, there are probably many cases for basic Git interop like the original bug where this would be nice, and it's much more straightforward to design, at least.)
What do we think about the name? Maybe I can come up with something, but I wonder if changing the name around to
jj git commit pull
instead is better?pull-commit
seems odd. We could also have ajj git commit push
and other variousjj git commit
commands along the lines of #2098.
commit
sounds like a verb. I don't have better suggestion, but if we choose sub-sub command namespace style, the name should be unambiguously noun. jj git plumbing
might be even better. :)
git fetch $URL refs/changes/$CHANGENO/$CHANGENO/$PATCHNO git checkout FETCH_HEAD
fwiw, these commands should work fine in colocated repo. I often do gh pr checkout
to pull commits for review.