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 pushing commits with conflicts #1477

Open
ilyagr opened this issue Apr 3, 2023 · 5 comments
Open

FR: Allow pushing commits with conflicts #1477

ilyagr opened this issue Apr 3, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@ilyagr
Copy link
Contributor

ilyagr commented Apr 3, 2023

This would be guarded by a flag, e.g. jj git push --conflicted-commits.

I wanted to have a tracking bug for this and jot down some thoughts. One potential obstacle is as follows:

With the current design, a conflict is stored in git as a .jjconflict file that points to the hash of a git object for each side of the conflict.

Suppose we have a commit that includes a conflict with a side that is a Git object not referenced by any other visible commit. This would often happen after a rebase. If we push it to Github, and then Github does git garbage collection, how do we ensure the git object for that side is not lost?

We probably don't want to push the special refs JJ uses to prevent GC locally. I'm not sure that even works correctly locally for a conflict with sides that are not in any other commit, visible or invisible, e.g. a conflict where a side was edited by the user (this would be a separate but related bug).

We might need to push an extra "hidden" branch or branches to github to keep track of all the sides of all the conflicts. This could also help with presenting conflicts in human-readable ways in the Git repo, but quite a few details would need to be worked out.

@chooglen
Copy link
Contributor

chooglen commented Apr 3, 2023

If we push it to Github, and then Github does git garbage collection, how do we ensure the git object for that side is not lost?

Alternatively, maybe we could extend the commit format to capture the objects on all sides of the conflict. E.g. if we have a conflict at path foo between blobs abcde and 12345, we could store them in the commit as foo.jjconflict.abcde and foo.jjconflict.12345.

@ilyagr
Copy link
Contributor Author

ilyagr commented Apr 3, 2023

I think that's a good idea. I don't understand Git well enough to be completely sure, but it seems these names in the tree could point to the very same Git objects as the current .jjconflict file mentions. They could even replace the current .jjconflict file and be somethink like .add1.jjconflit, .add2.jjconflit, .remove1.jjconflict, etc.

(We could still include some info in the .jjconflict file, like the revisions the sides come from, but it would all be non-essential metadata).

@ilyagr
Copy link
Contributor Author

ilyagr commented Apr 3, 2023

As an aside, I'd even appreciate being able to see this file in my workspace (e.g. there could be a command switching between jj showing the automerge in the workspace and the .add1.jjconflict files). For some complicated edit-move or edit-split conflict, I could manually rename the files to stack the right diffs on top of the right files and then switch back to the auto-merge view.

@martinvonz
Copy link
Member

Changing the storage of conflicts in Git sounds good to me, but I think we should revisit how we represent conflicts to start with before that, so we don't have to update it again. For that reason, it might be good to address #1176 first, to see if dropping the room for labels in conflict terms seems reasonable (I really would like to drop that). I also tried replacing the current unordered sets of positive and negative terms by a single list. You can see how that looks in #1480.

@ilyagr
Copy link
Contributor Author

ilyagr commented Nov 12, 2023

A lot has changed since April. Quick update based on a Discord discussion:

  • We are now using a different conflict format, so the previous obstacles to implementing this are gone and there may be a few new ones.
  • One new obstacle: jj stores some conflict metadata outside Git, mainly for performance reasons. This data would have to be recreated when pulling conflicted commits.

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

3 participants