-
Notifications
You must be signed in to change notification settings - Fork 596
docs: Add guide for handling divergent changes #7061
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
base: main
Are you sure you want to change the base?
Conversation
c4642db
to
97a57fe
Compare
## What are divergent changes? | ||
|
||
A [divergent change][glossary_divergent_change] occurs when multiple visible | ||
commits have the same change ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a link to https://jj-vcs.github.io/jj/prerelease/glossary/#visible-commits?
When I was new to jj
(coming from git
), I found it tricky to navigate/understand the docs because there was a bunch of new terminology that seemed to be assumed knowledge, so it'd be handy to linkify these sorts of things.
visible even if it was hidden before. | ||
|
||
- It is made the working copy. `jj edit REV` will make `REV` visible if it | ||
wasn't already. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 97a57fe:
We should add the case where a new ref is imported from git, e.g. by the user running git fetch
or otherwise directly manipulating the git repo. For me this is the most common source of divergent change IDs, and it's especially confusing because "I didn't do anything, I just git fetch
ed!", which in pure git is one of the least destructive things you can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(See #4388 in case you are wondering why somebody would use git fetch
. This is a very common workflow with Github and Gitlab, which provide non-branch refs for every PR, saving you the work of adding every contributor's fork as a remote.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this sound?
A visible descendant is added locally. For example,
jj new REV
will makeREV
visible even if it was hidden before.A visible descendant is fetched from a remote. If the hidden commit was pushed to a remote, others may base new commits off of them. When their new commits are fetched, their visibility makes the hidden commit visible again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds great to me! I didn't realize that this was the specific mechanism by which my fetches were causing me grief.
I kinda think that jj
itself should help with this. by noticing when previously-hidden commits become visible again. (And distinguishing between commits that were hidden manually with abandon
and those that were hidden implicitly by just updating a change). Though this is out of scope for a docs change, of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, mostly left some minor nits with discussion points
But, a hidden commit can become visible again. This can happen if: | ||
|
||
- A visible descendant is added. For example, `jj new REV` will make `REV` | ||
visible even if it was hidden before. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: if you want to be complete here, the bookmark
commands also should be mentioned
Divergent changes also occur if two different users or processes amend the same | ||
change, creating two visible successors. This can happen when: | ||
|
||
- Multiple people edit the same change simultaneously in different repositories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: expand this to mention to mention a coworker working on the same branch and then re-pushing, since many don't understand that as a rewrite
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you referring to a coworker appending a new commit to your branch (as opposed to amending a commit)? Do you think this suggestion would address that too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean this case here: #7004
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this sound if I replace all the bullet points with this?
Another author modifies commits in a branch that you have also modified
locally.You perform operations on the same change from different workspaces of the
same repository.Two programs modify the repository at the same time. For example, you run
jj describe
and, while writing your commit description, an IDE integration
fetches and rebases the branch you're working on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that should be good enough
@@ -540,15 +540,6 @@ with something like `jj desc -m "Revert the merge of D into B`. Now, commit `@` | |||
undoes the merge of `D` into `B`. If necessary, you can now rebase it | |||
elsewhere, e.g. `jj rebase -r @ -d main`. | |||
|
|||
### How do I deal with divergent changes ('??' after the [change ID])? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should leave the FAQ entry, and link to the new doc for more details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally did that, but then realized we keep old versions of the documentation published.
Removing this question will only affect /latest/
and /prerelease/
.
If someone needs a permanent link to documentation, I think they really should be linking to a specific version.
It also seemed untenable to keep old FAQ questions around forever for this purpose.
What do others think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing this question will only affect
/latest/
and/prerelease/
.
No, the point is that someone reading the FAQ will find the divergent answer, and then follow the link to the new doc to get all the details. Two ways to discover the answer are better than one. Just to note, I'm not concerned about versions of the docs, just that the info is discoverable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @ilyagr's opinion on that should matter. I have no preference here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think people often link to the /latest
version of the docs. for example, most links inside jj
's source code are to /latest
.
Joy's point also seems reasonable to me; this would make the article more discoverable, and I don't see much harm in the FAQ question remaining.
So, I'd keep the question, even if it becomes a stub.
jj log -r 'divergent()' | ||
|
||
# Abandon the unwanted commit using its commit ID | ||
jj abandon <unwanted-commit-id> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 97a57fe:
I think this instance of jj abandon
(the one right after jj log -r 'divertgent()'
, since Github display doesn't have enough context) should illustrate that you can provide multiple commit IDs. If you abandon them one at a time, descendants (which you intend to abandon anyway) get rebased and chenge their commit IDs from under you, and get conflicts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one below (in "duplicate and abandon") I think should also do this: it should probably illustrate duplicating commits one by one, for simplicity's sake, but then abandon them all at once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, I don't feel strongly about this -- if you're unsure at all you can just ignore me. This PR is super valuable and I don't mean to hang it up or waste mental energy on minutae.
Divergent changes are so frequently asked that I think it deserves more explanation than a FAQ entry can give it.
I think making a new "Guides" section and putting this there makes us better able to explain what's going on.
Checklist
If applicable:
CHANGELOG.md
README.md
,docs/
,demos/
)cli/src/config-schema.json
)