You learn to resolve those cases when 2 developers try to move the same remote Bookmark in 2 different, incompatible positions.
Bookmark Conflicts
In general, as long as updating a Bookmark's position means moving it forward along the history tree, everything goes smoothly.
It's less natural for a Bookmark to go backwards in history, or even
to jump to a parallel branch. If you try to do that with Git, it won't
complain, but your next git push will likely be rejected, with an
error such as:
! [rejected] feature/my_feature_branch -> feature/my_feature_branch (non-fast-forward)
error: failed to push some refs to 'ssh://git@yourrepo.com/repo/my -project.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Jujutsu tries to anticipate the problem and shows an error even before
the push, already when you attempt to move the Bookmark.
In the theirs repository, try moving the foo Bookmark from k to
o:
@ sz (empty)
│ ○ k foo Hello, world
│ ○ st
├─╯
│ ○ o bar
├─╯
◆ u main
│
~
$ jj bookmark move foo --to o
Error: Refusing to move bookmark backwards or sideways: foo
Hint: Use --allow-backwards to allow it.
Your Coworker Forces Their Way
If you really want to win this fight, you can always use the
--allow-backwards parameter. Let's suppose that's the path your
coworker decides to take:
jj bookmark move foo --to o --allow-backwards
@ sz (empty)
│ ○ k foo@origin Hello, world
│ ○ st
├─╯
│ ○ o bar foo*
├─╯
◆ u main
│
~
2 things to notice:
- Since now
fooandfoo@originare on different Changes, Jujutsu thinks it's appropriate to display both of them. - The asterisk in
foo*invites your coworker to align. Which they do with a push:
jj git push -b foo
@ sz (empty)
│ ○ k Hello, world
│ ○ st
├─╯
│ ○ o bar foo
├─╯
◆ u main
│
~
What Happens in Your Repository
Go back to ours repository. Unaware of the Bookmark's move, you
keep working on foo, adding another change:
jj new -m "Hola, mundo"
echo "Hola, mundo" > hello.txt
@ ol Hola, mundo
○ k foo Hello, world
○ s
│ ○ os bar
├─╯
◆ u main
│
~
You even reckon it's a good moment to advance foo from k to ol:
jj bookmark advance
@ ol foo* Hola, mundo
○ k foo@origin Hello, world
○ s
│ ○ os bar
├─╯
◆ u main
│
~
Right, Jujutsu marks foo with a * inviting you to align
foo@origin with a push:
$ jj git push -b foo
Changes to push to origin:
bookmark: foo [move forward from 938fe989965e to 0952644707a7]
Warning: The following references unexpectedly moved on the remote:
refs/heads/foo (reason: stale info)
Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again.
Error: Failed to push some bookmarks
Rejected.
Conflicts
Here's the log:
@ ol foo?? foo@git Hola, mundo
○ k Hello, world
○ s
│ ○ os bar foo?? foo@origin
├─╯
◆ u main
│
~
It also helps to list the bookmarks:
$ jj bookmark list foo
foo (conflicted):
- ksvskswq 938fe989 Hello, world
+ olnvmuqu 09526447 Hola, mundo
+ ossuomlo fa22ec04 (no description set)
@git (behind by 1 commits): olnvmuqu 09526447 Hola, mundo
@origin (behind by 3 commits): ossuomlo fa22ec04 (no description set)
Hint: Some bookmarks have conflicts. Use `jj bookmark set <name> -r <rev>` to resolve.
OK, calm down: there are 4 instances of foo now. How should you
interpret the situation?
- There are 2
foo??, one onoland one onos. Jujutsu is telling you that your local branchfoopoints to both.- On one hand, it wanted to keep
fooonol, where you moved it withjj bookmark advance. - On the other, the information coming from
originsays thatfooshould point toos.
- On one hand, it wanted to keep
What to do? Undecided, Jujutsu lets foo target both. That's why it
displays a ??.
foo@gitreminds you that in the underlying Git repository thefoobranch is still pointing tool.- Finally,
foo@originshows you the last known position offooonorigin, after the fetch.
Apparerently the situation can't be reconciled automatically. You'd better talk to your coworker and clarify what they had in mind.
Resolve a Bookmark Conflict
One possible solution for having in foo both the changes in ol and
those in os is to create a merge Change:
jj new -r ol -r os -m "Merge"
@ p (empty) Merge
├─╮
│ ○ os bar foo?? foo@origin
○ │ ol foo?? foo@git Hola, mundo
○ │ k Hello, world
○ │ s
├─╯
◆ u main
│
~
The new Change p looks like a good place to put the foo Bookmark:
jj bookmark move foo -t p
@ p (empty) foo* Merge
├─╮
│ ○ os bar foo@origin
○ │ ol Hola, mundo
○ │ k Hello, world
○ │ s
├─╯
◆ u main
│
~
Lovely! There are no more conflicts, only the invitation to push:
jj git push -b foo
@ p (empty) foo Merge
├─╮
│ ○ os bar
○ │ ol Hola, mundo
○ │ k Hello, world
○ │ s
├─╯
◆ u main
│
~
All clear. Your coworker is forgiven.