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