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

rebase: skip duplicate divergent commits by default #6302

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

scott2000
Copy link
Contributor

This is a partial fix for #5381 and #2979. It doesn't handle the general case (it only detects duplicate changes between divergent commits with the same change ID), but I think it should handle many useful cases, especially for users with the change-id header enabled. I'm looking for feedback about whether this is a good general approach and about the implementation.

This serves a similar purpose to Git's patch ID mechanism, however it is slightly different in that it only compares commits which have the same change ID as each other (divergent changes), and it does a full comparison of the commits to see if they would have identical trees if rebased onto the same parents. Since most changes aren't divergent, I believe this should have a negligible performance cost in most cases.

I think skipping these commits by default makes sense for jj rebase, since usually this will be a helpful behavior for the user. With this behavior, a safe first step when encountering divergent changes would be to rebase one branch on top of the other, since that will abandon any divergent changes that have identical contents to existing commits, leaving behind any non-trivial divergent changes for the user to resolve manually.

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

I'm going to introduce more options other than empty, so this struct
will hold all of the options related to abandoning rebased commits.
This serves a similar purpose to Git's patch ID mechanism, however it is
slightly different in that it only compares commits which have the same
change ID as each other (divergent changes), and it does a full
comparison of the commits to see if they would have identical trees if
rebased onto the same parents. Since most changes aren't divergent, I
believe this should have a negligible performance cost in most cases.
I think skipping these commits by default makes sense for `jj rebase`,
since usually this will be a helpful behavior for the user. With this
behavior, a safe first step when encountering divergent changes would be
to rebase one branch on top of the other, since that will abandon any
divergent changes that have identical contents to existing commits,
leaving behind any non-trivial divergent changes for the user to resolve
manually.
.range(&ResolvedRevsetExpression::commits(self.new_parents.clone())),
)
.evaluate(self.mut_repo)
.map_err(|err| BackendError::Other(Box::new(err)))?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we're only interested in ancestors of the new parents (which I think are equivalent to the ancestors of the rebase destination), maybe we can abandon divergent commits before starting the rebase process?

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.

2 participants