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: --allow-empty for squash and unsquash. #1406

Open
yshui opened this issue Mar 21, 2023 · 13 comments
Open

FR: --allow-empty for squash and unsquash. #1406

yshui opened this issue Mar 21, 2023 · 13 comments

Comments

@yshui
Copy link

yshui commented Mar 21, 2023

I just started using jj, so maybe there is a better way to do this:

Scenario

While I was working on a big feature, I noticed a bug in the code base. The fix is a one-liner, and I want to commit it separately first, then continue working on the big feature.

With git, I would git add -p the change and then git commit. With jj, I would jj describe the bug fix, jj new to create a new working copy, jj unsquash -i to move everything except the bug fix.

The problem

Because the bug fix is small and everything else is big, unsquashing everything else is annoying. It would be easier to jj unsquash --allow-empty everything first, keeping the parent commit, then jj squash -i to move only the bug fix.

@yshui
Copy link
Author

yshui commented Mar 21, 2023

Maybe there could be a jj swap switch swaps a commit with its parent?

@yshui
Copy link
Author

yshui commented Mar 21, 2023

Oh, there is jj split. But it has the same problem because the right side starts with all the changes included. Could there be a version of jj split that starts with nothing?

@martinvonz
Copy link
Member

Oh, there is jj split. But it has the same problem because the right side starts with all the changes included. Could there be a version of jj split that starts with nothing?

Exactly, jj split is what I would use. If it starts with nothing, the left and right side would be the same and your diff tool wouldn't know show a diff at all, right?

@yshui
Copy link
Author

yshui commented Mar 21, 2023

If I want to start with nothing, I would expect the left side to contain all changes, which I can apply to the right side.

@joyously
Copy link

Isn't there a move command?

@martinvonz
Copy link
Member

If I want to start with nothing, I would expect the left side to contain all changes, which I can apply to the right side.

I'm not sure I follow, so let's make it concrete with an example. Let's say the parent commit has a file that looks like this:

a
b
c
d
e

Your working copy looks like this:

A
b
C
d
E

Let's say the bug fix is the a->A change. What would you like to see on the left and right side?

@yshui
Copy link
Author

yshui commented Mar 21, 2023

left | right
  A  |   a
  b  |   b
  C  |   c
  d  |   d
  E  |   e

And I change right to contain Abcde.

@martinvonz
Copy link
Member

I see. That would make it harder to review your changes before you save, though, because you would review the changes that remain (i.e. going into the child commit). It might still be a useful feature.

@yshui
Copy link
Author

yshui commented Mar 21, 2023

Another option is to keep the left and right side as it but make the left side editable and use that as the middle commit.

@necauqua
Copy link
Contributor

necauqua commented Mar 21, 2023

Probably I didn't get it, but for:

While I was working on a big feature, I noticed a bug in the code base. The fix is a one-liner, and I want to commit it separately first, then continue working on the big feature.

What I would do with jj is:

jj new -A @- # new wc commit, -A being --insert-after, meaning children of @- (so, the previous wc, our big work) are rebased on top of it
echo "fix" > file
jj describe -m "fixed"
jj edit @+ # go back to our work

jj new even has an -m parameter so you can use that instead of describe for it to be even shorter :) Describe would be better if you wanted to run it without -m so you'd have an editor.

With jj the mindset should be that you can always move off the working commit and come back, no stashes or anything, that's like one of the main features (the one I personally extremely like)

@yshui
Copy link
Author

yshui commented Mar 21, 2023

echo "fix" > file

So the fix is already part of the wc, I'd like to move it from the wc, instead of creating a new commit and redo it. redoing it might be fine if the fix is really just a one-liner. But sometimes the fix can be large enough to be annoying to redo, and still just be a small part of the changes in wc.

@necauqua
Copy link
Contributor

jj restore --from @+ <paths> might work in place of the echo then.
But the most generic case would indeed be jj split

@martinvonz
Copy link
Member

Another option is to keep the left and right side as it but make the left side editable and use that as the middle commit.

I think I like that option better because the diff is from left to right as usual. It still has the problem that it's hard to inspect the changes that will go into the parent commit before confirming. Of course, the current solution has the problem that it's hard to inspect the changes that will go into the child commit. It might be best if the diff tool could show both diffs compared to the initial versions, probably with 3 panes next to each other. But I don't think most diff tools support that, so that's probably not really an option except for in TUIs/GUIs we control.

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

No branches or pull requests

4 participants