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: docs: Git equivalent of git merge --squash <branch> #5537

Open
jalil-salame opened this issue Jan 31, 2025 · 10 comments
Open

FR: docs: Git equivalent of git merge --squash <branch> #5537

jalil-salame opened this issue Jan 31, 2025 · 10 comments
Labels
enhancement New feature or request

Comments

@jalil-salame
Copy link

Is your feature request related to a problem? Please describe.
The only times I've had to drop down to git in the last few weeks has been for squash merges .

Describe the solution you'd like
I'd like a way to perform a squash merge directly from jj, and the ability/inability to do so to be documented in the docs. Specifically, jj new main && jj squash --from main..feature-branch --to @ doesn't work as it inserts conflicts markers (when git merge --squash doesn't).

Describe alternatives you've considered

  • Not documenting/implementing it

Additional context
I don't like squash merges, but they help clean up the git history when a coworker has merged in the main branch to their feature branch instead of rebasing.

@joyously
Copy link

What's the difference with jj new main feature-branch ?

@ilyagr
Copy link
Contributor

ilyagr commented Jan 31, 2025

The idea of jj squash --from main..feature-branch --to @ is clever; I wonder why it didn't work. Perhaps it should be made to work.

Following Joy's comment, this could also work:

jj new main feature-branch
jj branch create tmp -r @ # Optional, you can just remember the change id instead
jj new main
jj restore --from tmp --to main

If the first of these commands results in conflicts, then some difference in merge algorithm between jj and git is to blame, and it would be less surprising that jj squash --from main..feature-branch --to @ resulted in conflicts.

You can also run jj describe -r main..feature-branch -r @ to adjust the commit message (with some care, multi-commit description editing can be a bit brittle).

There was also some discussion of allowing something like:

jj new main
# Not yet implemented
jj restore --from 'auto-merge(main,feature-branch)' --into @

@PhilipMetzger PhilipMetzger added the enhancement New feature or request label Jan 31, 2025
@martinvonz
Copy link
Member

I'm also curious why the jj squash failed. Just to be sure, was the fork point of main and feature-branch at main? I.e. was feature-branch a descendant of main? Because otherwise it could simply be conflicts between the feature branch and the main branch you were seeing.

@jalil-salame
Copy link
Author

  • jj new main && git merge --squash feature-branch had no conflicts
  • jj new main && jj squash --from main..feature-branch --to @ had conflicts
  • feature-branch had branched off a parent of main and then merged main in (multiple times), which is why I wanted to squash it.
  • Current solution is to teach my coworker about git rebase and have them update the branch by rebase instead of merge (also maybe disable the github buttons).
  • I will test some of the other commands and post the results.

@jalil-salame
Copy link
Author

What's the difference with jj new main feature-branch ?

IIRC that creates a merge commit instead of a squash merge, which is what i want.

@martinvonz
Copy link
Member

Is the repo you ran into it publicly available? I would still like to know why the jj squash caused conflicts. My best guess is that it's related to the same change being made multiple times (

jj/lib/src/merge.rs

Lines 85 to 91 in cfe5915

// All sides made the same change.
// This matches what Git and Mercurial do (in the 3-way case at least), but not
// what Darcs does. It means that repeated 3-way merging of multiple trees may
// give different results depending on the order of merging.
// TODO: Consider removing this special case, making the algorithm more strict,
// and maybe add a more lenient version that is used when the user explicitly
// asks for conflict resolution.
).

@jalil-salame
Copy link
Author

jalil-salame commented Feb 2, 2025

Is the repo you ran into it publicly available?

Sadly no :c

My best guess is that it's related to the same change being made multiple times (

jj/lib/src/merge.rs

Lines 85 to 91 in cfe5915

// All sides made the same change.
// This matches what Git and Mercurial do (in the 3-way case at least), but not
// what Darcs does. It means that repeated 3-way merging of multiple trees may
// give different results depending on the order of merging.
// TODO: Consider removing this special case, making the algorithm more strict,
// and maybe add a more lenient version that is used when the user explicitly
// asks for conflict resolution.
).

This sounds like the reason, I remember that during the review I asked to revert some unnecessary changes, which were probably badly resolved merge conflicts.

@GreyTeardrop
Copy link

GreyTeardrop commented Feb 2, 2025

I faced a similar issue recently - a long-running feature branch that had several merged from main along its history. Even though the branch at its current state did not have any conflicts with main, simply squashing it with all those merge commits resulted in some conflicts. I ended up manually recreating branch state from its latest merge point with main and rebasing that commit. Not sure if that would universally work though.

jj new "heads(::trunk() & ::feature-branch)"
jj restore --from feature-branch
jj rebase -d "trunk()"

@martinvonz
Copy link
Member

Yes, that should universally work. Btw, you can use fork_point(trunk() | feature_branch) to simplify a bit.

@jalil-salame
Copy link
Author

Sorry for the delay, these work:

@ilyagr

jj new main feature-branch
jj branch create tmp -r @ # Optional, you can just remember the change id instead
jj new main
jj restore --from tmp --to main

And

@GreyTeardrop + @martinvonz

jj new "fork_point(trunk() | feature-branch)"
jj restore --from feature-branch
jj rebase -d "trunk()"

They should be added to the docs as alternatives to git merge --squash.

I'll try to create a public repo with the issue during the weekend so that we can test against it and hopefully improve jj squash --from 'trunk()..feature-branch' --to @ so that it no longer causes merge conflicts.

jj squash has the benefit of letting you edit the description with all the squashed descriptions in the buffer, unlike the ones using jj restore.

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

6 participants