Remote Bookmarks¶
Glossary¶
v position of the working copy
o uninteresting commit
a interesting commit
a <- bk Bookmark <bk> (pointing to "a")
Goals¶
- allow many bookmarks on server, without cluttering client
- prevent client from moving or activating ‘master’
- simplify pushing to a bookmark
- avoid confusing ‘sync/divergence’ logic
- avoid tracking
Clone¶
Server:
o-a <- master
\
b <- featureX
Client:
$ hg clone --config extension.remotebookmarks=True
o-a <- remote/master
\v
b <- remote/featureX
$ hg book
(none) # Note server bookmarks don't pollute UI
$ hg book --all
remote/master
remote/featureX
$ hg book --config bookmarks.showremotes=glob:remote/feature*
remote/featureX
# also affects which bookmarks appear in 'hg smartlog' output
Bookmark creation¶
Client:
o-a <- remote/master
\v
b <- remote/featureX
$ hg book featureX # I chose this name to explicitly conflict
o-a <- remote/master
\v
b <- remote/featureX, featureX*
$ hg book remote/foo
error: unable to create remote bookmark
Checkout remote bookmark¶
$ hg checkout remote/master
(remote/master not made active)
v
o-a <- remote/master # master is not made active
\
b <- remote/featureX, featureX
Pull¶
Server:
o-a <- master
\
b
\
c <- featureX
Client:
o-a <- remote/master
\v
b <- remote/featureX, featureX
$ hg pull
o-a <- remote/master
\v
b <- featureX # pull never moves local bookmarks
\
c <- remote/featureX
Push single bookmark¶
Client:
o-a <- remote/master
\
b <- remote/featureX
\v
d <- featureX
$ hg push -r . --to [remote/]featureX
o-a <- remote/master
\
b
\v
d <- remote/featureX, featureX
Push multiple bookmarks¶
Client:
e <- foo
/
o-a <- remote/master
\
b <- remote/featureX
\v
d <- featureX
$ hg push --to *:* --to foo:master
# *:* pushes bookmarks to the ones of the same name.
# foo:master pushes foo to master.
# foo:* or *:foo is not valid
# --to <name> only works if pushing a single head,
# and acts like <pushed-head>:<name>
e <- remote/master, foo
/
o-a
\
b
\v
d <- remote/featureX, featureX
# maybe allow tracking to be defined in .hg/hgrc
$ hg push --config bookmarks.remotemap.foo=master
$ hg push --config bookmarks.remotemap.*=*
Pull from multiple sources¶
Client:
o-a <- remote/master
\
b <- remote/featureX
$ hg pull ssh://somehost//somepath/repo
o-a <- remote/master
\
b <- remote/featureX # no change
\
c
Alternatively:
$ hg pull crew --config paths.crew=ssh://...
o-a <- remote/master
\
b <- remote/foo
\
c <- remote/foo@crew
Differences From Git¶
- no default ‘master’. Avoids ‘origin/master vs master’ confusion.
- no tracking branches (sorta). Avoids ever requiring configuring the upstream (like git pull requires).
- ‘remote’ instead of ‘origin’. More descriptive.
Open Issues¶
- What happens to the remote/bookmarks if the commit is rebased in the local repo? Does it disappear? Shouldn’t happen too often because of phases.
- No local @ by default means hg clone checkout needs to checkout to @default instead
- don’t allow writable operations on remote bookmarks locally
- store as remote-reference/pointers(?), not as bookmarks. So we could store remote branch ‘heads’ etc as well
- don’t do multiple bookmarks at once via –to (yet). If pushing, auto sync bookmarks that have the same name on the server
- how does it collide with divergent bookmark markers
- how does bookmark deletion propogate?
Alternative approach from dsop: making bookmarks a tuple (name, namespace).
BC Breakages¶
- local bookmarks will no longer sync
- bookmark divergence will not act the same (though we could make it appear to by showing remote bookmarks)
- hg push -B master might delete master on the server since you don’t have a local master
- ‘hg update remote/stable && hg pull && hg update’ won’t take you to stable. It will take you to tip
Discussion¶
- –to vs –as vs –dest vs ...
- {namespace}::{name} vs {name}@{namespace} vs {namespace}/{name} vs remote/{name}[@path]
- remote vs default
- tracking branch heads using the same mechanisms
- reference vs pointer vs name vs ...
- Bookmarks bikeshed