-
Notifications
You must be signed in to change notification settings - Fork 751
Description
This is a slightly edited and expanded version of my proposal from #4871, intended to replace --allow-new
, git.push-new-bookmarks
, and git.auto-local-bookmark
with a single mechanism that generalizes the existing tracking system and that I hope should be simpler, easier to learn, and more flexible at elegantly adapting to various workflows around remote bookmarks.
I don’t think this solution is perfect because bookmark tracking in general has dodgy semantics, IMO; being used for both the fetch and push end leads to weirdness that @arxanas has pointed out in the past and that we work around with things like trunk()
in the default immutable heads. Ideally, it should probably be split into multiple separate concepts for the “direction of travel”. But I feel this proposal would be better than the status quo, the configuration knobs should make it comparably convenient for the important use cases, and hopefully the result would feel less inelegant than the current situation does to me and seemingly many others.
(I’m open to discussion of more fundamental reworks of the tracking system along these lines, but kindly request we do so in another issue, because I feel it’s a can of worms with a lot of UX questions that would need resolving, so I worry about it blocking an incremental improvement.)
Outline
-
We extend the concept of tracking a bookmark on a remote to apply to ones that don’t yet exist on that remote.
jj git push
will only push bookmarks that are tracked, whether they are new or pre‐existing. This means that the default behaviour will remain as currently, i.e. no--allow-new
by default. -
--allow-new
is eliminated and replaced by the more orthogonaljj bookmark track ⟨bookmark⟩@⟨remote⟩
before pushing. If youjj git push
and the lack of tracking is the only thing preventing a push, it can print a hint to this effct. -
It’s fairly likely we’d want to add a
--track-on ⟨remote⟩
option tojj bookmark create
that sets up the tracking for you. -
To make the UX more convenient for cases like the single‐remote one where people are usually creating new bookmarks to push to one obvious remote, we introduce an
auto-track-bookmarks
option, which takes a (list of) pattern(s) likeglob:*@origin
, or possibly even a revset. This would affect both fetched bookmarks and newly‐created ones. -
git.auto-local-bookmark = true
andgit.push-new-bookmarks = true
can both be deprecated and replaced with something likeauto-track-bookmarks = "glob:*@origin"
orauto-track-bookmarks = "glob:*@*"
. I think this matches the semantics people want for a “one‐remote repository”.In a shared repository where you only create bookmarks to push your work but you don’t want everyone else’s work to be mutable, you could do
auto-track-bookmarks = "glob:emily/*@origin"
based on yourtemplates.git_push_bookmark
or manual branch naming. In this scenario, if you don’t have a consistent format (everyone just uses the same namespace but only some bookmarks are owned by you), then your options fall back to the more explicitjj bookmark create --track-on
orjj bookmark track
orjj git push --named
. This would be slightly less convenient than the current case where you can setgit.push-new-bookmarks = true
butgit.auto-local-bookmark = false
. (However, it behaves more consistently when cloning a new copy of a repository.)
Advantages
-
This eliminates the weird thing where new local bookmarks “want to be pushed to every remote by default” but are held back by a flag/setting, whereas bookmarks that come down from a remote are associated with it and you need to opt in to syncing them with a local one. I find the current model very strange, and believe the mental model here is much simpler: newly‐created bookmarks are local (…because you’re creating them locally), and tracking is the sole thing that determines whether a local bookmark is synced with a remote on fetch and push.
-
@senekor’s tutorial can introduce bookmark tracking up front as the way we tell Jujutsu which bookmarks we want to be synced with which remotes, which is important to learn and a common source of confusion for new users. This would still mean telling them to set a configuration setting if he doesn’t want people to have to explicitly specify
--track-on origin
for new bookmarks, but hopefully the setting makes a lot more sense than the current “disable some safety behaviour to work around (what I see as) an exception to the general tracking model” one. -
Automatic tracking of a subset of bookmarks is useful in other cases, too. In Nixpkgs, I often have to push manual merges to
staging
orstaging-next
to resolve conflicts. However, we also create versions of these for each stable release, i.e.staging-25.05
andstaging-next-25.05
. Being able to setauto-track-bookmarks = "glob:staging*@origin"
would be handy for this. -
This would help pave the way to the request to support tracking multiple bookmarks on different remotes that have the same name but are otherwise unrelated, because the model would be “local bookmarks have a set of remote bookmarks they sync with” and so you could add UI to track a remote bookmark under a different local name.
Unresolved questions
-
How exactly should
auto-track-bookmarks
behave? Some potential options:- The first time we consider a bookmark – whether new locally or fetched from a remote – we store its tracking status according to the current
auto-track-bookmarks
. - If a bookmark has not been explicitly tracked or untracked, then operations that care about its tracking status check
auto-track-bookmarks
. auto-track-bookmarks
takes precedence over manual tracking; you cannot manually untrack a bookmark it matches.
(iii) seems like the most conceptually elegant option, but I’m mostly ambivalent. (i) and (ii) are only distinguished by what happens when you change your
auto-track-bookmarks
setting. With (ii) you can’t explicitly “forget” having expressed an opinion about whether a bookmark should be tracked, which seems kind of weird. - The first time we consider a bookmark – whether new locally or fetched from a remote – we store its tracking status according to the current
-
How exactly should
jj bookmark (un)track
behave, especially in interaction withauto-track-bookmarks
? Do we want the setting to be “timeless” but the command to care about what bookmarks or remotes exist, or shouldjj bookmark track 'glob:*@*'
be equivalent to settingauto-track-bookmarks = "glob:*@*"
?This basically comes down to what we want the data model to look like, I think. Clearly this proposal is moving in the direction of “local bookmarks have an associated set of remote bookmarks that may or may not yet exist”. Two obvious models:
- Store a map from local bookmarks to remote bookmark names; use
auto-track-bookmarks
as a fallback. This would be compatible with all of the possibleauto-track-bookmarks
behaviours, I think, butjj bookmark (un)track
would behave differently to the setting. - Store a list of every
bookmark (un)track
command in chronological order; whenever considering a remote operation, start with the assessment ofauto-track-bookmarks
, then amend it based on eachbookmark (un)track
in sequence. I believe this is how @senekor was imagining it would work, and it would correspond to the (1.ii) behaviour forauto-track-bookmarks
. (Obviously this would be a ridiculous way to actually store it and you’d have some fancy normalized glob intersection structure, but it’s just about the actual end result.)
- Store a map from local bookmarks to remote bookmark names; use
-
jj bookmark create --track-on
has overlap withjj git push --named
; it’s unclear to me whether we’d want to eliminate it in favour of this functionality or if we value having a one‐shot create‐and‐push command that takes custom names and sets up the tracking. If we want to keep it,jj git push --named
would presumably set up the tracking according to the remotes you’re pushing the new bookmark to, sojj git push --remote ⟨remote⟩ --named ⟨bookmark⟩=⟨rev⟩
would be short forjj bookmark create --track-on ⟨remote⟩ -r ⟨rev⟩ ⟨bookmark⟩ && jj git push -b ⟨bookmark⟩
, which would be short forjj bookmark create -r ⟨rev⟩ ⟨bookmark⟩ && jj bookmark track ⟨bookmark⟩@⟨remote⟩ && jj git push -b ⟨bookmark⟩
. -
Maybe we’d want to move away from
⟨bookmark⟩@⟨remote⟩
syntax for tracking if people find the idea of tracking a bookmark that doesn’t yet exist on a remote to be confusing (I personally don’t really find it confusing). We would also probably want to adjust it if we start allowing tracking bookmarks under different names. -
Is the workflow compromise in (5) of the outline acceptable for the simpler model and increased flexibility? If many people don’t want to track fetched bookmarks, really want all new bookmarks to push with
jj bookmark create ⟨bookmark⟩ && jj git push
without any additional flags, don’t want to use any of the listed alternatives, and don’t want to define an alias forjj bookmark create --track-on ⟨remote⟩
, then this could be a deal‐breaker for the proposalI personally think that most use cases for automatic tracking fall under the “single‐person repository, track everything” or “shared repository with a consistent bookmark naming scheme, track only my bookmarks” cases that this proposal handles well, and the available options for this awkward case still seem okay to me. We already make such users pass
--allow-new
or configure a setting already.