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

Splitting a parent of a merge commit results in weird changes to the commit graph #3483

Closed
ilyagr opened this issue Apr 11, 2024 · 8 comments · Fixed by #3485
Closed

Splitting a parent of a merge commit results in weird changes to the commit graph #3483

ilyagr opened this issue Apr 11, 2024 · 8 comments · Fixed by #3485
Labels
🐛bug Something isn't working

Comments

@ilyagr
Copy link
Contributor

ilyagr commented Apr 11, 2024

Steps to Reproduce the Problem

I'm very curious if others can reproduce this.

UPDATE: I might replace the jj-bug repo shortly; the bug turned out to be simply about splitting any parent of any merge commit anyway.

  1. jj git clone --colocate https://github.com/ilyagr/jj-bug (Get a perfectly organized and orderly repo 🤣 )
  2. cd jj-bug
  3. jj branch track 'glob:*@origin'

Then:

$ jj log -r ilya-
○  xpzxqz ilyagr@ 50 minutes ago conflictsides f503642
│  conflicts.rs: label conflict number and sides next to conflict markers
~

○  txsstw ilyagr@ 1 hour ago diffedit3 be2133e
│  diff editor: bundle a new `:builtin-web` GUI diff editor
~

○  nutytz ilyagr@ 1 hour ago gvimdiff 4a41932
│  merge_tools.toml: add gvimdiff config
~

○  ypqnrx ilyagr@ 1 hour ago verdate 3aded1d
│  cli version: Put `+` before build data instead of `-`
~
$ jj split -r conflictsides CHANGELOG.md  # Accept the descriptions as they are in the editor
Rebased 11 descendant commits
First part: xpzxqz 6cc476f conflicts.rs: label conflict number and sides next to conflict markers
Second part: tvootm 40d7ded conflictsides*| conflicts.rs: label conflict number and sides next to conflict markers
New conflicts appeared in these commits:
  trmunt 09a627e local-de3*| (conflict) Use local ../diffedit3-working
To resolve the conflicts, start by updating to it:
  jj new trmunttywktn
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.

$ jj log -r ilya-   # Changes weirdly
○  tvootm ilyagr@ 2 minutes ago conflictsides* 40d7ded
│  conflicts.rs: label conflict number and sides next to conflict markers
~

What happened to all the other parents of ilya?

Specifications

  • Platform: Mac OS
  • Version: a few days old, customized: jj 0.16.0+20240405-fd26902376c1dc96
@ilyagr ilyagr added the 🐛bug Something isn't working label Apr 11, 2024
@ilyagr ilyagr changed the title Splitting a commit results in weird changes to the commit graph Splitting a parent of a merge commit results in weird changes to the commit graph Apr 11, 2024
@yuja
Copy link
Contributor

yuja commented Apr 11, 2024

cmd_split() rebases the children onto exactly one new parent. That's probably the problem. I'm not sure why it can't do rebase_descendants().

https://github.com/martinvonz/jj/blob/1bfacea2f9fe12d8f58ecc2d3984a33b95083b55/cli/src/commands/split.rs#L179-L197

@emesterhazy
Copy link
Contributor

IIRC a direct call to MutableRepo::rebase_descendants doesn't work in the --siblings case since we need to add two new parents. The bug seems to be that we're dropping any other parents that child had previously. This is very similar to what we're doing in jj parallelize, except that the bug isn't present there because we include the uninvolved parents.

I can't really tell what's happening in Iyla's example, but it's clear that the uninvolved (i.e. not split) parents were dropped if you print a more complete graph before and after the split.

I'll upload a fix.

emesterhazy added a commit that referenced this issue Apr 11, 2024
…ommit

Ilya reported this in #3483.

The bug was introduced in
9763207.

Before this fix, `jj split` dropped any parents what weren't involved in the
split when it rebased the children of the commit being split. This meant that
any children which were merge commits lost their other parents unintentionally.

Fixes #3483
@yuja
Copy link
Contributor

yuja commented Apr 11, 2024

a direct call to MutableRepo::rebase_descendants doesn't work in the --siblings case since we need to add two new parents.

Perhaps, the commit could be recorded as rewritten to two new commits? If the original commit had a branch, it will diverge. It's not ideal, but I think is technically correct.

emesterhazy added a commit that referenced this issue Apr 11, 2024
Ilya reported this in #3483.

The bug was introduced in 9763207.

Before this fix, `jj split` dropped any parents what weren't involved in the
split when it rebased the children of the commit being split. This meant that
any children which were merge commits lost their other parents unintentionally.

Fixes #3483
emesterhazy added a commit that referenced this issue Apr 11, 2024
Ilya reported this in #3483.

The bug was introduced in 9763207.

Before this fix, `jj split` dropped any parents what weren't involved in the
split when it rebased the children of the commit being split. This meant that
any children which were merge commits lost their other parents unintentionally.

Fixes #3483
@emesterhazy
Copy link
Contributor

I'm pretty sure that I tried this when I first implemented --siblings and it caused the original commit to become divergent (not just the branches).

Since then set_rewritten_commit only now only accepts one argument after e55168f.

The docs for set_divergent_rewrite seem to suggest the rebasing won't happen the way we want it to.
https://github.com/martinvonz/jj/blame/a786802b4017f6e20cc3ecde054e249e4f8ec005/lib/src/repo.rs#L834-L841

I'll try and see if I can get this to work, but if you have a specific suggestion that you think will work please let me know.

emesterhazy added a commit that referenced this issue Apr 11, 2024
Ilya reported this in #3483.

The bug was introduced in 9763207.

Before this fix, `jj split` dropped any parents what weren't involved in the
split when it rebased the children of the commit being split. This meant that
any children which were merge commits lost their other parents unintentionally.

Fixes #3483
@martinvonz
Copy link
Member

I'm pretty sure that I tried this when I first implemented --siblings and it caused the original commit to become divergent (not just the branches).

Divergence just means that there is more than one visible commit with the same change id, so that shouldn't be the case.

The docs for set_divergent_rewrite seem to suggest the rebasing won't happen the way we want it to. https://github.com/martinvonz/jj/blame/a786802b4017f6e20cc3ecde054e249e4f8ec005/lib/src/repo.rs#L834-L841

Oh, good point. I really should have thought about that myself since I made the change.

I don't know if there's a better way of doing this then. I think I'm getting close to done with the rebase API refactoring. Hopefully this can be rewritten and simplified once that's done.

@emesterhazy
Copy link
Contributor

I busted out the old set_rewritten_commit function that takes a vec of commit IDs to see what happens. Looks like you're right that the commit doesn't become divergent, so I must have been thinking of the branches. Doing this does change where @ ends up after the split though when --siblings is used, and of course branches become divergent.

#3486

Maybe it's better to fix with the current PR and rewrite when the API changes are complete?

emesterhazy added a commit that referenced this issue Apr 11, 2024
Ilya reported this in #3483.

The bug was introduced in 9763207.

Before this fix, `jj split` dropped any parents what weren't involved in the
split when it rebased the children of the commit being split. This meant that
any children which were merge commits lost their other parents unintentionally.

Fixes #3483
emesterhazy added a commit that referenced this issue Apr 11, 2024
Ilya reported this in #3483.

The bug was introduced in 9763207.

Before this fix, `jj split` dropped any parents what weren't involved in the
split when it rebased the children of the commit being split. This meant that
any children which were merge commits lost their other parents unintentionally.

Fixes #3483
@ilyagr
Copy link
Contributor Author

ilyagr commented Apr 11, 2024

Thank you all very much!

This is far less subtle than I expected, it doesn't explain other issues I think I was seeing. I thought we'd have a test for this and, well, now we do :).

@ilyagr
Copy link
Contributor Author

ilyagr commented Apr 11, 2024

~~Actually, no, we don't have that test. I'll hopefully remember to add it ~~

Update: The test will be there after #3488.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants